Commit c45e8035 authored by Borislav Petkov's avatar Borislav Petkov

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: default avatar"Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Cc: x86@kernel.org
Link: https://lkml.kernel.org/r/20181107170218.7596-12-bp@alien8.de
parent d430a305
...@@ -293,17 +293,18 @@ static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc) ...@@ -293,17 +293,18 @@ static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc)
u16 eq_id; u16 eq_id;
u8 *buf; u8 *buf;
/* Am I looking at an equivalence table header? */ if (!verify_equivalence_table(ucode, size, true))
if (hdr[0] != UCODE_MAGIC || return 0;
hdr[1] != UCODE_EQUIV_CPU_TABLE_TYPE ||
hdr[2] == 0)
return CONTAINER_HDR_SZ;
buf = ucode; buf = ucode;
eq = (struct equiv_cpu_entry *)(buf + CONTAINER_HDR_SZ); 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); eq_id = find_equiv_id(eq, desc->cpuid_1_eax);
buf += hdr[2] + CONTAINER_HDR_SZ; buf += hdr[2] + CONTAINER_HDR_SZ;
...@@ -316,29 +317,29 @@ static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc) ...@@ -316,29 +317,29 @@ static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc)
while (size > 0) { while (size > 0) {
struct microcode_amd *mc; struct microcode_amd *mc;
u32 patch_size; u32 patch_size;
int ret;
hdr = (u32 *)buf; ret = verify_patch(x86_family(desc->cpuid_1_eax), buf, size, &patch_size, true);
if (ret < 0) {
if (hdr[0] != UCODE_UCODE_TYPE) /*
break; * Patch verification failed, skip to the next
* container, if there's one:
/* Sanity-check patch size. */ */
patch_size = hdr[1]; goto out;
if (patch_size > PATCH_MAX_SIZE) } else if (ret > 0) {
break; goto skip;
}
/* Skip patch section header: */
buf += SECTION_HDR_SIZE;
size -= SECTION_HDR_SIZE;
mc = (struct microcode_amd *)buf; mc = (struct microcode_amd *)(buf + SECTION_HDR_SIZE);
if (eq_id == mc->hdr.processor_rev_id) { if (eq_id == mc->hdr.processor_rev_id) {
desc->psize = patch_size; desc->psize = patch_size;
desc->mc = mc; desc->mc = mc;
} }
buf += patch_size; skip:
size -= patch_size; /* 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) ...@@ -355,6 +356,7 @@ static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc)
return 0; return 0;
} }
out:
return orig_size - size; return orig_size - size;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment