From 07e43365379ef5bd9fb53a45306af02025442b92 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Fri, 7 Mar 2025 14:09:34 +0800
Subject: [PATCH 1/2] Fix SbatLevelRT prediction when Secure Boot is disabled

Since shim 15.8, instead of using SBAT automatic as the default
candidate, it always resets SbatLevel to SBAT_ORIGINAL. To make the
prediction work for shim >= 15.8, the additinal check is added to adjust
the SBAT candidate.

Also fix POLICY_RESET for not setting sbat_reset to true and a few
typos.

Signed-off-by: Gary Lin <glin@suse.com>
---
 src/efi-variable.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/src/efi-variable.c b/src/efi-variable.c
index 9c56eec..b70f63b 100644
--- a/src/efi-variable.c
+++ b/src/efi-variable.c
@@ -100,6 +100,7 @@ __tpm_event_efi_variable_build_event(const tpm_parsed_event_t *parsed, const voi
 #define POLICY_LATEST		1
 #define POLICY_AUTOMATIC	2
 #define POLICY_RESET		3
+#define POLICY_NOTREAD		255
 
 #define SBAT_ORIGINAL "sbat,1,2021030218\n"
 
@@ -169,6 +170,7 @@ efi_sbatlevel_get_record(buffer_t *sbatlevel)
 	buffer_t *result = NULL;
 	uint8_t secureboot;
 	uint8_t sbatpolicy;
+	uint32_t auto_date;
 	uint32_t current_date;
 	uint32_t candidate_date;
 	bool sbat_reset = false;
@@ -178,6 +180,11 @@ efi_sbatlevel_get_record(buffer_t *sbatlevel)
 		return NULL;
 	}
 
+	if (!fetch_sbat_datestamp(sbat_automatic, strlen(sbat_automatic), &auto_date)) {
+		error("Unable to get datestamp of SBAT automatic\n");
+		return NULL;
+	}
+
 	buffer = runtime_read_efi_variable(SECUREBOOT_VARNAME);
 	if (buffer == NULL || !buffer_get_u8(buffer, &secureboot))
 		secureboot = 0;
@@ -185,7 +192,7 @@ efi_sbatlevel_get_record(buffer_t *sbatlevel)
 
 	buffer = runtime_read_efi_variable(SBATPOLICY_VARNAME);
 	if (buffer == NULL || !buffer_get_u8(buffer, &sbatpolicy))
-		sbatpolicy = POLICY_AUTOMATIC;
+		sbatpolicy = POLICY_NOTREAD;
 	buffer_free(buffer);
 
 	switch (sbatpolicy) {
@@ -200,9 +207,24 @@ efi_sbatlevel_get_record(buffer_t *sbatlevel)
 			infomsg("SBAT cannot be reset when Secure Boot is enabled.\n");
 			sbat_candidate = sbat_automatic;
 		} else {
+			sbat_reset = true;
 			sbat_candidate = SBAT_ORIGINAL;
 		}
 		break;
+	case POLICY_NOTREAD:
+		if (secureboot == 1) {
+			sbat_candidate = sbat_automatic;
+		} else {
+			/* shim 15.8 always resets SbatLevel when Secure Boot is disabled.
+			 * The automatic datestamp of shim 15.8 is 2023012900. */
+			if (auto_date >= 2023012900) {
+				sbat_reset = true;
+				sbat_candidate = SBAT_ORIGINAL;
+			} else {
+				sbat_candidate = sbat_automatic;
+			}
+		}
+		break;
 	default:
 		error("Invalid SBAT policy\n");
 		return NULL;
@@ -217,12 +239,12 @@ efi_sbatlevel_get_record(buffer_t *sbatlevel)
 
 	if (!fetch_sbat_datestamp(sbat_current, sbatlvlrt->size, &current_date)
 	 || !fetch_sbat_datestamp(sbat_candidate, strlen(sbat_candidate), &candidate_date)) {
-		error("Unable to get SBAT timestamp\n");
+		error("Unable to get SBAT datestamp\n");
 		goto fail;
 	}
 
-	debug("Current SBAT datestampe: %u\n", current_date);
-	debug("Candidate SBAT datestampe: %u\n", candidate_date);
+	debug("Current SBAT datestamp: %u\n", current_date);
+	debug("Candidate SBAT datestamp: %u\n", candidate_date);
 
 	if (current_date >= candidate_date && sbat_reset == false) {
 		debug("Use current SbatLevel\n");
-- 
2.43.0

