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.

Call fs_overwrite() instead.

Signed-off-by: Cedric Hombourger <[email protected]>
---
 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
index 
7dee57d594a971572f09c6b6be6727a15acf0f77..fdefaa1b0604d5313f8b20f3d31f477e1d3e40ed
 100644
--- 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,
                ret = EFI_DEVICE_ERROR;
                goto out;
        }
-       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)) {
                ret = EFI_DEVICE_ERROR;
                goto out;
        }

-- 
2.47.3

Reply via email to