diff options
| -rw-r--r-- | include/sbat.h | 3 | ||||
| -rw-r--r-- | pe.c | 93 | ||||
| -rw-r--r-- | sbat.c | 11 | ||||
| -rw-r--r-- | shim.c | 21 |
4 files changed, 63 insertions, 65 deletions
diff --git a/include/sbat.h b/include/sbat.h index 94ce01cb..9230b587 100644 --- a/include/sbat.h +++ b/include/sbat.h @@ -11,6 +11,7 @@ struct sbat_var { const CHAR8 *component_generation; list_t list; }; +extern list_t sbat_var; EFI_STATUS parse_sbat_var(list_t *entries); void cleanup_sbat_var(list_t *entries); @@ -27,7 +28,7 @@ struct sbat_entry { EFI_STATUS parse_sbat(char *sbat_base, size_t sbat_size, size_t *sbats, struct sbat_entry ***sbat); void cleanup_sbat_entries(size_t n, struct sbat_entry **entries); -EFI_STATUS verify_sbat(size_t n, struct sbat_entry **entries, list_t *var_entries); +EFI_STATUS verify_sbat(size_t n, struct sbat_entry **entries); #endif /* !SBAT_H_ */ // vim:fenc=utf-8:tw=75:noet @@ -1040,67 +1040,49 @@ handle_image (void *data, unsigned int datasize, if (secure_mode ()) { unsigned int i; - EFI_STATUS efi_status; size_t n; - struct sbat_entry **entries; - struct sbat_entry *entry = NULL; - list_t sbat_var_entries; - INIT_LIST_HEAD(&sbat_var_entries); - - if (SBATBase && SBATSize) { - char *sbat_data; - size_t sbat_size; - - sbat_size = SBATSize + 1; - sbat_data = AllocatePool(sbat_size); - if (!sbat_data) { - console_print(L"Failed to allocate SBAT buffer\n"); - return EFI_OUT_OF_RESOURCES; - } - CopyMem(sbat_data, SBATBase, SBATSize); - sbat_data[SBATSize] = '\0'; - - efi_status = parse_sbat(sbat_data, sbat_size, &n, &entries); - if (EFI_ERROR(efi_status)) { - perror(L"SBAT data not correct: %r\n", - efi_status); - return efi_status; - } + struct sbat_entry **entries = NULL; + char *sbat_data; + size_t sbat_size; - dprint(L"SBAT data\n"); - for (i = 0; i < n; i++) { - entry = entries[i]; - dprint(L"%a, %a, %a, %a, %a, %a\n", - entry->component_name, - entry->component_generation, - entry->vendor_name, - entry->vendor_package_name, - entry->vendor_version, - entry->vendor_url); - } - } else { - perror(L"SBAT data not found\n"); - return EFI_UNSUPPORTED; + if (SBATBase == NULL || SBATSize == 0) { + if (list_empty(&sbat_var)) + return EFI_SUCCESS; + dprint(L"No .sbat section data\n"); + return EFI_SECURITY_VIOLATION; } - efi_status = parse_sbat_var(&sbat_var_entries); - /* - * Until a SBAT variable is installed into the systems, it is expected that - * attempting to parse the variable will fail with an EFI_NOT_FOUND error. - * - * Do not consider that error fatal for now. - */ - if (EFI_ERROR(efi_status) && efi_status != EFI_NOT_FOUND) { - perror(L"Parsing SBAT variable failed: %r\n", - efi_status); + sbat_size = SBATSize + 1; + sbat_data = AllocatePool(sbat_size); + if (!sbat_data) { + console_print(L"Failed to allocate .sbat section buffer\n"); + return EFI_OUT_OF_RESOURCES; + } + CopyMem(sbat_data, SBATBase, SBATSize); + sbat_data[SBATSize] = '\0'; + + efi_status = parse_sbat(sbat_data, sbat_size, &n, &entries); + FreePool(sbat_data); + if (EFI_ERROR(efi_status)) { + perror(L"Could not parse .sbat section data: %r\n", efi_status); return efi_status; } - if (efi_status == EFI_SUCCESS) - efi_status = verify_sbat(n, entries, &sbat_var_entries); - if (efi_status == EFI_NOT_FOUND) - efi_status = EFI_SUCCESS; + dprint(L"SBAT data\n"); + for (i = 0; i < n; i++) { + dprint(L"%a, %a, %a, %a, %a, %a\n", + entries[i]->component_name, + entries[i]->component_generation, + entries[i]->vendor_name, + entries[i]->vendor_package_name, + entries[i]->vendor_version, + entries[i]->vendor_url); + } + efi_status = verify_sbat(n, entries); + if (entries) + for (i = 0; i < n; i++) + FreePool(entries[i]); if (EFI_ERROR(efi_status)) { if (verbose) console_print(L"Verification failed: %r\n", efi_status); @@ -1111,11 +1093,6 @@ handle_image (void *data, unsigned int datasize, efi_status = verify_buffer(data, datasize, &context, sha256hash, sha1hash); - - if (entries) - for (i = 0; i < n; i++) - FreePool(entries[i]); - if (EFI_ERROR(efi_status)) { if (verbose) console_print(L"Verification failed: %r\n", efi_status); @@ -194,20 +194,20 @@ cleanup_sbat_var(list_t *entries) } EFI_STATUS -verify_sbat(size_t n, struct sbat_entry **entries, list_t *sbat_entries) +verify_sbat(size_t n, struct sbat_entry **entries) { unsigned int i; list_t *pos = NULL; EFI_STATUS efi_status = EFI_SUCCESS; struct sbat_var *sbat_var_entry; - if (!entries || list_empty(sbat_entries)) { - dprint(L"SBAT variable not present or malformed\n"); - return EFI_INVALID_PARAMETER; + if (list_empty(&sbat_var)) { + dprint(L"SBAT variable not present\n"); + return EFI_SUCCESS; } for (i = 0; i < n; i++) { - list_for_each(pos, sbat_entries) { + list_for_each(pos, &sbat_var) { sbat_var_entry = list_entry(pos, struct sbat_var, list); efi_status = verify_single_entry(entries[i], sbat_var_entry); if (EFI_ERROR(efi_status)) @@ -216,7 +216,6 @@ verify_sbat(size_t n, struct sbat_entry **entries, list_t *sbat_entries) } dprint(L"all entries from SBAT section verified\n"); - cleanup_sbat_var(sbat_entries); return efi_status; } @@ -43,6 +43,8 @@ static CHAR16 *second_stage; void *load_options; UINT32 load_options_size; +list_t sbat_var; + /* * The vendor certificate used for validating the second stage loader */ @@ -1751,6 +1753,8 @@ shim_init(void) void shim_fini(void) { + cleanup_sbat_var(&sbat_var); + /* * Remove our protocols */ @@ -1853,11 +1857,13 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab) CHAR16 *msgs[] = { L"import_mok_state() failed", L"shim_init() failed", + L"import of SBAT data failed", NULL }; enum { IMPORT_MOK_STATE, SHIM_INIT, + IMPORT_SBAT, } msg = IMPORT_MOK_STATE; /* @@ -1888,6 +1894,21 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab) */ debug_hook(); + INIT_LIST_HEAD(&sbat_var); + efi_status = parse_sbat_var(&sbat_var); + /* + * Until a SBAT variable is installed into the systems, it is expected that + * attempting to parse the variable will fail with an EFI_NOT_FOUND error. + * + * Do not consider that error fatal for now. + */ + if (EFI_ERROR(efi_status) && efi_status != EFI_NOT_FOUND) { + perror(L"Parsing SBAT variable failed: %r\n", + efi_status); + msg = IMPORT_SBAT; + goto die; + } + /* * Before we do anything else, validate our non-volatile, * boot-services-only state variables are what we think they are. |
