Skip to content

Commit

Permalink
x86/microcode/intel: Check patch signature before saving microcode fo…
Browse files Browse the repository at this point in the history
…r early loading

commit 1a371e6 upstream.

Currently, scan_microcode() leverages microcode_matches() to check
if the microcode matches the CPU by comparing the family and model.
However, the processor stepping and flags of the microcode signature
should also be considered when saving a microcode patch for early
update.

Use find_matching_signature() in scan_microcode() and get rid of the
now-unused microcode_matches() which is a good cleanup in itself.

Complete the verification of the patch being saved for early loading in
save_microcode_patch() directly. This needs to be done there too because
save_mc_for_early() will call save_microcode_patch() too.

The second reason why this needs to be done is because the loader still
tries to support, at least hypothetically, mixed-steppings systems and
thus adds all patches to the cache that belong to the same CPU model
albeit with different steppings.

For example:

  microcode: CPU: sig=0x906ec, pf=0x2, rev=0xd6
  microcode: mc_saved[0]: sig=0x906e9, pf=0x2a, rev=0xd6, total size=0x19400, date = 2020-04-23
  microcode: mc_saved[1]: sig=0x906ea, pf=0x22, rev=0xd6, total size=0x19000, date = 2020-04-27
  microcode: mc_saved[2]: sig=0x906eb, pf=0x2, rev=0xd6, total size=0x19400, date = 2020-04-23
  microcode: mc_saved[3]: sig=0x906ec, pf=0x22, rev=0xd6, total size=0x19000, date = 2020-04-27
  microcode: mc_saved[4]: sig=0x906ed, pf=0x22, rev=0xd6, total size=0x19400, date = 2020-04-23

The patch which is being saved for early loading, however, can only be
the one which fits the CPU this runs on so do the signature verification
before saving.

 [ bp: Do signature verification in save_microcode_patch()
       and rewrite commit message. ]

Fixes: ec400dd ("x86/microcode_intel_early.c: Early update ucode on Intel's CPU")
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: stable@vger.kernel.org
Link: https://bugzilla.kernel.org/show_bug.cgi?id=208535
Link: https://lkml.kernel.org/r/20201113015923.13960-1-yu.c.chen@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Chen Yu authored and Greg Kroah-Hartman committed Nov 24, 2020
1 parent 05636ea commit 717311a
Showing 1 changed file with 2 additions and 47 deletions.
49 changes: 2 additions & 47 deletions arch/x86/kernel/cpu/microcode/intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,51 +132,6 @@ load_microcode(struct mc_saved_data *mc_saved_data, unsigned long *initrd,
}
}

/*
* Given CPU signature and a microcode patch, this function finds if the
* microcode patch has matching family and model with the CPU.
*/
static enum ucode_state
matching_model_microcode(struct microcode_header_intel *mc_header,
unsigned long sig)
{
unsigned int fam, model;
unsigned int fam_ucode, model_ucode;
struct extended_sigtable *ext_header;
unsigned long total_size = get_totalsize(mc_header);
unsigned long data_size = get_datasize(mc_header);
int ext_sigcount, i;
struct extended_signature *ext_sig;

fam = __x86_family(sig);
model = x86_model(sig);

fam_ucode = __x86_family(mc_header->sig);
model_ucode = x86_model(mc_header->sig);

if (fam == fam_ucode && model == model_ucode)
return UCODE_OK;

/* Look for ext. headers: */
if (total_size <= data_size + MC_HEADER_SIZE)
return UCODE_NFOUND;

ext_header = (void *) mc_header + data_size + MC_HEADER_SIZE;
ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
ext_sigcount = ext_header->count;

for (i = 0; i < ext_sigcount; i++) {
fam_ucode = __x86_family(ext_sig->sig);
model_ucode = x86_model(ext_sig->sig);

if (fam == fam_ucode && model == model_ucode)
return UCODE_OK;

ext_sig++;
}
return UCODE_NFOUND;
}

static int
save_microcode(struct mc_saved_data *mc_saved_data,
struct microcode_intel **mc_saved_src,
Expand Down Expand Up @@ -321,8 +276,8 @@ get_matching_model_microcode(int cpu, unsigned long start,
* the platform, we need to find and save microcode patches
* with the same family and model as the BSP.
*/
if (matching_model_microcode(mc_header, uci->cpu_sig.sig) !=
UCODE_OK) {
if (!find_matching_signature(mc_header, uci->cpu_sig.sig,
uci->cpu_sig.pf)) {
ucode_ptr += mc_size;
continue;
}
Expand Down

0 comments on commit 717311a

Please sign in to comment.