From 221206b4da6e6e8e3d2782f3903956e55299be40 Mon Sep 17 00:00:00 2001
From: "Luke T. Shumaker" <lukeshu@lukeshu.com>
Date: Thu, 30 May 2024 14:15:06 -0600
Subject: Fix building vboot on i686

---
 .../0001-don-t-treat-warnings-as-errors.patch      |  26 ---
 ...inuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch | 178 +++++++++++++++++++++
 .../0001-don-t-treat-warnings-as-errors.patch      |  35 ----
 ...inuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch | 178 +++++++++++++++++++++
 .../0001-don-t-treat-warnings-as-errors.patch      |  35 ----
 ...inuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch | 178 +++++++++++++++++++++
 .../0001-don-t-treat-warnings-as-errors.patch      |  26 ---
 ...inuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch | 178 +++++++++++++++++++++
 .../0001-don-t-treat-warnings-as-errors.patch      |  26 ---
 ...inuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch | 178 +++++++++++++++++++++
 .../0001-don-t-treat-warnings-as-errors.patch      |  35 ----
 ...inuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch | 178 +++++++++++++++++++++
 .../0001-don-t-treat-warnings-as-errors.patch      |  35 ----
 ...inuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch | 178 +++++++++++++++++++++
 14 files changed, 1246 insertions(+), 218 deletions(-)
 delete mode 100644 config/submodule/coreboot/coreboot413/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
 create mode 100644 config/submodule/coreboot/coreboot413/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
 delete mode 100644 config/submodule/coreboot/default/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
 create mode 100644 config/submodule/coreboot/default/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
 delete mode 100644 config/submodule/coreboot/dell/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
 create mode 100644 config/submodule/coreboot/dell/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
 delete mode 100644 config/submodule/coreboot/fam15h_rdimm/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
 create mode 100644 config/submodule/coreboot/fam15h_rdimm/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
 delete mode 100644 config/submodule/coreboot/fam15h_udimm/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
 create mode 100644 config/submodule/coreboot/fam15h_udimm/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
 delete mode 100644 config/submodule/coreboot/haswell/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
 create mode 100644 config/submodule/coreboot/haswell/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
 delete mode 100644 config/submodule/coreboot/i945/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
 create mode 100644 config/submodule/coreboot/i945/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch

diff --git a/config/submodule/coreboot/coreboot413/vboot/patches/0001-don-t-treat-warnings-as-errors.patch b/config/submodule/coreboot/coreboot413/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
deleted file mode 100644
index eb491a37..00000000
--- a/config/submodule/coreboot/coreboot413/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 49569081d248e6eea3d4fb8a2cfb70154d9fd91f Mon Sep 17 00:00:00 2001
-From: Leah Rowe <info@minifree.org>
-Date: Tue, 21 May 2024 23:14:51 +0100
-Subject: [PATCH 1/1] don't treat warnings as errors
-
-Signed-off-by: Leah Rowe <info@minifree.org>
----
- Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/Makefile b/Makefile
-index 8f1bd148..67a282ee 100644
---- a/Makefile
-+++ b/Makefile
-@@ -124,7 +124,7 @@ endif
- # Provide default CC and CFLAGS for firmware builds; if you have any -D flags,
- # please add them after this point (e.g., -DVBOOT_DEBUG).
- DEBUG_FLAGS := $(if ${DEBUG},-g -O0,-g -Os)
--WERROR := -Werror
-+WERROR := -Wno-error -w
- FIRMWARE_FLAGS := -nostdinc -ffreestanding -fno-builtin -fno-stack-protector
- COMMON_FLAGS := -pipe ${WERROR} -Wall -Wstrict-prototypes -Wtype-limits \
- 	-Wundef -Wmissing-prototypes -Wno-trigraphs -Wredundant-decls -Wshadow \
--- 
-2.39.2
-
diff --git a/config/submodule/coreboot/coreboot413/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch b/config/submodule/coreboot/coreboot413/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
new file mode 100644
index 00000000..1ac41de6
--- /dev/null
+++ b/config/submodule/coreboot/coreboot413/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
@@ -0,0 +1,178 @@
+From 195f61375aeec9eec16604ec59f6eda2e6058cc1 Mon Sep 17 00:00:00 2001
+From: "Luke T. Shumaker" <lukeshu@lukeshu.com>
+Date: Thu, 30 May 2024 14:08:33 -0600
+Subject: [PATCH 1/1] extract_vmlinuz.c: Fix the bounds check on
+ vmlinuz_header_{offset,size}
+
+The check on vmlinuz_header_offset and vmlinuz_header_size is obviously
+wrong:
+
+	if (!vmlinuz_header_size ||
+	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+	    kpart_data) {
+		return 1;
+	}
+
+`kpart_data + some_unsigned_values` can obviously never be `> kpart_data`,
+unless something has overflowed!  And `vmlinuz_header_offset` hasn't even
+been set yet (besides being initialized to zero)!
+
+GCC will deduce that if the check didn't cause the function to bail, then
+vmlinuz_header_size (a uint32_t) must be "negative"; that is: in the range
+[2GiB,4GiB).
+
+On platforms where size_t is 32-bits, this is *especially* broken.
+memcpy's size argument must be in the range [0,2GiB).  Because GCC has
+proved that vmlinuz_header_size is higher than that, it will fail to
+compile:
+
+	host/lib/extract_vmlinuz.c:67:9: error: 'memcpy' specified bound between 2147483648 and 4294967295 exceeds maximum object size 2147483647 [-Werror=stringop-overflow=]
+
+So, fix the check.
+
+I can now say that what I suspect the original author meant to write would
+be the following patch, if `vmlinuz_header_offset` were already set:
+
+	-kpart_data + vmlinuz_header_offset + vmlinuz_header_size > kpart_data
+	+now        + vmlinuz_header_offset + vmlinuz_header_size > kpart_size
+
+This hypothesis is supported by `now` not getting incremented by
+`kblob_size` the way it is for the keyblock and preamble sizes.
+
+However, we can also see that even this "corrected" bounds check is
+insufficient: it does not detect the vmlinuz_header overflowing into
+kblob_data.
+
+OK, so let's describe the fix:
+
+Have a `*vmlinuz_header` pointer instead of a
+`uint64_t vmlinuz_header_offset`, to be more similar to all the other
+regions.  With this change, the correct check becomes a simple
+
+      vmlinuz_header + vmlinuz_header_size > kblob_data
+
+While we're at it, make some changes that could have helped avoid this in
+the first place:
+
+ - Add comments.
+ - Calculate the vmlinuz_header offset right away, instead of waiting.
+ - Go ahead and increment `now` by `kblob_size`, to increase regularity.
+
+Change-Id: I5c03e49070b6dd2e04459566ef7dd129d27736e4
+---
+ host/lib/extract_vmlinuz.c | 72 +++++++++++++++++++++++++++-----------
+ 1 file changed, 51 insertions(+), 21 deletions(-)
+
+diff --git a/host/lib/extract_vmlinuz.c b/host/lib/extract_vmlinuz.c
+index 4ccfcf33..d2c09443 100644
+--- a/host/lib/extract_vmlinuz.c
++++ b/host/lib/extract_vmlinuz.c
+@@ -15,16 +15,44 @@
+ 
+ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 		   void **vmlinuz_out, size_t *vmlinuz_size) {
++	// We're going to be extracting `vmlinuz_header` and
++	// `kblob_data`, and returning the concatenation of them.
++	//
++	// kpart_data = +-[kpart_size]------------------------------------+
++	//              |                                                 |
++	//  keyblock  = | +-[keyblock->keyblock_size]-------------------+ |
++	//              | | struct vb2_keyblock          keyblock       | |
++	//              | | char []                      ...data...     | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  preamble  = | +-[preamble->preamble_size]-------------------+ |
++	//              | | struct vb2_kernel_preamble   preamble       | |
++	//              | | char []                       ...data...    | |
++	//              | | char []                      vmlinuz_header | |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  kblob_data= | +-[preamble->body_signature.data_size]--------+ |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//              +-------------------------------------------------+
++
+ 	size_t now = 0;
++	// The 3 sections of kpart_data.
++	struct vb2_keyblock *keyblock = NULL;
+ 	struct vb2_kernel_preamble *preamble = NULL;
+ 	uint8_t *kblob_data = NULL;
+ 	uint32_t kblob_size = 0;
++	// vmlinuz_header
++	uint8_t *vmlinuz_header = NULL;
+ 	uint32_t vmlinuz_header_size = 0;
+-	uint64_t vmlinuz_header_address = 0;
+-	uint64_t vmlinuz_header_offset = 0;
++	// The concatenated result.
+ 	void *vmlinuz = NULL;
+ 
+-	struct vb2_keyblock *keyblock = (struct vb2_keyblock *)kpart_data;
++	// Isolate the 3 sections of kpart_data.
++
++	keyblock = (struct vb2_keyblock *)kpart_data;
+ 	now += keyblock->keyblock_size;
+ 	if (now > kpart_size)
+ 		return 1;
+@@ -36,37 +64,39 @@ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 
+ 	kblob_data = kpart_data + now;
+ 	kblob_size = preamble->body_signature.data_size;
+-
+-	if (!kblob_data || (now + kblob_size) > kpart_size)
++	now += kblob_size;
++	if (now > kpart_size)
+ 		return 1;
+ 
++	// Find `vmlinuz_header` within `preamble`.
++
+ 	if (preamble->header_version_minor > 0) {
+-		vmlinuz_header_address = preamble->vmlinuz_header_address;
++		// calculate the vmlinuz_header offset from
++		// the beginning of the kpart_data.  The kblob doesn't
++		// include the body_load_offset, but does include
++		// the keyblock and preamble sections.
++		size_t vmlinuz_header_offset =
++			preamble->vmlinuz_header_address -
++			preamble->body_load_address +
++			keyblock->keyblock_size +
++			preamble->preamble_size;
++
++		vmlinuz_header = kpart_data + vmlinuz_header_offset;
+ 		vmlinuz_header_size = preamble->vmlinuz_header_size;
+ 	}
+ 
+-	if (!vmlinuz_header_size ||
+-	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+-	    kpart_data) {
++	if (!vmlinuz_header ||
++	    !vmlinuz_header_size ||
++	    vmlinuz_header + vmlinuz_header_size > kblob_data) {
+ 		return 1;
+ 	}
+ 
+-	// calculate the vmlinuz_header offset from
+-	// the beginning of the kpart_data.  The kblob doesn't
+-	// include the body_load_offset, but does include
+-	// the keyblock and preamble sections.
+-	vmlinuz_header_offset = vmlinuz_header_address -
+-		preamble->body_load_address +
+-		keyblock->keyblock_size +
+-		preamble->preamble_size;
++	// Concatenate and return.
+ 
+ 	vmlinuz = malloc(vmlinuz_header_size + kblob_size);
+ 	if (vmlinuz == NULL)
+ 		return 1;
+-
+-	memcpy(vmlinuz, kpart_data + vmlinuz_header_offset,
+-	       vmlinuz_header_size);
+-
++	memcpy(vmlinuz, vmlinuz_header, vmlinuz_header_size);
+ 	memcpy(vmlinuz + vmlinuz_header_size, kblob_data, kblob_size);
+ 
+ 	*vmlinuz_out = vmlinuz;
+-- 
+2.45.1
+
diff --git a/config/submodule/coreboot/default/vboot/patches/0001-don-t-treat-warnings-as-errors.patch b/config/submodule/coreboot/default/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
deleted file mode 100644
index 9e14dc7d..00000000
--- a/config/submodule/coreboot/default/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From d94300a671688746f2fb3d77eefa631a3ed90306 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <info@minifree.org>
-Date: Sun, 19 May 2024 23:35:52 +0100
-Subject: [PATCH 1/1] don't treat warnings as errors
-
-Signed-off-by: Leah Rowe <info@minifree.org>
----
- Makefile | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/Makefile b/Makefile
-index 4cb265b2..4ba8b2da 100644
---- a/Makefile
-+++ b/Makefile
-@@ -114,7 +114,7 @@ endif
- # Provide default CC and CFLAGS for firmware builds; if you have any -D flags,
- # please add them after this point (e.g., -DVBOOT_DEBUG).
- DEBUG_FLAGS := $(if $(filter-out 0,${DEBUG}),-g -Og,-g -Os)
--WERROR := -Werror
-+WERROR := -Wno-error -w
- FIRMWARE_FLAGS := -nostdinc -ffreestanding -fno-builtin -fno-stack-protector
- COMMON_FLAGS := -pipe ${WERROR} -Wall -Wstrict-prototypes -Wtype-limits \
- 	-Wundef -Wmissing-prototypes -Wno-trigraphs -Wredundant-decls -Wshadow \
-@@ -128,7 +128,7 @@ COMMON_FLAGS := -pipe ${WERROR} -Wall -Wstrict-prototypes -Wtype-limits \
- # returns: $(1) if compiler was successful, empty string otherwise
- test_ccflag = $(shell \
- 	printf "$(2)\nvoid _start(void) {}\n" | \
--	$(CC) -nostdlib -Werror $(1) -xc -c - -o /dev/null \
-+	$(CC) -nostdlib -Wno-error -w $(1) -xc -c - -o /dev/null \
- 	>/dev/null 2>&1 && echo "$(1)")
- 
- COMMON_FLAGS += $(call test_ccflag,-Wimplicit-fallthrough)
--- 
-2.39.2
-
diff --git a/config/submodule/coreboot/default/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch b/config/submodule/coreboot/default/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
new file mode 100644
index 00000000..1ac41de6
--- /dev/null
+++ b/config/submodule/coreboot/default/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
@@ -0,0 +1,178 @@
+From 195f61375aeec9eec16604ec59f6eda2e6058cc1 Mon Sep 17 00:00:00 2001
+From: "Luke T. Shumaker" <lukeshu@lukeshu.com>
+Date: Thu, 30 May 2024 14:08:33 -0600
+Subject: [PATCH 1/1] extract_vmlinuz.c: Fix the bounds check on
+ vmlinuz_header_{offset,size}
+
+The check on vmlinuz_header_offset and vmlinuz_header_size is obviously
+wrong:
+
+	if (!vmlinuz_header_size ||
+	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+	    kpart_data) {
+		return 1;
+	}
+
+`kpart_data + some_unsigned_values` can obviously never be `> kpart_data`,
+unless something has overflowed!  And `vmlinuz_header_offset` hasn't even
+been set yet (besides being initialized to zero)!
+
+GCC will deduce that if the check didn't cause the function to bail, then
+vmlinuz_header_size (a uint32_t) must be "negative"; that is: in the range
+[2GiB,4GiB).
+
+On platforms where size_t is 32-bits, this is *especially* broken.
+memcpy's size argument must be in the range [0,2GiB).  Because GCC has
+proved that vmlinuz_header_size is higher than that, it will fail to
+compile:
+
+	host/lib/extract_vmlinuz.c:67:9: error: 'memcpy' specified bound between 2147483648 and 4294967295 exceeds maximum object size 2147483647 [-Werror=stringop-overflow=]
+
+So, fix the check.
+
+I can now say that what I suspect the original author meant to write would
+be the following patch, if `vmlinuz_header_offset` were already set:
+
+	-kpart_data + vmlinuz_header_offset + vmlinuz_header_size > kpart_data
+	+now        + vmlinuz_header_offset + vmlinuz_header_size > kpart_size
+
+This hypothesis is supported by `now` not getting incremented by
+`kblob_size` the way it is for the keyblock and preamble sizes.
+
+However, we can also see that even this "corrected" bounds check is
+insufficient: it does not detect the vmlinuz_header overflowing into
+kblob_data.
+
+OK, so let's describe the fix:
+
+Have a `*vmlinuz_header` pointer instead of a
+`uint64_t vmlinuz_header_offset`, to be more similar to all the other
+regions.  With this change, the correct check becomes a simple
+
+      vmlinuz_header + vmlinuz_header_size > kblob_data
+
+While we're at it, make some changes that could have helped avoid this in
+the first place:
+
+ - Add comments.
+ - Calculate the vmlinuz_header offset right away, instead of waiting.
+ - Go ahead and increment `now` by `kblob_size`, to increase regularity.
+
+Change-Id: I5c03e49070b6dd2e04459566ef7dd129d27736e4
+---
+ host/lib/extract_vmlinuz.c | 72 +++++++++++++++++++++++++++-----------
+ 1 file changed, 51 insertions(+), 21 deletions(-)
+
+diff --git a/host/lib/extract_vmlinuz.c b/host/lib/extract_vmlinuz.c
+index 4ccfcf33..d2c09443 100644
+--- a/host/lib/extract_vmlinuz.c
++++ b/host/lib/extract_vmlinuz.c
+@@ -15,16 +15,44 @@
+ 
+ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 		   void **vmlinuz_out, size_t *vmlinuz_size) {
++	// We're going to be extracting `vmlinuz_header` and
++	// `kblob_data`, and returning the concatenation of them.
++	//
++	// kpart_data = +-[kpart_size]------------------------------------+
++	//              |                                                 |
++	//  keyblock  = | +-[keyblock->keyblock_size]-------------------+ |
++	//              | | struct vb2_keyblock          keyblock       | |
++	//              | | char []                      ...data...     | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  preamble  = | +-[preamble->preamble_size]-------------------+ |
++	//              | | struct vb2_kernel_preamble   preamble       | |
++	//              | | char []                       ...data...    | |
++	//              | | char []                      vmlinuz_header | |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  kblob_data= | +-[preamble->body_signature.data_size]--------+ |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//              +-------------------------------------------------+
++
+ 	size_t now = 0;
++	// The 3 sections of kpart_data.
++	struct vb2_keyblock *keyblock = NULL;
+ 	struct vb2_kernel_preamble *preamble = NULL;
+ 	uint8_t *kblob_data = NULL;
+ 	uint32_t kblob_size = 0;
++	// vmlinuz_header
++	uint8_t *vmlinuz_header = NULL;
+ 	uint32_t vmlinuz_header_size = 0;
+-	uint64_t vmlinuz_header_address = 0;
+-	uint64_t vmlinuz_header_offset = 0;
++	// The concatenated result.
+ 	void *vmlinuz = NULL;
+ 
+-	struct vb2_keyblock *keyblock = (struct vb2_keyblock *)kpart_data;
++	// Isolate the 3 sections of kpart_data.
++
++	keyblock = (struct vb2_keyblock *)kpart_data;
+ 	now += keyblock->keyblock_size;
+ 	if (now > kpart_size)
+ 		return 1;
+@@ -36,37 +64,39 @@ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 
+ 	kblob_data = kpart_data + now;
+ 	kblob_size = preamble->body_signature.data_size;
+-
+-	if (!kblob_data || (now + kblob_size) > kpart_size)
++	now += kblob_size;
++	if (now > kpart_size)
+ 		return 1;
+ 
++	// Find `vmlinuz_header` within `preamble`.
++
+ 	if (preamble->header_version_minor > 0) {
+-		vmlinuz_header_address = preamble->vmlinuz_header_address;
++		// calculate the vmlinuz_header offset from
++		// the beginning of the kpart_data.  The kblob doesn't
++		// include the body_load_offset, but does include
++		// the keyblock and preamble sections.
++		size_t vmlinuz_header_offset =
++			preamble->vmlinuz_header_address -
++			preamble->body_load_address +
++			keyblock->keyblock_size +
++			preamble->preamble_size;
++
++		vmlinuz_header = kpart_data + vmlinuz_header_offset;
+ 		vmlinuz_header_size = preamble->vmlinuz_header_size;
+ 	}
+ 
+-	if (!vmlinuz_header_size ||
+-	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+-	    kpart_data) {
++	if (!vmlinuz_header ||
++	    !vmlinuz_header_size ||
++	    vmlinuz_header + vmlinuz_header_size > kblob_data) {
+ 		return 1;
+ 	}
+ 
+-	// calculate the vmlinuz_header offset from
+-	// the beginning of the kpart_data.  The kblob doesn't
+-	// include the body_load_offset, but does include
+-	// the keyblock and preamble sections.
+-	vmlinuz_header_offset = vmlinuz_header_address -
+-		preamble->body_load_address +
+-		keyblock->keyblock_size +
+-		preamble->preamble_size;
++	// Concatenate and return.
+ 
+ 	vmlinuz = malloc(vmlinuz_header_size + kblob_size);
+ 	if (vmlinuz == NULL)
+ 		return 1;
+-
+-	memcpy(vmlinuz, kpart_data + vmlinuz_header_offset,
+-	       vmlinuz_header_size);
+-
++	memcpy(vmlinuz, vmlinuz_header, vmlinuz_header_size);
+ 	memcpy(vmlinuz + vmlinuz_header_size, kblob_data, kblob_size);
+ 
+ 	*vmlinuz_out = vmlinuz;
+-- 
+2.45.1
+
diff --git a/config/submodule/coreboot/dell/vboot/patches/0001-don-t-treat-warnings-as-errors.patch b/config/submodule/coreboot/dell/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
deleted file mode 100644
index 9e14dc7d..00000000
--- a/config/submodule/coreboot/dell/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From d94300a671688746f2fb3d77eefa631a3ed90306 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <info@minifree.org>
-Date: Sun, 19 May 2024 23:35:52 +0100
-Subject: [PATCH 1/1] don't treat warnings as errors
-
-Signed-off-by: Leah Rowe <info@minifree.org>
----
- Makefile | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/Makefile b/Makefile
-index 4cb265b2..4ba8b2da 100644
---- a/Makefile
-+++ b/Makefile
-@@ -114,7 +114,7 @@ endif
- # Provide default CC and CFLAGS for firmware builds; if you have any -D flags,
- # please add them after this point (e.g., -DVBOOT_DEBUG).
- DEBUG_FLAGS := $(if $(filter-out 0,${DEBUG}),-g -Og,-g -Os)
--WERROR := -Werror
-+WERROR := -Wno-error -w
- FIRMWARE_FLAGS := -nostdinc -ffreestanding -fno-builtin -fno-stack-protector
- COMMON_FLAGS := -pipe ${WERROR} -Wall -Wstrict-prototypes -Wtype-limits \
- 	-Wundef -Wmissing-prototypes -Wno-trigraphs -Wredundant-decls -Wshadow \
-@@ -128,7 +128,7 @@ COMMON_FLAGS := -pipe ${WERROR} -Wall -Wstrict-prototypes -Wtype-limits \
- # returns: $(1) if compiler was successful, empty string otherwise
- test_ccflag = $(shell \
- 	printf "$(2)\nvoid _start(void) {}\n" | \
--	$(CC) -nostdlib -Werror $(1) -xc -c - -o /dev/null \
-+	$(CC) -nostdlib -Wno-error -w $(1) -xc -c - -o /dev/null \
- 	>/dev/null 2>&1 && echo "$(1)")
- 
- COMMON_FLAGS += $(call test_ccflag,-Wimplicit-fallthrough)
--- 
-2.39.2
-
diff --git a/config/submodule/coreboot/dell/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch b/config/submodule/coreboot/dell/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
new file mode 100644
index 00000000..1ac41de6
--- /dev/null
+++ b/config/submodule/coreboot/dell/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
@@ -0,0 +1,178 @@
+From 195f61375aeec9eec16604ec59f6eda2e6058cc1 Mon Sep 17 00:00:00 2001
+From: "Luke T. Shumaker" <lukeshu@lukeshu.com>
+Date: Thu, 30 May 2024 14:08:33 -0600
+Subject: [PATCH 1/1] extract_vmlinuz.c: Fix the bounds check on
+ vmlinuz_header_{offset,size}
+
+The check on vmlinuz_header_offset and vmlinuz_header_size is obviously
+wrong:
+
+	if (!vmlinuz_header_size ||
+	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+	    kpart_data) {
+		return 1;
+	}
+
+`kpart_data + some_unsigned_values` can obviously never be `> kpart_data`,
+unless something has overflowed!  And `vmlinuz_header_offset` hasn't even
+been set yet (besides being initialized to zero)!
+
+GCC will deduce that if the check didn't cause the function to bail, then
+vmlinuz_header_size (a uint32_t) must be "negative"; that is: in the range
+[2GiB,4GiB).
+
+On platforms where size_t is 32-bits, this is *especially* broken.
+memcpy's size argument must be in the range [0,2GiB).  Because GCC has
+proved that vmlinuz_header_size is higher than that, it will fail to
+compile:
+
+	host/lib/extract_vmlinuz.c:67:9: error: 'memcpy' specified bound between 2147483648 and 4294967295 exceeds maximum object size 2147483647 [-Werror=stringop-overflow=]
+
+So, fix the check.
+
+I can now say that what I suspect the original author meant to write would
+be the following patch, if `vmlinuz_header_offset` were already set:
+
+	-kpart_data + vmlinuz_header_offset + vmlinuz_header_size > kpart_data
+	+now        + vmlinuz_header_offset + vmlinuz_header_size > kpart_size
+
+This hypothesis is supported by `now` not getting incremented by
+`kblob_size` the way it is for the keyblock and preamble sizes.
+
+However, we can also see that even this "corrected" bounds check is
+insufficient: it does not detect the vmlinuz_header overflowing into
+kblob_data.
+
+OK, so let's describe the fix:
+
+Have a `*vmlinuz_header` pointer instead of a
+`uint64_t vmlinuz_header_offset`, to be more similar to all the other
+regions.  With this change, the correct check becomes a simple
+
+      vmlinuz_header + vmlinuz_header_size > kblob_data
+
+While we're at it, make some changes that could have helped avoid this in
+the first place:
+
+ - Add comments.
+ - Calculate the vmlinuz_header offset right away, instead of waiting.
+ - Go ahead and increment `now` by `kblob_size`, to increase regularity.
+
+Change-Id: I5c03e49070b6dd2e04459566ef7dd129d27736e4
+---
+ host/lib/extract_vmlinuz.c | 72 +++++++++++++++++++++++++++-----------
+ 1 file changed, 51 insertions(+), 21 deletions(-)
+
+diff --git a/host/lib/extract_vmlinuz.c b/host/lib/extract_vmlinuz.c
+index 4ccfcf33..d2c09443 100644
+--- a/host/lib/extract_vmlinuz.c
++++ b/host/lib/extract_vmlinuz.c
+@@ -15,16 +15,44 @@
+ 
+ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 		   void **vmlinuz_out, size_t *vmlinuz_size) {
++	// We're going to be extracting `vmlinuz_header` and
++	// `kblob_data`, and returning the concatenation of them.
++	//
++	// kpart_data = +-[kpart_size]------------------------------------+
++	//              |                                                 |
++	//  keyblock  = | +-[keyblock->keyblock_size]-------------------+ |
++	//              | | struct vb2_keyblock          keyblock       | |
++	//              | | char []                      ...data...     | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  preamble  = | +-[preamble->preamble_size]-------------------+ |
++	//              | | struct vb2_kernel_preamble   preamble       | |
++	//              | | char []                       ...data...    | |
++	//              | | char []                      vmlinuz_header | |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  kblob_data= | +-[preamble->body_signature.data_size]--------+ |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//              +-------------------------------------------------+
++
+ 	size_t now = 0;
++	// The 3 sections of kpart_data.
++	struct vb2_keyblock *keyblock = NULL;
+ 	struct vb2_kernel_preamble *preamble = NULL;
+ 	uint8_t *kblob_data = NULL;
+ 	uint32_t kblob_size = 0;
++	// vmlinuz_header
++	uint8_t *vmlinuz_header = NULL;
+ 	uint32_t vmlinuz_header_size = 0;
+-	uint64_t vmlinuz_header_address = 0;
+-	uint64_t vmlinuz_header_offset = 0;
++	// The concatenated result.
+ 	void *vmlinuz = NULL;
+ 
+-	struct vb2_keyblock *keyblock = (struct vb2_keyblock *)kpart_data;
++	// Isolate the 3 sections of kpart_data.
++
++	keyblock = (struct vb2_keyblock *)kpart_data;
+ 	now += keyblock->keyblock_size;
+ 	if (now > kpart_size)
+ 		return 1;
+@@ -36,37 +64,39 @@ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 
+ 	kblob_data = kpart_data + now;
+ 	kblob_size = preamble->body_signature.data_size;
+-
+-	if (!kblob_data || (now + kblob_size) > kpart_size)
++	now += kblob_size;
++	if (now > kpart_size)
+ 		return 1;
+ 
++	// Find `vmlinuz_header` within `preamble`.
++
+ 	if (preamble->header_version_minor > 0) {
+-		vmlinuz_header_address = preamble->vmlinuz_header_address;
++		// calculate the vmlinuz_header offset from
++		// the beginning of the kpart_data.  The kblob doesn't
++		// include the body_load_offset, but does include
++		// the keyblock and preamble sections.
++		size_t vmlinuz_header_offset =
++			preamble->vmlinuz_header_address -
++			preamble->body_load_address +
++			keyblock->keyblock_size +
++			preamble->preamble_size;
++
++		vmlinuz_header = kpart_data + vmlinuz_header_offset;
+ 		vmlinuz_header_size = preamble->vmlinuz_header_size;
+ 	}
+ 
+-	if (!vmlinuz_header_size ||
+-	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+-	    kpart_data) {
++	if (!vmlinuz_header ||
++	    !vmlinuz_header_size ||
++	    vmlinuz_header + vmlinuz_header_size > kblob_data) {
+ 		return 1;
+ 	}
+ 
+-	// calculate the vmlinuz_header offset from
+-	// the beginning of the kpart_data.  The kblob doesn't
+-	// include the body_load_offset, but does include
+-	// the keyblock and preamble sections.
+-	vmlinuz_header_offset = vmlinuz_header_address -
+-		preamble->body_load_address +
+-		keyblock->keyblock_size +
+-		preamble->preamble_size;
++	// Concatenate and return.
+ 
+ 	vmlinuz = malloc(vmlinuz_header_size + kblob_size);
+ 	if (vmlinuz == NULL)
+ 		return 1;
+-
+-	memcpy(vmlinuz, kpart_data + vmlinuz_header_offset,
+-	       vmlinuz_header_size);
+-
++	memcpy(vmlinuz, vmlinuz_header, vmlinuz_header_size);
+ 	memcpy(vmlinuz + vmlinuz_header_size, kblob_data, kblob_size);
+ 
+ 	*vmlinuz_out = vmlinuz;
+-- 
+2.45.1
+
diff --git a/config/submodule/coreboot/fam15h_rdimm/vboot/patches/0001-don-t-treat-warnings-as-errors.patch b/config/submodule/coreboot/fam15h_rdimm/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
deleted file mode 100644
index 1dbf6c13..00000000
--- a/config/submodule/coreboot/fam15h_rdimm/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 2c5c8d9a5c999a5eedd9f17acb0bd3924524657d Mon Sep 17 00:00:00 2001
-From: Leah Rowe <info@minifree.org>
-Date: Tue, 21 May 2024 23:21:14 +0100
-Subject: [PATCH 1/1] don't treat warnings as errors
-
-Signed-off-by: Leah Rowe <info@minifree.org>
----
- Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/Makefile b/Makefile
-index 0539e8d7..5d8c240c 100644
---- a/Makefile
-+++ b/Makefile
-@@ -136,7 +136,7 @@ endif
- #
- # Flag ordering: arch, then -f, then -m, then -W
- DEBUG_FLAGS := $(if ${DEBUG},-g -O0,-g -Os)
--WERROR := -Werror
-+WERROR := -Wno-error -w
- FIRMWARE_FLAGS := -nostdinc -ffreestanding -fno-builtin -fno-stack-protector
- COMMON_FLAGS := -pipe ${WERROR} -Wall -Wstrict-prototypes -Wtype-limits \
- 	-Wundef -Wmissing-prototypes -Wno-trigraphs -Wredundant-decls -Wshadow \
--- 
-2.39.2
-
diff --git a/config/submodule/coreboot/fam15h_rdimm/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch b/config/submodule/coreboot/fam15h_rdimm/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
new file mode 100644
index 00000000..1ac41de6
--- /dev/null
+++ b/config/submodule/coreboot/fam15h_rdimm/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
@@ -0,0 +1,178 @@
+From 195f61375aeec9eec16604ec59f6eda2e6058cc1 Mon Sep 17 00:00:00 2001
+From: "Luke T. Shumaker" <lukeshu@lukeshu.com>
+Date: Thu, 30 May 2024 14:08:33 -0600
+Subject: [PATCH 1/1] extract_vmlinuz.c: Fix the bounds check on
+ vmlinuz_header_{offset,size}
+
+The check on vmlinuz_header_offset and vmlinuz_header_size is obviously
+wrong:
+
+	if (!vmlinuz_header_size ||
+	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+	    kpart_data) {
+		return 1;
+	}
+
+`kpart_data + some_unsigned_values` can obviously never be `> kpart_data`,
+unless something has overflowed!  And `vmlinuz_header_offset` hasn't even
+been set yet (besides being initialized to zero)!
+
+GCC will deduce that if the check didn't cause the function to bail, then
+vmlinuz_header_size (a uint32_t) must be "negative"; that is: in the range
+[2GiB,4GiB).
+
+On platforms where size_t is 32-bits, this is *especially* broken.
+memcpy's size argument must be in the range [0,2GiB).  Because GCC has
+proved that vmlinuz_header_size is higher than that, it will fail to
+compile:
+
+	host/lib/extract_vmlinuz.c:67:9: error: 'memcpy' specified bound between 2147483648 and 4294967295 exceeds maximum object size 2147483647 [-Werror=stringop-overflow=]
+
+So, fix the check.
+
+I can now say that what I suspect the original author meant to write would
+be the following patch, if `vmlinuz_header_offset` were already set:
+
+	-kpart_data + vmlinuz_header_offset + vmlinuz_header_size > kpart_data
+	+now        + vmlinuz_header_offset + vmlinuz_header_size > kpart_size
+
+This hypothesis is supported by `now` not getting incremented by
+`kblob_size` the way it is for the keyblock and preamble sizes.
+
+However, we can also see that even this "corrected" bounds check is
+insufficient: it does not detect the vmlinuz_header overflowing into
+kblob_data.
+
+OK, so let's describe the fix:
+
+Have a `*vmlinuz_header` pointer instead of a
+`uint64_t vmlinuz_header_offset`, to be more similar to all the other
+regions.  With this change, the correct check becomes a simple
+
+      vmlinuz_header + vmlinuz_header_size > kblob_data
+
+While we're at it, make some changes that could have helped avoid this in
+the first place:
+
+ - Add comments.
+ - Calculate the vmlinuz_header offset right away, instead of waiting.
+ - Go ahead and increment `now` by `kblob_size`, to increase regularity.
+
+Change-Id: I5c03e49070b6dd2e04459566ef7dd129d27736e4
+---
+ host/lib/extract_vmlinuz.c | 72 +++++++++++++++++++++++++++-----------
+ 1 file changed, 51 insertions(+), 21 deletions(-)
+
+diff --git a/host/lib/extract_vmlinuz.c b/host/lib/extract_vmlinuz.c
+index 4ccfcf33..d2c09443 100644
+--- a/host/lib/extract_vmlinuz.c
++++ b/host/lib/extract_vmlinuz.c
+@@ -15,16 +15,44 @@
+ 
+ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 		   void **vmlinuz_out, size_t *vmlinuz_size) {
++	// We're going to be extracting `vmlinuz_header` and
++	// `kblob_data`, and returning the concatenation of them.
++	//
++	// kpart_data = +-[kpart_size]------------------------------------+
++	//              |                                                 |
++	//  keyblock  = | +-[keyblock->keyblock_size]-------------------+ |
++	//              | | struct vb2_keyblock          keyblock       | |
++	//              | | char []                      ...data...     | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  preamble  = | +-[preamble->preamble_size]-------------------+ |
++	//              | | struct vb2_kernel_preamble   preamble       | |
++	//              | | char []                       ...data...    | |
++	//              | | char []                      vmlinuz_header | |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  kblob_data= | +-[preamble->body_signature.data_size]--------+ |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//              +-------------------------------------------------+
++
+ 	size_t now = 0;
++	// The 3 sections of kpart_data.
++	struct vb2_keyblock *keyblock = NULL;
+ 	struct vb2_kernel_preamble *preamble = NULL;
+ 	uint8_t *kblob_data = NULL;
+ 	uint32_t kblob_size = 0;
++	// vmlinuz_header
++	uint8_t *vmlinuz_header = NULL;
+ 	uint32_t vmlinuz_header_size = 0;
+-	uint64_t vmlinuz_header_address = 0;
+-	uint64_t vmlinuz_header_offset = 0;
++	// The concatenated result.
+ 	void *vmlinuz = NULL;
+ 
+-	struct vb2_keyblock *keyblock = (struct vb2_keyblock *)kpart_data;
++	// Isolate the 3 sections of kpart_data.
++
++	keyblock = (struct vb2_keyblock *)kpart_data;
+ 	now += keyblock->keyblock_size;
+ 	if (now > kpart_size)
+ 		return 1;
+@@ -36,37 +64,39 @@ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 
+ 	kblob_data = kpart_data + now;
+ 	kblob_size = preamble->body_signature.data_size;
+-
+-	if (!kblob_data || (now + kblob_size) > kpart_size)
++	now += kblob_size;
++	if (now > kpart_size)
+ 		return 1;
+ 
++	// Find `vmlinuz_header` within `preamble`.
++
+ 	if (preamble->header_version_minor > 0) {
+-		vmlinuz_header_address = preamble->vmlinuz_header_address;
++		// calculate the vmlinuz_header offset from
++		// the beginning of the kpart_data.  The kblob doesn't
++		// include the body_load_offset, but does include
++		// the keyblock and preamble sections.
++		size_t vmlinuz_header_offset =
++			preamble->vmlinuz_header_address -
++			preamble->body_load_address +
++			keyblock->keyblock_size +
++			preamble->preamble_size;
++
++		vmlinuz_header = kpart_data + vmlinuz_header_offset;
+ 		vmlinuz_header_size = preamble->vmlinuz_header_size;
+ 	}
+ 
+-	if (!vmlinuz_header_size ||
+-	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+-	    kpart_data) {
++	if (!vmlinuz_header ||
++	    !vmlinuz_header_size ||
++	    vmlinuz_header + vmlinuz_header_size > kblob_data) {
+ 		return 1;
+ 	}
+ 
+-	// calculate the vmlinuz_header offset from
+-	// the beginning of the kpart_data.  The kblob doesn't
+-	// include the body_load_offset, but does include
+-	// the keyblock and preamble sections.
+-	vmlinuz_header_offset = vmlinuz_header_address -
+-		preamble->body_load_address +
+-		keyblock->keyblock_size +
+-		preamble->preamble_size;
++	// Concatenate and return.
+ 
+ 	vmlinuz = malloc(vmlinuz_header_size + kblob_size);
+ 	if (vmlinuz == NULL)
+ 		return 1;
+-
+-	memcpy(vmlinuz, kpart_data + vmlinuz_header_offset,
+-	       vmlinuz_header_size);
+-
++	memcpy(vmlinuz, vmlinuz_header, vmlinuz_header_size);
+ 	memcpy(vmlinuz + vmlinuz_header_size, kblob_data, kblob_size);
+ 
+ 	*vmlinuz_out = vmlinuz;
+-- 
+2.45.1
+
diff --git a/config/submodule/coreboot/fam15h_udimm/vboot/patches/0001-don-t-treat-warnings-as-errors.patch b/config/submodule/coreboot/fam15h_udimm/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
deleted file mode 100644
index 1dbf6c13..00000000
--- a/config/submodule/coreboot/fam15h_udimm/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 2c5c8d9a5c999a5eedd9f17acb0bd3924524657d Mon Sep 17 00:00:00 2001
-From: Leah Rowe <info@minifree.org>
-Date: Tue, 21 May 2024 23:21:14 +0100
-Subject: [PATCH 1/1] don't treat warnings as errors
-
-Signed-off-by: Leah Rowe <info@minifree.org>
----
- Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/Makefile b/Makefile
-index 0539e8d7..5d8c240c 100644
---- a/Makefile
-+++ b/Makefile
-@@ -136,7 +136,7 @@ endif
- #
- # Flag ordering: arch, then -f, then -m, then -W
- DEBUG_FLAGS := $(if ${DEBUG},-g -O0,-g -Os)
--WERROR := -Werror
-+WERROR := -Wno-error -w
- FIRMWARE_FLAGS := -nostdinc -ffreestanding -fno-builtin -fno-stack-protector
- COMMON_FLAGS := -pipe ${WERROR} -Wall -Wstrict-prototypes -Wtype-limits \
- 	-Wundef -Wmissing-prototypes -Wno-trigraphs -Wredundant-decls -Wshadow \
--- 
-2.39.2
-
diff --git a/config/submodule/coreboot/fam15h_udimm/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch b/config/submodule/coreboot/fam15h_udimm/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
new file mode 100644
index 00000000..1ac41de6
--- /dev/null
+++ b/config/submodule/coreboot/fam15h_udimm/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
@@ -0,0 +1,178 @@
+From 195f61375aeec9eec16604ec59f6eda2e6058cc1 Mon Sep 17 00:00:00 2001
+From: "Luke T. Shumaker" <lukeshu@lukeshu.com>
+Date: Thu, 30 May 2024 14:08:33 -0600
+Subject: [PATCH 1/1] extract_vmlinuz.c: Fix the bounds check on
+ vmlinuz_header_{offset,size}
+
+The check on vmlinuz_header_offset and vmlinuz_header_size is obviously
+wrong:
+
+	if (!vmlinuz_header_size ||
+	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+	    kpart_data) {
+		return 1;
+	}
+
+`kpart_data + some_unsigned_values` can obviously never be `> kpart_data`,
+unless something has overflowed!  And `vmlinuz_header_offset` hasn't even
+been set yet (besides being initialized to zero)!
+
+GCC will deduce that if the check didn't cause the function to bail, then
+vmlinuz_header_size (a uint32_t) must be "negative"; that is: in the range
+[2GiB,4GiB).
+
+On platforms where size_t is 32-bits, this is *especially* broken.
+memcpy's size argument must be in the range [0,2GiB).  Because GCC has
+proved that vmlinuz_header_size is higher than that, it will fail to
+compile:
+
+	host/lib/extract_vmlinuz.c:67:9: error: 'memcpy' specified bound between 2147483648 and 4294967295 exceeds maximum object size 2147483647 [-Werror=stringop-overflow=]
+
+So, fix the check.
+
+I can now say that what I suspect the original author meant to write would
+be the following patch, if `vmlinuz_header_offset` were already set:
+
+	-kpart_data + vmlinuz_header_offset + vmlinuz_header_size > kpart_data
+	+now        + vmlinuz_header_offset + vmlinuz_header_size > kpart_size
+
+This hypothesis is supported by `now` not getting incremented by
+`kblob_size` the way it is for the keyblock and preamble sizes.
+
+However, we can also see that even this "corrected" bounds check is
+insufficient: it does not detect the vmlinuz_header overflowing into
+kblob_data.
+
+OK, so let's describe the fix:
+
+Have a `*vmlinuz_header` pointer instead of a
+`uint64_t vmlinuz_header_offset`, to be more similar to all the other
+regions.  With this change, the correct check becomes a simple
+
+      vmlinuz_header + vmlinuz_header_size > kblob_data
+
+While we're at it, make some changes that could have helped avoid this in
+the first place:
+
+ - Add comments.
+ - Calculate the vmlinuz_header offset right away, instead of waiting.
+ - Go ahead and increment `now` by `kblob_size`, to increase regularity.
+
+Change-Id: I5c03e49070b6dd2e04459566ef7dd129d27736e4
+---
+ host/lib/extract_vmlinuz.c | 72 +++++++++++++++++++++++++++-----------
+ 1 file changed, 51 insertions(+), 21 deletions(-)
+
+diff --git a/host/lib/extract_vmlinuz.c b/host/lib/extract_vmlinuz.c
+index 4ccfcf33..d2c09443 100644
+--- a/host/lib/extract_vmlinuz.c
++++ b/host/lib/extract_vmlinuz.c
+@@ -15,16 +15,44 @@
+ 
+ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 		   void **vmlinuz_out, size_t *vmlinuz_size) {
++	// We're going to be extracting `vmlinuz_header` and
++	// `kblob_data`, and returning the concatenation of them.
++	//
++	// kpart_data = +-[kpart_size]------------------------------------+
++	//              |                                                 |
++	//  keyblock  = | +-[keyblock->keyblock_size]-------------------+ |
++	//              | | struct vb2_keyblock          keyblock       | |
++	//              | | char []                      ...data...     | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  preamble  = | +-[preamble->preamble_size]-------------------+ |
++	//              | | struct vb2_kernel_preamble   preamble       | |
++	//              | | char []                       ...data...    | |
++	//              | | char []                      vmlinuz_header | |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  kblob_data= | +-[preamble->body_signature.data_size]--------+ |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//              +-------------------------------------------------+
++
+ 	size_t now = 0;
++	// The 3 sections of kpart_data.
++	struct vb2_keyblock *keyblock = NULL;
+ 	struct vb2_kernel_preamble *preamble = NULL;
+ 	uint8_t *kblob_data = NULL;
+ 	uint32_t kblob_size = 0;
++	// vmlinuz_header
++	uint8_t *vmlinuz_header = NULL;
+ 	uint32_t vmlinuz_header_size = 0;
+-	uint64_t vmlinuz_header_address = 0;
+-	uint64_t vmlinuz_header_offset = 0;
++	// The concatenated result.
+ 	void *vmlinuz = NULL;
+ 
+-	struct vb2_keyblock *keyblock = (struct vb2_keyblock *)kpart_data;
++	// Isolate the 3 sections of kpart_data.
++
++	keyblock = (struct vb2_keyblock *)kpart_data;
+ 	now += keyblock->keyblock_size;
+ 	if (now > kpart_size)
+ 		return 1;
+@@ -36,37 +64,39 @@ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 
+ 	kblob_data = kpart_data + now;
+ 	kblob_size = preamble->body_signature.data_size;
+-
+-	if (!kblob_data || (now + kblob_size) > kpart_size)
++	now += kblob_size;
++	if (now > kpart_size)
+ 		return 1;
+ 
++	// Find `vmlinuz_header` within `preamble`.
++
+ 	if (preamble->header_version_minor > 0) {
+-		vmlinuz_header_address = preamble->vmlinuz_header_address;
++		// calculate the vmlinuz_header offset from
++		// the beginning of the kpart_data.  The kblob doesn't
++		// include the body_load_offset, but does include
++		// the keyblock and preamble sections.
++		size_t vmlinuz_header_offset =
++			preamble->vmlinuz_header_address -
++			preamble->body_load_address +
++			keyblock->keyblock_size +
++			preamble->preamble_size;
++
++		vmlinuz_header = kpart_data + vmlinuz_header_offset;
+ 		vmlinuz_header_size = preamble->vmlinuz_header_size;
+ 	}
+ 
+-	if (!vmlinuz_header_size ||
+-	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+-	    kpart_data) {
++	if (!vmlinuz_header ||
++	    !vmlinuz_header_size ||
++	    vmlinuz_header + vmlinuz_header_size > kblob_data) {
+ 		return 1;
+ 	}
+ 
+-	// calculate the vmlinuz_header offset from
+-	// the beginning of the kpart_data.  The kblob doesn't
+-	// include the body_load_offset, but does include
+-	// the keyblock and preamble sections.
+-	vmlinuz_header_offset = vmlinuz_header_address -
+-		preamble->body_load_address +
+-		keyblock->keyblock_size +
+-		preamble->preamble_size;
++	// Concatenate and return.
+ 
+ 	vmlinuz = malloc(vmlinuz_header_size + kblob_size);
+ 	if (vmlinuz == NULL)
+ 		return 1;
+-
+-	memcpy(vmlinuz, kpart_data + vmlinuz_header_offset,
+-	       vmlinuz_header_size);
+-
++	memcpy(vmlinuz, vmlinuz_header, vmlinuz_header_size);
+ 	memcpy(vmlinuz + vmlinuz_header_size, kblob_data, kblob_size);
+ 
+ 	*vmlinuz_out = vmlinuz;
+-- 
+2.45.1
+
diff --git a/config/submodule/coreboot/haswell/vboot/patches/0001-don-t-treat-warnings-as-errors.patch b/config/submodule/coreboot/haswell/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
deleted file mode 100644
index 73d796c8..00000000
--- a/config/submodule/coreboot/haswell/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From dd263a01c6f1b63fc12a2a3e96e87a8cee8d987c Mon Sep 17 00:00:00 2001
-From: Leah Rowe <info@minifree.org>
-Date: Tue, 21 May 2024 23:21:49 +0100
-Subject: [PATCH 1/1] don't treat warnings as errors
-
-Signed-off-by: Leah Rowe <info@minifree.org>
----
- Makefile | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/Makefile b/Makefile
-index e3739dc0..a11dccbd 100644
---- a/Makefile
-+++ b/Makefile
-@@ -112,7 +112,7 @@ endif
- # Provide default CC and CFLAGS for firmware builds; if you have any -D flags,
- # please add them after this point (e.g., -DVBOOT_DEBUG).
- DEBUG_FLAGS := $(if $(filter-out 0,${DEBUG}),-g -Og,-g -Os)
--WERROR := -Werror
-+WERROR := -Wno-error -w
- FIRMWARE_FLAGS := -nostdinc -ffreestanding -fno-builtin -fno-stack-protector
- COMMON_FLAGS := -pipe ${WERROR} -Wall -Wstrict-prototypes -Wtype-limits \
- 	-Wundef -Wmissing-prototypes -Wno-trigraphs -Wredundant-decls -Wshadow \
-@@ -126,7 +126,7 @@ COMMON_FLAGS := -pipe ${WERROR} -Wall -Wstrict-prototypes -Wtype-limits \
- # returns: $(1) if compiler was successful, empty string otherwise
- test_ccflag = $(shell \
- 	printf "$(2)\nvoid _start(void) {}\n" | \
--	$(CC) -nostdlib -Werror $(1) -xc -c - -o /dev/null \
-+	$(CC) -nostdlib -Wno-error -w $(1) -xc -c - -o /dev/null \
- 	>/dev/null 2>&1 && echo "$(1)")
- 
- COMMON_FLAGS += $(call test_ccflag,-Wimplicit-fallthrough)
--- 
-2.39.2
-
diff --git a/config/submodule/coreboot/haswell/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch b/config/submodule/coreboot/haswell/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
new file mode 100644
index 00000000..1ac41de6
--- /dev/null
+++ b/config/submodule/coreboot/haswell/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
@@ -0,0 +1,178 @@
+From 195f61375aeec9eec16604ec59f6eda2e6058cc1 Mon Sep 17 00:00:00 2001
+From: "Luke T. Shumaker" <lukeshu@lukeshu.com>
+Date: Thu, 30 May 2024 14:08:33 -0600
+Subject: [PATCH 1/1] extract_vmlinuz.c: Fix the bounds check on
+ vmlinuz_header_{offset,size}
+
+The check on vmlinuz_header_offset and vmlinuz_header_size is obviously
+wrong:
+
+	if (!vmlinuz_header_size ||
+	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+	    kpart_data) {
+		return 1;
+	}
+
+`kpart_data + some_unsigned_values` can obviously never be `> kpart_data`,
+unless something has overflowed!  And `vmlinuz_header_offset` hasn't even
+been set yet (besides being initialized to zero)!
+
+GCC will deduce that if the check didn't cause the function to bail, then
+vmlinuz_header_size (a uint32_t) must be "negative"; that is: in the range
+[2GiB,4GiB).
+
+On platforms where size_t is 32-bits, this is *especially* broken.
+memcpy's size argument must be in the range [0,2GiB).  Because GCC has
+proved that vmlinuz_header_size is higher than that, it will fail to
+compile:
+
+	host/lib/extract_vmlinuz.c:67:9: error: 'memcpy' specified bound between 2147483648 and 4294967295 exceeds maximum object size 2147483647 [-Werror=stringop-overflow=]
+
+So, fix the check.
+
+I can now say that what I suspect the original author meant to write would
+be the following patch, if `vmlinuz_header_offset` were already set:
+
+	-kpart_data + vmlinuz_header_offset + vmlinuz_header_size > kpart_data
+	+now        + vmlinuz_header_offset + vmlinuz_header_size > kpart_size
+
+This hypothesis is supported by `now` not getting incremented by
+`kblob_size` the way it is for the keyblock and preamble sizes.
+
+However, we can also see that even this "corrected" bounds check is
+insufficient: it does not detect the vmlinuz_header overflowing into
+kblob_data.
+
+OK, so let's describe the fix:
+
+Have a `*vmlinuz_header` pointer instead of a
+`uint64_t vmlinuz_header_offset`, to be more similar to all the other
+regions.  With this change, the correct check becomes a simple
+
+      vmlinuz_header + vmlinuz_header_size > kblob_data
+
+While we're at it, make some changes that could have helped avoid this in
+the first place:
+
+ - Add comments.
+ - Calculate the vmlinuz_header offset right away, instead of waiting.
+ - Go ahead and increment `now` by `kblob_size`, to increase regularity.
+
+Change-Id: I5c03e49070b6dd2e04459566ef7dd129d27736e4
+---
+ host/lib/extract_vmlinuz.c | 72 +++++++++++++++++++++++++++-----------
+ 1 file changed, 51 insertions(+), 21 deletions(-)
+
+diff --git a/host/lib/extract_vmlinuz.c b/host/lib/extract_vmlinuz.c
+index 4ccfcf33..d2c09443 100644
+--- a/host/lib/extract_vmlinuz.c
++++ b/host/lib/extract_vmlinuz.c
+@@ -15,16 +15,44 @@
+ 
+ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 		   void **vmlinuz_out, size_t *vmlinuz_size) {
++	// We're going to be extracting `vmlinuz_header` and
++	// `kblob_data`, and returning the concatenation of them.
++	//
++	// kpart_data = +-[kpart_size]------------------------------------+
++	//              |                                                 |
++	//  keyblock  = | +-[keyblock->keyblock_size]-------------------+ |
++	//              | | struct vb2_keyblock          keyblock       | |
++	//              | | char []                      ...data...     | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  preamble  = | +-[preamble->preamble_size]-------------------+ |
++	//              | | struct vb2_kernel_preamble   preamble       | |
++	//              | | char []                       ...data...    | |
++	//              | | char []                      vmlinuz_header | |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  kblob_data= | +-[preamble->body_signature.data_size]--------+ |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//              +-------------------------------------------------+
++
+ 	size_t now = 0;
++	// The 3 sections of kpart_data.
++	struct vb2_keyblock *keyblock = NULL;
+ 	struct vb2_kernel_preamble *preamble = NULL;
+ 	uint8_t *kblob_data = NULL;
+ 	uint32_t kblob_size = 0;
++	// vmlinuz_header
++	uint8_t *vmlinuz_header = NULL;
+ 	uint32_t vmlinuz_header_size = 0;
+-	uint64_t vmlinuz_header_address = 0;
+-	uint64_t vmlinuz_header_offset = 0;
++	// The concatenated result.
+ 	void *vmlinuz = NULL;
+ 
+-	struct vb2_keyblock *keyblock = (struct vb2_keyblock *)kpart_data;
++	// Isolate the 3 sections of kpart_data.
++
++	keyblock = (struct vb2_keyblock *)kpart_data;
+ 	now += keyblock->keyblock_size;
+ 	if (now > kpart_size)
+ 		return 1;
+@@ -36,37 +64,39 @@ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 
+ 	kblob_data = kpart_data + now;
+ 	kblob_size = preamble->body_signature.data_size;
+-
+-	if (!kblob_data || (now + kblob_size) > kpart_size)
++	now += kblob_size;
++	if (now > kpart_size)
+ 		return 1;
+ 
++	// Find `vmlinuz_header` within `preamble`.
++
+ 	if (preamble->header_version_minor > 0) {
+-		vmlinuz_header_address = preamble->vmlinuz_header_address;
++		// calculate the vmlinuz_header offset from
++		// the beginning of the kpart_data.  The kblob doesn't
++		// include the body_load_offset, but does include
++		// the keyblock and preamble sections.
++		size_t vmlinuz_header_offset =
++			preamble->vmlinuz_header_address -
++			preamble->body_load_address +
++			keyblock->keyblock_size +
++			preamble->preamble_size;
++
++		vmlinuz_header = kpart_data + vmlinuz_header_offset;
+ 		vmlinuz_header_size = preamble->vmlinuz_header_size;
+ 	}
+ 
+-	if (!vmlinuz_header_size ||
+-	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+-	    kpart_data) {
++	if (!vmlinuz_header ||
++	    !vmlinuz_header_size ||
++	    vmlinuz_header + vmlinuz_header_size > kblob_data) {
+ 		return 1;
+ 	}
+ 
+-	// calculate the vmlinuz_header offset from
+-	// the beginning of the kpart_data.  The kblob doesn't
+-	// include the body_load_offset, but does include
+-	// the keyblock and preamble sections.
+-	vmlinuz_header_offset = vmlinuz_header_address -
+-		preamble->body_load_address +
+-		keyblock->keyblock_size +
+-		preamble->preamble_size;
++	// Concatenate and return.
+ 
+ 	vmlinuz = malloc(vmlinuz_header_size + kblob_size);
+ 	if (vmlinuz == NULL)
+ 		return 1;
+-
+-	memcpy(vmlinuz, kpart_data + vmlinuz_header_offset,
+-	       vmlinuz_header_size);
+-
++	memcpy(vmlinuz, vmlinuz_header, vmlinuz_header_size);
+ 	memcpy(vmlinuz + vmlinuz_header_size, kblob_data, kblob_size);
+ 
+ 	*vmlinuz_out = vmlinuz;
+-- 
+2.45.1
+
diff --git a/config/submodule/coreboot/i945/vboot/patches/0001-don-t-treat-warnings-as-errors.patch b/config/submodule/coreboot/i945/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
deleted file mode 100644
index 91f2eee8..00000000
--- a/config/submodule/coreboot/i945/vboot/patches/0001-don-t-treat-warnings-as-errors.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 59c393f2a928770c2d397bc93d388543c2d94dab Mon Sep 17 00:00:00 2001
-From: Leah Rowe <info@minifree.org>
-Date: Tue, 21 May 2024 23:22:50 +0100
-Subject: [PATCH 1/1] don't treat warnings as errors
-
-Signed-off-by: Leah Rowe <info@minifree.org>
----
- Makefile | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/Makefile b/Makefile
-index a4390522..d2ec9aa3 100644
---- a/Makefile
-+++ b/Makefile
-@@ -125,7 +125,7 @@ endif
- # Provide default CC and CFLAGS for firmware builds; if you have any -D flags,
- # please add them after this point (e.g., -DVBOOT_DEBUG).
- DEBUG_FLAGS := $(if $(filter-out 0,${DEBUG}),-g -Og,-g -Os)
--WERROR := -Werror
-+WERROR := -Wno-error -w
- FIRMWARE_FLAGS := -nostdinc -ffreestanding -fno-builtin -fno-stack-protector
- COMMON_FLAGS := -pipe ${WERROR} -Wall -Wstrict-prototypes -Wtype-limits \
- 	-Wundef -Wmissing-prototypes -Wno-trigraphs -Wredundant-decls -Wshadow \
-@@ -162,7 +162,7 @@ CFLAGS += -std=gnu11
- # returns: $(1) if compiler was successful, empty string otherwise
- test_ccflag = $(shell \
- 	printf "$(2)\nvoid _start(void) {}\n" | \
--	$(CC) -nostdlib -Werror $(1) -xc -c - -o /dev/null \
-+	$(CC) -nostdlib -Wno-error -w $(1) -xc -c - -o /dev/null \
- 	>/dev/null 2>&1 && echo "$(1)")
- 
- COMMON_FLAGS += $(call test_ccflag,-Wimplicit-fallthrough)
--- 
-2.39.2
-
diff --git a/config/submodule/coreboot/i945/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch b/config/submodule/coreboot/i945/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
new file mode 100644
index 00000000..1ac41de6
--- /dev/null
+++ b/config/submodule/coreboot/i945/vboot/patches/0001-extract_vmlinuz.c-Fix-the-bounds-check-on-vmlinuz_he.patch
@@ -0,0 +1,178 @@
+From 195f61375aeec9eec16604ec59f6eda2e6058cc1 Mon Sep 17 00:00:00 2001
+From: "Luke T. Shumaker" <lukeshu@lukeshu.com>
+Date: Thu, 30 May 2024 14:08:33 -0600
+Subject: [PATCH 1/1] extract_vmlinuz.c: Fix the bounds check on
+ vmlinuz_header_{offset,size}
+
+The check on vmlinuz_header_offset and vmlinuz_header_size is obviously
+wrong:
+
+	if (!vmlinuz_header_size ||
+	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+	    kpart_data) {
+		return 1;
+	}
+
+`kpart_data + some_unsigned_values` can obviously never be `> kpart_data`,
+unless something has overflowed!  And `vmlinuz_header_offset` hasn't even
+been set yet (besides being initialized to zero)!
+
+GCC will deduce that if the check didn't cause the function to bail, then
+vmlinuz_header_size (a uint32_t) must be "negative"; that is: in the range
+[2GiB,4GiB).
+
+On platforms where size_t is 32-bits, this is *especially* broken.
+memcpy's size argument must be in the range [0,2GiB).  Because GCC has
+proved that vmlinuz_header_size is higher than that, it will fail to
+compile:
+
+	host/lib/extract_vmlinuz.c:67:9: error: 'memcpy' specified bound between 2147483648 and 4294967295 exceeds maximum object size 2147483647 [-Werror=stringop-overflow=]
+
+So, fix the check.
+
+I can now say that what I suspect the original author meant to write would
+be the following patch, if `vmlinuz_header_offset` were already set:
+
+	-kpart_data + vmlinuz_header_offset + vmlinuz_header_size > kpart_data
+	+now        + vmlinuz_header_offset + vmlinuz_header_size > kpart_size
+
+This hypothesis is supported by `now` not getting incremented by
+`kblob_size` the way it is for the keyblock and preamble sizes.
+
+However, we can also see that even this "corrected" bounds check is
+insufficient: it does not detect the vmlinuz_header overflowing into
+kblob_data.
+
+OK, so let's describe the fix:
+
+Have a `*vmlinuz_header` pointer instead of a
+`uint64_t vmlinuz_header_offset`, to be more similar to all the other
+regions.  With this change, the correct check becomes a simple
+
+      vmlinuz_header + vmlinuz_header_size > kblob_data
+
+While we're at it, make some changes that could have helped avoid this in
+the first place:
+
+ - Add comments.
+ - Calculate the vmlinuz_header offset right away, instead of waiting.
+ - Go ahead and increment `now` by `kblob_size`, to increase regularity.
+
+Change-Id: I5c03e49070b6dd2e04459566ef7dd129d27736e4
+---
+ host/lib/extract_vmlinuz.c | 72 +++++++++++++++++++++++++++-----------
+ 1 file changed, 51 insertions(+), 21 deletions(-)
+
+diff --git a/host/lib/extract_vmlinuz.c b/host/lib/extract_vmlinuz.c
+index 4ccfcf33..d2c09443 100644
+--- a/host/lib/extract_vmlinuz.c
++++ b/host/lib/extract_vmlinuz.c
+@@ -15,16 +15,44 @@
+ 
+ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 		   void **vmlinuz_out, size_t *vmlinuz_size) {
++	// We're going to be extracting `vmlinuz_header` and
++	// `kblob_data`, and returning the concatenation of them.
++	//
++	// kpart_data = +-[kpart_size]------------------------------------+
++	//              |                                                 |
++	//  keyblock  = | +-[keyblock->keyblock_size]-------------------+ |
++	//              | | struct vb2_keyblock          keyblock       | |
++	//              | | char []                      ...data...     | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  preamble  = | +-[preamble->preamble_size]-------------------+ |
++	//              | | struct vb2_kernel_preamble   preamble       | |
++	//              | | char []                       ...data...    | |
++	//              | | char []                      vmlinuz_header | |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//  kblob_data= | +-[preamble->body_signature.data_size]--------+ |
++	//              | | char []                       ...data...    | |
++	//              | +---------------------------------------------+ |
++	//              |                                                 |
++	//              +-------------------------------------------------+
++
+ 	size_t now = 0;
++	// The 3 sections of kpart_data.
++	struct vb2_keyblock *keyblock = NULL;
+ 	struct vb2_kernel_preamble *preamble = NULL;
+ 	uint8_t *kblob_data = NULL;
+ 	uint32_t kblob_size = 0;
++	// vmlinuz_header
++	uint8_t *vmlinuz_header = NULL;
+ 	uint32_t vmlinuz_header_size = 0;
+-	uint64_t vmlinuz_header_address = 0;
+-	uint64_t vmlinuz_header_offset = 0;
++	// The concatenated result.
+ 	void *vmlinuz = NULL;
+ 
+-	struct vb2_keyblock *keyblock = (struct vb2_keyblock *)kpart_data;
++	// Isolate the 3 sections of kpart_data.
++
++	keyblock = (struct vb2_keyblock *)kpart_data;
+ 	now += keyblock->keyblock_size;
+ 	if (now > kpart_size)
+ 		return 1;
+@@ -36,37 +64,39 @@ int ExtractVmlinuz(void *kpart_data, size_t kpart_size,
+ 
+ 	kblob_data = kpart_data + now;
+ 	kblob_size = preamble->body_signature.data_size;
+-
+-	if (!kblob_data || (now + kblob_size) > kpart_size)
++	now += kblob_size;
++	if (now > kpart_size)
+ 		return 1;
+ 
++	// Find `vmlinuz_header` within `preamble`.
++
+ 	if (preamble->header_version_minor > 0) {
+-		vmlinuz_header_address = preamble->vmlinuz_header_address;
++		// calculate the vmlinuz_header offset from
++		// the beginning of the kpart_data.  The kblob doesn't
++		// include the body_load_offset, but does include
++		// the keyblock and preamble sections.
++		size_t vmlinuz_header_offset =
++			preamble->vmlinuz_header_address -
++			preamble->body_load_address +
++			keyblock->keyblock_size +
++			preamble->preamble_size;
++
++		vmlinuz_header = kpart_data + vmlinuz_header_offset;
+ 		vmlinuz_header_size = preamble->vmlinuz_header_size;
+ 	}
+ 
+-	if (!vmlinuz_header_size ||
+-	    kpart_data + vmlinuz_header_offset + vmlinuz_header_size >
+-	    kpart_data) {
++	if (!vmlinuz_header ||
++	    !vmlinuz_header_size ||
++	    vmlinuz_header + vmlinuz_header_size > kblob_data) {
+ 		return 1;
+ 	}
+ 
+-	// calculate the vmlinuz_header offset from
+-	// the beginning of the kpart_data.  The kblob doesn't
+-	// include the body_load_offset, but does include
+-	// the keyblock and preamble sections.
+-	vmlinuz_header_offset = vmlinuz_header_address -
+-		preamble->body_load_address +
+-		keyblock->keyblock_size +
+-		preamble->preamble_size;
++	// Concatenate and return.
+ 
+ 	vmlinuz = malloc(vmlinuz_header_size + kblob_size);
+ 	if (vmlinuz == NULL)
+ 		return 1;
+-
+-	memcpy(vmlinuz, kpart_data + vmlinuz_header_offset,
+-	       vmlinuz_header_size);
+-
++	memcpy(vmlinuz, vmlinuz_header, vmlinuz_header_size);
+ 	memcpy(vmlinuz + vmlinuz_header_size, kblob_data, kblob_size);
+ 
+ 	*vmlinuz_out = vmlinuz;
+-- 
+2.45.1
+
-- 
cgit v1.2.1