From 3bd098ea88d36cdaa550cdd384f7a08d3586d7e5 Mon Sep 17 00:00:00 2001 From: Gary Lin Date: Thu, 28 Jul 2016 15:11:14 +0800 Subject: [PATCH 1/2] MokManager: Remove the usage of APPEND_WRITE We got the bug report about the usage of APPEND_WRITE that may cause the failure when writing a variable in Lenovo machines. Although EFI_VARIABLE_APPEND_WRITE already exists in the UEFI spec for years, unfortunately, some vendors just ignore it and never implement the attribute. This commit removes the usage of EFI_VARIABLE_APPEND_WRITE to make MokManager work on those machines. https://github.com/rhinstaller/shim/issues/55 Signed-off-by: Gary Lin --- MokManager.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/MokManager.c b/MokManager.c index 2de6853..9ed7b4b 100644 --- a/MokManager.c +++ b/MokManager.c @@ -23,8 +23,6 @@ #define SHIM_VENDOR L"Shim" #endif -#define EFI_VARIABLE_APPEND_WRITE 0x00000040 - EFI_GUID SHIM_LOCK_GUID = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }; EFI_GUID EFI_CERT_SHA224_GUID = { 0xb6e5233, 0xa65c, 0x44c9, {0x94, 0x7, 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd} }; EFI_GUID EFI_CERT_SHA384_GUID = { 0xff3e5307, 0x9fd0, 0x48c9, {0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1} }; @@ -863,6 +861,53 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt, return EFI_SUCCESS; } +static EFI_STATUS write_db (CHAR16 *db_name, void *MokNew, UINTN MokNewSize) +{ + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; + EFI_STATUS status; + UINT32 attributes; + void *old_data = NULL; + void *new_data = NULL; + UINTN old_size; + UINTN new_size; + + status = get_variable_attr(db_name, (UINT8 **)&old_data, &old_size, + shim_lock_guid, &attributes); + if (EFI_ERROR(status) && status != EFI_NOT_FOUND) { + return status; + } + + /* Check if the old db is compromised or not */ + if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) { + FreePool(old_data); + old_data = NULL; + old_size = 0; + } + + new_size = old_size + MokNewSize; + new_data = AllocatePool(new_size); + if (new_data == NULL) { + status = EFI_OUT_OF_RESOURCES; + goto out; + } + + CopyMem(new_data, old_data, old_size); + CopyMem(new_data + old_size, MokNew, MokNewSize); + + status = uefi_call_wrapper(RT->SetVariable, 5, db_name, + &shim_lock_guid, + EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS, + new_size, new_data); + +out: + if (old_size > 0) { + FreePool(old_data); + } + + return status; +} + static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate, BOOLEAN MokX) { @@ -917,12 +962,7 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate, 0, NULL); } else { /* Write new MOK */ - efi_status = uefi_call_wrapper(RT->SetVariable, 5, db_name, - &shim_lock_guid, - EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_APPEND_WRITE, - MokNewSize, MokNew); + efi_status = write_db(db_name, MokNew, MokNewSize); } if (efi_status != EFI_SUCCESS) { -- 2.9.2 From 3c000e67cc9c5ddd84f5a34b77e6ee8df4fe3ae5 Mon Sep 17 00:00:00 2001 From: Gary Lin Date: Wed, 3 Aug 2016 16:53:51 +0800 Subject: [PATCH 2/2] MokManager: Try APPEND_WRITE first Try to append the MOK/MOKX list first and then fallback to the normal SetVariable if the firmware doesn't support EFI_VARIABLE_APPEND_WRITE. Signed-off-by: Gary Lin --- MokManager.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MokManager.c b/MokManager.c index 9ed7b4b..3933ee0 100644 --- a/MokManager.c +++ b/MokManager.c @@ -871,6 +871,16 @@ static EFI_STATUS write_db (CHAR16 *db_name, void *MokNew, UINTN MokNewSize) UINTN old_size; UINTN new_size; + status = uefi_call_wrapper(RT->SetVariable, 5, db_name, + &shim_lock_guid, + EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_APPEND_WRITE, + MokNewSize, MokNew); + if (status == EFI_SUCCESS || status != EFI_INVALID_PARAMETER) { + return status; + } + status = get_variable_attr(db_name, (UINT8 **)&old_data, &old_size, shim_lock_guid, &attributes); if (EFI_ERROR(status) && status != EFI_NOT_FOUND) { -- 2.9.2