summaryrefslogtreecommitdiff
path: root/shim.c
diff options
context:
space:
mode:
Diffstat (limited to 'shim.c')
-rw-r--r--shim.c107
1 files changed, 91 insertions, 16 deletions
diff --git a/shim.c b/shim.c
index f311914d..690cb091 100644
--- a/shim.c
+++ b/shim.c
@@ -86,6 +86,7 @@ int loader_is_participating;
#define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }}
UINT8 insecure_mode;
+UINT8 ignore_db;
typedef enum {
DATA_FOUND,
@@ -393,28 +394,31 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
EFI_GUID secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
EFI_GUID shim_var = SHIM_LOCK_GUID;
- if (check_db_hash(L"db", secure_var, sha256hash, SHA256_DIGEST_SIZE,
- EFI_CERT_SHA256_GUID) == DATA_FOUND) {
- update_verification_method(VERIFIED_BY_HASH);
- return EFI_SUCCESS;
- }
- if (check_db_hash(L"db", secure_var, sha1hash, SHA1_DIGEST_SIZE,
- EFI_CERT_SHA1_GUID) == DATA_FOUND) {
- verification_method = VERIFIED_BY_HASH;
- update_verification_method(VERIFIED_BY_HASH);
- return EFI_SUCCESS;
+ if (!ignore_db) {
+ if (check_db_hash(L"db", secure_var, sha256hash, SHA256_DIGEST_SIZE,
+ EFI_CERT_SHA256_GUID) == DATA_FOUND) {
+ update_verification_method(VERIFIED_BY_HASH);
+ return EFI_SUCCESS;
+ }
+ if (check_db_hash(L"db", secure_var, sha1hash, SHA1_DIGEST_SIZE,
+ EFI_CERT_SHA1_GUID) == DATA_FOUND) {
+ verification_method = VERIFIED_BY_HASH;
+ update_verification_method(VERIFIED_BY_HASH);
+ return EFI_SUCCESS;
+ }
+ if (check_db_cert(L"db", secure_var, cert, sha256hash) == DATA_FOUND) {
+ verification_method = VERIFIED_BY_CERT;
+ update_verification_method(VERIFIED_BY_CERT);
+ return EFI_SUCCESS;
+ }
}
+
if (check_db_hash(L"MokList", shim_var, sha256hash, SHA256_DIGEST_SIZE,
EFI_CERT_SHA256_GUID) == DATA_FOUND) {
verification_method = VERIFIED_BY_HASH;
update_verification_method(VERIFIED_BY_HASH);
return EFI_SUCCESS;
}
- if (check_db_cert(L"db", secure_var, cert, sha256hash) == DATA_FOUND) {
- verification_method = VERIFIED_BY_CERT;
- update_verification_method(VERIFIED_BY_CERT);
- return EFI_SUCCESS;
- }
if (check_db_cert(L"MokList", shim_var, cert, sha256hash) == DATA_FOUND) {
verification_method = VERIFIED_BY_CERT;
update_verification_method(VERIFIED_BY_CERT);
@@ -1428,7 +1432,7 @@ EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
if (check_var(L"MokNew") || check_var(L"MokSB") ||
check_var(L"MokPW") || check_var(L"MokAuth") ||
- check_var(L"MokDel")) {
+ check_var(L"MokDel") || check_var(L"MokDB")) {
efi_status = start_image(image_handle, MOK_MANAGER);
if (efi_status != EFI_SUCCESS) {
@@ -1482,6 +1486,71 @@ static EFI_STATUS check_mok_sb (void)
}
/*
+ * Verify that MokDBState is valid, and if appropriate set ignore db mode
+ */
+
+static EFI_STATUS check_mok_db (void)
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS status = EFI_SUCCESS;
+ UINT8 *MokDBState = NULL;
+ UINTN MokDBStateSize = 0;
+ UINT32 attributes;
+
+ status = get_variable_attr(L"MokDBState", &MokDBState, &MokDBStateSize,
+ shim_lock_guid, &attributes);
+
+ if (status != EFI_SUCCESS)
+ return EFI_ACCESS_DENIED;
+
+ ignore_db = 0;
+
+ /*
+ * Delete and ignore the variable if it's been set from or could be
+ * modified by the OS
+ */
+ if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
+ Print(L"MokDBState is compromised! Clearing it\n");
+ if (LibDeleteVariable(L"MokDBState", &shim_lock_guid) != EFI_SUCCESS) {
+ Print(L"Failed to erase MokDBState\n");
+ }
+ status = EFI_ACCESS_DENIED;
+ } else {
+ if (*(UINT8 *)MokDBState == 1) {
+ ignore_db = 1;
+ }
+ }
+
+ FreePool(MokDBState);
+
+ return status;
+}
+
+static EFI_STATUS mok_ignore_db()
+{
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
+ EFI_STATUS efi_status = EFI_SUCCESS;
+ UINT8 Data = 1;
+ UINTN DataSize = sizeof(UINT8);
+
+ check_mok_db();
+
+ if (ignore_db) {
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokIgnoreDB",
+ &shim_lock_guid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS
+ | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize, (void *)&Data);
+ if (efi_status != EFI_SUCCESS) {
+ Print(L"Failed to set MokIgnoreDB %d\n", efi_status);
+ }
+ }
+
+ return efi_status;
+
+}
+
+/*
* Check the load options to specify the second stage loader
*/
EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
@@ -1653,6 +1722,12 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
efi_status = mirror_mok_list();
/*
+ * Create the runtime MokIgnoreDB variable so the kernel can make
+ * use of it
+ */
+ efi_status = mok_ignore_db();
+
+ /*
* Hand over control to the second stage bootloader
*/