From 33d4ba32c93cba64832ce73c50cfd316200c0be3 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sun, 7 Jan 2018 11:53:34 +0100 Subject: [PATCH 1/5] systemd-boot: Return EFI_STATUS instead of INTN for file_read() file_read() wants to return both a EFI_STATUS (INTN) and a file length (UINTN). This seems rather fishy for either large files or when returning errors (which are defined as positive numbers). Let's just be more clear and return EFI_STATUS and let the file length be a pointer. --- src/boot/efi/boot.c | 18 +++++++++--------- src/boot/efi/shim.c | 5 ++++- src/boot/efi/util.c | 21 +++++++++------------ src/boot/efi/util.h | 2 +- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 06331da2d41..9d5ea6ed93e 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1142,11 +1142,10 @@ static VOID config_entry_add_from_file(Config *config, EFI_HANDLE *device, CHAR1 static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) { CHAR8 *content = NULL; UINTN sec; - UINTN len; EFI_STATUS err; - len = file_read(root_dir, L"\\loader\\loader.conf", 0, 0, &content); - if (len > 0) + err = file_read(root_dir, L"\\loader\\loader.conf", 0, 0, &content, NULL); + if (!EFI_ERROR(err)) config_defaults_load_from_file(config, content); FreePool(content); @@ -1190,8 +1189,8 @@ static VOID config_load_entries(Config *config, EFI_HANDLE *device, EFI_FILE *ro if (StrnCmp(f->FileName, L"auto-", 5) == 0) continue; - len = file_read(entries_dir, f->FileName, 0, 0, &content); - if (len > 0) + err = file_read(entries_dir, f->FileName, 0, 0, &content, NULL); + if (!EFI_ERROR(err)) config_entry_add_from_file(config, device, f->FileName, content, loaded_image_path); FreePool(content); } @@ -1526,8 +1525,8 @@ static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_ima if (EFI_ERROR(err)) continue; - len = file_read(linux_dir, f->FileName, offs[0], szs[0], &content); - if (len <= 0) + err = file_read(linux_dir, f->FileName, offs[0], szs[0], &content, NULL); + if (EFI_ERROR(err)) continue; /* read properties from the embedded os-release file */ @@ -1568,9 +1567,10 @@ static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_ima entry = config_entry_add_loader(config, loaded_image->DeviceHandle, LOADER_LINUX, conf, 'l', os_name, path); FreePool(content); + content = NULL; /* read the embedded cmdline file */ - len = file_read(linux_dir, f->FileName, offs[1], szs[1] - 1 , &content); - if (len > 0) { + err = file_read(linux_dir, f->FileName, offs[1], szs[1] - 1, &content, NULL); + if (!EFI_ERROR(err)) { cmdline = stra_to_str(content); entry->options = cmdline; cmdline = NULL; diff --git a/src/boot/efi/shim.c b/src/boot/efi/shim.c index 6d7d814c5cc..7c479048c10 100644 --- a/src/boot/efi/shim.c +++ b/src/boot/efi/shim.c @@ -179,7 +179,10 @@ static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROT dev_path_str = DevicePathToStr(dev_path); FreePool(dev_path); - file_size = file_read(root, dev_path_str, 0, 0, &file_buffer); + status = file_read(root, dev_path_str, 0, 0, &file_buffer, &file_size); + if (EFI_ERROR(status)) + return status; + FreePool(dev_path_str); uefi_call_wrapper(root->Close, 1, root); diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index b165f31005f..bff8ba8d206 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -304,12 +304,10 @@ CHAR8 *strchra(CHAR8 *s, CHAR8 c) { return NULL; } -INTN file_read(EFI_FILE_HANDLE dir, CHAR16 *name, UINTN off, UINTN size, CHAR8 **content) { +EFI_STATUS file_read(EFI_FILE_HANDLE dir, CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size) { EFI_FILE_HANDLE handle; CHAR8 *buf; - UINTN buflen; EFI_STATUS err; - UINTN len; err = uefi_call_wrapper(dir->Open, 5, dir, &handle, name, EFI_FILE_MODE_READ, 0ULL); if (EFI_ERROR(err)) @@ -319,10 +317,9 @@ INTN file_read(EFI_FILE_HANDLE dir, CHAR16 *name, UINTN off, UINTN size, CHAR8 * EFI_FILE_INFO *info; info = LibFileInfo(handle); - buflen = info->FileSize+1; + size = info->FileSize+1; FreePool(info); - } else - buflen = size; + } if (off > 0) { err = uefi_call_wrapper(handle->SetPosition, 2, handle, off); @@ -330,17 +327,17 @@ INTN file_read(EFI_FILE_HANDLE dir, CHAR16 *name, UINTN off, UINTN size, CHAR8 * return err; } - buf = AllocatePool(buflen); - err = uefi_call_wrapper(handle->Read, 3, handle, &buflen, buf); + buf = AllocatePool(size); + err = uefi_call_wrapper(handle->Read, 3, handle, &size, buf); if (!EFI_ERROR(err)) { - buf[buflen] = '\0'; + buf[size] = '\0'; *content = buf; - len = buflen; + if (content_size) + *content_size = size; } else { - len = err; FreePool(buf); } uefi_call_wrapper(handle->Close, 1, handle); - return len; + return err; } diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index 35150aea769..49632ffcbc4 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -45,5 +45,5 @@ CHAR8 *strchra(CHAR8 *s, CHAR8 c); CHAR16 *stra_to_path(CHAR8 *stra); CHAR16 *stra_to_str(CHAR8 *stra); -INTN file_read(EFI_FILE_HANDLE dir, CHAR16 *name, UINTN off, UINTN size, CHAR8 **content); +EFI_STATUS file_read(EFI_FILE_HANDLE dir, CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size); #endif From c1d4e298bc5b80788ab0cbfdfc066140678612a8 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sun, 28 Jan 2018 17:06:22 +0100 Subject: [PATCH 2/5] systemd-boot: Make automatic entries configurable Hiding automatic entries allows for giving custom entry names like "Windows 10" instead of "Windows Boot Manager" by creating an appropriate loader file in the loader/entries folder. Note that it is already doable by renaming bootmgfw.efi (or the other auto-detected boot loaders) and then using the renamed file for a custom entry. But windows will automatically recreate the boot loader on updates, including the default EFI bootloader entry if that one is missing. Make hiding EFI reboot a separate option because there is no simple way to create it with a custom loader entry and people may still want that around while still hiding the other auto entries. Also, turn no_editor into a positive boolean name while we're touching this code. --- src/boot/efi/boot.c | 44 +++++++++++++++++++++++++++++++++++++------ src/shared/bootspec.c | 6 ++++++ src/shared/bootspec.h | 2 ++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 9d5ea6ed93e..e0438281e1a 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -68,7 +68,9 @@ typedef struct { CHAR16 *entry_default_pattern; CHAR16 *entry_oneshot; CHAR16 *options_edit; - BOOLEAN no_editor; + BOOLEAN editor; + BOOLEAN auto_entries; + BOOLEAN auto_firmware; } Config; static VOID cursor_left(UINTN *cursor, UINTN *first) { @@ -392,7 +394,9 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { Print(L"OsIndicationsSupported: %d\n", (UINT64)*b); FreePool(b); } - Print(L"\n"); + + Print(L"\n--- press key ---\n\n"); + console_key_read(&key, TRUE); Print(L"timeout: %d\n", config->timeout_sec); if (config->timeout_sec_efivar >= 0) @@ -400,7 +404,9 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { Print(L"timeout (config): %d\n", config->timeout_sec_config); if (config->entry_default_pattern) Print(L"default pattern: '%s'\n", config->entry_default_pattern); - Print(L"editor: %s\n", yes_no(!config->no_editor)); + Print(L"editor: %s\n", yes_no(config->editor)); + Print(L"auto-entries: %s\n", yes_no(config->auto_entries)); + Print(L"auto-firmware: %s\n", yes_no(config->auto_firmware)); Print(L"\n"); Print(L"config entry count: %d\n", config->entry_count); @@ -774,7 +780,7 @@ static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry, CHAR16 *load case KEYPRESS(0, 0, 'e'): /* only the options of configured entries can be edited */ - if (config->no_editor || config->entries[idx_highlight]->type == LOADER_UNDEFINED) + if (!config->editor || config->entries[idx_highlight]->type == LOADER_UNDEFINED) break; uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK); uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, y_max-1); @@ -1006,7 +1012,23 @@ static VOID config_defaults_load_from_file(Config *config, CHAR8 *content) { if (EFI_ERROR(parse_boolean(value, &on))) continue; - config->no_editor = !on; + config->editor = on; + } + + if (strcmpa((CHAR8 *)"auto-entries", key) == 0) { + BOOLEAN on; + + if (EFI_ERROR(parse_boolean(value, &on))) + continue; + config->auto_entries = on; + } + + if (strcmpa((CHAR8 *)"auto-firmware", key) == 0) { + BOOLEAN on; + + if (EFI_ERROR(parse_boolean(value, &on))) + continue; + config->auto_firmware = on; } } } @@ -1144,6 +1166,10 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) { UINTN sec; EFI_STATUS err; + config->editor = TRUE; + config->auto_entries = TRUE; + config->auto_firmware = TRUE; + err = file_read(root_dir, L"\\loader\\loader.conf", 0, 0, &content, NULL); if (!EFI_ERROR(err)) config_defaults_load_from_file(config, content); @@ -1428,6 +1454,9 @@ static BOOLEAN config_entry_add_loader_auto(Config *config, EFI_HANDLE *device, ConfigEntry *entry; EFI_STATUS err; + if (!config->auto_entries) + return FALSE; + /* do not add an entry for ourselves */ if (loaded_image_path && StriCmp(loader, loaded_image_path) == 0) return FALSE; @@ -1453,6 +1482,9 @@ static VOID config_entry_add_osx(Config *config) { UINTN handle_count = 0; EFI_HANDLE *handles = NULL; + if (!config->auto_entries) + return; + err = LibLocateHandle(ByProtocol, &FileSystemProtocol, NULL, &handle_count, &handles); if (!EFI_ERROR(err)) { UINTN i; @@ -1761,7 +1793,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { L"auto-efi-default", '\0', L"EFI Default Loader", L"\\EFI\\Boot\\boot" EFI_MACHINE_TYPE_NAME ".efi"); config_entry_add_osx(&config); - if (efivar_get_raw(&global_guid, L"OsIndicationsSupported", &b, &size) == EFI_SUCCESS) { + if (config.auto_firmware && efivar_get_raw(&global_guid, L"OsIndicationsSupported", &b, &size) == EFI_SUCCESS) { UINT64 osind = (UINT64)*b; if (osind & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c index 9c3bdd47de4..8f3faeecb39 100644 --- a/src/shared/bootspec.c +++ b/src/shared/bootspec.c @@ -142,6 +142,8 @@ void boot_config_free(BootConfig *config) { free(config->default_pattern); free(config->timeout); free(config->editor); + free(config->auto_entries); + free(config->auto_firmware); free(config->entry_oneshot); free(config->entry_default); @@ -194,6 +196,10 @@ int boot_loader_read_conf(const char *path, BootConfig *config) { r = free_and_strdup(&config->timeout, p); else if (streq(buf, "editor")) r = free_and_strdup(&config->editor, p); + else if (streq(buf, "auto-entries")) + r = free_and_strdup(&config->auto_entries, p); + else if (streq(buf, "auto-firmware")) + r = free_and_strdup(&config->auto_firmware, p); else { log_notice("%s:%u: Unknown line \"%s\"", path, line, buf); continue; diff --git a/src/shared/bootspec.h b/src/shared/bootspec.h index d9c641bf081..fe875454b1d 100644 --- a/src/shared/bootspec.h +++ b/src/shared/bootspec.h @@ -40,6 +40,8 @@ typedef struct BootConfig { char *default_pattern; char *timeout; char *editor; + char *auto_entries; + char *auto_firmware; char *entry_oneshot; char *entry_default; From 4c8c9f9f8a39b1e9798958241fe68bd7b7459073 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Sat, 6 Jan 2018 19:21:48 +0100 Subject: [PATCH 3/5] systemd-boot: Try harder not to add ourselves to the list We don't need to check if we are adding ourselves to the list if we know that it's the windows or EFI shell loaders. If we are adding the EFI default loader, additionally try to see if we can find the systemd-boot magic string and skip this entry if we do. --- src/boot/efi/boot.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index e0438281e1a..4768366c1ee 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1458,8 +1458,28 @@ static BOOLEAN config_entry_add_loader_auto(Config *config, EFI_HANDLE *device, return FALSE; /* do not add an entry for ourselves */ - if (loaded_image_path && StriCmp(loader, loaded_image_path) == 0) - return FALSE; + if (loaded_image_path) { + UINTN len; + CHAR8 *content; + + if (StriCmp(loader, loaded_image_path) == 0) + return FALSE; + + /* look for systemd-boot magic string */ + err = file_read(root_dir, loader, 0, 100*1024, &content, &len); + if (!EFI_ERROR(err)) { + CHAR8 *start = content; + CHAR8 *last = content + len - sizeof(magic) - 1; + + for (; start <= last; start++) + if (start[0] == magic[0] && CompareMem(start, magic, sizeof(magic) - 1) == 0) { + FreePool(content); + return FALSE; + } + + FreePool(content); + } + } /* check existence */ err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, loader, EFI_FILE_MODE_READ, 0ULL); @@ -1785,9 +1805,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { config_sort_entries(&config); /* if we find some well-known loaders, add them to the end of the list */ - config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path, + config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, NULL, L"auto-windows", 'w', L"Windows Boot Manager", L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"); - config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path, + config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, NULL, L"auto-efi-shell", 's', L"EFI Shell", L"\\shell" EFI_MACHINE_TYPE_NAME ".efi"); config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path, L"auto-efi-default", '\0', L"EFI Default Loader", L"\\EFI\\Boot\\boot" EFI_MACHINE_TYPE_NAME ".efi"); From 12643e7c4311a883dd732c40a06e96bc7b908111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 7 Mar 2018 08:55:04 +0100 Subject: [PATCH 4/5] systemd-boot: reduce indentation in config_entry_add_linux() No functional change. --- src/boot/efi/boot.c | 199 ++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 99 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 4768366c1ee..68b3e79155d 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1527,119 +1527,120 @@ static VOID config_entry_add_osx(Config *config) { } } -static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_image, EFI_FILE *root_dir) { +static VOID config_entry_add_linux(Config *config, EFI_LOADED_IMAGE *loaded_image, EFI_FILE *root_dir) { EFI_FILE_HANDLE linux_dir; EFI_STATUS err; ConfigEntry *entry; err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &linux_dir, L"\\EFI\\Linux", EFI_FILE_MODE_READ, 0ULL); - if (!EFI_ERROR(err)) { - for (;;) { - CHAR16 buf[256]; - UINTN bufsize; - EFI_FILE_INFO *f; - CHAR8 *sections[] = { - (UINT8 *)".osrel", - (UINT8 *)".cmdline", - NULL - }; - UINTN offs[ELEMENTSOF(sections)-1] = {}; - UINTN szs[ELEMENTSOF(sections)-1] = {}; - UINTN addrs[ELEMENTSOF(sections)-1] = {}; - CHAR8 *content = NULL; - UINTN len; - CHAR8 *line; - UINTN pos = 0; - CHAR8 *key, *value; - CHAR16 *os_name = NULL; - CHAR16 *os_id = NULL; - CHAR16 *os_version = NULL; - CHAR16 *os_build = NULL; + if (EFI_ERROR(err)) + return; - bufsize = sizeof(buf); - err = uefi_call_wrapper(linux_dir->Read, 3, linux_dir, &bufsize, buf); - if (bufsize == 0 || EFI_ERROR(err)) - break; + for (;;) { + CHAR16 buf[256]; + UINTN bufsize = sizeof buf; + EFI_FILE_INFO *f; + CHAR8 *sections[] = { + (UINT8 *)".osrel", + (UINT8 *)".cmdline", + NULL + }; + UINTN offs[ELEMENTSOF(sections)-1] = {}; + UINTN szs[ELEMENTSOF(sections)-1] = {}; + UINTN addrs[ELEMENTSOF(sections)-1] = {}; + CHAR8 *content = NULL; + UINTN len; + CHAR8 *line; + UINTN pos = 0; + CHAR8 *key, *value; + CHAR16 *os_name = NULL; + CHAR16 *os_id = NULL; + CHAR16 *os_version = NULL; + CHAR16 *os_build = NULL; - f = (EFI_FILE_INFO *) buf; - if (f->FileName[0] == '.') + err = uefi_call_wrapper(linux_dir->Read, 3, linux_dir, &bufsize, buf); + if (bufsize == 0 || EFI_ERROR(err)) + break; + + f = (EFI_FILE_INFO *) buf; + if (f->FileName[0] == '.') + continue; + if (f->Attribute & EFI_FILE_DIRECTORY) + continue; + len = StrLen(f->FileName); + if (len < 5) + continue; + if (StriCmp(f->FileName + len - 4, L".efi") != 0) + continue; + + /* look for .osrel and .cmdline sections in the .efi binary */ + err = pe_file_locate_sections(linux_dir, f->FileName, sections, addrs, offs, szs); + if (EFI_ERROR(err)) + continue; + + err = file_read(linux_dir, f->FileName, offs[0], szs[0], &content, NULL); + if (EFI_ERROR(err)) + continue; + + /* read properties from the embedded os-release file */ + line = content; + while ((line = line_get_key_value(content, (CHAR8 *)"=", &pos, &key, &value))) { + if (strcmpa((CHAR8 *)"PRETTY_NAME", key) == 0) { + FreePool(os_name); + os_name = stra_to_str(value); continue; - if (f->Attribute & EFI_FILE_DIRECTORY) - continue; - len = StrLen(f->FileName); - if (len < 5) - continue; - if (StriCmp(f->FileName + len - 4, L".efi") != 0) - continue; - - /* look for .osrel and .cmdline sections in the .efi binary */ - err = pe_file_locate_sections(linux_dir, f->FileName, sections, addrs, offs, szs); - if (EFI_ERROR(err)) - continue; - - err = file_read(linux_dir, f->FileName, offs[0], szs[0], &content, NULL); - if (EFI_ERROR(err)) - continue; - - /* read properties from the embedded os-release file */ - line = content; - while ((line = line_get_key_value(content, (CHAR8 *)"=", &pos, &key, &value))) { - if (strcmpa((CHAR8 *)"PRETTY_NAME", key) == 0) { - FreePool(os_name); - os_name = stra_to_str(value); - continue; - } - - if (strcmpa((CHAR8 *)"ID", key) == 0) { - FreePool(os_id); - os_id = stra_to_str(value); - continue; - } - - if (strcmpa((CHAR8 *)"VERSION_ID", key) == 0) { - FreePool(os_version); - os_version = stra_to_str(value); - continue; - } - - if (strcmpa((CHAR8 *)"BUILD_ID", key) == 0) { - FreePool(os_build); - os_build = stra_to_str(value); - continue; - } } - if (os_name && os_id && (os_version || os_build)) { - CHAR16 *conf; - CHAR16 *path; - CHAR16 *cmdline; - - conf = PoolPrint(L"%s-%s", os_id, os_version ? : os_build); - path = PoolPrint(L"\\EFI\\Linux\\%s", f->FileName); - entry = config_entry_add_loader(config, loaded_image->DeviceHandle, LOADER_LINUX, conf, 'l', os_name, path); - - FreePool(content); - content = NULL; - /* read the embedded cmdline file */ - err = file_read(linux_dir, f->FileName, offs[1], szs[1] - 1, &content, NULL); - if (!EFI_ERROR(err)) { - cmdline = stra_to_str(content); - entry->options = cmdline; - cmdline = NULL; - } - FreePool(cmdline); - FreePool(conf); - FreePool(path); + if (strcmpa((CHAR8 *)"ID", key) == 0) { + FreePool(os_id); + os_id = stra_to_str(value); + continue; } - FreePool(os_name); - FreePool(os_id); - FreePool(os_version); - FreePool(os_build); - FreePool(content); + if (strcmpa((CHAR8 *)"VERSION_ID", key) == 0) { + FreePool(os_version); + os_version = stra_to_str(value); + continue; + } + + if (strcmpa((CHAR8 *)"BUILD_ID", key) == 0) { + FreePool(os_build); + os_build = stra_to_str(value); + continue; + } } - uefi_call_wrapper(linux_dir->Close, 1, linux_dir); + + if (os_name && os_id && (os_version || os_build)) { + CHAR16 *conf; + CHAR16 *path; + CHAR16 *cmdline; + + conf = PoolPrint(L"%s-%s", os_id, os_version ? : os_build); + path = PoolPrint(L"\\EFI\\Linux\\%s", f->FileName); + entry = config_entry_add_loader(config, loaded_image->DeviceHandle, LOADER_LINUX, conf, 'l', os_name, path); + + FreePool(content); + content = NULL; + /* read the embedded cmdline file */ + err = file_read(linux_dir, f->FileName, offs[1], szs[1] - 1, &content, NULL); + if (!EFI_ERROR(err)) { + cmdline = stra_to_str(content); + entry->options = cmdline; + cmdline = NULL; + } + FreePool(cmdline); + FreePool(conf); + FreePool(path); + } + + FreePool(os_name); + FreePool(os_id); + FreePool(os_version); + FreePool(os_build); + FreePool(content); } + + uefi_call_wrapper(linux_dir->Close, 1, linux_dir); } static EFI_STATUS image_start(EFI_HANDLE parent_image, const Config *config, const ConfigEntry *entry) { From 70756b3b4da53dce771176ffc71bd90dd5c7e040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 7 Mar 2018 08:51:09 +0100 Subject: [PATCH 5/5] systemd-boot: fix off-by-one buffer overrun We'd allocate a buffer of some size and then write zero to the byte one after. --- src/boot/efi/util.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index bff8ba8d206..cd75c13f2b4 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -327,16 +327,15 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, CHAR16 *name, UINTN off, UINTN size, C return err; } - buf = AllocatePool(size); + buf = AllocatePool(size + 1); err = uefi_call_wrapper(handle->Read, 3, handle, &size, buf); if (!EFI_ERROR(err)) { buf[size] = '\0'; *content = buf; if (content_size) *content_size = size; - } else { + } else FreePool(buf); - } uefi_call_wrapper(handle->Close, 1, handle); return err;