Merge git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus
[pandora-kernel.git] / fs / squashfs / super.c
index 401cc8c..6f26abe 100644 (file)
@@ -2,7 +2,7 @@
  * Squashfs - a compressed read only filesystem for Linux
  *
  * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- * Phillip Lougher <phillip@lougher.demon.co.uk>
+ * Phillip Lougher <phillip@squashfs.org.uk>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -83,7 +83,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
        long long root_inode;
        unsigned short flags;
        unsigned int fragments;
-       u64 lookup_table_start, xattr_id_table_start;
+       u64 lookup_table_start, xattr_id_table_start, next_table;
        int err;
 
        TRACE("Entered squashfs_fill_superblock\n");
@@ -217,8 +217,10 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
        /* Handle xattrs */
        sb->s_xattr = squashfs_xattr_handlers;
        xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start);
-       if (xattr_id_table_start == SQUASHFS_INVALID_BLK)
+       if (xattr_id_table_start == SQUASHFS_INVALID_BLK) {
+               next_table = msblk->bytes_used;
                goto allocate_id_index_table;
+       }
 
        /* Allocate and read xattr id lookup table */
        msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
@@ -230,17 +232,20 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
                if (err != -ENOTSUPP)
                        goto failed_mount;
        }
+       next_table = msblk->xattr_table;
 
 allocate_id_index_table:
        /* Allocate and read id index table */
        msblk->id_table = squashfs_read_id_index_table(sb,
-               le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids));
+               le64_to_cpu(sblk->id_table_start), next_table,
+               le16_to_cpu(sblk->no_ids));
        if (IS_ERR(msblk->id_table)) {
                ERROR("unable to read id index table\n");
                err = PTR_ERR(msblk->id_table);
                msblk->id_table = NULL;
                goto failed_mount;
        }
+       next_table = msblk->id_table[0];
 
        /* Handle inode lookup table */
        lookup_table_start = le64_to_cpu(sblk->lookup_table_start);
@@ -249,20 +254,21 @@ allocate_id_index_table:
 
        /* Allocate and read inode lookup table */
        msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
-               lookup_table_start, msblk->inodes);
+               lookup_table_start, next_table, msblk->inodes);
        if (IS_ERR(msblk->inode_lookup_table)) {
                ERROR("unable to read inode lookup table\n");
                err = PTR_ERR(msblk->inode_lookup_table);
                msblk->inode_lookup_table = NULL;
                goto failed_mount;
        }
+       next_table = msblk->inode_lookup_table[0];
 
        sb->s_export_op = &squashfs_export_ops;
 
 handle_fragments:
        fragments = le32_to_cpu(sblk->fragments);
        if (fragments == 0)
-               goto allocate_root;
+               goto check_directory_table;
 
        msblk->fragment_cache = squashfs_cache_init("fragment",
                SQUASHFS_CACHED_FRAGMENTS, msblk->block_size);
@@ -273,15 +279,29 @@ handle_fragments:
 
        /* Allocate and read fragment index table */
        msblk->fragment_index = squashfs_read_fragment_index_table(sb,
-               le64_to_cpu(sblk->fragment_table_start), fragments);
+               le64_to_cpu(sblk->fragment_table_start), next_table, fragments);
        if (IS_ERR(msblk->fragment_index)) {
                ERROR("unable to read fragment index table\n");
                err = PTR_ERR(msblk->fragment_index);
                msblk->fragment_index = NULL;
                goto failed_mount;
        }
+       next_table = msblk->fragment_index[0];
+
+check_directory_table:
+       /* Sanity check directory_table */
+       if (msblk->directory_table >= next_table) {
+               err = -EINVAL;
+               goto failed_mount;
+       }
+
+       /* Sanity check inode_table */
+       if (msblk->inode_table >= msblk->directory_table) {
+               err = -EINVAL;
+               goto failed_mount;
+       }
 
-allocate_root:
+       /* allocate root */
        root = new_inode(sb);
        if (!root) {
                err = -ENOMEM;
@@ -473,5 +493,5 @@ static const struct super_operations squashfs_super_ops = {
 module_init(init_squashfs_fs);
 module_exit(exit_squashfs_fs);
 MODULE_DESCRIPTION("squashfs 4.0, a compressed read-only filesystem");
-MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>");
+MODULE_AUTHOR("Phillip Lougher <phillip@squashfs.org.uk>");
 MODULE_LICENSE("GPL");