From 2a0a577aad4337eab24812911df248a9a8c4ebd0 Mon Sep 17 00:00:00 2001 From: Hoyeonjiki Kim Date: Tue, 17 Nov 2020 12:32:08 +0900 Subject: [PATCH 01/39] env: mmc: Correct partition comparison in mmc_offset_try_partition The function mmc_offset_try_partition searches the MMC partition for locating environment data, by comparing the partition names with config "u-boot,mmc-env-parition". However, it only compares the first word-size bytes (size of 'const char *'), which may make the function to find unintended partition. Correct the function not to partially compare the partition name with config "u-boot,mmc-env-partition". Fixes: c9e87ba66540 ("env: Save environment at the end of an MMC partition") Signed-off-by: Hoyeonjiki Kim Reviewed-by: Wolfgang Denk --- env/mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env/mmc.c b/env/mmc.c index 4e67180b23..ee376c3e0c 100644 --- a/env/mmc.c +++ b/env/mmc.c @@ -42,7 +42,7 @@ static inline int mmc_offset_try_partition(const char *str, int copy, s64 *val) if (ret < 0) return ret; - if (!strncmp((const char *)info.name, str, sizeof(str))) + if (!strncmp((const char *)info.name, str, sizeof(info.name))) break; } From 5a7885cca50fbc90c52839c4bef0a2cf316ad4fe Mon Sep 17 00:00:00 2001 From: Arnaud Aujon Chevallier Date: Sun, 15 Nov 2020 12:54:10 +0100 Subject: [PATCH 02/39] arm: vexpress: don't reset flags in board_init to avoid losing previous ones Re-submitted because of missing description and signed-off. flags reset in board_init caused bugs when executing command like editenv because the reallocated flag was lost. Tested-by: Michael Opdenacker Signed-off-by: Arnaud Aujon Chevallier --- board/armltd/vexpress/vexpress_common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/board/armltd/vexpress/vexpress_common.c b/board/armltd/vexpress/vexpress_common.c index 70f6cd80d5..8fea8ff352 100644 --- a/board/armltd/vexpress/vexpress_common.c +++ b/board/armltd/vexpress/vexpress_common.c @@ -55,7 +55,6 @@ int board_init(void) { gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; gd->bd->bi_arch_number = MACH_TYPE_VEXPRESS; - gd->flags = 0; icache_enable(); flash__init(); From cc34f04efd63dfdd31ef2dbfd46c15fb485b2888 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Fri, 13 Nov 2020 16:37:46 +0100 Subject: [PATCH 03/39] tools: image-host.c: use random instead of rand According to the manpage of rand, it is recommended to use random instead of rand. This commit updates the function get_random_data to use random. Reported-by: Coverity (CID: 312953) Signed-off-by: Philippe Reynes Reviewed-by: Simon Glass --- tools/image-host.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/image-host.c b/tools/image-host.c index 7cef78eab8..5e1dec2338 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -339,10 +339,10 @@ static int get_random_data(void *data, int size) goto out; } - srand(date.tv_nsec); + srandom(date.tv_nsec); for (i = 0; i < size; i++) { - *tmp = rand() & 0xff; + *tmp = random() & 0xff; tmp++; } From 26927493161e16d90101c8a6abae551597d46e72 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Fri, 13 Nov 2020 15:15:18 +0100 Subject: [PATCH 04/39] tools: image-host.c: use correct variable for strerrno In the function get_random_data, strerrno is called with the variable ret (which is the return of the function clock_gettime). It should be called with errnor. This commit fixes this mistake. Reported-by: Coverity (CID: 312956) Signed-off-by: Philippe Reynes Reviewed-by: Simon Glass --- tools/image-host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/image-host.c b/tools/image-host.c index 5e1dec2338..e32cc64257 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -335,7 +335,7 @@ static int get_random_data(void *data, int size) ret = clock_gettime(CLOCK_MONOTONIC, &date); if (ret < 0) { printf("%s: clock_gettime has failed (err=%d, str=%s)\n", - __func__, ret, strerror(ret)); + __func__, ret, strerror(errno)); goto out; } From 6a457bb29535c4e743dc4c487caf20a122cea435 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 16 Nov 2020 22:01:31 +0100 Subject: [PATCH 05/39] common: fit: add missing newline The debug statement doesn't end with a newline. Add it. Signed-off-by: Michael Walle --- common/common_fit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/common_fit.c b/common/common_fit.c index a993308100..219674d467 100644 --- a/common/common_fit.c +++ b/common/common_fit.c @@ -67,7 +67,7 @@ int fit_find_config_node(const void *fdt) if (board_fit_config_name_match(name)) continue; - debug("Selecting config '%s'", name); + debug("Selecting config '%s'\n", name); return node; } From e157a1114e4f9294219f4257d0e7983ecb4c328d Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Mon, 26 Oct 2020 10:40:24 -0500 Subject: [PATCH 06/39] tools: dumpimage: Remove remaining mentions of the -i option The -i option of the dumpimage tool has been removed so it should no longer be documented in the README file. Refer readers to the tool's help output rather than maintain a copy of the usage in the README. Finally, adjust the example dumpfile invocation in imagetool.h to use the -o option instead of the removed -i option. Fixes: 12b831879a76 ("tools: dumpimage: Simplify arguments") Signed-off-by: Tyler Hicks Cc: Martyn Welch Acked-by: Martyn Welch --- README | 12 ++---------- tools/imagetool.h | 6 +++--- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/README b/README index cb49aa15da..7b73a1c973 100644 --- a/README +++ b/README @@ -3832,16 +3832,8 @@ when your kernel is intended to use an initial ramdisk: Load Address: 0x00000000 Entry Point: 0x00000000 -The "dumpimage" is a tool to disassemble images built by mkimage. Its "-i" -option performs the converse operation of the mkimage's second form (the "-d" -option). Given an image built by mkimage, the dumpimage extracts a "data file" -from the image: - - tools/dumpimage -i image -T type -p position data_file - -i ==> extract from the 'image' a specific 'data_file' - -T ==> set image type to 'type' - -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image' - +The "dumpimage" tool can be used to disassemble or list the contents of images +built by mkimage. See dumpimage's help output (-h) for details. Installing a Linux Image: ------------------------- diff --git a/tools/imagetool.h b/tools/imagetool.h index acbc48e9be..8726792c8c 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -126,9 +126,9 @@ struct image_type_params { struct image_tool_params *); /* * This function is used by the command to retrieve a component - * (sub-image) from the image (i.e. dumpimage -i -p - * ). - * Thus the code to extract a file from an image must be put here. + * (sub-image) from the image (i.e. dumpimage -p + * -o ). Thus the code to extract a file + * from an image must be put here. * * Returns 0 if the file was successfully retrieved from the image, * or a negative value on error. From 7291332a73c2b0ae94eec8361c5f4c89f8ff5ad2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 30 Oct 2020 06:11:12 +0100 Subject: [PATCH 07/39] env: typo enougth %s/enougth/enough/ Signed-off-by: Heinrich Schuchardt Acked-by: Joe Hershberger --- env/nowhere.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env/nowhere.c b/env/nowhere.c index d33fdf27d0..d43a2d6b51 100644 --- a/env/nowhere.c +++ b/env/nowhere.c @@ -30,7 +30,7 @@ static int env_nowhere_init(void) static int env_nowhere_load(void) { /* - * for SPL, set env_valid = ENV_INVALID is enougth as env_get_char() + * for SPL, set env_valid = ENV_INVALID is enough as env_get_char() * return the default env if env_get is used * and SPL don't used env_import to reduce its size * For U-Boot proper, import the default environment to allow reload. From aef04a8aa1164bf2605db102fa051a34f646c0a1 Mon Sep 17 00:00:00 2001 From: Matteo Ghidoni Date: Thu, 29 Oct 2020 13:48:01 +0100 Subject: [PATCH 08/39] km: replace hardcoded address for imported environment Instead of using an hard coded address, make use of an already defined address for importing the environment for ramfs and nfs boot. This allows boards having different mapping to use the same code. CC: Heiko Schocher CC: Tom Rini Signed-off-by: Matteo Ghidoni Signed-off-by: Holger Brunck --- board/keymile/scripts/develop-arm.txt | 2 +- board/keymile/scripts/develop-common.txt | 2 +- board/keymile/scripts/develop-ppc_82xx.txt | 2 +- board/keymile/scripts/develop-ppc_8xx.txt | 2 +- board/keymile/scripts/ramfs-arm.txt | 2 +- board/keymile/scripts/ramfs-common.txt | 2 +- board/keymile/scripts/ramfs-ppc_82xx.txt | 2 +- board/keymile/scripts/ramfs-ppc_8xx.txt | 2 +- include/configs/km/keymile-common.h | 8 ++++---- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/board/keymile/scripts/develop-arm.txt b/board/keymile/scripts/develop-arm.txt index d3c974f1f9..4c12d3e1c4 100644 --- a/board/keymile/scripts/develop-arm.txt +++ b/board/keymile/scripts/develop-arm.txt @@ -1 +1 @@ -setup_debug_env=tftpboot 0x200000 scripts/develop-common.txt && env import -t 0x200000 ${filesize} && run configure +setup_debug_env=tftpboot ${load_addr_r} scripts/develop-common.txt && env import -t ${load_addr_r} ${filesize} && run configure diff --git a/board/keymile/scripts/develop-common.txt b/board/keymile/scripts/develop-common.txt index f77a26abe8..4384c0da30 100644 --- a/board/keymile/scripts/develop-common.txt +++ b/board/keymile/scripts/develop-common.txt @@ -9,4 +9,4 @@ toolchain=/opt/eldk rootfssize=0 set_uimage=printenv uimage || setenv uimage uImage set_tftppath=if test ${hostname} = kmcoge5un; then setenv tftppath CI5UN; else if test ${hostname} = kmcoge5ne; then setenv tftppath CI5NE; else setenv tftppath ${IVM_Symbol}; fi; fi -try_import_nfs_path=if tftpboot 0x200000 ${tftppath}/nfs-path.txt; then env import -t 0x200000 ${filesize}; else echo no auto nfs path imported; echo you can set nfsargs in /tftpboot/${tftppath}/nfs-path.txt and rerun develop; fi +try_import_nfs_path=if tftpboot ${load_addr_r} ${tftppath}/nfs-path.txt; then env import -t ${load_addr_r} ${filesize}; else echo no auto nfs path imported; echo you can set nfsargs in /tftpboot/${tftppath}/nfs-path.txt and rerun develop; fi diff --git a/board/keymile/scripts/develop-ppc_82xx.txt b/board/keymile/scripts/develop-ppc_82xx.txt index d3c974f1f9..4c12d3e1c4 100644 --- a/board/keymile/scripts/develop-ppc_82xx.txt +++ b/board/keymile/scripts/develop-ppc_82xx.txt @@ -1 +1 @@ -setup_debug_env=tftpboot 0x200000 scripts/develop-common.txt && env import -t 0x200000 ${filesize} && run configure +setup_debug_env=tftpboot ${load_addr_r} scripts/develop-common.txt && env import -t ${load_addr_r} ${filesize} && run configure diff --git a/board/keymile/scripts/develop-ppc_8xx.txt b/board/keymile/scripts/develop-ppc_8xx.txt index d3c974f1f9..4c12d3e1c4 100644 --- a/board/keymile/scripts/develop-ppc_8xx.txt +++ b/board/keymile/scripts/develop-ppc_8xx.txt @@ -1 +1 @@ -setup_debug_env=tftpboot 0x200000 scripts/develop-common.txt && env import -t 0x200000 ${filesize} && run configure +setup_debug_env=tftpboot ${load_addr_r} scripts/develop-common.txt && env import -t ${load_addr_r} ${filesize} && run configure diff --git a/board/keymile/scripts/ramfs-arm.txt b/board/keymile/scripts/ramfs-arm.txt index 87e984e179..93f87fabab 100644 --- a/board/keymile/scripts/ramfs-arm.txt +++ b/board/keymile/scripts/ramfs-arm.txt @@ -1 +1 @@ -setup_debug_env=tftpboot 0x200000 scripts/ramfs-common.txt && env import -t 0x200000 ${filesize} && run configure +setup_debug_env=tftpboot ${load_addr_r} scripts/ramfs-common.txt && env import -t ${load_addr_r} ${filesize} && run configure diff --git a/board/keymile/scripts/ramfs-common.txt b/board/keymile/scripts/ramfs-common.txt index 290c602aab..e590a2bee6 100644 --- a/board/keymile/scripts/ramfs-common.txt +++ b/board/keymile/scripts/ramfs-common.txt @@ -12,4 +12,4 @@ tftpkernel=tftpboot ${load_addr_r} ${tftppath}/${uimage} tftpramfs=tftpboot ${rootfsaddr} ${tftppath}/rootfsImage set_uimage=printenv uimage || setenv uimage uImage set_tftppath=if test ${hostname} = kmcoge5un; then setenv tftppath CI5UN; else if test ${hostname} = kmcoge5ne; then setenv tftppath CI5NE; else setenv tftppath ${IVM_Symbol}; fi; fi -try_import_rootfssize=if tftpboot 0x200000 ${tftppath}/rootfssize.txt; then env import -t 0x200000 ${filesize}; else echo no auto rootfs size; echo you can set rootfssize in /tftpboot/${tftppath}/rootfssize.txt and rerun ramfs; fi +try_import_rootfssize=if tftpboot ${load_addr_r} ${tftppath}/rootfssize.txt; then env import -t ${load_addr_r} ${filesize}; else echo no auto rootfs size; echo you can set rootfssize in /tftpboot/${tftppath}/rootfssize.txt and rerun ramfs; fi diff --git a/board/keymile/scripts/ramfs-ppc_82xx.txt b/board/keymile/scripts/ramfs-ppc_82xx.txt index 87e984e179..93f87fabab 100644 --- a/board/keymile/scripts/ramfs-ppc_82xx.txt +++ b/board/keymile/scripts/ramfs-ppc_82xx.txt @@ -1 +1 @@ -setup_debug_env=tftpboot 0x200000 scripts/ramfs-common.txt && env import -t 0x200000 ${filesize} && run configure +setup_debug_env=tftpboot ${load_addr_r} scripts/ramfs-common.txt && env import -t ${load_addr_r} ${filesize} && run configure diff --git a/board/keymile/scripts/ramfs-ppc_8xx.txt b/board/keymile/scripts/ramfs-ppc_8xx.txt index 87e984e179..93f87fabab 100644 --- a/board/keymile/scripts/ramfs-ppc_8xx.txt +++ b/board/keymile/scripts/ramfs-ppc_8xx.txt @@ -1 +1 @@ -setup_debug_env=tftpboot 0x200000 scripts/ramfs-common.txt && env import -t 0x200000 ${filesize} && run configure +setup_debug_env=tftpboot ${load_addr_r} scripts/ramfs-common.txt && env import -t ${load_addr_r} ${filesize} && run configure diff --git a/include/configs/km/keymile-common.h b/include/configs/km/keymile-common.h index c1968048a7..851b13e063 100644 --- a/include/configs/km/keymile-common.h +++ b/include/configs/km/keymile-common.h @@ -90,12 +90,12 @@ "set_fdthigh cramfsloadkernel flashargs add_default " \ "addpanic boot\0" \ "develop=" \ - "tftp 200000 scripts/develop-${arch}.txt && " \ - "env import -t 200000 ${filesize} && " \ + "tftp ${load_addr_r} scripts/develop-${arch}.txt && " \ + "env import -t ${load_addr_r} ${filesize} && " \ "run setup_debug_env\0" \ "ramfs=" \ - "tftp 200000 scripts/ramfs-${arch}.txt && " \ - "env import -t 200000 ${filesize} && " \ + "tftp ${load_addr_r} scripts/ramfs-${arch}.txt && " \ + "env import -t ${load_addr_r} ${filesize} && " \ "run setup_debug_env\0" \ "" From c904a0b762aedccf603ce492687450efb0e8924c Mon Sep 17 00:00:00 2001 From: Holger Brunck Date: Thu, 29 Oct 2020 13:54:54 +0100 Subject: [PATCH 09/39] km/ppc: use Kconfig for MEMTEST configuration Also change back SYS_MEMTEST_END to 0x00f00000. 0xe00000 was wrong and introduced due to the global Kconfig migration of this option in u-boot. CC: Heiko Schocher CC: Tom Rini Signed-off-by: Holger Brunck --- board/keymile/km83xx/Kconfig | 6 ++++++ board/keymile/km83xx/km83xx.c | 8 ++------ include/configs/kmcoge5ne.h | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/board/keymile/km83xx/Kconfig b/board/keymile/km83xx/Kconfig index bbafabdcb2..8247ae39d3 100644 --- a/board/keymile/km83xx/Kconfig +++ b/board/keymile/km83xx/Kconfig @@ -15,6 +15,12 @@ config KM_ENABLE_FULL_DM_DTS_SUPPORT select PHYLIB endmenu +config SYS_MEMTEST_START + default 0x00100000 + +config SYS_MEMTEST_END + default 0x00f00000 + if TARGET_KMETER1 config SYS_BOARD diff --git a/board/keymile/km83xx/km83xx.c b/board/keymile/km83xx/km83xx.c index 9eb000cca4..a984165e24 100644 --- a/board/keymile/km83xx/km83xx.c +++ b/board/keymile/km83xx/km83xx.c @@ -236,12 +236,8 @@ void post_word_store(ulong value) int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset) { - /* - * These match CONFIG_SYS_MEMTEST_START and - * (CONFIG_SYS_MEMTEST_END - CONFIG_SYS_MEMTEST_START) - */ - *vstart = 0x00100000; - *size = 0xe00000; + *vstart = CONFIG_SYS_MEMTEST_START; + *size = CONFIG_SYS_MEMTEST_END - CONFIG_SYS_MEMTEST_START; debug("arch_memory_test_prepare 0x%08X 0x%08X\n", *vstart, *size); return 0; diff --git a/include/configs/kmcoge5ne.h b/include/configs/kmcoge5ne.h index 4d01f236c3..cdfb280aee 100644 --- a/include/configs/kmcoge5ne.h +++ b/include/configs/kmcoge5ne.h @@ -51,7 +51,7 @@ /* enable POST tests */ #define CONFIG_POST (CONFIG_SYS_POST_MEMORY|CONFIG_SYS_POST_MEM_REGIONS) #define CONFIG_POST_EXTERNAL_WORD_FUNCS /* use own functions, not generic */ -#define CPM_POST_WORD_ADDR 0x00f00000 +#define CPM_POST_WORD_ADDR CONFIG_SYS_MEMTEST_END #define CONFIG_TESTPIN_REG gprt3 /* for kmcoge5ne */ #define CONFIG_TESTPIN_MASK 0x20 /* for kmcoge5ne */ From e04072536efcbe504596ea980077eb63c52082b0 Mon Sep 17 00:00:00 2001 From: Steven Lawrance Date: Thu, 29 Oct 2020 18:27:34 +0100 Subject: [PATCH 10/39] drivers: led: bcm6858: set the correct led polarity register This change sets the output (hardware) polarity register instead of the input (software) polarity register for the bcm6858 LED controller. The logic was inverted (a LED configued active high behaved as active low). Signed-off-by: Steven Lawrance Reviewed-by: Philippe Reynes --- drivers/led/led_bcm6858.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/led/led_bcm6858.c b/drivers/led/led_bcm6858.c index b415d8b2b4..511185ffad 100644 --- a/drivers/led/led_bcm6858.c +++ b/drivers/led/led_bcm6858.c @@ -40,8 +40,8 @@ #define LED_FLASH_RATE_CONTROL_REG0 0x10 /* Soft LED input register */ #define LED_SW_LED_IP_REG 0xb8 -/* Soft LED input polarity register */ -#define LED_SW_LED_IP_PPOL_REG 0xbc +/* Parallel LED Output Polarity Register */ +#define LED_PLED_OP_PPOL_REG 0xc0 struct bcm6858_led_priv { void __iomem *regs; @@ -198,9 +198,9 @@ static int bcm6858_led_probe(struct udevice *dev) /* configure the polarity */ if (dev_read_bool(dev, "active-low")) - clrbits_32(regs + LED_SW_LED_IP_PPOL_REG, 1 << pin); + clrbits_32(regs + LED_PLED_OP_PPOL_REG, 1 << pin); else - setbits_32(regs + LED_SW_LED_IP_PPOL_REG, 1 << pin); + setbits_32(regs + LED_PLED_OP_PPOL_REG, 1 << pin); } return 0; From c49b0eb034710f08fc68cbfa2c23811e10667ad9 Mon Sep 17 00:00:00 2001 From: Gerard Koskamp Date: Fri, 30 Oct 2020 13:41:58 +0000 Subject: [PATCH 11/39] fs/squashfs: Fix index off by 1 for inode SQFS_LDIR_TYPE I've created a squashfs file system with Yocto (it use squashfs-tools) and u-boot command sqfsls give the error:'Error while searching inode: unknown type.' After some digging in the code I found that the index is off by 1. This patch fix this issue and I can successful use the sqfsls command. After search for the squashfs format I found a link talk about a similar issue but this time in the documentation. The link is: https://github.com/AgentD/squashfs-tools-ng/commit/e6588526838caece9529 Signed-off-by: Gerard Koskamp Tested-by: Joao Marcos Costa --- fs/squashfs/sqfs_inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/squashfs/sqfs_inode.c b/fs/squashfs/sqfs_inode.c index 14d70cf678..e76ec7cbdf 100644 --- a/fs/squashfs/sqfs_inode.c +++ b/fs/squashfs/sqfs_inode.c @@ -49,7 +49,7 @@ int sqfs_inode_size(struct squashfs_base_inode *inode, u32 blk_size) return sizeof(*ldir); di = ldir->index; - while (l < i_count + 1) { + while (l < i_count) { sz = get_unaligned_le32(&di->size) + 1; index_list_size += sz; di = (void *)di + sizeof(*di) + sz; @@ -57,7 +57,7 @@ int sqfs_inode_size(struct squashfs_base_inode *inode, u32 blk_size) } return sizeof(*ldir) + index_list_size + - (i_count + 1) * SQFS_DIR_INDEX_BASE_LENGTH; + i_count * SQFS_DIR_INDEX_BASE_LENGTH; } case SQFS_LREG_TYPE: { From 9b5546c37ab020039f06855eae28fbd56adb096b Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Sat, 31 Oct 2020 09:07:49 +0800 Subject: [PATCH 12/39] fs: btrfs: inode: handle uninitialized type before returning it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In btrfs_lookup_path() the local variable @type should always be updated after we hit any file/dir. But if @filename is NULL from the very beginning, then we don't initialize it and return it directly. To prevent such problem from happening, we initialize @type to BTRFS_FT_UNKNOWN. For normal execution route, it will get updated for each filename we resolved. Buf if we didn't find any path, we check if the type is still FT_UNKNOWN and ret == 0. If true we know there is something wrong, just return -EUCLEAN to inform the caller. Reported-by: Coverity CID 312958 Signed-off-by: Qu Wenruo Reviewed-by: Marek BehĂșn --- fs/btrfs/inode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ff330280e0..019d532a1a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -251,7 +251,7 @@ int btrfs_lookup_path(struct btrfs_root *root, u64 ino, const char *filename, const char *cur = filename; u64 next_ino; u8 next_type; - u8 type; + u8 type = BTRFS_FT_UNKNOWN; int len; int ret = 0; @@ -335,6 +335,10 @@ next: cur += len; } + /* We haven't found anything, but still get no error? */ + if (type == BTRFS_FT_UNKNOWN && !ret) + ret = -EUCLEAN; + if (!ret) { *root_ret = root; *ino_ret = ino; From 4891c4e595b48ee41b7d8062bb599d05a938ea0a Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Sat, 31 Oct 2020 09:07:51 +0800 Subject: [PATCH 13/39] fs: btrfs: initialize @ret to 0 to prevent uninitialized return value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In show_dir() if we hit a ROOT_ITEM, we can exit with uninitialized @ret. Fix it by initializing it to 0. Reported-by: Coverity CID 312955 Signed-off-by: Qu Wenruo Reviewed-by: Marek BehĂșn --- fs/btrfs/btrfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c index e48972ffa2..346b2c4341 100644 --- a/fs/btrfs/btrfs.c +++ b/fs/btrfs/btrfs.c @@ -36,7 +36,7 @@ static int show_dir(struct btrfs_root *root, struct extent_buffer *eb, char *target = NULL; char filetime[32]; time_t mtime; - int ret; + int ret = 0; btrfs_dir_item_key_to_cpu(eb, di, &key); From 1b1e0c019588afc64a639b89fd0b6cd12534bce4 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:10:59 +0100 Subject: [PATCH 14/39] fs/squashfs: fix board hang-up when calling .exists() add missing squashfs function to prevent dangling or null pointers. For exemple, when calling test [ -e somefile ], squashfs.exists may be called. Signed-off-by: Richard Genoud Reviewed-by: Joao Marcos Costa --- fs/fs.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/fs.c b/fs/fs.c index 29ad4d1a69..fb27c910d4 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -287,6 +287,7 @@ static struct fstype_info fstypes[] = { { .fstype = FS_TYPE_SQUASHFS, .name = "squashfs", + .null_dev_desc_ok = false, .probe = sqfs_probe, .opendir = sqfs_opendir, .readdir = sqfs_readdir, @@ -295,6 +296,12 @@ static struct fstype_info fstypes[] = { .size = sqfs_size, .close = sqfs_close, .closedir = sqfs_closedir, + .exists = fs_exists_unsupported, + .uuid = fs_uuid_unsupported, + .write = fs_write_unsupported, + .ln = fs_ln_unsupported, + .unlink = fs_unlink_unsupported, + .mkdir = fs_mkdir_unsupported, }, #endif { From f268768d43bbf11c7107597abef57c6b86b6b229 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:00 +0100 Subject: [PATCH 15/39] fs/squashfs: sqfs_opendir: fix some memory leaks and dangling pointers When trying to load an non-existing file, the cpu hangs! Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 15208b4dab..1fdb9ac534 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -821,22 +821,37 @@ int sqfs_opendir(const char *filename, struct fs_dir_stream **dirsp) if (!dirs) return -EINVAL; + /* these should be set to NULL to prevent dangling pointers */ + dirs->dir_header = NULL; + dirs->entry = NULL; + dirs->table = NULL; + dirs->inode_table = NULL; + dirs->dir_table = NULL; + ret = sqfs_read_inode_table(&inode_table); - if (ret) - return -EINVAL; + if (ret) { + ret = -EINVAL; + goto free_dirs; + } metablks_count = sqfs_read_directory_table(&dir_table, &pos_list); - if (metablks_count < 1) - return -EINVAL; + if (metablks_count < 1) { + ret = -EINVAL; + goto free_inode_table; + } /* Tokenize filename */ token_count = sqfs_count_tokens(filename); - if (token_count < 0) - return -EINVAL; + if (token_count < 0) { + ret = -EINVAL; + goto free_inode_table; + } path = strdup(filename); - if (!path) - return -ENOMEM; + if (!path) { + ret = -EINVAL; + goto free_inode_table; + } token_list = malloc(token_count * sizeof(char *)); if (!token_list) { @@ -882,6 +897,12 @@ free_tokens: free(pos_list); free_path: free(path); +free_inode_table: + if (ret) + free(inode_table); +free_dirs: + if (ret) + free(dirs); return ret; } From ea1b1651c6a8db2b7f889bfe8dd796a59af7e0fe Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:01 +0100 Subject: [PATCH 16/39] fs/squashfs: sqfs_opendir: simplify error handling Using only one label permits to prevents bugs when moving code around. Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 1fdb9ac534..b94a971520 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -812,9 +812,9 @@ free_dtb: int sqfs_opendir(const char *filename, struct fs_dir_stream **dirsp) { unsigned char *inode_table = NULL, *dir_table = NULL; - int j, token_count, ret = 0, metablks_count; + int j, token_count = 0, ret = 0, metablks_count; struct squashfs_dir_stream *dirs; - char **token_list, *path; + char **token_list = NULL, *path = NULL; u32 *pos_list = NULL; dirs = malloc(sizeof(*dirs)); @@ -831,38 +831,38 @@ int sqfs_opendir(const char *filename, struct fs_dir_stream **dirsp) ret = sqfs_read_inode_table(&inode_table); if (ret) { ret = -EINVAL; - goto free_dirs; + goto out; } metablks_count = sqfs_read_directory_table(&dir_table, &pos_list); if (metablks_count < 1) { ret = -EINVAL; - goto free_inode_table; + goto out; } /* Tokenize filename */ token_count = sqfs_count_tokens(filename); if (token_count < 0) { ret = -EINVAL; - goto free_inode_table; + goto out; } path = strdup(filename); if (!path) { ret = -EINVAL; - goto free_inode_table; + goto out; } token_list = malloc(token_count * sizeof(char *)); if (!token_list) { ret = -EINVAL; - goto free_path; + goto out; } /* Fill tokens list */ ret = sqfs_tokenize(token_list, token_count, path); if (ret) - goto free_tokens; + goto out; /* * ldir's (extended directory) size is greater than dir, so it works as * a general solution for the malloc size, since 'i' is a union. @@ -872,7 +872,7 @@ int sqfs_opendir(const char *filename, struct fs_dir_stream **dirsp) ret = sqfs_search_dir(dirs, token_list, token_count, pos_list, metablks_count); if (ret) - goto free_tokens; + goto out; if (le16_to_cpu(dirs->i_dir.inode_type) == SQFS_DIR_TYPE) dirs->size = le16_to_cpu(dirs->i_dir.file_size); @@ -890,19 +890,16 @@ int sqfs_opendir(const char *filename, struct fs_dir_stream **dirsp) *dirsp = (struct fs_dir_stream *)dirs; -free_tokens: +out: for (j = 0; j < token_count; j++) free(token_list[j]); free(token_list); free(pos_list); -free_path: free(path); -free_inode_table: - if (ret) + if (ret) { free(inode_table); -free_dirs: - if (ret) free(dirs); + } return ret; } From 87d11e08e4792b3d188143972ba3a1651a52beee Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:02 +0100 Subject: [PATCH 17/39] fs/squashfs: sqfs_closedir: fix memory leak sqfs_dirs wasn't freed anywhere. Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index b94a971520..0ac922af9e 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1573,4 +1573,5 @@ void sqfs_closedir(struct fs_dir_stream *dirs) free(sqfs_dirs->inode_table); free(sqfs_dirs->dir_table); free(sqfs_dirs->dir_header); + free(sqfs_dirs); } From 5487477802e0ad7bfad046af25f4a04cfd98cb7a Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:03 +0100 Subject: [PATCH 18/39] fs/squashfs: sqfs_split_path: fix memory leak and dangling pointers *file and *dir were not freed on error Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 0ac922af9e..58b8bfc66d 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1089,15 +1089,27 @@ static int sqfs_split_path(char **file, char **dir, const char *path) char *dirc, *basec, *bname, *dname, *tmp_path; int ret = 0; + *file = NULL; + *dir = NULL; + dirc = NULL; + basec = NULL; + bname = NULL; + dname = NULL; + tmp_path = NULL; + /* check for first slash in path*/ if (path[0] == '/') { tmp_path = strdup(path); - if (!tmp_path) - return -ENOMEM; + if (!tmp_path) { + ret = -ENOMEM; + goto out; + } } else { tmp_path = malloc(strlen(path) + 2); - if (!tmp_path) - return -ENOMEM; + if (!tmp_path) { + ret = -ENOMEM; + goto out; + } tmp_path[0] = '/'; strcpy(tmp_path + 1, path); } @@ -1106,13 +1118,13 @@ static int sqfs_split_path(char **file, char **dir, const char *path) dirc = strdup(tmp_path); if (!dirc) { ret = -ENOMEM; - goto free_tmp; + goto out; } basec = strdup(tmp_path); if (!basec) { ret = -ENOMEM; - goto free_dirc; + goto out; } dname = sqfs_dirname(dirc); @@ -1122,14 +1134,14 @@ static int sqfs_split_path(char **file, char **dir, const char *path) if (!*file) { ret = -ENOMEM; - goto free_basec; + goto out; } if (*dname == '\0') { *dir = malloc(2); if (!*dir) { ret = -ENOMEM; - goto free_basec; + goto out; } (*dir)[0] = '/'; @@ -1138,15 +1150,19 @@ static int sqfs_split_path(char **file, char **dir, const char *path) *dir = strdup(dname); if (!*dir) { ret = -ENOMEM; - goto free_basec; + goto out; } } -free_basec: +out: + if (ret) { + free(*file); + free(*dir); + *dir = NULL; + *file = NULL; + } free(basec); -free_dirc: free(dirc); -free_tmp: free(tmp_path); return ret; From 7d23b2c5fb093142400467d8b81ba84786ed6f2c Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:04 +0100 Subject: [PATCH 19/39] fs/squashfs: sqfs_read_directory_table: fix memory leak pos_list wasn't freed on every error Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 58b8bfc66d..9d460e8bed 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -722,6 +722,8 @@ static int sqfs_read_directory_table(unsigned char **dir_table, u32 **pos_list) unsigned long dest_len = 0; bool compressed; + *dir_table = NULL; + *pos_list = NULL; /* DIRECTORY TABLE */ table_size = get_unaligned_le64(&sblk->fragment_table_start) - get_unaligned_le64(&sblk->directory_table_start); @@ -736,35 +738,31 @@ static int sqfs_read_directory_table(unsigned char **dir_table, u32 **pos_list) return -ENOMEM; if (sqfs_disk_read(start, n_blks, dtb) < 0) - goto free_dtb; + goto out; /* Parse directory table (metadata block) header */ ret = sqfs_read_metablock(dtb, table_offset, &compressed, &src_len); if (ret) - goto free_dtb; + goto out; /* Calculate total size to store the whole decompressed table */ metablks_count = sqfs_count_metablks(dtb, table_offset, table_size); if (metablks_count < 1) - goto free_dtb; + goto out; *dir_table = malloc(metablks_count * SQFS_METADATA_BLOCK_SIZE); if (!*dir_table) - goto free_dtb; + goto out; *pos_list = malloc(metablks_count * sizeof(u32)); - if (!*pos_list) { - free(*dir_table); - goto free_dtb; - } + if (!*pos_list) + goto out; ret = sqfs_get_metablk_pos(*pos_list, dtb, table_offset, metablks_count); if (ret) { metablks_count = -1; - free(*dir_table); - free(*pos_list); - goto free_dtb; + goto out; } src_table = dtb + table_offset + SQFS_HEADER_SIZE; @@ -780,8 +778,7 @@ static int sqfs_read_directory_table(unsigned char **dir_table, u32 **pos_list) &dest_len, src_table, src_len); if (ret) { metablks_count = -1; - free(*dir_table); - goto free_dtb; + goto out; } if (dest_len < SQFS_METADATA_BLOCK_SIZE) { @@ -803,7 +800,13 @@ static int sqfs_read_directory_table(unsigned char **dir_table, u32 **pos_list) src_table += src_len + SQFS_HEADER_SIZE; } -free_dtb: +out: + if (metablks_count < 1) { + free(*dir_table); + free(*pos_list); + *dir_table = NULL; + *pos_list = NULL; + } free(dtb); return metablks_count; From 01e71ec61ab84bcdd4df708f8930d5acf1c2674d Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:05 +0100 Subject: [PATCH 20/39] fs/squashfs: sqfs_search_dir: fix dangling pointer dirs->entry shouldn't be left dangling as it could be freed twice. Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 9d460e8bed..78893b5c85 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -485,6 +485,7 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, if (!ret) break; free(dirs->entry); + dirs->entry = NULL; } if (ret) { @@ -530,6 +531,7 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, if (ret) return -EINVAL; free(dirs->entry); + dirs->entry = NULL; ret = sqfs_search_dir(dirs, sym_tokens, token_count, m_list, m_count); @@ -537,6 +539,7 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, } else if (!sqfs_is_dir(get_unaligned_le16(&dir->inode_type))) { printf("** Cannot find directory. **\n"); free(dirs->entry); + dirs->entry = NULL; return -EINVAL; } @@ -556,6 +559,7 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, if (sqfs_is_empty_dir(table)) { printf("Empty directory.\n"); free(dirs->entry); + dirs->entry = NULL; return SQFS_EMPTY_DIR; } @@ -564,6 +568,7 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, dirs->entry_count = dirs->dir_header->count + 1; dirs->size -= SQFS_DIR_HEADER_SIZE; free(dirs->entry); + dirs->entry = NULL; } offset = sqfs_dir_offset(table, m_list, m_count); From cd54591afd42c547f43a7d509862f20e09264cde Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:06 +0100 Subject: [PATCH 21/39] fs/squashfs: sqfs_search_dir: fix memory leaks path, target, res, rem and sym_tokens were not free on error nor success. Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 64 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 78893b5c85..1714306e74 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -434,7 +434,7 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, { struct squashfs_super_block *sblk = ctxt.sblk; char *path, *target, **sym_tokens, *res, *rem; - int j, ret, new_inode_number, offset; + int j, ret = 0, new_inode_number, offset; struct squashfs_symlink_inode *sym; struct squashfs_ldir_inode *ldir; struct squashfs_dir_inode *dir; @@ -442,6 +442,12 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, struct fs_dirent *dent; unsigned char *table; + res = NULL; + rem = NULL; + path = NULL; + target = NULL; + sym_tokens = NULL; + dirsp = (struct fs_dir_stream *)dirs; /* Start by root inode */ @@ -477,7 +483,8 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, for (j = 0; j < token_count; j++) { if (!sqfs_is_dir(get_unaligned_le16(&dir->inode_type))) { printf("** Cannot find directory. **\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } while (!sqfs_readdir(dirsp, &dent)) { @@ -490,7 +497,8 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, if (ret) { printf("** Cannot find directory. **\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } /* Redefine inode as the found token */ @@ -507,40 +515,63 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, sym = (struct squashfs_symlink_inode *)table; /* Get first j + 1 tokens */ path = sqfs_concat_tokens(token_list, j + 1); + if (!path) { + ret = -ENOMEM; + goto out; + } /* Resolve for these tokens */ target = sqfs_resolve_symlink(sym, path); + if (!target) { + ret = -ENOMEM; + goto out; + } /* Join remaining tokens */ rem = sqfs_concat_tokens(token_list + j + 1, token_count - j - 1); + if (!rem) { + ret = -ENOMEM; + goto out; + } /* Concatenate remaining tokens and symlink's target */ res = malloc(strlen(rem) + strlen(target) + 1); + if (!res) { + ret = -ENOMEM; + goto out; + } strcpy(res, target); res[strlen(target)] = '/'; strcpy(res + strlen(target) + 1, rem); token_count = sqfs_count_tokens(res); - if (token_count < 0) - return -EINVAL; + if (token_count < 0) { + ret = -EINVAL; + goto out; + } sym_tokens = malloc(token_count * sizeof(char *)); - if (!sym_tokens) - return -EINVAL; + if (!sym_tokens) { + ret = -EINVAL; + goto out; + } /* Fill tokens list */ ret = sqfs_tokenize(sym_tokens, token_count, res); - if (ret) - return -EINVAL; + if (ret) { + ret = -EINVAL; + goto out; + } free(dirs->entry); dirs->entry = NULL; ret = sqfs_search_dir(dirs, sym_tokens, token_count, m_list, m_count); - return ret; + goto out; } else if (!sqfs_is_dir(get_unaligned_le16(&dir->inode_type))) { printf("** Cannot find directory. **\n"); free(dirs->entry); dirs->entry = NULL; - return -EINVAL; + ret = -EINVAL; + goto out; } /* Check if it is an extended dir. */ @@ -560,7 +591,8 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, printf("Empty directory.\n"); free(dirs->entry); dirs->entry = NULL; - return SQFS_EMPTY_DIR; + ret = SQFS_EMPTY_DIR; + goto out; } dirs->table += SQFS_DIR_HEADER_SIZE; @@ -579,7 +611,13 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, else memcpy(&dirs->i_ldir, ldir, sizeof(*ldir)); - return 0; +out: + free(res); + free(rem); + free(path); + free(target); + free(sym_tokens); + return ret; } /* From 4c83d2755776d4dd5e15a930d48db1082fc0d1cc Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:07 +0100 Subject: [PATCH 22/39] fs/squashfs: sqfs_read_inode_table: fix dangling pointer inode_table should not be left dangling as it may be freed in sqfs_opendir Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 1714306e74..72181f3833 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -731,6 +731,7 @@ static int sqfs_read_inode_table(unsigned char **inode_table) src_table, src_len); if (ret) { free(*inode_table); + *inode_table = NULL; goto free_itb; } From dc3312c43c82ff9335b2bf4ee4f72365e824adfd Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:08 +0100 Subject: [PATCH 23/39] fs/squashfs: sqfs_concat_tokens: check if malloc succeeds memory allocation should always be checked Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 72181f3833..7da2e09cc3 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -242,6 +242,9 @@ static char *sqfs_concat_tokens(char **token_list, int token_count) length = sqfs_get_tokens_length(token_list, token_count); result = malloc(length + 1); + if (!result) + return NULL; + result[length] = '\0'; for (i = 0; i < token_count; i++) { From 508a9dc7f694df11c7de7460f888f508e40a2046 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:09 +0100 Subject: [PATCH 24/39] fs/squashfs: sqfs_size: fix dangling pointer dirs->entry dirs->entry shouldn't be left dangling as it could be freed twice. Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 7da2e09cc3..3b008b5235 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1569,6 +1569,7 @@ int sqfs_size(const char *filename, loff_t *size) if (!ret) break; free(dirs->entry); + dirs->entry = NULL; } if (ret) { @@ -1582,6 +1583,7 @@ int sqfs_size(const char *filename, loff_t *size) ipos = sqfs_find_inode(dirs->inode_table, i_number, sblk->inodes, sblk->block_size); free(dirs->entry); + dirs->entry = NULL; base = (struct squashfs_base_inode *)ipos; switch (get_unaligned_le16(&base->inode_type)) { From 35475f83a107901551c31f7bc70f5266862a33e4 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:10 +0100 Subject: [PATCH 25/39] fs/squashfs: sqfs_size: remove useless sqfs_closedir() as sqfs_opendir failed, there's no need to call sqfs_closedir Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 3b008b5235..f4cac3e4bf 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1557,7 +1557,6 @@ int sqfs_size(const char *filename, loff_t *size) */ ret = sqfs_opendir(dir, &dirsp); if (ret) { - sqfs_closedir(dirsp); ret = -EINVAL; goto free_strings; } From d1d8d75f69f82f7ef7c55b58a7d9e73055956f3c Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:11 +0100 Subject: [PATCH 26/39] fs/squashfs: sqfs_read: fix dangling pointer dirs->entry dirs->entry shouldn't be left dangling as it could be freed twice. Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index f4cac3e4bf..13e64bea93 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1336,6 +1336,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, break; free(dirs->entry); + dirs->entry = NULL; } if (ret) { From b34949fe9baaae49003b2981213495bab3afef9b Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:12 +0100 Subject: [PATCH 27/39] fs/squashfs: sqfs_read: remove useless sqfs_closedir() as sqfs_opendir failed, there's no need to call sqfs_closedir Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 13e64bea93..1ac0762588 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1323,7 +1323,6 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, sqfs_split_path(&file, &dir, filename); ret = sqfs_opendir(dir, &dirsp); if (ret) { - sqfs_closedir(dirsp); goto free_paths; } From 7ce9745cbeae7733a7068f19a7fc3ec8f21dc38c Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:13 +0100 Subject: [PATCH 28/39] fs/squashfs: sqfs_read: fix memory leak sqfs_closedir() should be called to free memory allocated by sqfs_opendir() Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 1ac0762588..a9e803cbac 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1341,7 +1341,6 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, if (ret) { printf("File not found.\n"); *actread = 0; - sqfs_closedir(dirsp); ret = -ENOENT; goto free_paths; } @@ -1532,6 +1531,7 @@ free_datablk: free_paths: free(file); free(dir); + sqfs_closedir(dirsp); return ret; } From 555459e7931f7ae34a4e10d1e21ce7aada7aa59b Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:14 +0100 Subject: [PATCH 29/39] fs/squashfs: sqfs_read: fix another memory leak data_buffer was allocated in a loop and freed only once. Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index a9e803cbac..cfea313e34 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1459,6 +1459,8 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, } data_offset += table_size; + free(data_buffer); + data_buffer = NULL; } free(finfo.blk_sizes); From c9b8e86f8bd238421b35ec15d88b4d3cac8a0992 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:15 +0100 Subject: [PATCH 30/39] fs/squashfs: sqfs_frag_lookup: simplify error handling For consistency with other functions. Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index cfea313e34..b97a961c5e 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -106,6 +106,10 @@ static int sqfs_frag_lookup(u32 inode_fragment_index, int block, offset, ret; u16 header; + metadata_buffer = NULL; + entries = NULL; + table = NULL; + if (inode_fragment_index >= get_unaligned_le32(&sblk->fragments)) return -EINVAL; @@ -117,12 +121,14 @@ static int sqfs_frag_lookup(u32 inode_fragment_index, /* Allocate a proper sized buffer to store the fragment index table */ table = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz); - if (!table) - return -ENOMEM; + if (!table) { + ret = -ENOMEM; + goto out; + } if (sqfs_disk_read(start, n_blks, table) < 0) { - free(table); - return -EINVAL; + ret = -EINVAL; + goto out; } block = SQFS_FRAGMENT_INDEX(inode_fragment_index); @@ -142,12 +148,12 @@ static int sqfs_frag_lookup(u32 inode_fragment_index, metadata_buffer = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz); if (!metadata_buffer) { ret = -ENOMEM; - goto free_table; + goto out; } if (sqfs_disk_read(start, n_blks, metadata_buffer) < 0) { ret = -EINVAL; - goto free_buffer; + goto out; } /* Every metadata block starts with a 16-bit header */ @@ -156,13 +162,13 @@ static int sqfs_frag_lookup(u32 inode_fragment_index, if (!metadata || !header) { ret = -ENOMEM; - goto free_buffer; + goto out; } entries = malloc(SQFS_METADATA_BLOCK_SIZE); if (!entries) { ret = -ENOMEM; - goto free_buffer; + goto out; } if (SQFS_COMPRESSED_METADATA(header)) { @@ -172,7 +178,7 @@ static int sqfs_frag_lookup(u32 inode_fragment_index, src_len); if (ret) { ret = -EINVAL; - goto free_entries; + goto out; } } else { memcpy(entries, metadata, SQFS_METADATA_SIZE(header)); @@ -181,11 +187,9 @@ static int sqfs_frag_lookup(u32 inode_fragment_index, *e = entries[offset]; ret = SQFS_COMPRESSED_BLOCK(e->size); -free_entries: +out: free(entries); -free_buffer: free(metadata_buffer); -free_table: free(table); return ret; From 53db0e24a8f981c1e303a1c745b8f0e28544096f Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:16 +0100 Subject: [PATCH 31/39] fs/squashfs: sqfs_get_abs_path: fix error check the return value of sqfs_tokenize(rel_tokens, rc, rel); wasn't checked. (but "ret" value was !) This is obviouly a typo. Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index b97a961c5e..825d5d13fa 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -359,7 +359,7 @@ static char *sqfs_get_abs_path(const char *base, const char *rel) if (ret) goto free_r_tokens; - sqfs_tokenize(rel_tokens, rc, rel); + ret = sqfs_tokenize(rel_tokens, rc, rel); if (ret) goto free_r_tokens; From 33686804d29e676177d408f1ce047b8c35185ddb Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:17 +0100 Subject: [PATCH 32/39] fs/squashfs: sqfs_get_abs_path: fix possible memory leak on error if sqfs_tokenize(rel_tokens, rc, rel); fails, the function exits without freeing the array base_tokens. Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 825d5d13fa..f41deece0a 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -340,28 +340,31 @@ static char *sqfs_get_abs_path(const char *base, const char *rel) char **base_tokens, **rel_tokens, *resolved = NULL; int ret, bc, rc, i, updir = 0, resolved_size = 0, offset = 0; + base_tokens = NULL; + rel_tokens = NULL; + /* Memory allocation for the token lists */ bc = sqfs_count_tokens(base); rc = sqfs_count_tokens(rel); if (bc < 1 || rc < 1) return NULL; - base_tokens = malloc(bc * sizeof(char *)); + base_tokens = calloc(bc, sizeof(char *)); if (!base_tokens) return NULL; - rel_tokens = malloc(rc * sizeof(char *)); + rel_tokens = calloc(rc, sizeof(char *)); if (!rel_tokens) - goto free_b_tokens; + goto out; /* Fill token lists */ ret = sqfs_tokenize(base_tokens, bc, base); if (ret) - goto free_r_tokens; + goto out; ret = sqfs_tokenize(rel_tokens, rc, rel); if (ret) - goto free_r_tokens; + goto out; /* count '..' occurrences in target path */ for (i = 0; i < rc; i++) { @@ -372,7 +375,7 @@ static char *sqfs_get_abs_path(const char *base, const char *rel) /* Remove the last token and the '..' occurrences */ bc = sqfs_clean_base_path(base_tokens, bc, updir); if (bc < 0) - goto free_r_tokens; + goto out; /* Calculate resolved path size */ if (!bc) @@ -383,7 +386,7 @@ static char *sqfs_get_abs_path(const char *base, const char *rel) resolved = malloc(resolved_size + 1); if (!resolved) - goto free_r_tokens_loop; + goto out; /* Set resolved path */ memset(resolved, '\0', resolved_size + 1); @@ -391,14 +394,15 @@ static char *sqfs_get_abs_path(const char *base, const char *rel) resolved[offset++] = '/'; offset += sqfs_join(rel_tokens, resolved + offset, updir, rc, '/'); -free_r_tokens_loop: - for (i = 0; i < rc; i++) - free(rel_tokens[i]); - for (i = 0; i < bc; i++) - free(base_tokens[i]); -free_r_tokens: +out: + if (rel_tokens) + for (i = 0; i < rc; i++) + free(rel_tokens[i]); + if (base_tokens) + for (i = 0; i < bc; i++) + free(base_tokens[i]); + free(rel_tokens); -free_b_tokens: free(base_tokens); return resolved; From 571b67ee1dcb989dc50575f14e87bfdef6bfd8db Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:18 +0100 Subject: [PATCH 33/39] fs/squashfs: sqfs_read: fix memory leak on finfo.blk_sizes finfo.blk_sizes may not be freed in case of error in the for loop Setting it to null and freeing it at the end makes prevents that from happening. Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 48 +++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index f41deece0a..d8d4584fbf 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1305,8 +1305,8 @@ static int sqfs_get_lregfile_info(struct squashfs_lreg_inode *lreg, int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, loff_t *actread) { - char *dir, *fragment_block, *datablock = NULL, *data_buffer = NULL; - char *fragment, *file, *resolved, *data; + char *dir = NULL, *fragment_block, *datablock = NULL, *data_buffer = NULL; + char *fragment = NULL, *file = NULL, *resolved, *data; u64 start, n_blks, table_size, data_offset, table_offset; int ret, j, i_number, datablk_count = 0; struct squashfs_super_block *sblk = ctxt.sblk; @@ -1331,7 +1331,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, sqfs_split_path(&file, &dir, filename); ret = sqfs_opendir(dir, &dirsp); if (ret) { - goto free_paths; + goto out; } dirs = (struct squashfs_dir_stream *)dirsp; @@ -1350,7 +1350,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, printf("File not found.\n"); *actread = 0; ret = -ENOENT; - goto free_paths; + goto out; } i_number = dirs->dir_header->inode_number + dirs->entry->inode_offset; @@ -1365,7 +1365,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, sblk->block_size); if (datablk_count < 0) { ret = -EINVAL; - goto free_paths; + goto out; } memcpy(finfo.blk_sizes, ipos + sizeof(*reg), @@ -1378,7 +1378,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, sblk->block_size); if (datablk_count < 0) { ret = -EINVAL; - goto free_paths; + goto out; } memcpy(finfo.blk_sizes, ipos + sizeof(*lreg), @@ -1390,7 +1390,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, resolved = sqfs_resolve_symlink(symlink, filename); ret = sqfs_read(resolved, buf, offset, len, actread); free(resolved); - goto free_paths; + goto out; case SQFS_BLKDEV_TYPE: case SQFS_CHRDEV_TYPE: case SQFS_LBLKDEV_TYPE: @@ -1402,14 +1402,14 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, default: printf("Unsupported entry type\n"); ret = -EINVAL; - goto free_paths; + goto out; } /* If the user specifies a length, check its sanity */ if (len) { if (len > finfo.size) { ret = -EINVAL; - goto free_paths; + goto out; } finfo.size = len; @@ -1420,7 +1420,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, datablock = malloc(get_unaligned_le32(&sblk->block_size)); if (!datablock) { ret = -ENOMEM; - goto free_paths; + goto out; } } @@ -1435,7 +1435,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, if (!data_buffer) { ret = -ENOMEM; - goto free_datablk; + goto out; } ret = sqfs_disk_read(start, n_blks, data_buffer); @@ -1446,7 +1446,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, * image with mksquashfs's -b option. */ printf("Error: too many data blocks to be read.\n"); - goto free_buffer; + goto out; } data = data_buffer + table_offset; @@ -1457,7 +1457,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, ret = sqfs_decompress(&ctxt, datablock, &dest_len, data, table_size); if (ret) - goto free_buffer; + goto out; memcpy(buf + offset + *actread, datablock, dest_len); *actread += dest_len; @@ -1471,14 +1471,12 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, data_buffer = NULL; } - free(finfo.blk_sizes); - /* * There is no need to continue if the file is not fragmented. */ if (!finfo.frag) { ret = 0; - goto free_buffer; + goto out; } start = frag_entry.start / ctxt.cur_dev->blksz; @@ -1490,12 +1488,12 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, if (!fragment) { ret = -ENOMEM; - goto free_buffer; + goto out; } ret = sqfs_disk_read(start, n_blks, fragment); if (ret < 0) - goto free_fragment; + goto out; /* File compressed and fragmented */ if (finfo.frag && finfo.comp) { @@ -1503,7 +1501,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, fragment_block = malloc(dest_len); if (!fragment_block) { ret = -ENOMEM; - goto free_fragment; + goto out; } ret = sqfs_decompress(&ctxt, fragment_block, &dest_len, @@ -1511,7 +1509,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, frag_entry.size); if (ret) { free(fragment_block); - goto free_fragment; + goto out; } for (j = offset + *actread; j < finfo.size; j++) { @@ -1530,17 +1528,15 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, } } -free_fragment: +out: free(fragment); -free_buffer: - if (datablk_count) + if (datablk_count) { free(data_buffer); -free_datablk: - if (datablk_count) free(datablock); -free_paths: + } free(file); free(dir); + free(finfo.blk_sizes); sqfs_closedir(dirsp); return ret; From ccd4c08a452b3703ee16ba730a84b7caadcff97a Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:19 +0100 Subject: [PATCH 34/39] fs/squashfs: sqfs_probe: fix possible memory leak on error If SquashFS magic number is invalid, there's a memory leak. Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index d8d4584fbf..7d6f0e88e3 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1090,8 +1090,8 @@ int sqfs_probe(struct blk_desc *fs_dev_desc, struct disk_partition *fs_partition /* Make sure it has a valid SquashFS magic number*/ if (get_unaligned_le32(&sblk->s_magic) != SQFS_MAGIC_NUMBER) { printf("Bad magic number for SquashFS image.\n"); - ctxt.cur_dev = NULL; - return -EINVAL; + ret = -EINVAL; + goto error; } ctxt.sblk = sblk; @@ -1099,12 +1099,16 @@ int sqfs_probe(struct blk_desc *fs_dev_desc, struct disk_partition *fs_partition ret = sqfs_decompressor_init(&ctxt); if (ret) { - ctxt.cur_dev = NULL; - free(ctxt.sblk); - return -EINVAL; + ret = -EINVAL; + goto error; } return 0; +error: + ctxt.cur_dev = NULL; + free(ctxt.sblk); + ctxt.sblk = NULL; + return ret; } static char *sqfs_basename(char *path) From 56cf1ceee38435a0c105d40336d12d19e1db8b1d Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:21 +0100 Subject: [PATCH 35/39] fs/squashfs: sqfs_probe: reset cur_dev/cur_part_info to NULL on error Resetting the context on error will prevent some checks like: if (!ctx.cur_dev) To pass when the probe method has failed Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 7d6f0e88e3..96806a4a31 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1085,7 +1085,7 @@ int sqfs_probe(struct blk_desc *fs_dev_desc, struct disk_partition *fs_partition ret = sqfs_read_sblk(&sblk); if (ret) - return ret; + goto error; /* Make sure it has a valid SquashFS magic number*/ if (get_unaligned_le32(&sblk->s_magic) != SQFS_MAGIC_NUMBER) { From 6d25bd3e9c1d317cdbd52a4c6bba11f912bb4d6a Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:22 +0100 Subject: [PATCH 36/39] fs/squashfs: sqfs_probe: use sqfs_decompressor_init() return value sqfs_decompressor_init() returns a value, so it's better to use it than to force the return value to EINVAL (it could be ENOMEM) Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 96806a4a31..435081638b 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1097,9 +1097,7 @@ int sqfs_probe(struct blk_desc *fs_dev_desc, struct disk_partition *fs_partition ctxt.sblk = sblk; ret = sqfs_decompressor_init(&ctxt); - if (ret) { - ret = -EINVAL; goto error; } From cbd5e40ede4e5c6aedce9475325bdf80b7fa839b Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:23 +0100 Subject: [PATCH 37/39] fs/squashfs: sqfs_read: don't write beyond buffer size The length of the buffer wasn't taken into account when writing to the given buffer. Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 435081638b..1ecdd01cf7 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1415,6 +1415,8 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, } finfo.size = len; + } else { + len = finfo.size; } if (datablk_count) { @@ -1461,9 +1463,13 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, if (ret) goto out; + if ((*actread + dest_len) > len) + dest_len = len - *actread; memcpy(buf + offset + *actread, datablock, dest_len); *actread += dest_len; } else { + if ((*actread + table_size) > len) + table_size = len - *actread; memcpy(buf + offset + *actread, data, table_size); *actread += table_size; } @@ -1471,6 +1477,8 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, data_offset += table_size; free(data_buffer); data_buffer = NULL; + if (*actread >= len) + break; } /* From 21b1b3bad58b50e5464b1bf016e7c96bf18ddb8d Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:24 +0100 Subject: [PATCH 38/39] fs/squashfs: sqfs_read: remove buggy offset functionality offset is the offset in the file read, not the offset in the destination buffer. If the offset is not null, this will lead to a memory corruption. So, for now, we are returning an error if the offset is used. Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 1ecdd01cf7..80a85e76e8 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1326,6 +1326,14 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, *actread = 0; + if (offset) { + /* + * TODO: implement reading at an offset in file + */ + printf("Error: reading at a specific offset in a squashfs file is not supported yet.\n"); + return -EINVAL; + } + /* * sqfs_opendir will uncompress inode and directory tables, and will * return a pointer to the directory that contains the requested file. @@ -1465,12 +1473,12 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, if ((*actread + dest_len) > len) dest_len = len - *actread; - memcpy(buf + offset + *actread, datablock, dest_len); + memcpy(buf + *actread, datablock, dest_len); *actread += dest_len; } else { if ((*actread + table_size) > len) table_size = len - *actread; - memcpy(buf + offset + *actread, data, table_size); + memcpy(buf + *actread, data, table_size); *actread += table_size; } @@ -1522,7 +1530,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, goto out; } - for (j = offset + *actread; j < finfo.size; j++) { + for (j = *actread; j < finfo.size; j++) { memcpy(buf + j, &fragment_block[finfo.offset + j], 1); (*actread)++; } @@ -1532,7 +1540,7 @@ int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, } else if (finfo.frag && !finfo.comp) { fragment_block = (void *)fragment + table_offset; - for (j = offset + *actread; j < finfo.size; j++) { + for (j = *actread; j < finfo.size; j++) { memcpy(buf + j, &fragment_block[finfo.offset + j], 1); (*actread)++; } From dd4866b43754b18f0c06672e341d93e16b8bf674 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:26 +0100 Subject: [PATCH 39/39] fs/squashfs: implement exists() function This permits to find a file and use the distro_bootcmd Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/fs.c | 2 +- fs/squashfs/sqfs.c | 38 ++++++++++++++++++++++++++++++++++++++ include/squashfs.h | 1 + 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/fs/fs.c b/fs/fs.c index fb27c910d4..7a4020607a 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -296,7 +296,7 @@ static struct fstype_info fstypes[] = { .size = sqfs_size, .close = sqfs_close, .closedir = sqfs_closedir, - .exists = fs_exists_unsupported, + .exists = sqfs_exists, .uuid = fs_uuid_unsupported, .write = fs_write_unsupported, .ln = fs_ln_unsupported, diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 80a85e76e8..608a2bb454 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1649,6 +1649,44 @@ free_strings: return ret; } +int sqfs_exists(const char *filename) +{ + struct fs_dir_stream *dirsp = NULL; + struct squashfs_dir_stream *dirs; + char *dir, *file; + struct fs_dirent *dent; + int ret; + + sqfs_split_path(&file, &dir, filename); + /* + * sqfs_opendir will uncompress inode and directory tables, and will + * return a pointer to the directory that contains the requested file. + */ + ret = sqfs_opendir(dir, &dirsp); + if (ret) { + ret = -EINVAL; + goto free_strings; + } + + dirs = (struct squashfs_dir_stream *)dirsp; + + while (!sqfs_readdir(dirsp, &dent)) { + ret = strcmp(dent->name, file); + if (!ret) + break; + free(dirs->entry); + dirs->entry = NULL; + } + + sqfs_closedir(dirsp); + +free_strings: + free(dir); + free(file); + + return ret == 0; +} + void sqfs_close(void) { free(ctxt.sblk); diff --git a/include/squashfs.h b/include/squashfs.h index 819cf8c2da..7489eefa1f 100644 --- a/include/squashfs.h +++ b/include/squashfs.h @@ -19,6 +19,7 @@ int sqfs_probe(struct blk_desc *fs_dev_desc, int sqfs_read(const char *filename, void *buf, loff_t offset, loff_t len, loff_t *actread); int sqfs_size(const char *filename, loff_t *size); +int sqfs_exists(const char *filename); void sqfs_close(void); void sqfs_closedir(struct fs_dir_stream *dirs);