]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
efi: add limit on how large files can be we load into memory at once
authorLennart Poettering <lennart@poettering.net>
Fri, 28 Jun 2024 17:43:31 +0000 (19:43 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 3 Jul 2024 14:15:04 +0000 (16:15 +0200)
src/boot/efi/util.c
src/boot/efi/util.h

index 6ceb032fa131b164a02fa8a55b4e89b3aa63f00f..3639afcb15d85bed7be233d283838ea265923c72 100644 (file)
@@ -9,6 +9,9 @@
 #include "version.h"
 #include "efivars.h"
 
+/* Never try to read more than 16G into memory (and on 32bit 1G) */
+#define FILE_READ_MAX MIN(SIZE_MAX/4, UINT64_C(16)*1024U*1024U*1024U)
+
 void convert_efi_path(char16_t *path) {
         assert(path);
 
@@ -107,7 +110,7 @@ EFI_STATUS chunked_read(EFI_FILE *file, size_t *size, void *buf) {
 EFI_STATUS file_read(
                 EFI_FILE *dir,
                 const char16_t *name,
-                uint64_t off,
+                uint64_t offset,
                 size_t size,
                 char **ret,
                 size_t *ret_size) {
@@ -131,14 +134,17 @@ EFI_STATUS file_read(
                 if (err != EFI_SUCCESS)
                         return err;
 
-                if (info->FileSize > SIZE_MAX)
+                if (info->FileSize > SIZE_MAX) /* overflow check */
                         return EFI_BAD_BUFFER_SIZE;
 
                 size = info->FileSize;
         }
 
-        if (off > 0) {
-                err = handle->SetPosition(handle, off);
+        if (size > FILE_READ_MAX) /* make sure we don't read unbounded data into RAM */
+                return EFI_BAD_BUFFER_SIZE;
+
+        if (offset > 0) {
+                err = handle->SetPosition(handle, offset);
                 if (err != EFI_SUCCESS)
                         return err;
         }
index 3a26bc5c9295d066c9ff25f2f581493734896154..dc16f3fb7678cb38565b85e844b1318e07244539 100644 (file)
@@ -86,7 +86,7 @@ char16_t *xstr8_to_path(const char *stra);
 char16_t *mangle_stub_cmdline(char16_t *cmdline);
 
 EFI_STATUS chunked_read(EFI_FILE *file, size_t *size, void *buf);
-EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, uint64_t off, size_t size, char **content, size_t *content_size);
+EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, uint64_t offset, size_t size, char **content, size_t *content_size);
 
 static inline void file_closep(EFI_FILE **handle) {
         if (!*handle)