File shim-bsc973496-mokmanager-no-append-write.patch of Package shim

From 3bd098ea88d36cdaa550cdd384f7a08d3586d7e5 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
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 <glin@suse.com>
---
 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 <glin@suse.com>
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 <glin@suse.com>
---
 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