Module Name:    src
Committed By:   snj
Date:           Thu Jul 26 21:02:29 UTC 2018

Modified Files:
        src/sys/arch/x86/x86 [netbsd-8]: cpu_ucode_intel.c
        src/sys/kern [netbsd-8]: kern_cpu.c

Log Message:
Pull up following revision(s) (requested by msaitoh in ticket #929):
        sys/arch/x86/x86/cpu_ucode_intel.c: 1.14
        sys/kern/kern_cpu.c: 1.74
Add cpu_ucode_intel_verify() to verify microcode image. Currently, we don't
verify extended signatures'checksum. I have no any image which has extended
signature. If an extended signature found, the function shows
"This image has extended signature table." and continue.
--
Don't allocate memory and return EFTYPE if sc->sc_blobsize==0 to prevent
panic in firmware_malloc().


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.12.2.1 src/sys/arch/x86/x86/cpu_ucode_intel.c
cvs rdiff -u -r1.71 -r1.71.10.1 src/sys/kern/kern_cpu.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/x86/cpu_ucode_intel.c
diff -u src/sys/arch/x86/x86/cpu_ucode_intel.c:1.12 src/sys/arch/x86/x86/cpu_ucode_intel.c:1.12.2.1
--- src/sys/arch/x86/x86/cpu_ucode_intel.c:1.12	Thu Jun  1 02:45:08 2017
+++ src/sys/arch/x86/x86/cpu_ucode_intel.c	Thu Jul 26 21:02:29 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_ucode_intel.c,v 1.12 2017/06/01 02:45:08 chs Exp $ */
+/* $NetBSD: cpu_ucode_intel.c,v 1.12.2.1 2018/07/26 21:02:29 snj Exp $ */
 /*
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_ucode_intel.c,v 1.12 2017/06/01 02:45:08 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_ucode_intel.c,v 1.12.2.1 2018/07/26 21:02:29 snj Exp $");
 
 #include "opt_xen.h"
 #include "opt_cpu_ucode.h"
@@ -104,6 +104,75 @@ cpu_ucode_intel_firmware_open(firmware_h
 }
 
 #ifndef XEN
+/* Check header version and checksum */
+static int
+cpu_ucode_intel_verify(struct intel1_ucode_header *buf)
+{
+	uint32_t data_size, total_size, payload_size, extended_table_size;
+#if 0 /* not yet */
+	struct intel1_ucode_ext_table *ext_table;
+	struct intel1_ucode_proc_signature *ext_psig;
+#endif
+	uint32_t sum;
+	int i;
+	
+	if ((buf->uh_header_ver != 1) || (buf->uh_loader_rev != 1))
+		return EINVAL;
+
+	/* Data size */
+	if (buf->uh_data_size == 0)
+		data_size = 2000;
+	else
+		data_size = buf->uh_data_size;
+
+	if ((data_size % 4) != 0) {
+		/* Wrong size */
+		return EINVAL;
+	}
+
+	/* Total size */
+	if (buf->uh_total_size == 0)
+		total_size = data_size + 48;
+	else
+		total_size = buf->uh_total_size;
+
+	if ((total_size % 1024) != 0) {
+		/* Wrong size */
+		return EINVAL;
+	}
+
+	payload_size = data_size + 48;
+
+	/* Extended table size */
+	extended_table_size = total_size - payload_size;
+
+	/*
+	 * Verify checksum of update data and header
+	 * (exclude extended signature).
+	 */
+	sum = 0;
+	for (i = 0; i < (payload_size / sizeof(uint32_t)); i++)
+		sum += *((uint32_t *)buf + i);
+	if (sum != 0) {
+		/* Checksum mismatch */
+		return EINVAL;
+	}
+
+	if (extended_table_size == 0)
+		return 0;
+
+#if 0
+	/* Verify extended signature's checksum */
+	ext_table = (void *)buf + payload_size;
+	ext_psig = (void *)ext_table + sizeof(struct intel1_ucode_ext_table);
+	printf("ext_table = %p, extsig = %p\n", ext_table, ext_psig);
+#else
+	printf("This image has extended signature table.");
+#endif
+
+	return 0;
+}
+
 int
 cpu_ucode_intel_apply(struct cpu_ucode_softc *sc, int cpuno)
 {
@@ -119,8 +188,10 @@ cpu_ucode_intel_apply(struct cpu_ucode_s
 		return EINVAL;
 
 	uh = (struct intel1_ucode_header *)(sc->sc_blob);
-	if (uh->uh_header_ver != 1 || uh->uh_loader_rev != 1)
+	rv = cpu_ucode_intel_verify(uh);
+	if (rv != 0)
 		return EINVAL;
+
 	ucodetarget = uh->uh_rev;
 
 	if ((uintptr_t)(sc->sc_blob) & 15) {

Index: src/sys/kern/kern_cpu.c
diff -u src/sys/kern/kern_cpu.c:1.71 src/sys/kern/kern_cpu.c:1.71.10.1
--- src/sys/kern/kern_cpu.c:1.71	Sat Aug 29 12:24:00 2015
+++ src/sys/kern/kern_cpu.c	Thu Jul 26 21:02:29 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_cpu.c,v 1.71 2015/08/29 12:24:00 maxv Exp $	*/
+/*	$NetBSD: kern_cpu.c,v 1.71.10.1 2018/07/26 21:02:29 snj Exp $	*/
 
 /*-
  * Copyright (c) 2007, 2008, 2009, 2010, 2012 The NetBSD Foundation, Inc.
@@ -56,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.71 2015/08/29 12:24:00 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.71.10.1 2018/07/26 21:02:29 snj Exp $");
 
 #include "opt_cpu_ucode.h"
 #include "opt_compat_netbsd.h"
@@ -619,6 +619,11 @@ cpu_ucode_load(struct cpu_ucode_softc *s
 	}
 
 	sc->sc_blobsize = firmware_get_size(fwh);
+	if (sc->sc_blobsize == 0) {
+		error = EFTYPE;
+		firmware_close(fwh);
+		goto err0;
+	}
 	sc->sc_blob = firmware_malloc(sc->sc_blobsize);
 	if (sc->sc_blob == NULL) {
 		error = ENOMEM;

Reply via email to