Browse Source

Merge branch '2020-09-18-assorted-bugfixes'

- SquashFS Coverity fixes
- bitflip fix in the alternate memtest command
- Disable networking on bcmstb boards where we didn't have any network
  drivers enabled.
Tom Rini 3 years ago
parent
commit
667ab37d58
7 changed files with 48 additions and 15 deletions
  1. 12 0
      cmd/Kconfig
  2. 16 5
      cmd/mem.c
  3. 1 0
      configs/bcm7260_defconfig
  4. 1 0
      configs/bcm7445_defconfig
  5. 13 7
      fs/squashfs/sqfs.c
  6. 1 2
      fs/squashfs/sqfs_dir.c
  7. 4 1
      fs/squashfs/sqfs_inode.c

+ 12 - 0
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

+ 16 - 5
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);

+ 1 - 0
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

+ 1 - 0
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

+ 13 - 7
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(&reg->start_block);
 	finfo->frag = SQFS_IS_FRAGMENTED(get_unaligned_le32(&reg->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));

+ 1 - 2
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:

+ 4 - 1
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);