Compare commits

..

1 Commits

Author SHA1 Message Date
Simon Glass
9dc49fc1c4 RFC: ext4: Add a few overflow checks in the writing code
Some memory allocations make use of data from the disk, so add some
overflow checks.

Adjust LOG2_BLOCK_SIZE() so it is easier to read.

Note: This is a trial to help figure out the best way to deal with these
sorts of things. Feedback welcome.

Series-to: u-boot
Series-cc: heinrich

Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-04-09 15:01:26 -06:00
4 changed files with 83 additions and 42 deletions

View File

@@ -1185,39 +1185,6 @@ int bootm_run(struct bootm_info *bmi)
int bootz_run(struct bootm_info *bmi)
{
struct bootm_headers *images = bmi->images;
ulong zi_start, zi_end;
int ret;
ret = bootm_run_states(bmi, BOOTM_STATE_START);
if (ret)
return ret;
images->ep = bmi->addr_img ? hextoul(bmi->addr_img, NULL) :
image_load_addr;
ret = bootz_setup(images->ep, &zi_start, &zi_end);
if (ret)
return ret;
lmb_reserve(images->ep, zi_end - zi_start);
/*
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
* have a header that provide this informaiton.
*/
if (bootm_find_images(images->ep, bmi->conf_ramdisk, bmi->conf_fdt,
images->ep, zi_end - zi_start))
return -EINVAL;
/*
* We are doing the BOOTM_STATE_LOADOS state ourselves, so must
* disable interrupts ourselves
*/
bootm_disable_interrupts();
images->os.os = IH_OS_LINUX;
return boot_run(bmi, "bootz", 0);
}

View File

@@ -20,6 +20,56 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end)
return -1;
}
/*
* zImage booting support
*/
static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[], struct bootm_headers *images)
{
ulong zi_start, zi_end;
struct bootm_info bmi;
int ret;
bootm_init(&bmi);
if (argc)
bmi.addr_img = argv[0];
if (argc > 1)
bmi.conf_ramdisk = argv[1];
if (argc > 2)
bmi.conf_fdt = argv[2];
/* do not set up argc and argv[] since nothing uses them */
ret = bootm_run_states(&bmi, BOOTM_STATE_START);
/* Setup Linux kernel zImage entry point */
if (!argc) {
images->ep = image_load_addr;
debug("* kernel: default image load address = 0x%08lx\n",
image_load_addr);
} else {
images->ep = hextoul(argv[0], NULL);
debug("* kernel: cmdline image address = 0x%08lx\n",
images->ep);
}
ret = bootz_setup(images->ep, &zi_start, &zi_end);
if (ret != 0)
return 1;
lmb_reserve(images->ep, zi_end - zi_start);
/*
* Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
* have a header that provide this informaiton.
*/
if (bootm_find_images(image_load_addr, cmd_arg1(argc, argv),
cmd_arg2(argc, argv), images->ep,
zi_end - zi_start))
return 1;
return 0;
}
int do_bootz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
struct bootm_info bmi;
@@ -28,6 +78,17 @@ int do_bootz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
/* Consume 'bootz' */
argc--; argv++;
if (bootz_start(cmdtp, flag, argc, argv, &images))
return 1;
/*
* We are doing the BOOTM_STATE_LOADOS state ourselves, so must
* disable interrupts ourselves
*/
bootm_disable_interrupts();
images.os.os = IH_OS_LINUX;
bootm_init(&bmi);
if (argc)
bmi.addr_img = argv[0];
@@ -38,10 +99,8 @@ int do_bootz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
bmi.cmd_name = "bootz";
ret = bootz_run(&bmi);
if (ret)
return CMD_RET_FAILURE;
return 0;
return ret;
}
U_BOOT_LONGHELP(bootz,

View File

@@ -108,8 +108,15 @@ int ext4fs_get_bgdtable(void)
{
int status;
struct ext_filesystem *fs = get_fs();
int gdsize_total = ROUND(fs->no_blkgrp * fs->gdsize, fs->blksz);
size_t alloc_size;
int gdsize_total;
if (__builtin_mul_overflow(fs->no_blkgrp, fs->gdsize, &alloc_size))
return -1;
gdsize_total = ROUND(alloc_size, fs->blksz);
fs->no_blk_pergdt = gdsize_total / fs->blksz;
if (!fs->no_blk_pergdt)
return -1;
/* allocate memory for gdtable */
fs->gdtable = zalloc(gdsize_total);
@@ -117,7 +124,7 @@ int ext4fs_get_bgdtable(void)
return -ENOMEM;
/* read the group descriptor table */
status = ext4fs_devread((lbaint_t)fs->gdtable_blkno * fs->sect_perblk,
0, fs->blksz * fs->no_blk_pergdt, fs->gdtable);
0, gdsize_total, fs->gdtable);
if (status == 0)
goto fail;
@@ -599,10 +606,17 @@ int ext4fs_init(void)
int i;
uint32_t real_free_blocks = 0;
struct ext_filesystem *fs = get_fs();
size_t alloc_size;
/* check for a reasonable block size, no more than 64K */
if (LOG2_BLOCK_SIZE(ext4fs_root) > 16)
goto fail;
/* populate fs */
fs->blksz = EXT2_BLOCK_SIZE(ext4fs_root);
fs->sect_perblk = fs->blksz >> fs->dev_desc->log2blksz;
if (!fs->sect_perblk)
goto fail;
/* get the superblock */
fs->sb = zalloc(SUPERBLOCK_SIZE);
@@ -629,7 +643,9 @@ int ext4fs_init(void)
}
/* load all the available bitmap block of the partition */
fs->blk_bmaps = zalloc(fs->no_blkgrp * sizeof(char *));
if (__builtin_mul_overflow(fs->no_blkgrp, sizeof(char *), &alloc_size))
goto fail;
fs->blk_bmaps = zalloc(alloc_size);
if (!fs->blk_bmaps)
goto fail;
for (i = 0; i < fs->no_blkgrp; i++) {
@@ -649,7 +665,7 @@ int ext4fs_init(void)
}
/* load all the available inode bitmap of the partition */
fs->inode_bmaps = zalloc(fs->no_blkgrp * sizeof(unsigned char *));
fs->inode_bmaps = zalloc(alloc_size);
if (!fs->inode_bmaps)
goto fail;
for (i = 0; i < fs->no_blkgrp; i++) {

View File

@@ -67,8 +67,7 @@ struct cmd_tbl;
#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data))
/* Log2 size of ext2 block in bytes. */
#define LOG2_BLOCK_SIZE(data) (le32_to_cpu \
(data->sblock.log2_block_size) \
#define LOG2_BLOCK_SIZE(data) (le32_to_cpu((data)->sblock.log2_block_size) \
+ EXT2_MIN_BLOCK_LOG_SIZE)
#define EXT2_FT_DIR 2