aboutsummaryrefslogtreecommitdiffstats
path: root/fs/squashfs/fragment.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/squashfs/fragment.c')
-rw-r--r--fs/squashfs/fragment.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c
index 7eef571443c6..1516a6490bfb 100644
--- a/fs/squashfs/fragment.c
+++ b/fs/squashfs/fragment.c
@@ -2,7 +2,7 @@
2 * Squashfs - a compressed read only filesystem for Linux 2 * Squashfs - a compressed read only filesystem for Linux
3 * 3 *
4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5 * Phillip Lougher <phillip@lougher.demon.co.uk> 5 * Phillip Lougher <phillip@squashfs.org.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -71,26 +71,29 @@ int squashfs_frag_lookup(struct super_block *sb, unsigned int fragment,
71 * Read the uncompressed fragment lookup table indexes off disk into memory 71 * Read the uncompressed fragment lookup table indexes off disk into memory
72 */ 72 */
73__le64 *squashfs_read_fragment_index_table(struct super_block *sb, 73__le64 *squashfs_read_fragment_index_table(struct super_block *sb,
74 u64 fragment_table_start, unsigned int fragments) 74 u64 fragment_table_start, u64 next_table, unsigned int fragments)
75{ 75{
76 unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(fragments); 76 unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(fragments);
77 __le64 *fragment_index; 77 __le64 *table;
78 int err;
79 78
80 /* Allocate fragment lookup table indexes */ 79 /*
81 fragment_index = kmalloc(length, GFP_KERNEL); 80 * Sanity check, length bytes should not extend into the next table -
82 if (fragment_index == NULL) { 81 * this check also traps instances where fragment_table_start is
83 ERROR("Failed to allocate fragment index table\n"); 82 * incorrectly larger than the next table start
84 return ERR_PTR(-ENOMEM); 83 */
85 } 84 if (fragment_table_start + length > next_table)
85 return ERR_PTR(-EINVAL);
86
87 table = squashfs_read_table(sb, fragment_table_start, length);
86 88
87 err = squashfs_read_table(sb, fragment_index, fragment_table_start, 89 /*
88 length); 90 * table[0] points to the first fragment table metadata block, this
89 if (err < 0) { 91 * should be less than fragment_table_start
90 ERROR("unable to read fragment index table\n"); 92 */
91 kfree(fragment_index); 93 if (!IS_ERR(table) && table[0] >= fragment_table_start) {
92 return ERR_PTR(err); 94 kfree(table);
95 return ERR_PTR(-EINVAL);
93 } 96 }
94 97
95 return fragment_index; 98 return table;
96} 99}