diff mbox series

squashfs: Fix sqfsls errors when root is a ldir

Message ID 2c0316b0-8f40-550b-d1cf-a72e812d55a4@snapit.group
State Changes Requested
Delegated to: Tom Rini
Headers show
Series squashfs: Fix sqfsls errors when root is a ldir | expand

Commit Message

Campbell Suter Dec. 15, 2021, 1:53 a.m. UTC
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(-)

Comments

Miquel Raynal Dec. 15, 2021, 11:20 a.m. UTC | #1
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
> +			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);


Thanks,
Miquèl
Tom Rini Jan. 28, 2022, 11:36 p.m. UTC | #2
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.
diff mbox series

Patch

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);