[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging-4.11] x86/ucode/amd: Fix more potential buffer overruns with microcode parsing



commit 4b4ec479731f6cbb9f9c11b5c0f6ab391c2e193d
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Thu Apr 9 10:17:10 2020 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Apr 9 10:17:10 2020 +0200

    x86/ucode/amd: Fix more potential buffer overruns with microcode parsing
    
    cpu_request_microcode() doesn't know the buffer is at least 4 bytes long
    before inspecting UCODE_MAGIC.
    
    install_equiv_cpu_table() doesn't know the boundary of the buffer it is
    interpreting as an equivalency table.  This case was clearly observed at one
    point in the past, given the subsequent overrun detection, but without
    comprehending that the damage was already done.
    
    Make the logic consistent with container_fast_forward() and pass size_left 
in
    to install_equiv_cpu_table().
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    master commit: 718d1432000079ea7120f6cb770372afe707ce27
    master date: 2020-04-01 14:00:12 +0100
---
 xen/arch/x86/microcode_amd.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/xen/arch/x86/microcode_amd.c b/xen/arch/x86/microcode_amd.c
index 5080e54409..cccfcaed2f 100644
--- a/xen/arch/x86/microcode_amd.c
+++ b/xen/arch/x86/microcode_amd.c
@@ -294,11 +294,20 @@ static int get_ucode_from_buffer_amd(
 static int install_equiv_cpu_table(
     struct microcode_amd *mc_amd,
     const void *data,
+    size_t size_left,
     size_t *offset)
 {
-    const struct mpbhdr *mpbuf = data + *offset + 4;
+    const struct mpbhdr *mpbuf;
     const struct equiv_cpu_entry *eq;
 
+    if ( size_left < (sizeof(*mpbuf) + 4) ||
+         (mpbuf = data + *offset + 4,
+          size_left - sizeof(*mpbuf) - 4 < mpbuf->len) )
+    {
+        printk(XENLOG_WARNING "microcode: No space for equivalent cpu 
table\n");
+        return -EINVAL;
+    }
+
     *offset += mpbuf->len + CONT_HDR_SIZE;     /* add header length */
 
     if ( mpbuf->type != UCODE_EQUIV_CPU_TABLE_TYPE )
@@ -413,7 +422,7 @@ static int cpu_request_microcode(unsigned int cpu, const 
void *buf,
 
     current_cpu_id = cpuid_eax(0x00000001);
 
-    if ( *(const uint32_t *)buf != UCODE_MAGIC )
+    if ( bufsize < 4 || *(const uint32_t *)buf != UCODE_MAGIC )
     {
         printk(KERN_ERR "microcode: Wrong microcode patch file magic\n");
         error = -EINVAL;
@@ -443,24 +452,13 @@ static int cpu_request_microcode(unsigned int cpu, const 
void *buf,
      */
     while ( offset < bufsize )
     {
-        error = install_equiv_cpu_table(mc_amd, buf, &offset);
+        error = install_equiv_cpu_table(mc_amd, buf, bufsize - offset, 
&offset);
         if ( error )
         {
             printk(KERN_ERR "microcode: installing equivalent cpu table 
failed\n");
             break;
         }
 
-        /*
-         * Could happen as we advance 'offset' early
-         * in install_equiv_cpu_table
-         */
-        if ( offset > bufsize )
-        {
-            printk(KERN_ERR "microcode: Microcode buffer overrun\n");
-            error = -EINVAL;
-            break;
-        }
-
         if ( find_equiv_cpu_id(mc_amd->equiv_cpu_table, current_cpu_id,
                                &equiv_cpu_id) )
             break;
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.11



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.