Commit bc9bc72e authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus

* git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus:
  Squashfs: update email address
  Squashfs: add extra sanity checks at mount time
  Squashfs: add sanity checks to fragment reading at mount time
  Squashfs: add sanity checks to lookup table reading at mount time
  Squashfs: add sanity checks to id reading at mount time
  Squashfs: add sanity checks to xattr reading at mount time
  Squashfs: reverse order of filesystem table reading
  Squashfs: move table allocation into squashfs_read_table()
parents 968d803c d7f2ff67
...@@ -6001,7 +6001,7 @@ F: Documentation/filesystems/spufs.txt ...@@ -6001,7 +6001,7 @@ F: Documentation/filesystems/spufs.txt
F: arch/powerpc/platforms/cell/spufs/ F: arch/powerpc/platforms/cell/spufs/
SQUASHFS FILE SYSTEM SQUASHFS FILE SYSTEM
M: Phillip Lougher <phillip@lougher.demon.co.uk> M: Phillip Lougher <phillip@squashfs.org.uk>
L: squashfs-devel@lists.sourceforge.net (subscribers-only) L: squashfs-devel@lists.sourceforge.net (subscribers-only)
W: http://squashfs.org.uk W: http://squashfs.org.uk
S: Maintained S: Maintained
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -393,19 +393,36 @@ struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *sb, ...@@ -393,19 +393,36 @@ struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *sb,
/* /*
* Read a filesystem table (uncompressed sequence of bytes) from disk * Read a filesystem table (uncompressed sequence of bytes) from disk
*/ */
int squashfs_read_table(struct super_block *sb, void *buffer, u64 block, void *squashfs_read_table(struct super_block *sb, u64 block, int length)
int length)
{ {
int pages = (length + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; int pages = (length + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
int i, res; int i, res;
void **data = kcalloc(pages, sizeof(void *), GFP_KERNEL); void *table, *buffer, **data;
if (data == NULL)
return -ENOMEM; table = buffer = kmalloc(length, GFP_KERNEL);
if (table == NULL)
return ERR_PTR(-ENOMEM);
data = kcalloc(pages, sizeof(void *), GFP_KERNEL);
if (data == NULL) {
res = -ENOMEM;
goto failed;
}
for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE) for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE)
data[i] = buffer; data[i] = buffer;
res = squashfs_read_data(sb, data, block, length | res = squashfs_read_data(sb, data, block, length |
SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages); SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages);
kfree(data); kfree(data);
return res;
if (res < 0)
goto failed;
return table;
failed:
kfree(table);
return ERR_PTR(res);
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
* Phillip Lougher <phillip@lougher.demon.co.uk> * Phillip Lougher <phillip@squashfs.org.uk>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
* Phillip Lougher <phillip@lougher.demon.co.uk> * Phillip Lougher <phillip@squashfs.org.uk>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -121,30 +121,38 @@ static struct dentry *squashfs_get_parent(struct dentry *child) ...@@ -121,30 +121,38 @@ static struct dentry *squashfs_get_parent(struct dentry *child)
* Read uncompressed inode lookup table indexes off disk into memory * Read uncompressed inode lookup table indexes off disk into memory
*/ */
__le64 *squashfs_read_inode_lookup_table(struct super_block *sb, __le64 *squashfs_read_inode_lookup_table(struct super_block *sb,
u64 lookup_table_start, unsigned int inodes) u64 lookup_table_start, u64 next_table, unsigned int inodes)
{ {
unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(inodes); unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(inodes);
__le64 *inode_lookup_table; __le64 *table;
int err;
TRACE("In read_inode_lookup_table, length %d\n", length); TRACE("In read_inode_lookup_table, length %d\n", length);
/* Allocate inode lookup table indexes */ /* Sanity check values */
inode_lookup_table = kmalloc(length, GFP_KERNEL);
if (inode_lookup_table == NULL) {
ERROR("Failed to allocate inode lookup table\n");
return ERR_PTR(-ENOMEM);
}
err = squashfs_read_table(sb, inode_lookup_table, lookup_table_start, /* there should always be at least one inode */
length); if (inodes == 0)
if (err < 0) { return ERR_PTR(-EINVAL);
ERROR("unable to read inode lookup table\n");
kfree(inode_lookup_table); /* length bytes should not extend into the next table - this check
return ERR_PTR(err); * also traps instances where lookup_table_start is incorrectly larger
* than the next table start
*/
if (lookup_table_start + length > next_table)
return ERR_PTR(-EINVAL);
table = squashfs_read_table(sb, lookup_table_start, length);
/*
* table[0] points to the first inode lookup table metadata block,
* this should be less than lookup_table_start
*/
if (!IS_ERR(table) && table[0] >= lookup_table_start) {
kfree(table);
return ERR_PTR(-EINVAL);
} }
return inode_lookup_table; return table;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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,26 +71,29 @@ int squashfs_frag_lookup(struct super_block *sb, unsigned int fragment,
* Read the uncompressed fragment lookup table indexes off disk into memory * Read the uncompressed fragment lookup table indexes off disk into memory
*/ */
__le64 *squashfs_read_fragment_index_table(struct super_block *sb, __le64 *squashfs_read_fragment_index_table(struct super_block *sb,
u64 fragment_table_start, unsigned int fragments) u64 fragment_table_start, u64 next_table, unsigned int fragments)
{ {
unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(fragments); unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(fragments);
__le64 *fragment_index; __le64 *table;
int err;
/* Allocate fragment lookup table indexes */ /*
fragment_index = kmalloc(length, GFP_KERNEL); * Sanity check, length bytes should not extend into the next table -
if (fragment_index == NULL) { * this check also traps instances where fragment_table_start is
ERROR("Failed to allocate fragment index table\n"); * incorrectly larger than the next table start
return ERR_PTR(-ENOMEM); */
} if (fragment_table_start + length > next_table)
return ERR_PTR(-EINVAL);
err = squashfs_read_table(sb, fragment_index, fragment_table_start, table = squashfs_read_table(sb, fragment_table_start, length);
length);
if (err < 0) { /*
ERROR("unable to read fragment index table\n"); * table[0] points to the first fragment table metadata block, this
kfree(fragment_index); * should be less than fragment_table_start
return ERR_PTR(err); */
if (!IS_ERR(table) && table[0] >= fragment_table_start) {
kfree(table);
return ERR_PTR(-EINVAL);
} }
return fragment_index; return table;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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, ...@@ -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 * Read uncompressed id lookup table indexes from disk into memory
*/ */
__le64 *squashfs_read_id_index_table(struct super_block *sb, __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); unsigned int length = SQUASHFS_ID_BLOCK_BYTES(no_ids);
__le64 *id_table; __le64 *table;
int err;
TRACE("In read_id_index_table, length %d\n", length); TRACE("In read_id_index_table, length %d\n", length);
/* Allocate id lookup table indexes */ /* Sanity check values */
id_table = kmalloc(length, GFP_KERNEL);
if (id_table == NULL) {
ERROR("Failed to allocate id index table\n");
return ERR_PTR(-ENOMEM);
}
err = squashfs_read_table(sb, id_table, id_table_start, length); /* there should always be at least one id */
if (err < 0) { if (no_ids == 0)
ERROR("unable to read id index table\n"); return ERR_PTR(-EINVAL);
kfree(id_table);
return ERR_PTR(err); /*
* 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);
/*
* 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;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -44,24 +44,24 @@ extern struct squashfs_cache_entry *squashfs_get_fragment(struct super_block *, ...@@ -44,24 +44,24 @@ extern struct squashfs_cache_entry *squashfs_get_fragment(struct super_block *,
u64, int); u64, int);
extern struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *, extern struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *,
u64, int); u64, int);
extern int squashfs_read_table(struct super_block *, void *, u64, int); extern void *squashfs_read_table(struct super_block *, u64, int);
/* decompressor.c */ /* decompressor.c */
extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int); extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int);
extern void *squashfs_decompressor_init(struct super_block *, unsigned short); extern void *squashfs_decompressor_init(struct super_block *, unsigned short);
/* export.c */ /* export.c */
extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, u64,
unsigned int); unsigned int);
/* fragment.c */ /* fragment.c */
extern int squashfs_frag_lookup(struct super_block *, unsigned int, u64 *); extern int squashfs_frag_lookup(struct super_block *, unsigned int, u64 *);
extern __le64 *squashfs_read_fragment_index_table(struct super_block *, extern __le64 *squashfs_read_fragment_index_table(struct super_block *,
u64, unsigned int); u64, u64, unsigned int);
/* id.c */ /* id.c */
extern int squashfs_get_id(struct super_block *, unsigned int, unsigned int *); extern int squashfs_get_id(struct super_block *, unsigned int, unsigned int *);
extern __le64 *squashfs_read_id_index_table(struct super_block *, u64, extern __le64 *squashfs_read_id_index_table(struct super_block *, u64, u64,
unsigned short); unsigned short);
/* inode.c */ /* inode.c */
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Squashfs * Squashfs
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Squashfs * Squashfs
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Squashfs * Squashfs
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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) ...@@ -83,7 +83,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
long long root_inode; long long root_inode;
unsigned short flags; unsigned short flags;
unsigned int fragments; unsigned int fragments;
u64 lookup_table_start, xattr_id_table_start; u64 lookup_table_start, xattr_id_table_start, next_table;
int err; int err;
TRACE("Entered squashfs_fill_superblock\n"); TRACE("Entered squashfs_fill_superblock\n");
...@@ -95,12 +95,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -95,12 +95,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
} }
msblk = sb->s_fs_info; msblk = sb->s_fs_info;
sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
if (sblk == NULL) {
ERROR("Failed to allocate squashfs_super_block\n");
goto failure;
}
msblk->devblksize = sb_min_blocksize(sb, BLOCK_SIZE); msblk->devblksize = sb_min_blocksize(sb, BLOCK_SIZE);
msblk->devblksize_log2 = ffz(~msblk->devblksize); msblk->devblksize_log2 = ffz(~msblk->devblksize);
...@@ -114,10 +108,12 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -114,10 +108,12 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
* of bytes_used) we need to set it to an initial sensible dummy value * of bytes_used) we need to set it to an initial sensible dummy value
*/ */
msblk->bytes_used = sizeof(*sblk); msblk->bytes_used = sizeof(*sblk);
err = squashfs_read_table(sb, sblk, SQUASHFS_START, sizeof(*sblk)); sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk));
if (err < 0) { if (IS_ERR(sblk)) {
ERROR("unable to read squashfs_super_block\n"); ERROR("unable to read squashfs_super_block\n");
err = PTR_ERR(sblk);
sblk = NULL;
goto failed_mount; goto failed_mount;
} }
...@@ -218,18 +214,61 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -218,18 +214,61 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
goto failed_mount; goto failed_mount;
} }
/* 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) {
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,
xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
if (IS_ERR(msblk->xattr_id_table)) {
ERROR("unable to read xattr id index table\n");
err = PTR_ERR(msblk->xattr_id_table);
msblk->xattr_id_table = NULL;
if (err != -ENOTSUPP)
goto failed_mount;
}
next_table = msblk->xattr_table;
allocate_id_index_table:
/* Allocate and read id index table */ /* Allocate and read id index table */
msblk->id_table = squashfs_read_id_index_table(sb, 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)) { if (IS_ERR(msblk->id_table)) {
ERROR("unable to read id index table\n");
err = PTR_ERR(msblk->id_table); err = PTR_ERR(msblk->id_table);
msblk->id_table = NULL; msblk->id_table = NULL;
goto failed_mount; goto failed_mount;
} }
next_table = msblk->id_table[0];
/* Handle inode lookup table */
lookup_table_start = le64_to_cpu(sblk->lookup_table_start);
if (lookup_table_start == SQUASHFS_INVALID_BLK)
goto handle_fragments;
/* Allocate and read inode lookup table */
msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
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); fragments = le32_to_cpu(sblk->fragments);
if (fragments == 0) if (fragments == 0)
goto allocate_lookup_table; goto check_directory_table;
msblk->fragment_cache = squashfs_cache_init("fragment", msblk->fragment_cache = squashfs_cache_init("fragment",
SQUASHFS_CACHED_FRAGMENTS, msblk->block_size); SQUASHFS_CACHED_FRAGMENTS, msblk->block_size);
...@@ -240,45 +279,29 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -240,45 +279,29 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
/* Allocate and read fragment index table */ /* Allocate and read fragment index table */
msblk->fragment_index = squashfs_read_fragment_index_table(sb, 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)) { if (IS_ERR(msblk->fragment_index)) {
ERROR("unable to read fragment index table\n");
err = PTR_ERR(msblk->fragment_index); err = PTR_ERR(msblk->fragment_index);
msblk->fragment_index = NULL; msblk->fragment_index = NULL;
goto failed_mount; goto failed_mount;
} }
next_table = msblk->fragment_index[0];
allocate_lookup_table: check_directory_table:
lookup_table_start = le64_to_cpu(sblk->lookup_table_start); /* Sanity check directory_table */
if (lookup_table_start == SQUASHFS_INVALID_BLK) if (msblk->directory_table >= next_table) {
goto allocate_xattr_table; err = -EINVAL;
/* Allocate and read inode lookup table */
msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
lookup_table_start, msblk->inodes);
if (IS_ERR(msblk->inode_lookup_table)) {
err = PTR_ERR(msblk->inode_lookup_table);
msblk->inode_lookup_table = NULL;
goto failed_mount; goto failed_mount;
} }
sb->s_export_op = &squashfs_export_ops; /* Sanity check inode_table */
if (msblk->inode_table >= msblk->directory_table) {
allocate_xattr_table: err = -EINVAL;
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)
goto allocate_root;
/* Allocate and read xattr id lookup table */
msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
if (IS_ERR(msblk->xattr_id_table)) {
err = PTR_ERR(msblk->xattr_id_table);
msblk->xattr_id_table = NULL;
if (err != -ENOTSUPP)
goto failed_mount; goto failed_mount;
} }
allocate_root:
/* allocate root */
root = new_inode(sb); root = new_inode(sb);
if (!root) { if (!root) {
err = -ENOMEM; err = -ENOMEM;
...@@ -318,11 +341,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -318,11 +341,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
kfree(sblk); kfree(sblk);
return err; return err;
failure:
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
return -ENOMEM;
} }
...@@ -475,5 +493,5 @@ static const struct super_operations squashfs_super_ops = { ...@@ -475,5 +493,5 @@ static const struct super_operations squashfs_super_ops = {
module_init(init_squashfs_fs); module_init(init_squashfs_fs);
module_exit(exit_squashfs_fs); module_exit(exit_squashfs_fs);
MODULE_DESCRIPTION("squashfs 4.0, a compressed read-only filesystem"); 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"); MODULE_LICENSE("GPL");
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2010 * Copyright (c) 2010
* Phillip Lougher <phillip@lougher.demon.co.uk> * Phillip Lougher <phillip@squashfs.org.uk>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2010 * Copyright (c) 2010
* Phillip Lougher <phillip@lougher.demon.co.uk> * Phillip Lougher <phillip@squashfs.org.uk>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -31,6 +31,7 @@ static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb, ...@@ -31,6 +31,7 @@ static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb,
u64 start, u64 *xattr_table_start, int *xattr_ids) u64 start, u64 *xattr_table_start, int *xattr_ids)
{ {
ERROR("Xattrs in filesystem, these will be ignored\n"); ERROR("Xattrs in filesystem, these will be ignored\n");
*xattr_table_start = start;
return ERR_PTR(-ENOTSUPP); return ERR_PTR(-ENOTSUPP);
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2010 * Copyright (c) 2010
* Phillip Lougher <phillip@lougher.demon.co.uk> * Phillip Lougher <phillip@squashfs.org.uk>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -67,34 +67,29 @@ __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 start, ...@@ -67,34 +67,29 @@ __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 start,
u64 *xattr_table_start, int *xattr_ids) u64 *xattr_table_start, int *xattr_ids)
{ {
unsigned int len; unsigned int len;
__le64 *xid_table; struct squashfs_xattr_id_table *id_table;
struct squashfs_xattr_id_table id_table;
int err; id_table = squashfs_read_table(sb, start, sizeof(*id_table));
if (IS_ERR(id_table))
return (__le64 *) id_table;
*xattr_table_start = le64_to_cpu(id_table->xattr_table_start);
*xattr_ids = le32_to_cpu(id_table->xattr_ids);
kfree(id_table);
/* Sanity check values */
/* there is always at least one xattr id */
if (*xattr_ids == 0)
return ERR_PTR(-EINVAL);
/* xattr_table should be less than start */
if (*xattr_table_start >= start)
return ERR_PTR(-EINVAL);
err = squashfs_read_table(sb, &id_table, start, sizeof(id_table));
if (err < 0) {
ERROR("unable to read xattr id table\n");
return ERR_PTR(err);
}
*xattr_table_start = le64_to_cpu(id_table.xattr_table_start);
*xattr_ids = le32_to_cpu(id_table.xattr_ids);
len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids); len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids);
TRACE("In read_xattr_index_table, length %d\n", len); TRACE("In read_xattr_index_table, length %d\n", len);
/* Allocate xattr id lookup table indexes */ return squashfs_read_table(sb, start + sizeof(*id_table), len);
xid_table = kmalloc(len, GFP_KERNEL);
if (xid_table == NULL) {
ERROR("Failed to allocate xattr id index table\n");
return ERR_PTR(-ENOMEM);
}
err = squashfs_read_table(sb, xid_table, start + sizeof(id_table), len);
if (err < 0) {
ERROR("unable to read xattr id index table\n");
kfree(xid_table);
return ERR_PTR(err);
}
return xid_table;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
* Phillip Lougher <phillip@lougher.demon.co.uk> * Phillip Lougher <phillip@squashfs.org.uk>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Squashfs - a compressed read only filesystem for Linux * Squashfs - a compressed read only filesystem for Linux
* *
* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
* Phillip Lougher <phillip@lougher.demon.co.uk> * Phillip Lougher <phillip@squashfs.org.uk>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment