]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Fix readdir_harder() on VirtualBox
authorJan Janssen <medhefgo@web.de>
Mon, 10 Jan 2022 10:16:26 +0000 (11:16 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 10 Jan 2022 20:40:52 +0000 (21:40 +0100)
Fixes: #22073
src/boot/efi/boot.c
src/boot/efi/util.c

index 189461974baa42e6ce0a5b4babb55cd8fc77462f..6ff1768d9b65cc8f156e15dbaee4aa4038ca5a4e 100644 (file)
@@ -1577,7 +1577,7 @@ static void config_load_entries(
                 _cleanup_freepool_ CHAR8 *content = NULL;
 
                 err = readdir_harder(entries_dir, &f, &f_size);
-                if (f_size == 0 || EFI_ERROR(err))
+                if (EFI_ERROR(err) || !f)
                         break;
 
                 if (f->FileName[0] == '.')
@@ -2019,7 +2019,7 @@ static void config_entry_add_linux(
                 CHAR8 *key, *value;
 
                 err = readdir_harder(linux_dir, &f, &f_size);
-                if (f_size == 0 || EFI_ERROR(err))
+                if (EFI_ERROR(err) || !f)
                         break;
 
                 if (f->FileName[0] == '.')
index ab21d774a25c5dbfbd1f0fbd754b7f2a81c0299f..db998ca8da99c0907dc4bb17adeb1b16b077b9b8 100644 (file)
@@ -592,7 +592,12 @@ EFI_STATUS readdir_harder(
          * the specified buffer needs to be freed by caller, after final use. */
 
         if (!*buffer) {
-                sz = offsetof(EFI_FILE_INFO, FileName) /* + 256 */;
+                /* Some broken firmware violates the EFI spec by still advancing the readdir
+                 * position when returning EFI_BUFFER_TOO_SMALL, effectively skipping over any files when
+                 * the buffer was too small. Therefore, start with a buffer that should handle FAT32 max
+                 * file name length.
+                 * As a side effect, most readdir_harder() calls will now be slightly faster. */
+                sz = sizeof(EFI_FILE_INFO) + 256 * sizeof(CHAR16);
                 *buffer = xallocate_pool(sz);
                 *buffer_size = sz;
         } else