[PATCH] squashfs: Fix sqfsls errors when root is a ldir

Previously, if root had more than 256 files or otherwise needed to be an ldir, sqfsls would emit the error 'Inode not found.' which was caused by code in sqfs_search_dir assuming it was a regular directory inode.
Signed-off-by: Campbell Suter campbell@snapit.group ---
fs/squashfs/sqfs.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index e2d91c654c..4d7bf76fa3 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -482,13 +482,20 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list,
/* Initialize squashfs_dir_stream members */ dirs->table += SQFS_DIR_HEADER_SIZE; - dirs->size = get_unaligned_le16(&dir->file_size) - SQFS_DIR_HEADER_SIZE; + if (le16_to_cpu(dirs->i_dir.inode_type) == SQFS_DIR_TYPE) + dirs->size = get_unaligned_le16(&dir->file_size); + else + dirs->size = get_unaligned_le32(&ldir->file_size); + dirs->size -= SQFS_DIR_HEADER_SIZE; dirs->entry_count = dirs->dir_header->count + 1;
/* No path given -> root directory */ if (!strcmp(token_list[0], "/")) { dirs->table = &dirs->dir_table[offset]; - memcpy(&dirs->i_dir, dir, sizeof(*dir)); + if (le16_to_cpu(dirs->i_dir.inode_type) == SQFS_DIR_TYPE) + memcpy(&dirs->i_dir, dir, sizeof(*dir)); + else + memcpy(&dirs->i_ldir, ldir, sizeof(*ldir)); return 0; }
@@ -608,7 +615,10 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, }
dirs->table += SQFS_DIR_HEADER_SIZE; - dirs->size = get_unaligned_le16(&dir->file_size); + if (le16_to_cpu(dirs->i_dir.inode_type) == SQFS_DIR_TYPE) + dirs->size = get_unaligned_le16(&dir->file_size); + else + dirs->size = get_unaligned_le32(&ldir->file_size); dirs->entry_count = dirs->dir_header->count + 1; dirs->size -= SQFS_DIR_HEADER_SIZE; free(dirs->entry);

Hi Campbell,
campbell@snapit.group wrote on Wed, 15 Dec 2021 14:53:43 +1300:
Previously, if root had more than 256 files or otherwise needed to be an ldir, sqfsls would emit the error 'Inode not found.' which was caused by code in sqfs_search_dir assuming it was a regular directory inode.
It would be good to group your commits into series, generated automatically with git-format-patch.
Also when you send different version of patches, you need to generate them with a different version in the subject prefix with the option: -v <version>
Otherwise for this commit: Reviewed-by: Miquel Raynal miquel.raynal@bootlin.com
Signed-off-by: Campbell Suter campbell@snapit.group
fs/squashfs/sqfs.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index e2d91c654c..4d7bf76fa3 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -482,13 +482,20 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, /* Initialize squashfs_dir_stream members */ dirs->table += SQFS_DIR_HEADER_SIZE;
- dirs->size = get_unaligned_le16(&dir->file_size) - SQFS_DIR_HEADER_SIZE;
- if (le16_to_cpu(dirs->i_dir.inode_type) == SQFS_DIR_TYPE)
dirs->size = get_unaligned_le16(&dir->file_size);
- else
dirs->size = get_unaligned_le32(&ldir->file_size);
- dirs->size -= SQFS_DIR_HEADER_SIZE; dirs->entry_count = dirs->dir_header->count + 1; /* No path given -> root directory */ if (!strcmp(token_list[0], "/")) { dirs->table = &dirs->dir_table[offset];
memcpy(&dirs->i_dir, dir, sizeof(*dir));
if (le16_to_cpu(dirs->i_dir.inode_type) == SQFS_DIR_TYPE)
memcpy(&dirs->i_dir, dir, sizeof(*dir));
else
return 0; } @@ -608,7 +615,10 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, } dirs->table += SQFS_DIR_HEADER_SIZE;memcpy(&dirs->i_ldir, ldir, sizeof(*ldir));
dirs->size = get_unaligned_le16(&dir->file_size);
if (le16_to_cpu(dirs->i_dir.inode_type) == SQFS_DIR_TYPE)
dirs->size = get_unaligned_le16(&dir->file_size);
else
dirs->entry_count = dirs->dir_header->count + 1; dirs->size -= SQFS_DIR_HEADER_SIZE; free(dirs->entry);dirs->size = get_unaligned_le32(&ldir->file_size);
Thanks, Miquèl

On Wed, Dec 15, 2021 at 02:53:43PM +1300, Campbell Suter wrote:
Previously, if root had more than 256 files or otherwise needed to be an ldir, sqfsls would emit the error 'Inode not found.' which was caused by code in sqfs_search_dir assuming it was a regular directory inode.
Signed-off-by: Campbell Suter campbell@snapit.group Reviewed-by: Miquel Raynal miquel.raynal@bootlin.com
This causes one of the tests to fail as it likely needs to be updated now.
participants (3)
-
Campbell Suter
-
Miquel Raynal
-
Tom Rini