lkml.org 
[lkml]   [2018]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 6/6] x86/microcode/AMD: Check the equivalence table size when scanning it
    Date
    Currently, the code scanning the CPU equivalence table read from a
    microcode container file assumes that it actually contains a terminating
    zero entry.
    Let's check also the size of this table to make sure that we don't read
    past it in case it actually doesn't.

    Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
    ---
    arch/x86/kernel/cpu/microcode/amd.c | 33 ++++++++++++++++++++++-----------
    1 file changed, 22 insertions(+), 11 deletions(-)

    diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
    index 2df366cc71ce..5ba933ce1d51 100644
    --- a/arch/x86/kernel/cpu/microcode/amd.c
    +++ b/arch/x86/kernel/cpu/microcode/amd.c
    @@ -39,6 +39,7 @@
    #include <asm/msr.h>

    static struct equiv_cpu_entry *equiv_cpu_table;
    +static unsigned int equiv_cpu_table_entries;

    /*
    * This points to the current valid container of microcode patches which we will
    @@ -63,12 +64,18 @@ static u8 amd_ucode_patch[PATCH_MAX_SIZE];
    static const char
    ucode_path[] __maybe_unused = "kernel/x86/microcode/AuthenticAMD.bin";

    -static u16 find_equiv_id(struct equiv_cpu_entry *equiv_table, u32 sig)
    +static u16 find_equiv_id(const struct equiv_cpu_entry *equiv_table,
    + unsigned int equiv_table_entries, u32 sig)
    {
    - for (; equiv_table && equiv_table->installed_cpu; equiv_table++) {
    - if (sig == equiv_table->installed_cpu)
    - return equiv_table->equiv_cpu;
    - }
    + unsigned int i;
    +
    + if (!equiv_table)
    + return 0;
    +
    + for (i = 0; i < equiv_table_entries && equiv_table[i].installed_cpu;
    + i++)
    + if (sig == equiv_table[i].installed_cpu)
    + return equiv_table[i].equiv_cpu;

    return 0;
    }
    @@ -237,7 +244,8 @@ static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc)
    eq = (struct equiv_cpu_entry *)(buf + CONTAINER_HDR_SZ);

    /* Find the equivalence ID of our CPU in this table: */
    - eq_id = find_equiv_id(eq, desc->cpuid_1_eax);
    + eq_id = find_equiv_id(eq, equiv_tbl_len / sizeof(*eq),
    + desc->cpuid_1_eax);

    buf += CONTAINER_HDR_SZ;
    buf += equiv_tbl_len;
    @@ -499,20 +507,21 @@ void reload_ucode_amd(void)
    static u16 __find_equiv_id(unsigned int cpu)
    {
    struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
    - return find_equiv_id(equiv_cpu_table, uci->cpu_sig.sig);
    + return find_equiv_id(equiv_cpu_table, equiv_cpu_table_entries,
    + uci->cpu_sig.sig);
    }

    static u32 find_cpu_family_by_equiv_cpu(u16 equiv_cpu)
    {
    - int i = 0;
    + unsigned int i;

    BUG_ON(!equiv_cpu_table);

    - while (equiv_cpu_table[i].equiv_cpu != 0) {
    + for (i = 0; i < equiv_cpu_table_entries &&
    + equiv_cpu_table[i].equiv_cpu != 0; i++)
    if (equiv_cpu == equiv_cpu_table[i].equiv_cpu)
    return equiv_cpu_table[i].installed_cpu;
    - i++;
    - }
    +
    return 0;
    }

    @@ -697,6 +706,7 @@ static unsigned int install_equiv_cpu_table(const u8 *buf, size_t buf_size)
    }

    memcpy(equiv_cpu_table, buf + CONTAINER_HDR_SZ, equiv_tbl_len);
    + equiv_cpu_table_entries = equiv_tbl_len / sizeof(struct equiv_cpu_entry);

    return equiv_tbl_len;
    }
    @@ -705,6 +715,7 @@ static void free_equiv_cpu_table(void)
    {
    vfree(equiv_cpu_table);
    equiv_cpu_table = NULL;
    + equiv_cpu_table_entries = 0;
    }

    static void cleanup(void)
    \
     
     \ /
      Last update: 2018-04-23 23:35    [W:8.830 / U:1.380 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site