|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] Fix two problems in the microcode parsers
On Thu, Sep 12, 2024 at 07:44:05PM +0100, Andrew Cooper wrote:
> On 12/09/2024 6:39 pm, Demi Marie Obenour wrote:
> > The microcode might come from a questionable source, so it is necessary
> > for the parsers to treat it as untrusted. The CPU will validate the
> > microcode before applying it, so loading microcode from unofficial
> > sources is actually a legitimate thing to do in some cases.
>
> While true, the better argument is that ucode blobs are mostly encrypted
> data, so a mis-step tends to fall over a very long way.
>
> >
> > Signed-off-by: Demi Marie Obenour <demi@xxxxxxxxxxxxxxxxxxxxxx>
> > ---
> > xen/arch/x86/cpu/microcode/amd.c | 1 +
> > xen/arch/x86/cpu/microcode/intel.c | 5 +++--
> > 2 files changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/xen/arch/x86/cpu/microcode/amd.c
> > b/xen/arch/x86/cpu/microcode/amd.c
> > index
> > d2a26967c6dbc4695602dd46d5836a6d88e15072..31ee5717c5f1c7d0b7e29d990cf4d1024d775900
> > 100644
> > --- a/xen/arch/x86/cpu/microcode/amd.c
> > +++ b/xen/arch/x86/cpu/microcode/amd.c
> > @@ -338,6 +338,7 @@ static struct microcode_patch *cf_check
> > cpu_request_microcode(
> > if ( size < sizeof(*et) ||
> > (et = buf)->type != UCODE_EQUIV_CPU_TABLE_TYPE ||
> > size - sizeof(*et) < et->len ||
> > + et->len < sizeof(et->eq[0]) ||
> > et->len % sizeof(et->eq[0]) ||
> > et->eq[(et->len / sizeof(et->eq[0])) - 1].installed_cpu )
> > {
>
> This is complicated by AMD having no spec in the slightest on their
> container format, but this change makes Xen reject a case that I
> reasoned was well formed (if unwise).
>
> IMO, the following binary is well formed:
>
> 0x00414d44 /* MAGIC */
> 0x00000000 /* type=equiv */
> 0x00000000 /* len=0, == no entries */
> /* no equiv entries */
> /* no ucode entries */
> 0x00414d44 /* MAGIC */
> ...
>
> and I believe that Xen would parse it correctly. Unless you think
> there's another case I've failed to consider?
The problem is that (et->len / sizeof(et->eq[0])) - 1 will underflow,
causing Xen to access et->eq[UINT32_MAX], which will (hopefully) crash.
The simplest solution is to drop that check, since
scan_equiv_cpu_table() already checks for terminating entries.
> AFACT the check you put in rejects the len < "1 entry" case.
>
> There is no shortage of ambiguity here; the equiv table has both an
> explicit length, and commonly has a NULL entry at the end. But, we can
> parse with a length of 0.
>
>
> > diff --git a/xen/arch/x86/cpu/microcode/intel.c
> > b/xen/arch/x86/cpu/microcode/intel.c
> > index
> > 6f6957058684d7275d62e525e88ff678db9eb6d2..7a383adbdf1b5cb58f2e4c89e3a1c11ecc053993
> > 100644
> > --- a/xen/arch/x86/cpu/microcode/intel.c
> > +++ b/xen/arch/x86/cpu/microcode/intel.c
> > @@ -158,8 +158,9 @@ static int microcode_sanity_check(const struct
> > microcode_patch *patch)
> > * 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) )
> > + if ( (total_size & 1023) || (total_size < MC_HEADER_SIZE) ||
> > + data_size > (total_size - MC_HEADER_SIZE) ||
> > + (data_size % 4) != 0 )
>
> The caller has already checked some properties.
>
> Furthermore, total_size of 0 in the header is a special case for
> pre-Pentium4 ucode and is substituted with a constant, so can never be 0
> in the variable here. Therefore, I don't think the (total_size <
> MC_HEADER_SIZE) check can ever fail.
Correct. Anything nonzero will either be greater than MC_HEADER_SIZE or
will be rejected due to (total_size & 1023) not being zero. That said,
the new code is much more obviously correct.
> data_size being 4-byte aligned probably should be checked, although I
> think the later cross-check (ext_sigtable fits exactly in the remaining
> space) should catch this before the function wanders off the buffer.
>
> ~Andrew
It's still undefined behavior (cast to an unaligned pointer).
--
Sincerely,
Demi Marie Obenour (she/her/hers)
Invisible Things Lab
Attachment:
signature.asc
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |