Blame SOURCES/0014-Make-sbat_var.S-parse-right-with-buggy-gcc-binutils.patch

9de34f
From 657b2483ca6e9fcf2ad8ac7ee577ff546d24c3aa Mon Sep 17 00:00:00 2001
9de34f
From: Peter Jones <pjones@redhat.com>
9de34f
Date: Mon, 5 Dec 2022 17:57:36 -0500
9de34f
Subject: [PATCH] Make sbat_var.S parse right with buggy gcc/binutils
9de34f
9de34f
In https://github.com/rhboot/shim/issues/533 , iokomin noticed that
9de34f
gas in binutils before 2.36 appears to be incorrectly concatenating
9de34f
string literals in '.asciz' directives, including an extra NUL character
9de34f
in between the strings, and this will cause us to incorrectly parse the
9de34f
.sbatlevel section in shim binaries.
9de34f
9de34f
This patch adds test cases that will cause the build to fail if this has
9de34f
happened, as well as changing sbat_var.S to to use '.ascii' and '.byte'
9de34f
to construct the data, rather than using '.asciz'.
9de34f
9de34f
Signed-off-by: Peter Jones <pjones@redhat.com>
9de34f
---
9de34f
 test-sbat.c     | 32 ++++++++++++++++++++++++++++++++
9de34f
 sbat_var.S      |  6 ++++--
9de34f
 include/test.mk |  2 +-
9de34f
 3 files changed, 37 insertions(+), 3 deletions(-)
9de34f
9de34f
diff --git a/test-sbat.c b/test-sbat.c
9de34f
index 72bebe7ae63..65bc6a84baa 100644
9de34f
--- a/test-sbat.c
9de34f
+++ b/test-sbat.c
9de34f
@@ -1107,6 +1107,36 @@ test_preserve_sbat_uefi_variable_bad_short(void)
9de34f
 		return 0;
9de34f
 }
9de34f
 
9de34f
+static int
9de34f
+test_sbat_var_asciz(void)
9de34f
+{
9de34f
+	EFI_STATUS status;
9de34f
+	char buf[1024] = "";
9de34f
+	UINT32 attrs = 0;
9de34f
+	UINTN size = sizeof(buf);
9de34f
+	char expected[] = SBAT_VAR_PREVIOUS;
9de34f
+
9de34f
+	status = set_sbat_uefi_variable();
9de34f
+	if (status != EFI_SUCCESS)
9de34f
+		return -1;
9de34f
+
9de34f
+	status = RT->GetVariable(SBAT_VAR_NAME, &SHIM_LOCK_GUID, &attrs, &size, buf);
9de34f
+	if (status != EFI_SUCCESS)
9de34f
+		return -1;
9de34f
+
9de34f
+	/*
9de34f
+	 * this should be enough to get past "sbat,", which handles the
9de34f
+	 * first error.
9de34f
+	 */
9de34f
+	if (size < (strlen(SBAT_VAR_SIG) + 2) || size != strlen(expected))
9de34f
+		return -1;
9de34f
+
9de34f
+	if (strncmp(expected, buf, size) != 0)
9de34f
+		return -1;
9de34f
+
9de34f
+	return 0;
9de34f
+}
9de34f
+
9de34f
 int
9de34f
 main(void)
9de34f
 {
9de34f
@@ -1155,6 +1185,8 @@ main(void)
9de34f
 	test(test_preserve_sbat_uefi_variable_version_older);
9de34f
 	test(test_preserve_sbat_uefi_variable_version_olderlonger);
9de34f
 
9de34f
+	test(test_sbat_var_asciz);
9de34f
+
9de34f
 	return 0;
9de34f
 }
9de34f
 
9de34f
diff --git a/sbat_var.S b/sbat_var.S
9de34f
index a115077ae4d..2a813a403b4 100644
9de34f
--- a/sbat_var.S
9de34f
+++ b/sbat_var.S
9de34f
@@ -14,7 +14,9 @@ sbat_var_payload_header:
9de34f
 .Lsbat_var_payload_header_end:
9de34f
 	.balign	1, 0
9de34f
 .Lsbat_var_previous:
9de34f
-	.asciz SBAT_VAR_PREVIOUS
9de34f
+	.ascii SBAT_VAR_PREVIOUS
9de34f
+	.byte	0
9de34f
 	.balign	1, 0
9de34f
 .Lsbat_var_latest:
9de34f
-	.asciz SBAT_VAR_LATEST
9de34f
+	.ascii SBAT_VAR_LATEST
9de34f
+	.byte 0
9de34f
diff --git a/include/test.mk b/include/test.mk
9de34f
index c0e2409517a..c37b84466ed 100644
9de34f
--- a/include/test.mk
9de34f
+++ b/include/test.mk
9de34f
@@ -92,7 +92,7 @@ test-mock-variables: CFLAGS+=-DHAVE_SHIM_LOCK_GUID
9de34f
 test-mok-mirror_FILES = mok.c globals.c tpm.c lib/guid.c lib/variables.c mock-variables.c
9de34f
 test-mok-mirror: CFLAGS+=-DHAVE_START_IMAGE -DHAVE_SHIM_LOCK_GUID
9de34f
 
9de34f
-test-sbat_FILES = csv.c lib/variables.c lib/guid.c sbat_var.S
9de34f
+test-sbat_FILES = csv.c lib/variables.c lib/guid.c sbat_var.S mock-variables.c
9de34f
 test-sbat :: CFLAGS+=-DHAVE_GET_VARIABLE -DHAVE_GET_VARIABLE_ATTR -DHAVE_SHIM_LOCK_GUID
9de34f
 
9de34f
 test-str_FILES = lib/string.c
9de34f
-- 
9de34f
2.38.1
9de34f