From: Anshul Dalal <anshuld@ti.com>
To: Sean Anderson <seanga2@gmail.com>,
"u-boot@lists.denx.de" <u-boot@lists.denx.de>
Cc: "Raghavendra, Vignesh" <vigneshr@ti.com>
Subject: Re: [BUG report] spl: image size check fails in spl_load()
Date: Thu, 20 Feb 2025 10:52:53 +0530 [thread overview]
Message-ID: <D7X0SJC303BY.Y2SK7Q0VHNTT@ti.com> (raw)
In-Reply-To: <b8af49dd-7999-a89f-600c-2d337bc6bb66@gmail.com>
On Wed Feb 19, 2025 at 9:17 PM IST, Sean Anderson wrote:
> On 2/18/25 01:07, Anshul Dalal wrote:
> > On Sat Feb 15, 2025 at 11:18 PM IST, Sean Anderson wrote:
> >> On 2/14/25 06:12, Anshul Dalal wrote:
> >>> Hi all!
> >>>
> >>> I was trying to implement falcon boot on TI AM62x EVM with the kernel image on
> >>> SD card's filesystem but the following check in `_spl_load` at
> >>> `include/spl_load.h:95` fails to -EIO as per the latest commit [89d3333]:
> >>>
> >>> return read < spl_image->size ? -EIO : 0;
> >>>
> >>> The check seems to be comparing the image size gathered from the header
> >>> (spl_image->size) with the number of bytes read form the loader.
> >>>
> >>> From spl_load.h:
> >>>
> >>> ret = spl_parse_image_header(spl_image, bootdev, header);
> >>> if (ret)
> >>> return ret;
> >>>
> >>> base_offset = spl_image->offset;
> >>> /* Only NOR sets this flag. */
> >>> if (IS_ENABLED(CONFIG_SPL_NOR_SUPPORT) &&
> >>> spl_image->flags & SPL_COPY_PAYLOAD_ONLY)
> >>> base_offset += sizeof(*header);
> >>> image_offset = ALIGN_DOWN(base_offset, spl_get_bl_len(info));
> >>> overhead = base_offset - image_offset;
> >>> size = ALIGN(spl_image->size + overhead, spl_get_bl_len(info));
> >>>
> >>> read = info->read(info, offset + image_offset, size,
> >>> map_sysmem(spl_image->load_addr - overhead, size));
> >>>
> >>> if (read < 0)
> >>> return read;
> >>>
> >>> return read < spl_image->size ? -EIO : 0;
> >>>
> >>> During kernel build process the header size is computed including the BSS
> >>> whereas it's removed when creating the uncompressed image. Therefore the size
> >>> of the uncompressed image on filesystem will be smaller than the size specified
> >>> in the header. Which leads to failure of the above check.
> >>>
> >>> From linux kernel's `arch/arm64/kernel/image.h:63`:
> >>>
> >>> #define HEAD_SYMBOLS \
> >>> DEFINE_IMAGE_LE64(_kernel_size_le, _end - _text); \
> >>> DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS);
> >>>
> >>> Disabling the check leads to a successful boot directly to the kernel.
> >>> Therefore it seems like the check is non functional as the size in the kernel
> >>> header does not correspond with the file size of the kernel image.
> >>
> >> Did this work before v2024.04?
> >>
> >
> > No, the check existed by v2024.04. I tested on the commit prior to
> > 775074165d97 (the commit that added the check) and falcon boot works.
>
> Sorry, that's what I meant. E.g. did this work in v2024.01 etc.
>
> Just wanted to determine whether this was a bug or a feature request.
>
> >> How exactly are you loading your image? E.g. what are the values of
> >>
> >
> > I have my DTB and kernel Image on the 1st partition of the SD card which
> > is FAT. Which also includes the u-boot.img in case falcon fails and we
> > need a fallback.
> >
> >> CONFIG_SPL_OS_BOOT
> >> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
> >> CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
> >> CONFIG_SPL_FALCON_BOOT_MMCSD
> >> CONFIG_SPL_FS_FAT
> >> CONFIG_SPL_FS_EXT4
> >> CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
> >> CONFIG_SUPPORT_EMMC_BOOT
> >>
> >
> > Since I'm not booting from RAW mmc but instead FS boot, I don't think
> > the SYS_MMCSD_RAW_* configs are relevant but in any case:
> >
> > CONFIG_SPL_OS_BOOT=y
> > CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
> > # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION is not set
> > # CONFIG_SPL_FALCON_BOOT_MMCSD is not set
> > CONFIG_SPL_FS_FAT=y
> > # CONFIG_SPL_FS_EXT4 is not set
> > CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img"
> > # CONFIG_SUPPORT_EMMC_BOOT is not set
> >
> > Some other relevant configs:
> >
> > CONFIG_SYS_MMCSD_FS_BOOT=y
> > CONFIG_SYS_MMCSD_FS_BOOT_PARTITION=1
> > CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x82000000
> > CONFIG_SPL_FS_LOAD_KERNEL_NAME="Image"
> > CONFIG_SPL_FS_LOAD_ARGS_NAME="k3-am625-sk.dtb"
> >
> >> From what I can tell, the OS_BOOT path should not call spl_load in the first place.
> >
> > It is called from spl_load_image_fat which is in turn called by
> > spl_load_image_fat_os as it's last return statement during falcon boot.
>
> Ah, there it is. This function is used both by OS_BOOT and regular boot. I intentionally
> tried not to touch the OS_BOOT path, but it looks like one change got in anyway.
>
> >>
> >> In any case, the root problem is that the size reported by the kernel is actually the
> >> space the kernel will need when it is loaded, and not the size of the data to load
> >> (which we need). So if we have a short read, we have no way of knowing if the filesystem
> >> is corrupt, the image was truncated while writing, or if it's just missing the bss. And
> >> we still have to rely of the image size so that we can load from e.g. NAND or SPI where
> >> there is no filesystem.
> >>
> >
> > There seems to be no way to get the actual size of the kernel image just
> > from the image header. I think we should drop the check (at least in
> > case of FS boot without a FIT image). On NAND or SPI, the size from the
> > header would be larger than the actual file size. So, at worst we would
> > have read some extra data where BSS was supposed to be anyways.
> >
> >> One way to fix this could be to move the length check to spl_load_info->read. This would
> >> involve updating all the callers and callees.
> >>
> >
> > I think it would be better handled in spl_load where we can more easily
> > have separate checks for FIT and a kernel image whereas
> > spl_info_info->read would have no way of knowing if the binary type
> > without passing in the header as well.
>
> Yeah, I thought about this after I sent the email...
>
> > I suggest we do something like the following in spl_load:
> >
> > if (image_get_magic(header) == FDT_MAGIC)
> > return read < spl_image->size ? -EIO : 0;
> > else
> > return read == 0 ? -EIO : 0;
>
> I would prefer not doing this sort of thing since it grows the size of every SPL, but only a
> few do falcon boot. Maybe it's better to skip the size check only for OS_BOOT and CMD_BOOTI.
>
> Or maybe we can move this hack to spl_fit_read. i.e:
>
> ret = fat_read_file(filename, buf, file_offset, size, &actread);
> if (ret)
> return ret;
>
> if (CONFIG_IS_ENABLED(OS_BOOT) && IS_ENABLED(CMD_BOOTI))
> return size;
> else
> return actread;
>
> I think this would have the least impact overall.
>
Looks good to me, we would need to do the same for ext4 in spl_ext.c. I
can send a patch with the fix if you'd like.
- Anshul
next prev parent reply other threads:[~2025-02-20 5:23 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20250214111251.2349093-1-anshuld@ti.com>
2025-02-15 17:48 ` [BUG report] spl: image size check fails in spl_load() Sean Anderson
2025-02-18 6:07 ` Anshul Dalal
2025-02-19 15:47 ` Sean Anderson
2025-02-20 5:22 ` Anshul Dalal [this message]
2025-02-21 2:18 ` Sean Anderson
2025-02-14 11:16 Anshul Dalal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=D7X0SJC303BY.Y2SK7Q0VHNTT@ti.com \
--to=anshuld@ti.com \
--cc=seanga2@gmail.com \
--cc=u-boot@lists.denx.de \
--cc=vigneshr@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox