From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xenproject.org>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
"Wei Liu" <wl@xen.org>, "Jan Beulich" <JBeulich@suse.com>,
"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [Xen-devel] [PATCH 6/7] x86/ucode/intel: Clean up microcode_sanity_check()
Date: Mon, 23 Mar 2020 10:17:23 +0000 [thread overview]
Message-ID: <20200323101724.15655-7-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <20200323101724.15655-1-andrew.cooper3@citrix.com>
Rewrite the size checks in a way which which doesn't depend on Xen being
compiled as 64bit.
Introduce a check missing from the old code, that total_size is a multiple of
1024 bytes, and drop unnecessarily defines/macros/structures.
No practical change in behaviour.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wl@xen.org>
CC: Roger Pau Monné <roger.pau@citrix.com>
---
xen/arch/x86/cpu/microcode/intel.c | 147 +++++++++++++++----------------------
1 file changed, 58 insertions(+), 89 deletions(-)
diff --git a/xen/arch/x86/cpu/microcode/intel.c b/xen/arch/x86/cpu/microcode/intel.c
index bc3bbf139e..2cccf9c26d 100644
--- a/xen/arch/x86/cpu/microcode/intel.c
+++ b/xen/arch/x86/cpu/microcode/intel.c
@@ -65,17 +65,15 @@ struct microcode_intel {
};
/* microcode format is extended from prescott processors */
-struct extended_signature {
- unsigned int sig;
- unsigned int pf;
- unsigned int cksum;
-};
-
struct extended_sigtable {
unsigned int count;
unsigned int cksum;
unsigned int reserved[3];
- struct extended_signature sigs[0];
+ struct {
+ unsigned int sig;
+ unsigned int pf;
+ unsigned int cksum;
+ } sigs[];
};
struct microcode_patch {
@@ -84,9 +82,6 @@ struct microcode_patch {
#define PPRO_UCODE_DATASIZE 2000
#define MC_HEADER_SIZE (sizeof(struct microcode_header_intel))
-#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable))
-#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature))
-#define DWSIZE (sizeof(u32))
static uint32_t get_datasize(const struct microcode_header_intel *hdr)
{
@@ -134,8 +129,6 @@ static bool signature_maches(const struct cpu_signature *cpu_sig,
return cpu_sig->pf & ucode_pf;
}
-#define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)
-
static int collect_cpu_info(struct cpu_signature *csig)
{
uint64_t msr_content;
@@ -160,93 +153,69 @@ static int collect_cpu_info(struct cpu_signature *csig)
return 0;
}
+/*
+ * Sanity check a blob which is expected to be a microcode patch. The 48 byte
+ * header is of a known format, and together with totalsize are within the
+ * bounds of the container. Everything else is unchecked.
+ */
static int microcode_sanity_check(const struct microcode_intel *mc)
{
- const struct microcode_header_intel *mc_header = &mc->hdr;
- const struct extended_sigtable *ext_header = NULL;
- const struct extended_signature *ext_sig;
- unsigned long total_size, data_size, ext_table_size;
- unsigned int ext_sigcount = 0, i;
- uint32_t sum, orig_sum;
-
- total_size = get_totalsize(mc_header);
- data_size = get_datasize(mc_header);
- if ( (data_size + MC_HEADER_SIZE) > total_size )
- {
- printk(KERN_ERR "microcode: error! "
- "Bad data size in microcode data file\n");
+ const struct extended_sigtable *ext;
+ unsigned int total_size = get_totalsize(&mc->hdr);
+ unsigned int data_size = get_datasize(&mc->hdr);
+ unsigned int i, ext_size;
+ uint32_t sum, *ptr;
+
+ /*
+ * Total size must be a multiple of 1024 bytes. Data size and the header
+ * must fit within it.
+ */
+ if ( (total_size & 1023) ||
+ data_size > (total_size - MC_HEADER_SIZE) )
return -EINVAL;
- }
- if ( (mc_header->ldrver != 1) || (mc_header->hdrver != 1) )
- {
- printk(KERN_ERR "microcode: error! "
- "Unknown microcode update format\n");
+ /* Checksum the main header and data. */
+ for ( sum = 0, ptr = (uint32_t *)mc;
+ ptr < (uint32_t *)&mc->data[data_size]; ++ptr )
+ sum += *ptr;
+
+ if ( sum != 0 )
return -EINVAL;
- }
- ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
- if ( ext_table_size )
- {
- if ( (ext_table_size < EXT_HEADER_SIZE) ||
- ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE) )
- {
- printk(KERN_ERR "microcode: error! "
- "Small exttable size in microcode data file\n");
- return -EINVAL;
- }
- ext_header = (void *)mc + MC_HEADER_SIZE + data_size;
- if ( ext_table_size != exttable_size(ext_header) )
- {
- printk(KERN_ERR "microcode: error! "
- "Bad exttable size in microcode data file\n");
- return -EFAULT;
- }
- ext_sigcount = ext_header->count;
- }
- /* check extended table checksum */
- if ( ext_table_size )
- {
- uint32_t ext_table_sum = 0;
- uint32_t *ext_tablep = (uint32_t *)ext_header;
+ /* Look to see if there is an extended signature table. */
+ ext_size = total_size - data_size - MC_HEADER_SIZE;
- i = ext_table_size / DWSIZE;
- while ( i-- )
- ext_table_sum += ext_tablep[i];
- if ( ext_table_sum )
- {
- printk(KERN_WARNING "microcode: aborting, "
- "bad extended signature table checksum\n");
- return -EINVAL;
- }
- }
+ /* No extended signature table? All done. */
+ if ( ext_size == 0 )
+ return 0;
- /* calculate the checksum */
- orig_sum = 0;
- i = (MC_HEADER_SIZE + data_size) / DWSIZE;
- while ( i-- )
- orig_sum += ((uint32_t *)mc)[i];
- if ( orig_sum )
- {
- printk(KERN_ERR "microcode: aborting, bad checksum\n");
+ /*
+ * Check the structure of the extended signature table, ensuring that it
+ * fits exactly in the remaining space.
+ */
+ ext = (void *)&mc->data[data_size];
+ if ( ext_size < sizeof(*ext) ||
+ (ext_size - sizeof(*ext)) % sizeof(ext->sigs[0]) ||
+ (ext_size - sizeof(*ext)) / sizeof(ext->sigs[0]) != ext->count )
return -EINVAL;
- }
- if ( !ext_table_size )
- return 0;
- /* check extended signature checksum */
- for ( i = 0; i < ext_sigcount; i++ )
- {
- ext_sig = (void *)ext_header + EXT_HEADER_SIZE +
- EXT_SIGNATURE_SIZE * i;
- sum = orig_sum
- - (mc_header->sig + mc_header->pf + mc_header->cksum)
- + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
- if ( sum )
- {
- printk(KERN_ERR "microcode: aborting, bad checksum\n");
+
+ /* Checksum the whole extended signature table. */
+ for ( sum = 0, ptr = (uint32_t *)ext;
+ ptr < (uint32_t *)&ext->sigs[ext->count]; ++ptr )
+ sum += *ptr;
+
+ if ( sum != 0 )
+ return -EINVAL;
+
+ /*
+ * Checksum each indiviudal extended signature as if it had been in the
+ * main header.
+ */
+ sum = mc->hdr.sig + mc->hdr.pf + mc->hdr.cksum;
+ for ( i = 0; i < ext->count; ++i )
+ if ( sum != (ext->sigs[i].sig + ext->sigs[i].pf + ext->sigs[i].cksum) )
return -EINVAL;
- }
- }
+
return 0;
}
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2020-03-23 10:18 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-23 10:17 [Xen-devel] [PATCH 0/7] x86/ucode: Cleanup and fixes - Part 3/n (Intel) Andrew Cooper
2020-03-23 10:17 ` [Xen-devel] [PATCH 1/7] x86/ucode: Document the behaviour of the microcode_ops hooks Andrew Cooper
2020-03-23 12:33 ` Jan Beulich
2020-03-23 13:26 ` Andrew Cooper
2020-03-23 14:24 ` Jan Beulich
2020-03-23 10:17 ` [Xen-devel] [PATCH 2/7] x86/ucode/intel: Adjust microcode_sanity_check() to not take void * Andrew Cooper
2020-03-25 13:23 ` Jan Beulich
2020-03-23 10:17 ` [Xen-devel] [PATCH 3/7] x86/ucode/intel: Remove gratuitous memory allocations from cpu_request_microcode() Andrew Cooper
2020-03-25 13:34 ` Jan Beulich
2020-03-23 10:17 ` [Xen-devel] [PATCH 4/7] x86/ucode/intel: Reimplement get_{data, total}size() helpers Andrew Cooper
2020-03-25 13:41 ` Jan Beulich
2020-03-26 14:35 ` Andrew Cooper
2020-03-26 14:56 ` Jan Beulich
2020-03-26 15:09 ` Andrew Cooper
2020-03-26 15:19 ` Jan Beulich
2020-03-23 10:17 ` [Xen-devel] [PATCH 5/7] x86/ucode/intel: Clean up microcode_update_match() Andrew Cooper
2020-03-25 13:51 ` Jan Beulich
2020-03-26 14:36 ` Andrew Cooper
2020-03-23 10:17 ` Andrew Cooper [this message]
2020-03-25 14:07 ` [Xen-devel] [PATCH 6/7] x86/ucode/intel: Clean up microcode_sanity_check() Jan Beulich
2020-03-26 14:41 ` Andrew Cooper
2020-03-26 15:02 ` Jan Beulich
2020-03-23 10:17 ` [Xen-devel] [PATCH 7/7] x86/ucode/intel: Fold structures together Andrew Cooper
2020-03-25 14:16 ` Jan Beulich
2020-03-25 14:32 ` Andrew Cooper
2020-03-26 12:24 ` Jan Beulich
2020-03-26 14:50 ` Andrew Cooper
2020-03-26 15:05 ` Jan Beulich
2020-03-27 12:40 ` Andrew Cooper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200323101724.15655-7-andrew.cooper3@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=JBeulich@suse.com \
--cc=roger.pau@citrix.com \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).