Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/x86/x86 Add cpu_ucode_intel_verify() to verify micr...



details:   https://anonhg.NetBSD.org/src/rev/26b7883e1d00
branches:  trunk
changeset: 361088:26b7883e1d00
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Thu Apr 12 10:30:24 2018 +0000

description:
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.

diffstat:

 sys/arch/x86/x86/cpu_ucode_intel.c |  77 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 74 insertions(+), 3 deletions(-)

diffs (106 lines):

diff -r 8f47ffcbb8c1 -r 26b7883e1d00 sys/arch/x86/x86/cpu_ucode_intel.c
--- a/sys/arch/x86/x86/cpu_ucode_intel.c        Thu Apr 12 08:03:55 2018 +0000
+++ b/sys/arch/x86/x86/cpu_ucode_intel.c        Thu Apr 12 10:30:24 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_ucode_intel.c,v 1.13 2018/03/17 15:56:32 christos Exp $ */
+/* $NetBSD: cpu_ucode_intel.c,v 1.14 2018/04/12 10:30:24 msaitoh 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.13 2018/03/17 15:56:32 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_ucode_intel.c,v 1.14 2018/04/12 10:30:24 msaitoh Exp $");
 
 #include "opt_xen.h"
 #include "opt_cpu_ucode.h"
@@ -104,6 +104,75 @@
 }
 
 #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 @@
                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) {



Home | Main Index | Thread Index | Old Index