[tip:x86/microcode] x86/microcode/AMD: Convert early parser to the new verification routines

From: tip-bot for Borislav Petkov
Date: Mon Nov 19 2018 - 05:18:53 EST


Commit-ID: c45e80358cb3c61eaf6f5d35af86c6a874935bd0
Gitweb: https://git.kernel.org/tip/c45e80358cb3c61eaf6f5d35af86c6a874935bd0
Author: Borislav Petkov <bp@xxxxxxx>
AuthorDate: Wed, 12 Sep 2018 18:33:34 +0200
Committer: Borislav Petkov <bp@xxxxxxx>
CommitDate: Mon, 19 Nov 2018 10:51:06 +0100

x86/microcode/AMD: Convert early parser to the new verification routines

Now that they have the required functionality, use them to verify the
equivalence table and each patch, thus making parse_container() more
readable.

Originally-by: "Maciej S. Szmigiero" <mail@xxxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Borislav Petkov <bp@xxxxxxx>
Cc: x86@xxxxxxxxxx
Link: https://lkml.kernel.org/r/20181107170218.7596-12-bp@xxxxxxxxx
---
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;
}