The image is not unloaded if a security violation occurs.
If efi_set_load_options() fails, we do not free the memory allocated for
the optional data. We do not unload the image.
* Unload the image if a security violation occurs.
* Free load_options if efi_set_load_options() fails.
* Unload the image if efi_set_load_options() fails.
Fixes: 53f6a5aa8626 ("efi_loader: Replace config option for initrd loading")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
void *load_option;
efi_uintn_t size;
efi_status_t ret;
+ u32 attributes;
- efi_create_indexed_name(varname, sizeof(varname), "Boot", n);
+ *handle = NULL;
+ *load_options = NULL;
+ efi_create_indexed_name(varname, sizeof(varname), "Boot", n);
load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
if (!load_option)
return EFI_LOAD_ERROR;
goto error;
}
- if (lo.attributes & LOAD_OPTION_ACTIVE) {
- u32 attributes;
-
- log_debug("trying to load \"%ls\" from %pD\n", lo.label,
- lo.file_path);
-
- if (EFI_DP_TYPE(lo.file_path, MEDIA_DEVICE, FILE_PATH)) {
- /* file_path doesn't contain a device path */
- ret = try_load_from_short_path(lo.file_path, handle);
- } else if (EFI_DP_TYPE(lo.file_path, MESSAGING_DEVICE, MSG_URI)) {
- if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT))
- ret = try_load_from_uri_path(
- (struct efi_device_path_uri *)lo.file_path,
- lo.label, handle);
- else
- ret = EFI_LOAD_ERROR;
- } else {
- ret = try_load_from_media(lo.file_path, handle);
- }
- if (ret != EFI_SUCCESS) {
- log_warning("Loading %ls '%ls' failed\n",
- varname, lo.label);
- goto error;
- }
+ if (!(lo.attributes & LOAD_OPTION_ACTIVE)) {
+ ret = EFI_LOAD_ERROR;
+ goto error;
+ }
- attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
- EFI_VARIABLE_RUNTIME_ACCESS;
- ret = efi_set_variable_int(u"BootCurrent",
- &efi_global_variable_guid,
- attributes, sizeof(n), &n, false);
- if (ret != EFI_SUCCESS)
- goto unload;
- /* try to register load file2 for initrd's */
- if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) {
- ret = efi_initrd_register();
- if (ret != EFI_SUCCESS)
- goto unload;
- }
+ log_debug("trying to load \"%ls\" from %pD\n", lo.label, lo.file_path);
- log_info("Booting: %ls\n", lo.label);
+ if (EFI_DP_TYPE(lo.file_path, MEDIA_DEVICE, FILE_PATH)) {
+ /* file_path doesn't contain a device path */
+ ret = try_load_from_short_path(lo.file_path, handle);
+ } else if (EFI_DP_TYPE(lo.file_path, MESSAGING_DEVICE, MSG_URI)) {
+ if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT))
+ ret = try_load_from_uri_path(
+ (struct efi_device_path_uri *)lo.file_path,
+ lo.label, handle);
+ else
+ ret = EFI_LOAD_ERROR;
} else {
- ret = EFI_LOAD_ERROR;
+ ret = try_load_from_media(lo.file_path, handle);
+ }
+ if (ret != EFI_SUCCESS) {
+ log_warning("Loading %ls '%ls' failed\n",
+ varname, lo.label);
+ goto error;
+ }
+
+ attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS;
+ ret = efi_set_variable_int(u"BootCurrent", &efi_global_variable_guid,
+ attributes, sizeof(n), &n, false);
+ if (ret != EFI_SUCCESS)
+ goto error;
+
+ /* try to register load file2 for initrd's */
+ if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) {
+ ret = efi_initrd_register();
+ if (ret != EFI_SUCCESS)
+ goto error;
}
- /* Set load options */
+ log_info("Booting: %ls\n", lo.label);
+
+ /* Ignore the optional data in auto-generated boot options */
if (size >= sizeof(efi_guid_t) &&
!guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated))
size = 0;
+ /* Set optional data in loaded file protocol */
if (size) {
*load_options = malloc(size);
if (!*load_options) {
}
memcpy(*load_options, lo.optional_data, size);
ret = efi_set_load_options(*handle, size, *load_options);
- } else {
- *load_options = NULL;
+ if (ret != EFI_SUCCESS)
+ free(load_options);
}
error:
- free(load_option);
-
- return ret;
-
-unload:
- if (EFI_CALL(efi_unload_image(*handle)) != EFI_SUCCESS)
+ if (ret != EFI_SUCCESS && *handle &&
+ EFI_CALL(efi_unload_image(*handle)) != EFI_SUCCESS)
log_err("Unloading image failed\n");
+
free(load_option);
return ret;
'efidebug boot order 1',
'efidebug test bootmgr'])
assert('\'HELLO1\' failed' in ''.join(output))
- assert('efi_start_image() returned: 26' in ''.join(output))
+ assert('efi_bootmgr_load() returned: 26' in ''.join(output))
output = u_boot_console.run_command_list([
'efidebug boot add -b 2 HELLO2 host 0:1 /helloworld.efi -s ""',
'efidebug boot order 2',
'efidebug test bootmgr'])
assert '\'HELLO2\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
with u_boot_console.log.section('Test Case 2b'):
# Test Case 2b, authenticated by db
'efidebug boot order 2',
'efidebug test bootmgr'])
assert '\'HELLO2\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
output = u_boot_console.run_command_list([
'efidebug boot order 1',
'bootefi bootmgr'])
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
with u_boot_console.log.section('Test Case 3b'):
# Test Case 3b, rejected by dbx even if db allows
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
def test_efi_signed_image_auth4(self, u_boot_console, efi_boot_env):
"""
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
def test_efi_signed_image_auth5(self, u_boot_console, efi_boot_env):
"""
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
with u_boot_console.log.section('Test Case 5d'):
# Test Case 5d, rejected if both of signatures are revoked
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
# Try rejection in reverse order.
u_boot_console.restart_uboot()
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
def test_efi_signed_image_auth6(self, u_boot_console, efi_boot_env):
"""
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
with u_boot_console.log.section('Test Case 6c'):
# Test Case 6c, rejected by image's digest in dbx
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
def test_efi_signed_image_auth7(self, u_boot_console, efi_boot_env):
"""
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
# sha512 of an x509 cert in dbx
u_boot_console.restart_uboot()
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
def test_efi_signed_image_auth8(self, u_boot_console, efi_boot_env):
"""
'efidebug test bootmgr'])
assert(not 'hELLO, world!' in ''.join(output))
assert('\'HELLO1\' failed' in ''.join(output))
- assert('efi_start_image() returned: 26' in ''.join(output))
+ assert('efi_bootmgr_load() returned: 26' in ''.join(output))
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO_a\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
with u_boot_console.log.section('Test Case 1b'):
# Test Case 1b, signed and authenticated by root CA
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
with u_boot_console.log.section('Test Case 2b'):
# Test Case 2b, signed and authenticated by root CA
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
with u_boot_console.log.section('Test Case 2c'):
# Test Case 2c, signed and authenticated by root CA
assert 'Hello, world!' in ''.join(output)
# Or,
# assert '\'HELLO_abc\' failed' in ''.join(output)
- # assert 'efi_start_image() returned: 26' in ''.join(output)
+ # assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
with u_boot_console.log.section('Test Case 3b'):
# Test Case 3b, revoked by root CA in dbx
'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
output = u_boot_console.run_command_list([
'efidebug boot order 1',
'efidebug test bootmgr'])
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
assert 'Hello, world!' not in ''.join(output)
def test_efi_unsigned_image_auth2(self, u_boot_console, efi_boot_env):
output = u_boot_console.run_command_list([
'efidebug boot order 1',
'efidebug test bootmgr'])
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
assert 'Hello, world!' not in ''.join(output)
with u_boot_console.log.section('Test Case 3b'):
output = u_boot_console.run_command_list([
'efidebug boot order 1',
'efidebug test bootmgr'])
- assert 'efi_start_image() returned: 26' in ''.join(output)
+ assert 'efi_bootmgr_load() returned: 26' in ''.join(output)
assert 'Hello, world!' not in ''.join(output)