summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sbat.h3
-rw-r--r--pe.c93
-rw-r--r--sbat.c11
-rw-r--r--shim.c21
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
diff --git a/pe.c b/pe.c
index bd974843..dee34725 100644
--- a/pe.c
+++ b/pe.c
@@ -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);
diff --git a/sbat.c b/sbat.c
index a4b75b29..a917b0f8 100644
--- a/sbat.c
+++ b/sbat.c
@@ -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;
}
diff --git a/shim.c b/shim.c
index 57b86b19..a7ebaee1 100644
--- a/shim.c
+++ b/shim.c
@@ -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.