This is a note to let you know that I've just added the patch titled

    x86, microcode, AMD: Extend ucode size verification

to the 2.6.32-longterm tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/longterm/longterm-queue-2.6.32.git;a=summary

The filename of the patch is:
     x86-microcode-amd-extend-ucode-size-verification.patch
and it can be found in the queue-2.6.32 subdirectory.

If you, or anyone else, feels it should not be added to the 2.6.32 longterm 
tree,
please let <[email protected]> know about it.


>From [email protected]  Mon Apr 11 15:48:17 2011
From: Borislav Petkov <[email protected]>
Date: Tue, 29 Mar 2011 21:29:54 +0200
Subject: x86, microcode, AMD: Extend ucode size verification
To: [email protected]
Cc: Greg Kroah-Hartman <[email protected]>, Borislav Petkov 
<[email protected]>, Boris Ostrovsky <[email protected]>
Message-ID: <[email protected]>


From: Borislav Petkov <[email protected]>

Upstream commit: 44d60c0f5c58c2168f31df9a481761451840eb54

The different families have a different max size for the ucode patch,
adjust size checking to the family we're running on. Also, do not
vzalloc the max size of the ucode but only the actual size that is
passed on from the firmware loader.

Cc: <[email protected]> # 32.x
Signed-off-by: Borislav Petkov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 arch/x86/kernel/microcode_amd.c |   63 +++++++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 19 deletions(-)

--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -63,7 +63,6 @@ struct microcode_amd {
        unsigned int                    mpb[0];
 };
 
-#define UCODE_MAX_SIZE                 2048
 #define UCODE_CONTAINER_SECTION_HDR    8
 #define UCODE_CONTAINER_HEADER_SIZE    12
 
@@ -125,6 +124,37 @@ static int get_matching_microcode(int cp
        return 1;
 }
 
+static unsigned int verify_ucode_size(int cpu, const u8 *buf, unsigned int 
size)
+{
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
+       unsigned int max_size, actual_size;
+
+#define F1XH_MPB_MAX_SIZE 2048
+#define F14H_MPB_MAX_SIZE 1824
+#define F15H_MPB_MAX_SIZE 4096
+
+       switch (c->x86) {
+       case 0x14:
+               max_size = F14H_MPB_MAX_SIZE;
+               break;
+       case 0x15:
+               max_size = F15H_MPB_MAX_SIZE;
+               break;
+       default:
+               max_size = F1XH_MPB_MAX_SIZE;
+               break;
+       }
+
+       actual_size = buf[4] + (buf[5] << 8);
+
+       if (actual_size > size || actual_size > max_size) {
+               pr_err("section size mismatch\n");
+               return 0;
+       }
+
+       return actual_size;
+}
+
 static int apply_microcode_amd(int cpu)
 {
        u32 rev, dummy;
@@ -164,11 +194,11 @@ static int get_ucode_data(void *to, cons
 }
 
 static void *
-get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size)
+get_next_ucode(int cpu, const u8 *buf, unsigned int size, unsigned int 
*mc_size)
 {
-       unsigned int total_size;
+       unsigned int actual_size = 0;
        u8 section_hdr[UCODE_CONTAINER_SECTION_HDR];
-       void *mc;
+       void *mc = NULL;
 
        if (get_ucode_data(section_hdr, buf, UCODE_CONTAINER_SECTION_HDR))
                return NULL;
@@ -179,23 +209,18 @@ get_next_ucode(const u8 *buf, unsigned i
                return NULL;
        }
 
-       total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
+       actual_size = verify_ucode_size(cpu, buf, size);
+       if (!actual_size)
+               return NULL;
 
-       if (total_size > size || total_size > UCODE_MAX_SIZE) {
-               printk(KERN_ERR "microcode: error: size mismatch\n");
+       mc = vmalloc(actual_size);
+       if (!mc)
                return NULL;
-       }
 
-       mc = vmalloc(UCODE_MAX_SIZE);
-       if (mc) {
-               memset(mc, 0, UCODE_MAX_SIZE);
-               if (get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR,
-                                  total_size)) {
-                       vfree(mc);
-                       mc = NULL;
-               } else
-                       *mc_size = total_size + UCODE_CONTAINER_SECTION_HDR;
-       }
+       memset(mc, 0, actual_size);
+       get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, actual_size);
+       *mc_size = actual_size + UCODE_CONTAINER_SECTION_HDR;
+
        return mc;
 }
 
@@ -264,7 +289,7 @@ generic_load_microcode(int cpu, const u8
                unsigned int uninitialized_var(mc_size);
                struct microcode_header_amd *mc_header;
 
-               mc = get_next_ucode(ucode_ptr, leftover, &mc_size);
+               mc = get_next_ucode(cpu, ucode_ptr, leftover, &mc_size);
                if (!mc)
                        break;
 


Patches currently in longterm-queue-2.6.32 which might be from [email protected] 
are

/home/gregkh/linux/longterm/longterm-queue-2.6.32/queue-2.6.32/x86-amd-ucode-remove-needless-log-messages.patch
/home/gregkh/linux/longterm/longterm-queue-2.6.32/queue-2.6.32/x86-microcode-amd-extend-ucode-size-verification.patch

_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to