lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20110426211321.EC7513E1886@tassilo.jf.intel.com>
Date:	Tue, 26 Apr 2011 14:13:21 -0700 (PDT)
From:	Andi Kleen <andi@...stfloor.org>
To:	bp@...64.org, greg@...ah.com, borislav.petkov@....com,
	stable@...nel.org, gregkh@...e.de, ak@...ux.intel.com,
	linux-kernel@...r.kernel.org, stable@...nel.org,
	tim.bird@...sony.com
Subject: [PATCH] [42/106] x86, microcode, AMD: Extend ucode size verification

2.6.35-longterm review patch.  If anyone has any objections, please let me know.

------------------

From: Borislav Petkov <borislav.petkov@....com>

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: <stable@...nel.org>
Signed-off-by: Borislav Petkov <borislav.petkov@....com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...e.de>
Signed-off-by: Andi Kleen <ak@...ux.intel.com>

---
 arch/x86/kernel/microcode_amd.c |   63 +++++++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 19 deletions(-)

Index: linux-2.6.35.y/arch/x86/kernel/microcode_amd.c
===================================================================
--- linux-2.6.35.y.orig/arch/x86/kernel/microcode_amd.c
+++ linux-2.6.35.y/arch/x86/kernel/microcode_amd.c
@@ -66,7 +66,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;
@@ -162,11 +192,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;
@@ -176,23 +206,18 @@ get_next_ucode(const u8 *buf, unsigned i
 		return NULL;
 	}
 
-	total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
-
-	if (total_size > size || total_size > UCODE_MAX_SIZE) {
-		pr_err("error: size mismatch\n");
+	actual_size = verify_ucode_size(cpu, buf, size);
+	if (!actual_size)
 		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;
-	}
+	mc = vmalloc(actual_size);
+	if (!mc)
+ 		return NULL;
+
+	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;
 }
 
@@ -258,7 +283,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;
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ