From a7dc37d38c8eddcd14008b115e254279bb88bbc1 Mon Sep 17 00:00:00 2001 From: Joao Marcos Costa Date: Fri, 11 Sep 2020 12:21:06 +0200 Subject: [PATCH 1/3] fs/squashfs: Fix Coverity Scan defects Fix control flow issues and null pointer dereferences. Signed-off-by: Joao Marcos Costa --- fs/squashfs/sqfs.c | 20 +++++++++++++------- fs/squashfs/sqfs_dir.c | 3 +-- fs/squashfs/sqfs_inode.c | 5 ++++- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index f67f7c4a40a..15208b4dab0 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -154,7 +154,7 @@ static int sqfs_frag_lookup(u32 inode_fragment_index, header = get_unaligned_le16(metadata_buffer + table_offset); metadata = metadata_buffer + table_offset + SQFS_HEADER_SIZE; - if (!metadata) { + if (!metadata || !header) { ret = -ENOMEM; goto free_buffer; } @@ -434,9 +434,9 @@ 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; - struct squashfs_ldir_inode *ldir = NULL; int j, ret, new_inode_number, offset; struct squashfs_symlink_inode *sym; + struct squashfs_ldir_inode *ldir; struct squashfs_dir_inode *dir; struct fs_dir_stream *dirsp; struct fs_dirent *dent; @@ -448,8 +448,8 @@ static int sqfs_search_dir(struct squashfs_dir_stream *dirs, char **token_list, table = sqfs_find_inode(dirs->inode_table, le32_to_cpu(sblk->inodes), sblk->inodes, sblk->block_size); - /* root is a regular directory, not an extended one */ dir = (struct squashfs_dir_inode *)table; + ldir = (struct squashfs_ldir_inode *)table; /* get directory offset in directory table */ offset = sqfs_dir_offset(table, m_list, m_count); @@ -1146,7 +1146,10 @@ static int sqfs_get_regfile_info(struct squashfs_reg_inode *reg, finfo->start = get_unaligned_le32(®->start_block); finfo->frag = SQFS_IS_FRAGMENTED(get_unaligned_le32(®->fragment)); - if (finfo->size < 1 || finfo->offset < 0 || finfo->start < 0) + if (finfo->frag && finfo->offset == 0xFFFFFFFF) + return -EINVAL; + + if (finfo->size < 1 || finfo->start == 0xFFFFFFFF) return -EINVAL; if (finfo->frag) { @@ -1156,7 +1159,7 @@ static int sqfs_get_regfile_info(struct squashfs_reg_inode *reg, if (ret < 0) return -EINVAL; finfo->comp = true; - if (fentry->size < 1 || fentry->start < 0) + if (fentry->size < 1 || fentry->start == 0x7FFFFFFF) return -EINVAL; } else { datablk_count = DIV_ROUND_UP(finfo->size, le32_to_cpu(blksz)); @@ -1181,7 +1184,10 @@ static int sqfs_get_lregfile_info(struct squashfs_lreg_inode *lreg, finfo->start = get_unaligned_le64(&lreg->start_block); finfo->frag = SQFS_IS_FRAGMENTED(get_unaligned_le32(&lreg->fragment)); - if (finfo->size < 1 || finfo->offset < 0 || finfo->start < 0) + if (finfo->frag && finfo->offset == 0xFFFFFFFF) + return -EINVAL; + + if (finfo->size < 1 || finfo->start == 0x7FFFFFFF) return -EINVAL; if (finfo->frag) { @@ -1191,7 +1197,7 @@ static int sqfs_get_lregfile_info(struct squashfs_lreg_inode *lreg, if (ret < 0) return -EINVAL; finfo->comp = true; - if (fentry->size < 1 || fentry->start < 0) + if (fentry->size < 1 || fentry->start == 0x7FFFFFFF) return -EINVAL; } else { datablk_count = DIV_ROUND_UP(finfo->size, le32_to_cpu(blksz)); diff --git a/fs/squashfs/sqfs_dir.c b/fs/squashfs/sqfs_dir.c index 00d2891e7da..a265b98fe68 100644 --- a/fs/squashfs/sqfs_dir.c +++ b/fs/squashfs/sqfs_dir.c @@ -34,8 +34,7 @@ int sqfs_dir_offset(void *dir_i, u32 *m_list, int m_count) struct squashfs_ldir_inode *ldir; struct squashfs_dir_inode *dir; u32 start_block; - u16 offset; - int j; + int j, offset; switch (get_unaligned_le16(&base->inode_type)) { case SQFS_DIR_TYPE: diff --git a/fs/squashfs/sqfs_inode.c b/fs/squashfs/sqfs_inode.c index 1387779a85f..1368f3063c5 100644 --- a/fs/squashfs/sqfs_inode.c +++ b/fs/squashfs/sqfs_inode.c @@ -142,8 +142,11 @@ int sqfs_read_metablock(unsigned char *file_mapping, int offset, u16 header; data = file_mapping + offset; + if (!data) + return -EFAULT; + header = get_unaligned((u16 *)data); - if (!header || !data) + if (!header) return -EINVAL; *compressed = SQFS_COMPRESSED_METADATA(header); From e03dd8a05f5f0fc3d99289e84debe0ae99e805bb Mon Sep 17 00:00:00 2001 From: Thomas Fitzsimmons Date: Fri, 11 Sep 2020 14:41:44 -0400 Subject: [PATCH 2/3] configs: bcmstb: Disable networking support Silence the "Driver Model for Ethernet drivers" migration warning for the bcm7445 and bcm7260 ports, neither of which supports networking yet. Signed-off-by: Thomas Fitzsimmons Reviewed-by: Tom Rini --- configs/bcm7260_defconfig | 1 + configs/bcm7445_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/bcm7260_defconfig b/configs/bcm7260_defconfig index f25659db48c..d1b05309e1e 100644 --- a/configs/bcm7260_defconfig +++ b/configs/bcm7260_defconfig @@ -27,6 +27,7 @@ CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_MMC=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +# CONFIG_NET is not set CONFIG_DM_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_BCMSTB=y diff --git a/configs/bcm7445_defconfig b/configs/bcm7445_defconfig index 18d31048ff1..1f9ab482a26 100644 --- a/configs/bcm7445_defconfig +++ b/configs/bcm7445_defconfig @@ -28,6 +28,7 @@ CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +# CONFIG_NET is not set CONFIG_DM_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_BCMSTB=y From 9989fb18bd5b6e2afe5f296b4c414f8d1c73d527 Mon Sep 17 00:00:00 2001 From: Ralph Siemsen Date: Wed, 9 Sep 2020 12:10:00 -0400 Subject: [PATCH 3/3] cmd: mem: fix range of bitflip test The bitflip test uses two equal sized memory buffers. This is achieved by splitting the range of memory into two pieces. The address of the second buffer, as well as the length of each buffer, were not correctly calculated. This caused bitflip test to access beyond the end of range. This patch fixes the pointer arithmetic problem. A second problem arises because u-boot "mtest" command expects the ending address to be inclusive. When computing (end - start) this results in missing 1 byte of the requested length. The bitflip test expects a count rather than an "ending" address. Thus it fails to test the last word of the requested range. Fixed by using (end - start + 1). Added Kconfig option to optionally disable the bitflip test, since it does add significantly to the time taken for "mtest". Fixes: 8e434cb705d463bc8cff935160e4fb4c77cb99ab ("cmd: mem: Add bitflip memory test to alternate mtest") Signed-off-by: Ralph Siemsen Reviewed-by: Stefan Roese --- cmd/Kconfig | 12 ++++++++++++ cmd/mem.c | 21 ++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 0761dbb7460..0c984d735d2 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -777,6 +777,18 @@ config SYS_ALT_MEMTEST help Use a more complete alternative memory test. +if SYS_ALT_MEMTEST + +config SYS_ALT_MEMTEST_BITFLIP + bool "Bitflip test" + default y + help + The alternative memory test includes bitflip test since 2020.07. + The bitflip test significantly increases the overall test time. + Bitflip test can optionally be disabled here. + +endif + config SYS_MEMTEST_START hex "default start address for mtest" default 0 diff --git a/cmd/mem.c b/cmd/mem.c index 9df5eb068a7..56e1d0755b6 100644 --- a/cmd/mem.c +++ b/cmd/mem.c @@ -985,6 +985,18 @@ static ulong test_bitflip_comparison(volatile unsigned long *bufa, return errs; } +static ulong mem_test_bitflip(vu_long *buf, ulong start, ulong end) +{ + /* + * Split the specified range into two halves. + * Note that mtest range is inclusive of start,end. + * Bitflip test instead uses a count (of 32-bit words). + */ + ulong half_size = (end - start + 1) / 2 / sizeof(unsigned long); + + return test_bitflip_comparison(buf, buf + half_size, half_size); +} + static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, vu_long pattern, int iteration) { @@ -1104,11 +1116,10 @@ static int do_mem_mtest(struct cmd_tbl *cmdtp, int flag, int argc, errs = mem_test_alt(buf, start, end, dummy); if (errs == -1UL) break; - count += errs; - errs = test_bitflip_comparison(buf, - buf + (end - start) / 2, - (end - start) / - sizeof(unsigned long)); + if (IS_ENABLED(CONFIG_SYS_ALT_MEMTEST_BITFLIP)) { + count += errs; + errs = mem_test_bitflip(buf, start, end); + } } else { errs = mem_test_quick(buf, start, end, pattern, iteration);