Skip to content

Commit 18a411c

Browse files
committed
Merge tag 'efi-next-for-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi
Pull EFI updates from Ard Biesheuvel: "Just some cleanups and bug fixes this time around: - Align handling of the compiled-in command line with the core kernel - Measure the initrd into the TPM also when it was loaded via the EFI file I/O protocols - Clean up TPM event log handling - Sanity check the EFI memory attributes table, and apply it after kexec too - Assorted other fixes" * tag 'efi-next-for-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi: efi: Fix memory leak in efivar_ssdt_load efi/libstub: Take command line overrides into account for loaded files efi/libstub: Fix command line fallback handling when loading files efi/libstub: Parse builtin command line after bootloader provided one x86/efi: Apply EFI Memory Attributes after kexec x86/efi: Drop support for the EFI_PROPERTIES_TABLE efi/memattr: Ignore table if the size is clearly bogus efi/zboot: Fix outdated comment about using LoadImage/StartImage efi/libstub: Free correct pointer on failure libstub,tpm: do not ignore failure case when reading final event log tpm: fix unsigned/signed mismatch errors related to __calc_tpm2_event_size tpm: do not ignore memblock_reserve return value tpm: fix signed/unsigned bug when checking event logs efi/libstub: measure initrd to PCR9 independent of source efi/libstub: remove unnecessary cmd_line_len from efi_convert_cmdline() efi/libstub: fix efi_parse_options() ignoring the default command line
2 parents fcb3ad4 + c5d91b1 commit 18a411c

File tree

14 files changed

+117
-133
lines changed

14 files changed

+117
-133
lines changed

arch/x86/platform/efi/efi.c

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,12 @@
5454
#include <asm/uv/uv.h>
5555

5656
static unsigned long efi_systab_phys __initdata;
57-
static unsigned long prop_phys = EFI_INVALID_TABLE_ADDR;
5857
static unsigned long uga_phys = EFI_INVALID_TABLE_ADDR;
5958
static unsigned long efi_runtime, efi_nr_tables;
6059

6160
unsigned long efi_fw_vendor, efi_config_table;
6261

6362
static const efi_config_table_type_t arch_tables[] __initconst = {
64-
{EFI_PROPERTIES_TABLE_GUID, &prop_phys, "PROP" },
6563
{UGA_IO_PROTOCOL_GUID, &uga_phys, "UGA" },
6664
#ifdef CONFIG_X86_UV
6765
{UV_SYSTEM_TABLE_GUID, &uv_systab_phys, "UVsystab" },
@@ -82,7 +80,6 @@ static const unsigned long * const efi_tables[] = {
8280
&efi_runtime,
8381
&efi_config_table,
8482
&efi.esrt,
85-
&prop_phys,
8683
&efi_mem_attr_table,
8784
#ifdef CONFIG_EFI_RCI2_TABLE
8885
&rci2_table_phys,
@@ -502,22 +499,6 @@ void __init efi_init(void)
502499
return;
503500
}
504501

505-
/* Parse the EFI Properties table if it exists */
506-
if (prop_phys != EFI_INVALID_TABLE_ADDR) {
507-
efi_properties_table_t *tbl;
508-
509-
tbl = early_memremap_ro(prop_phys, sizeof(*tbl));
510-
if (tbl == NULL) {
511-
pr_err("Could not map Properties table!\n");
512-
} else {
513-
if (tbl->memory_protection_attribute &
514-
EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA)
515-
set_bit(EFI_NX_PE_DATA, &efi.flags);
516-
517-
early_memunmap(tbl, sizeof(*tbl));
518-
}
519-
}
520-
521502
set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
522503
efi_clean_memmap();
523504

@@ -784,6 +765,7 @@ static void __init kexec_enter_virtual_mode(void)
784765

785766
efi_sync_low_kernel_mappings();
786767
efi_native_runtime_setup();
768+
efi_runtime_update_mappings();
787769
#endif
788770
}
789771

arch/x86/platform/efi/efi_64.c

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -412,51 +412,9 @@ static int __init efi_update_mem_attr(struct mm_struct *mm, efi_memory_desc_t *m
412412

413413
void __init efi_runtime_update_mappings(void)
414414
{
415-
efi_memory_desc_t *md;
416-
417-
/*
418-
* Use the EFI Memory Attribute Table for mapping permissions if it
419-
* exists, since it is intended to supersede EFI_PROPERTIES_TABLE.
420-
*/
421415
if (efi_enabled(EFI_MEM_ATTR)) {
422416
efi_disable_ibt_for_runtime = false;
423417
efi_memattr_apply_permissions(NULL, efi_update_mem_attr);
424-
return;
425-
}
426-
427-
/*
428-
* EFI_MEMORY_ATTRIBUTES_TABLE is intended to replace
429-
* EFI_PROPERTIES_TABLE. So, use EFI_PROPERTIES_TABLE to update
430-
* permissions only if EFI_MEMORY_ATTRIBUTES_TABLE is not
431-
* published by the firmware. Even if we find a buggy implementation of
432-
* EFI_MEMORY_ATTRIBUTES_TABLE, don't fall back to
433-
* EFI_PROPERTIES_TABLE, because of the same reason.
434-
*/
435-
436-
if (!efi_enabled(EFI_NX_PE_DATA))
437-
return;
438-
439-
for_each_efi_memory_desc(md) {
440-
unsigned long pf = 0;
441-
442-
if (!(md->attribute & EFI_MEMORY_RUNTIME))
443-
continue;
444-
445-
if (!(md->attribute & EFI_MEMORY_WB))
446-
pf |= _PAGE_PCD;
447-
448-
if ((md->attribute & EFI_MEMORY_XP) ||
449-
(md->type == EFI_RUNTIME_SERVICES_DATA))
450-
pf |= _PAGE_NX;
451-
452-
if (!(md->attribute & EFI_MEMORY_RO) &&
453-
(md->type != EFI_RUNTIME_SERVICES_CODE))
454-
pf |= _PAGE_RW;
455-
456-
if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
457-
pf |= _PAGE_ENC;
458-
459-
efi_update_mappings(md, pf);
460418
}
461419
}
462420

drivers/firmware/efi/Kconfig

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,10 @@ config EFI_ZBOOT
8484
help
8585
Create the bootable image as an EFI application that carries the
8686
actual kernel image in compressed form, and decompresses it into
87-
memory before executing it via LoadImage/StartImage EFI boot service
88-
calls. For compatibility with non-EFI loaders, the payload can be
89-
decompressed and executed by the loader as well, provided that the
90-
loader implements the decompression algorithm and that non-EFI boot
91-
is supported by the encapsulated image. (The compression algorithm
92-
used is described in the zboot image header)
87+
memory before executing it. For compatibility with non-EFI loaders,
88+
the payload can be decompressed and executed by the loader as well,
89+
provided that the loader implements the decompression algorithm.
90+
(The compression algorithm used is described in the zboot header)
9391

9492
config EFI_ARMSTUB_DTB_LOADER
9593
bool "Enable the DTB loader"

drivers/firmware/efi/efi.c

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ static __init int efivar_ssdt_load(void)
273273
efi_char16_t *name = NULL;
274274
efi_status_t status;
275275
efi_guid_t guid;
276+
int ret = 0;
276277

277278
if (!efivar_ssdt[0])
278279
return 0;
@@ -294,8 +295,8 @@ static __init int efivar_ssdt_load(void)
294295
efi_char16_t *name_tmp =
295296
krealloc(name, name_size, GFP_KERNEL);
296297
if (!name_tmp) {
297-
kfree(name);
298-
return -ENOMEM;
298+
ret = -ENOMEM;
299+
goto out;
299300
}
300301
name = name_tmp;
301302
continue;
@@ -309,26 +310,38 @@ static __init int efivar_ssdt_load(void)
309310
pr_info("loading SSDT from variable %s-%pUl\n", efivar_ssdt, &guid);
310311

311312
status = efi.get_variable(name, &guid, NULL, &data_size, NULL);
312-
if (status != EFI_BUFFER_TOO_SMALL || !data_size)
313-
return -EIO;
313+
if (status != EFI_BUFFER_TOO_SMALL || !data_size) {
314+
ret = -EIO;
315+
goto out;
316+
}
314317

315318
data = kmalloc(data_size, GFP_KERNEL);
316-
if (!data)
317-
return -ENOMEM;
319+
if (!data) {
320+
ret = -ENOMEM;
321+
goto out;
322+
}
318323

319324
status = efi.get_variable(name, &guid, NULL, &data_size, data);
320325
if (status == EFI_SUCCESS) {
321-
acpi_status ret = acpi_load_table(data, NULL);
322-
if (ret)
323-
pr_err("failed to load table: %u\n", ret);
324-
else
326+
acpi_status acpi_ret = acpi_load_table(data, NULL);
327+
if (ACPI_FAILURE(acpi_ret)) {
328+
pr_err("efivar_ssdt: failed to load table: %u\n",
329+
acpi_ret);
330+
} else {
331+
/*
332+
* The @data will be in use by ACPI engine,
333+
* do not free it!
334+
*/
325335
continue;
336+
}
326337
} else {
327-
pr_err("failed to get var data: 0x%lx\n", status);
338+
pr_err("efivar_ssdt: failed to get var data: 0x%lx\n", status);
328339
}
329340
kfree(data);
330341
}
331-
return 0;
342+
out:
343+
kfree(name);
344+
return ret;
332345
}
333346
#else
334347
static inline int efivar_ssdt_load(void) { return 0; }
@@ -433,7 +446,9 @@ static int __init efisubsys_init(void)
433446
error = generic_ops_register();
434447
if (error)
435448
goto err_put;
436-
efivar_ssdt_load();
449+
error = efivar_ssdt_load();
450+
if (error)
451+
pr_err("efi: failed to load SSDT, error %d.\n", error);
437452
platform_device_register_simple("efivars", 0, NULL, 0);
438453
}
439454

drivers/firmware/efi/libstub/efi-stub-helper.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
327327
* Size of memory allocated return in *cmd_line_len.
328328
* Returns NULL on error.
329329
*/
330-
char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len)
330+
char *efi_convert_cmdline(efi_loaded_image_t *image)
331331
{
332332
const efi_char16_t *options = efi_table_attr(image, load_options);
333333
u32 options_size = efi_table_attr(image, load_options_size);
@@ -405,7 +405,6 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len)
405405
snprintf((char *)cmdline_addr, options_bytes, "%.*ls",
406406
options_bytes - 1, options);
407407

408-
*cmd_line_len = options_bytes;
409408
return (char *)cmdline_addr;
410409
}
411410

@@ -621,10 +620,6 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image,
621620
status = efi_load_initrd_dev_path(&initrd, hard_limit);
622621
if (status == EFI_SUCCESS) {
623622
efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
624-
if (initrd.size > 0 &&
625-
efi_measure_tagged_event(initrd.base, initrd.size,
626-
EFISTUB_EVT_INITRD) == EFI_SUCCESS)
627-
efi_info("Measured initrd data into PCR 9\n");
628623
} else if (status == EFI_NOT_FOUND) {
629624
status = efi_load_initrd_cmdline(image, &initrd, soft_limit,
630625
hard_limit);
@@ -637,6 +632,11 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image,
637632
if (status != EFI_SUCCESS)
638633
goto failed;
639634

635+
if (initrd.size > 0 &&
636+
efi_measure_tagged_event(initrd.base, initrd.size,
637+
EFISTUB_EVT_INITRD) == EFI_SUCCESS)
638+
efi_info("Measured initrd data into PCR 9\n");
639+
640640
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(initrd),
641641
(void **)&tbl);
642642
if (status != EFI_SUCCESS)

drivers/firmware/efi/libstub/efi-stub.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ static u32 get_supported_rt_services(void)
112112

113113
efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr)
114114
{
115-
int cmdline_size = 0;
116115
efi_status_t status;
117116
char *cmdline;
118117

@@ -121,35 +120,32 @@ efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr)
121120
* protocol. We are going to copy the command line into the
122121
* device tree, so this can be allocated anywhere.
123122
*/
124-
cmdline = efi_convert_cmdline(image, &cmdline_size);
123+
cmdline = efi_convert_cmdline(image);
125124
if (!cmdline) {
126125
efi_err("getting command line via LOADED_IMAGE_PROTOCOL\n");
127126
return EFI_OUT_OF_RESOURCES;
128127
}
129128

130-
if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
131-
IS_ENABLED(CONFIG_CMDLINE_FORCE) ||
132-
cmdline_size == 0) {
133-
status = efi_parse_options(CONFIG_CMDLINE);
134-
if (status != EFI_SUCCESS) {
135-
efi_err("Failed to parse options\n");
129+
if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
130+
status = efi_parse_options(cmdline);
131+
if (status != EFI_SUCCESS)
136132
goto fail_free_cmdline;
137-
}
138133
}
139134

140-
if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && cmdline_size > 0) {
141-
status = efi_parse_options(cmdline);
142-
if (status != EFI_SUCCESS) {
143-
efi_err("Failed to parse options\n");
135+
if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
136+
IS_ENABLED(CONFIG_CMDLINE_FORCE) ||
137+
cmdline[0] == 0) {
138+
status = efi_parse_options(CONFIG_CMDLINE);
139+
if (status != EFI_SUCCESS)
144140
goto fail_free_cmdline;
145-
}
146141
}
147142

148143
*cmdline_ptr = cmdline;
149144
return EFI_SUCCESS;
150145

151146
fail_free_cmdline:
152-
efi_bs_call(free_pool, cmdline_ptr);
147+
efi_err("Failed to parse options\n");
148+
efi_bs_call(free_pool, cmdline);
153149
return status;
154150
}
155151

drivers/firmware/efi/libstub/efistub.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ void efi_free(unsigned long size, unsigned long addr);
10561056

10571057
void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_size);
10581058

1059-
char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len);
1059+
char *efi_convert_cmdline(efi_loaded_image_t *image);
10601060

10611061
efi_status_t efi_get_memory_map(struct efi_boot_memmap **map,
10621062
bool install_cfg_tbl);

drivers/firmware/efi/libstub/file.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,12 @@ static efi_status_t efi_open_device_path(efi_file_protocol_t **volume,
175175
return status;
176176
}
177177

178+
#ifndef CONFIG_CMDLINE
179+
#define CONFIG_CMDLINE
180+
#endif
181+
182+
static const efi_char16_t builtin_cmdline[] = L"" CONFIG_CMDLINE;
183+
178184
/*
179185
* Check the cmdline for a LILO-style file= arguments.
180186
*
@@ -189,6 +195,8 @@ efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
189195
unsigned long *load_addr,
190196
unsigned long *load_size)
191197
{
198+
const bool ignore_load_options = IS_ENABLED(CONFIG_CMDLINE_OVERRIDE) ||
199+
IS_ENABLED(CONFIG_CMDLINE_FORCE);
192200
const efi_char16_t *cmdline = efi_table_attr(image, load_options);
193201
u32 cmdline_len = efi_table_attr(image, load_options_size);
194202
unsigned long efi_chunk_size = ULONG_MAX;
@@ -197,6 +205,7 @@ efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
197205
unsigned long alloc_addr;
198206
unsigned long alloc_size;
199207
efi_status_t status;
208+
bool twopass;
200209
int offset;
201210

202211
if (!load_addr || !load_size)
@@ -209,6 +218,16 @@ efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
209218
efi_chunk_size = EFI_READ_CHUNK_SIZE;
210219

211220
alloc_addr = alloc_size = 0;
221+
222+
if (!ignore_load_options && cmdline_len > 0) {
223+
twopass = IS_ENABLED(CONFIG_CMDLINE_BOOL) ||
224+
IS_ENABLED(CONFIG_CMDLINE_EXTEND);
225+
} else {
226+
do_builtin: cmdline = builtin_cmdline;
227+
cmdline_len = ARRAY_SIZE(builtin_cmdline) - 1;
228+
twopass = false;
229+
}
230+
212231
do {
213232
struct finfo fi;
214233
unsigned long size;
@@ -290,6 +309,9 @@ efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
290309
efi_call_proto(volume, close);
291310
} while (offset > 0);
292311

312+
if (twopass)
313+
goto do_builtin;
314+
293315
*load_addr = alloc_addr;
294316
*load_size = alloc_size;
295317

drivers/firmware/efi/libstub/tpm.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static void efi_retrieve_tcg2_eventlog(int version, efi_physical_addr_t log_loca
5757
struct linux_efi_tpm_eventlog *log_tbl = NULL;
5858
unsigned long first_entry_addr, last_entry_addr;
5959
size_t log_size, last_entry_size;
60-
int final_events_size = 0;
60+
u32 final_events_size = 0;
6161

6262
first_entry_addr = (unsigned long) log_location;
6363

@@ -110,9 +110,9 @@ static void efi_retrieve_tcg2_eventlog(int version, efi_physical_addr_t log_loca
110110
*/
111111
if (final_events_table && final_events_table->nr_events) {
112112
struct tcg_pcr_event2_head *header;
113-
int offset;
113+
u32 offset;
114114
void *data;
115-
int event_size;
115+
u32 event_size;
116116
int i = final_events_table->nr_events;
117117

118118
data = (void *)final_events_table;
@@ -124,6 +124,9 @@ static void efi_retrieve_tcg2_eventlog(int version, efi_physical_addr_t log_loca
124124
event_size = __calc_tpm2_event_size(header,
125125
(void *)(long)log_location,
126126
false);
127+
/* If calc fails this is a malformed log */
128+
if (!event_size)
129+
break;
127130
final_events_size += event_size;
128131
i--;
129132
}

0 commit comments

Comments
 (0)