]> Pileus Git - ~andy/linux/blobdiff - fs/squashfs/id.c
Merge branch 'gpio/next' of git://git.secretlab.ca/git/linux-2.6
[~andy/linux] / fs / squashfs / id.c
index d8f32452638e192f4418ff7ffd226a27c7f373c3..a70858e0fb4457069d270f51ffd58b13d40606b4 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
@@ -66,27 +66,37 @@ int squashfs_get_id(struct super_block *sb, unsigned int index,
  * Read uncompressed id lookup table indexes from disk into memory
  */
 __le64 *squashfs_read_id_index_table(struct super_block *sb,
-                       u64 id_table_start, unsigned short no_ids)
+               u64 id_table_start, u64 next_table, unsigned short no_ids)
 {
        unsigned int length = SQUASHFS_ID_BLOCK_BYTES(no_ids);
-       __le64 *id_table;
-       int err;
+       __le64 *table;
 
        TRACE("In read_id_index_table, length %d\n", length);
 
-       /* Allocate id lookup table indexes */
-       id_table = kmalloc(length, GFP_KERNEL);
-       if (id_table == NULL) {
-               ERROR("Failed to allocate id index table\n");
-               return ERR_PTR(-ENOMEM);
-       }
+       /* Sanity check values */
+
+       /* there should always be at least one id */
+       if (no_ids == 0)
+               return ERR_PTR(-EINVAL);
+
+       /*
+        * length bytes should not extend into the next table - this check
+        * also traps instances where id_table_start is incorrectly larger
+        * than the next table start
+        */
+       if (id_table_start + length > next_table)
+               return ERR_PTR(-EINVAL);
+
+       table = squashfs_read_table(sb, id_table_start, length);
 
-       err = squashfs_read_table(sb, id_table, id_table_start, length);
-       if (err < 0) {
-               ERROR("unable to read id index table\n");
-               kfree(id_table);
-               return ERR_PTR(err);
+       /*
+        * table[0] points to the first id lookup table metadata block, this
+        * should be less than id_table_start
+        */
+       if (!IS_ERR(table) && table[0] >= id_table_start) {
+               kfree(table);
+               return ERR_PTR(-EINVAL);
        }
 
-       return id_table;
+       return table;
 }