Skip to content

Commit

Permalink
fs/squashfs: Only use export table if available
Browse files Browse the repository at this point in the history
For a squashfs filesystem, the fragment table is followed by
the following tables: NFS export table, ID table, xattr table.

The export and xattr tables are both completely optional, but
the ID table is mandatory. The Linux implementation refuses to
mount the image if the ID table is missing. Tables that are no
present have their location in the super block set
to 0xFFFFFFFFFFFFFFFF.

The u-boot implementation previously assumed that it can always
rely on the export table location as an upper bound for the fragment
table, trying (and failing) to read past filesystem bounds if it
is not present.

This patch changes the driver to use the ID table instead and only
use the export table location if it lies between the two.

Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
  • Loading branch information
AgentD authored and trini committed Jan 11, 2023
1 parent f08dcd9 commit bf48dde
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions fs/squashfs/sqfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ static int sqfs_calc_n_blks(__le64 start, __le64 end, u64 *offset)
static int sqfs_frag_lookup(u32 inode_fragment_index,
struct squashfs_fragment_block_entry *e)
{
u64 start, n_blks, src_len, table_offset, start_block;
u64 start, end, exp_tbl, n_blks, src_len, table_offset, start_block;
unsigned char *metadata_buffer, *metadata, *table;
struct squashfs_fragment_block_entry *entries;
struct squashfs_super_block *sblk = ctxt.sblk;
Expand All @@ -115,11 +115,17 @@ static int sqfs_frag_lookup(u32 inode_fragment_index,
if (inode_fragment_index >= get_unaligned_le32(&sblk->fragments))
return -EINVAL;

start = get_unaligned_le64(&sblk->fragment_table_start) /
ctxt.cur_dev->blksz;
start = get_unaligned_le64(&sblk->fragment_table_start);
end = get_unaligned_le64(&sblk->id_table_start);
exp_tbl = get_unaligned_le64(&sblk->export_table_start);

if (exp_tbl > start && exp_tbl < end)
end = exp_tbl;

n_blks = sqfs_calc_n_blks(sblk->fragment_table_start,
sblk->export_table_start,
&table_offset);
cpu_to_le64(end), &table_offset);

start /= ctxt.cur_dev->blksz;

/* Allocate a proper sized buffer to store the fragment index table */
table = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz);
Expand Down

0 comments on commit bf48dde

Please sign in to comment.