From d8c64b7f90b053d7bdf8d83133d9a4cc5be788dd Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Thu, 9 Jul 2015 13:02:54 +0200 Subject: [PATCH 1/2] boot: fix memleaks in os-release parser There is no guarantee that the os-release section contains each key only once, nor any guarantee that all keys are present. Make sure we properly free memory in both cases. Not that it matters much, as we're short-living, anyway. But correct code is always nicer to read.. --- src/boot/efi/boot.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index eb1a4e3b66..861adff29f 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1547,16 +1547,19 @@ static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_ima 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; } @@ -1571,11 +1574,11 @@ static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_ima config_entry_add_loader(config, loaded_image->DeviceHandle, LOADER_LINUX, conf, 'l', os_name, path); FreePool(conf); FreePool(path); - FreePool(os_name); - FreePool(os_id); - FreePool(os_version); } + FreePool(os_name); + FreePool(os_id); + FreePool(os_version); FreePool(content); } uefi_call_wrapper(linux_dir->Close, 1, linux_dir); From 59658d1958a7990722240e23c25163e98aa013c8 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Thu, 9 Jul 2015 13:04:58 +0200 Subject: [PATCH 2/2] boot: use BUILD_ID if VERSION_ID is not present According to os-release(5), VERSION_ID is not mandatory and BUILD_ID only needs to be unique underneath VERSION_ID. Therefore, assuming a missing VERSION_ID field means 'empty', we can rely on BUILD_ID to be unique. Use BUILD_ID if VERSION_ID is not present. This way, rolling-release distros can still provide a proper os-release entry without crafting random VERSION_ID strings. This fixes #186. --- src/boot/efi/boot.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 861adff29f..827c11844c 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1517,6 +1517,7 @@ static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_ima CHAR16 *os_name = NULL; CHAR16 *os_id = NULL; CHAR16 *os_version = NULL; + CHAR16 *os_build = NULL; bufsize = sizeof(buf); err = uefi_call_wrapper(linux_dir->Read, 3, linux_dir, &bufsize, buf); @@ -1563,13 +1564,19 @@ static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_ima 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) { + if (os_name && os_id && (os_version || os_build)) { CHAR16 *conf; CHAR16 *path; - conf = PoolPrint(L"%s-%s", os_id, os_version); + conf = PoolPrint(L"%s-%s", os_id, os_version ? : os_build); path = PoolPrint(L"\\EFI\\Linux\\%s", f->FileName); config_entry_add_loader(config, loaded_image->DeviceHandle, LOADER_LINUX, conf, 'l', os_name, path); FreePool(conf); @@ -1579,6 +1586,7 @@ static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_ima FreePool(os_name); FreePool(os_id); FreePool(os_version); + FreePool(os_build); FreePool(content); } uefi_call_wrapper(linux_dir->Close, 1, linux_dir);