diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index e4d1831256..889516787b 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1572,7 +1572,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] == '.') @@ -2007,7 +2007,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] == '.') diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index 76e4eef1eb..71639721b7 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -596,7 +596,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