[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20181107170218.7596-12-bp@alien8.de>
Date: Wed, 7 Nov 2018 18:02:13 +0100
From: Borislav Petkov <bp@...en8.de>
To: X86 ML <x86@...nel.org>
Cc: "Maciej S . Szmigiero" <mail@...iej.szmigiero.name>,
Tom Lendacky <thomas.lendacky@....com>,
LKML <linux-kernel@...r.kernel.org>
Subject: [PATCH 11/16] x86/microcode/AMD: Convert early parser to the new verification routines
From: Borislav Petkov <bp@...e.de>
Now that they have the required functionality, use them to verify the
equivalence table and each patch, thus making parse_container() more
readable.
Based on a patch by "Maciej S. Szmigiero" <mail@...iej.szmigiero.name>.
Signed-off-by: Borislav Petkov <bp@...e.de>
---
arch/x86/kernel/cpu/microcode/amd.c | 46 +++++++++++++++--------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
index 79216cfb9f72..5775dc996df3 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -293,17 +293,18 @@ static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc)
u16 eq_id;
u8 *buf;
- /* Am I looking at an equivalence table header? */
- if (hdr[0] != UCODE_MAGIC ||
- hdr[1] != UCODE_EQUIV_CPU_TABLE_TYPE ||
- hdr[2] == 0)
- return CONTAINER_HDR_SZ;
+ if (!verify_equivalence_table(ucode, size, true))
+ return 0;
buf = ucode;
eq = (struct equiv_cpu_entry *)(buf + CONTAINER_HDR_SZ);
- /* Find the equivalence ID of our CPU in this table: */
+ /*
+ * Find the equivalence ID of our CPU in this table. Even if this table
+ * doesn't contain a patch for the CPU, scan through the whole container
+ * so that it can be skipped in case there are other containers appended.
+ */
eq_id = find_equiv_id(eq, desc->cpuid_1_eax);
buf += hdr[2] + CONTAINER_HDR_SZ;
@@ -316,29 +317,29 @@ static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc)
while (size > 0) {
struct microcode_amd *mc;
u32 patch_size;
+ int ret;
- hdr = (u32 *)buf;
-
- if (hdr[0] != UCODE_UCODE_TYPE)
- break;
-
- /* Sanity-check patch size. */
- patch_size = hdr[1];
- if (patch_size > PATCH_MAX_SIZE)
- break;
-
- /* Skip patch section header: */
- buf += SECTION_HDR_SIZE;
- size -= SECTION_HDR_SIZE;
+ ret = verify_patch(x86_family(desc->cpuid_1_eax), buf, size, &patch_size, true);
+ if (ret < 0) {
+ /*
+ * Patch verification failed, skip to the next
+ * container, if there's one:
+ */
+ goto out;
+ } else if (ret > 0) {
+ goto skip;
+ }
- mc = (struct microcode_amd *)buf;
+ mc = (struct microcode_amd *)(buf + SECTION_HDR_SIZE);
if (eq_id == mc->hdr.processor_rev_id) {
desc->psize = patch_size;
desc->mc = mc;
}
- buf += patch_size;
- size -= patch_size;
+skip:
+ /* Skip patch section header too: */
+ buf += patch_size + SECTION_HDR_SIZE;
+ size -= patch_size + SECTION_HDR_SIZE;
}
/*
@@ -355,6 +356,7 @@ static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc)
return 0;
}
+out:
return orig_size - size;
}
--
2.19.1
Powered by blists - more mailing lists