A couple of minor additional sanity check patches for corrupted information,
and some fixes. Apart from that there's a minor loop optimisation. These sanity checks mainly exist to trap maliciously corrupted filesystems either through using a deliberately modified mksquashfs, or where the user has deliberately chosen to generate uncompressed metadata and then corrupted it. Normally metadata in Squashfs filesystems is compressed, which means corruption (either accidental or malicious) is detected when trying to decompress the metadata. So corrupted data does not normally get as far as the code paths in question here. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJSMJLmAAoJEJAch/D1fbHUXSUP/1kCIu6EgpFHtrgjiaOV2RZh WiQ+Hxnn6F6f6Zvt3GKwCrj0nmIiGxhPeOrg8EXt26UYlFQi2NBzqHU/kcrHwz/H re2BObRb50FdUb/MfqtIiyXPmjwb0AlY+XuaG8+xnc6snoZ9076T6qSEeoqvehU5 cVqgTsFoGNpU+4ymtXUe2bgGsSZN+o0zPdqiM49b9zfHCgbe66fLrI7NTTiygdg5 vE9mAq0WGxSv6x7SvQyl2+PIZyBpZkYth7kJ9tBk6iEXFIhCy4EGHff/U08WaT9E sLMKpy65E2rSxr9L5TXXquKinyWFhlx6yhBYzkJ1TKM8FmGSclmixWzQVhI+5S1B 1IJR4W/Nq8cfiBaGTOGLtGywuvYAFRuAgjZyodiIgCU2QTxhu5/7h5HZx8ZpjO0x wiEuL+6iup8tzPi0x+2XoFKZpV5wi8ozKZ9hiE2dQe2ckTSKYAxUDh0dez+ZiI/W J1dyvwn8aB4PQMBSRM7g7PKdGrnb1ZaFzdUt9iloqX1BXmE2ZSG1sHKnBL8Lcrmq dRylQ1hzr3o+xVJLZKB+fWlOWZe7YiQM0uMeAXtPyT3gumlO3tqVHOxvHo4DyHx/ 1YmNBL0nSjZJMwG5TCLiV//s/qFXV4d8YN9KngIkliEgGHRvRuIWXHI37WaPt9k5 OV6uNKK4sy2roTjc8pL/ =r/lz -----END PGP SIGNATURE----- Merge tag 'squashfs-updates' of git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-next Pull squashfs updates from Phillip Lougher: "A couple of minor additional sanity check patches for corrupted information, and some fixes. Apart from that there's a minor loop optimisation. These sanity checks mainly exist to trap maliciously corrupted filesystems either through using a deliberately modified mksquashfs, or where the user has deliberately chosen to generate uncompressed metadata and then corrupted it. Normally metadata in Squashfs filesystems is compressed, which means corruption (either accidental or malicious) is detected when trying to decompress the metadata. So corrupted data does not normally get as far as the code paths in question here" * tag 'squashfs-updates' of git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-next: Squashfs: add corruption check for type in squashfs_readdir() Squashfs: add corruption check in get_dir_index_using_offset() Squashfs: fix corruption checks in squashfs_readdir() Squashfs: fix corruption checks in squashfs_lookup() Squashfs: fix corruption check in get_dir_index_using_name() Squashfs: Optimized uncompressed buffer loop Squashfs: sanity check information from disk
This commit is contained in:
commit
53bf710832
|
@ -167,17 +167,14 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
|
|||
/*
|
||||
* Block is uncompressed.
|
||||
*/
|
||||
int i, in, pg_offset = 0;
|
||||
|
||||
for (i = 0; i < b; i++) {
|
||||
wait_on_buffer(bh[i]);
|
||||
if (!buffer_uptodate(bh[i]))
|
||||
goto block_release;
|
||||
}
|
||||
int in, pg_offset = 0;
|
||||
|
||||
for (bytes = length; k < b; k++) {
|
||||
in = min(bytes, msblk->devblksize - offset);
|
||||
bytes -= in;
|
||||
wait_on_buffer(bh[k]);
|
||||
if (!buffer_uptodate(bh[k]))
|
||||
goto block_release;
|
||||
while (in) {
|
||||
if (pg_offset == PAGE_CACHE_SIZE) {
|
||||
page++;
|
||||
|
|
|
@ -54,6 +54,7 @@ static int get_dir_index_using_offset(struct super_block *sb,
|
|||
{
|
||||
struct squashfs_sb_info *msblk = sb->s_fs_info;
|
||||
int err, i, index, length = 0;
|
||||
unsigned int size;
|
||||
struct squashfs_dir_index dir_index;
|
||||
|
||||
TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %lld\n",
|
||||
|
@ -81,8 +82,14 @@ static int get_dir_index_using_offset(struct super_block *sb,
|
|||
*/
|
||||
break;
|
||||
|
||||
size = le32_to_cpu(dir_index.size) + 1;
|
||||
|
||||
/* size should never be larger than SQUASHFS_NAME_LEN */
|
||||
if (size > SQUASHFS_NAME_LEN)
|
||||
break;
|
||||
|
||||
err = squashfs_read_metadata(sb, NULL, &index_start,
|
||||
&index_offset, le32_to_cpu(dir_index.size) + 1);
|
||||
&index_offset, size);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
|
@ -105,9 +112,8 @@ static int squashfs_readdir(struct file *file, struct dir_context *ctx)
|
|||
struct inode *inode = file_inode(file);
|
||||
struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
|
||||
u64 block = squashfs_i(inode)->start + msblk->directory_table;
|
||||
int offset = squashfs_i(inode)->offset, length, dir_count, size,
|
||||
type, err;
|
||||
unsigned int inode_number;
|
||||
int offset = squashfs_i(inode)->offset, length, err;
|
||||
unsigned int inode_number, dir_count, size, type;
|
||||
struct squashfs_dir_header dirh;
|
||||
struct squashfs_dir_entry *dire;
|
||||
|
||||
|
@ -200,6 +206,9 @@ static int squashfs_readdir(struct file *file, struct dir_context *ctx)
|
|||
((short) le16_to_cpu(dire->inode_number));
|
||||
type = le16_to_cpu(dire->type);
|
||||
|
||||
if (type > SQUASHFS_MAX_DIR_TYPE)
|
||||
goto failed_read;
|
||||
|
||||
if (!dir_emit(ctx, dire->name, size,
|
||||
inode_number,
|
||||
squashfs_filetype_table[type]))
|
||||
|
|
|
@ -79,7 +79,8 @@ static int get_dir_index_using_name(struct super_block *sb,
|
|||
int len)
|
||||
{
|
||||
struct squashfs_sb_info *msblk = sb->s_fs_info;
|
||||
int i, size, length = 0, err;
|
||||
int i, length = 0, err;
|
||||
unsigned int size;
|
||||
struct squashfs_dir_index *index;
|
||||
char *str;
|
||||
|
||||
|
@ -103,6 +104,8 @@ static int get_dir_index_using_name(struct super_block *sb,
|
|||
|
||||
|
||||
size = le32_to_cpu(index->size) + 1;
|
||||
if (size > SQUASHFS_NAME_LEN)
|
||||
break;
|
||||
|
||||
err = squashfs_read_metadata(sb, index->name, &index_start,
|
||||
&index_offset, size);
|
||||
|
@ -144,7 +147,8 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry,
|
|||
struct squashfs_dir_entry *dire;
|
||||
u64 block = squashfs_i(dir)->start + msblk->directory_table;
|
||||
int offset = squashfs_i(dir)->offset;
|
||||
int err, length, dir_count, size;
|
||||
int err, length;
|
||||
unsigned int dir_count, size;
|
||||
|
||||
TRACE("Entered squashfs_lookup [%llx:%x]\n", block, offset);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
#define SQUASHFS_COMP_OPTS(flags) SQUASHFS_BIT(flags, \
|
||||
SQUASHFS_COMP_OPT)
|
||||
|
||||
/* Max number of types and file types */
|
||||
/* Inode types including extended types */
|
||||
#define SQUASHFS_DIR_TYPE 1
|
||||
#define SQUASHFS_REG_TYPE 2
|
||||
#define SQUASHFS_SYMLINK_TYPE 3
|
||||
|
@ -103,6 +103,9 @@
|
|||
#define SQUASHFS_LFIFO_TYPE 13
|
||||
#define SQUASHFS_LSOCKET_TYPE 14
|
||||
|
||||
/* Max type value stored in directory entry */
|
||||
#define SQUASHFS_MAX_DIR_TYPE 7
|
||||
|
||||
/* Xattr types */
|
||||
#define SQUASHFS_XATTR_USER 0
|
||||
#define SQUASHFS_XATTR_TRUSTED 1
|
||||
|
|
Loading…
Reference in New Issue