Hi Cedric,
On 2026-10-26T16:37:26, Cedric Hombourger <[email protected]> wrote:
> efi_loader: do not trim files in Write()
>
> UEFI describes Write() as writing the given bytes at the current file
> position, growing the file if required, with partial writes only on a
> data error (EFI_FILE_PROTOCOL.Write(), UEFI 2.10, section 13.5.6).
> Nothing in it allows a successful Write() to drop data after the
> written range.
>
> The UEFI SCT checks this: its Write() basic test writes 50 bytes at
> position 0 of a 200 byte file and expects the file size to stay 200
> (SimpleFileSystemBBTestFunction.c, BBTestWriteBasicTestCheckpoint1 in
> edk2-test). EDK2 behaves this way too: its FAT driver only grows the
> file when a write goes past the end.
>
> efi_file_write_int() calls fs_write(), which trims the file at the end
> of the written range. A write in the middle of a file loses all the data
> after it. For example, a 256 MiB file written in small pieces ends up
> with the size of the last write.
Not quite. The file ends up cut at the end of the last write, i.e.
offset + len (602112 bytes in your cover letter), not at the size of
the last write.
> Call fs_overwrite() instead.
Please can you say in the commit message that this only fixes FAT.
With the fallback in fs_overwrite(), Write() on an exFAT ESP still
trims the file.
> [...]
>
> lib/efi_loader/efi_file.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
> diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c
> @@ -686,8 +686,8 @@ static efi_status_t efi_file_write_int(struct
> efi_file_handle *this,
> - if (fs_write(fh->path, map_to_sysmem(buffer), fh->offset, *buffer_size,
> - &actwrite)) {
> + if (fs_overwrite(fh->path, map_to_sysmem(buffer), fh->offset,
> + *buffer_size, &actwrite)) {
Please can you add a test for this. efi_selftest_block_device.c
already writes 'U-Boot' to 'u-boot.txt' under CONFIG_FAT_WRITE. It
could reopen the file, write a couple of bytes at position 0, then
check that GetInfo() still reports 7 bytes and that the rest of the
content is unchanged. That is the same case as the SCT checkpoint you
mention.
BTW once this is applied, an EFI app can only shrink a file by calling
Delete() and recreating it, since efi_file_setinfo() refuses a size
change ('Truncation not supported'). That is correct for Write(), but
supporting truncation in SetInfo() would be a good follow-up. The SCT
set-up likely needs it anyway?
Regards,
Simon