Commit 413c8915 authored by Maciej S. Szmigiero's avatar Maciej S. Szmigiero Committed by Borislav Petkov

x86/microcode/AMD: Check the equivalence table size when scanning it

Currently, the code scanning the CPU equivalence table read from a
microcode container file assumes that it actually contains a terminating
zero entry.

Check also the size of this table to make sure that no reads past its
end happen, in case there's no terminating zero entry at the end of the
table.

 [ bp: Adjust to new changes. ]
Signed-off-by: default avatarMaciej 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-16-bp@alien8.de
parent 39cd7c17
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <asm/msr.h> #include <asm/msr.h>
static struct equiv_cpu_table { static struct equiv_cpu_table {
unsigned int num_entries;
struct equiv_cpu_entry *entry; struct equiv_cpu_entry *entry;
} equiv_table; } equiv_table;
...@@ -67,13 +68,19 @@ ucode_path[] __maybe_unused = "kernel/x86/microcode/AuthenticAMD.bin"; ...@@ -67,13 +68,19 @@ ucode_path[] __maybe_unused = "kernel/x86/microcode/AuthenticAMD.bin";
static u16 find_equiv_id(struct equiv_cpu_table *et, u32 sig) static u16 find_equiv_id(struct equiv_cpu_table *et, u32 sig)
{ {
struct equiv_cpu_entry *entry = et->entry; unsigned int i;
for (; entry && entry->installed_cpu; entry++) { if (!et || !et->num_entries)
if (sig == entry->installed_cpu) return 0;
return entry->equiv_cpu;
} for (i = 0; i < et->num_entries; i++) {
struct equiv_cpu_entry *e = &et->entry[i];
if (sig == e->installed_cpu)
return e->equiv_cpu;
e++;
}
return 0; return 0;
} }
...@@ -302,6 +309,7 @@ static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc) ...@@ -302,6 +309,7 @@ static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc)
buf = ucode; buf = ucode;
table.entry = (struct equiv_cpu_entry *)(buf + CONTAINER_HDR_SZ); table.entry = (struct equiv_cpu_entry *)(buf + CONTAINER_HDR_SZ);
table.num_entries = hdr[2] / sizeof(struct equiv_cpu_entry);
/* /*
* Find the equivalence ID of our CPU in this table. Even if this table * Find the equivalence ID of our CPU in this table. Even if this table
...@@ -728,6 +736,7 @@ static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size) ...@@ -728,6 +736,7 @@ static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size)
} }
memcpy(equiv_table.entry, buf + CONTAINER_HDR_SZ, equiv_tbl_len); memcpy(equiv_table.entry, buf + CONTAINER_HDR_SZ, equiv_tbl_len);
equiv_table.num_entries = equiv_tbl_len / sizeof(struct equiv_cpu_entry);
/* add header length */ /* add header length */
return equiv_tbl_len + CONTAINER_HDR_SZ; return equiv_tbl_len + CONTAINER_HDR_SZ;
...@@ -736,7 +745,7 @@ static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size) ...@@ -736,7 +745,7 @@ static size_t install_equiv_cpu_table(const u8 *buf, size_t buf_size)
static void free_equiv_cpu_table(void) static void free_equiv_cpu_table(void)
{ {
vfree(equiv_table.entry); vfree(equiv_table.entry);
equiv_table.entry = NULL; memset(&equiv_table, 0, sizeof(equiv_table));
} }
static void cleanup(void) static void cleanup(void)
......
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