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

Re: [PATCH] x86/hvmloader: fix usage of NULL with cpuid_count()


  • To: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • From: Alejandro Vallejo <agarciav@xxxxxxx>
  • Date: Fri, 25 Apr 2025 13:54:06 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=citrix.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=DpA0IsOcL84k4K+IiDU2FFoW7pmc4NixteRXMA26fP4=; b=RvegQIwJysy+e86tYHFbYQ3LWiHR82Hv2QVPO7VaRy41YZmZZlv8B+OLHw0hgLR6zFf85bKR2SuyN7pqlF2TuG7+pMMyvBGSOtw1MPQswsqC8IJg5SYphXqfEzNd7L2Y38MneAARWAipbxP7N6wfd495b6M5YJYnyf+qC7lidCpfjCuttis3KZCKiwuj+DO21cRSC/NgnPATZrIs6UVjQPpKefUEFR4FS9dwfU0JxN7WksWgC/Mzf5uXiiCa0T19tFqsRRqH7o99caE+6i6aMvTNvX3zFEm+sVzNgTqG7O77VEsjYXDPl0xL3ZT7Q8wS4D7NFWb6dIwlCov0S/6fwg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=OPgPAoxhY6BD/oqQ0O3/m0Dia8mgL+WWu/tLvNtwNsR2yU+etoUyuyr3HyoGHAAIii9Tn576pQXzKX3H3HxDoOfB0dxX5RFQv04sFC9ZN7XxMs66YMaymz72MGYU5I2GwD+3p72t46TszCNxR6+iBVE2SDSS9idDr7AcQIgtQzt0bPADNNfZ9B+CwmLk0tmIUx4zF7m/9Gbop4oHxtZZtvF7HiA08DanPBf5MM5D2FVW+UF9icSRBBXY/dSKe5kuAN/YEDL1Ic8toT+uL3lbzSYZwvgo3e680ndym1OSxCGU9IcxnEwsjnWetVtJLGEPnEmHvuoNpyfgLvmnyurvdw==
  • Cc: <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Xen-devel <xen-devel-bounces@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Fri, 25 Apr 2025 12:54:24 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Fri Apr 25, 2025 at 1:44 PM BST, Roger Pau Monné wrote:
> On Fri, Apr 25, 2025 at 01:23:30PM +0100, Alejandro Vallejo wrote:
>> On Thu Apr 24, 2025 at 1:58 PM BST, Roger Pau Monne wrote:
>> > The commit that added support for retrieving the APIC IDs from the APs
>> > introduced several usages of cpuid() with NULL parameters, which is not
>> > handled by the underlying implementation.  For GCC I expect this results in
>> > writes to the physical address at 0, however for Clang the generated code
>> > in smp.o is:
>> >
>> > tools/firmware/hvmloader/smp.o: file format elf32-i386
>> >
>> > Disassembly of section .text:
>> >
>> > 00000000 <smp_initialise>:
>> >        0: 55                            pushl   %ebp
>> >        1: 89 e5                         movl    %esp, %ebp
>> >        3: 53                            pushl   %ebx
>> >        4: 31 c0                         xorl    %eax, %eax
>> >        6: 31 c9                         xorl    %ecx, %ecx
>> >        8: 0f a2                         cpuid
>> >
>> > Showing the usage of a NULL pointer results in undefined behavior, and
>> > clang refusing to generate further code after it.
>> >
>> > Fix by using a temporary variable in cpuid_count() in place for any NULL
>> > parameter.
>> >
>> > Fixes: 9ad0db58c7e2 ('tools/hvmloader: Retrieve APIC IDs from the APs 
>> > themselves')
>> > Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
>> 
>> Ugh, that's on me. I was sure I saw the pattern in Xen (from where the
>> code came from), but clearly I hallucinated.
>> 
>> > ---
>> > Could also be fixed by using the temporary variable in the call sites,
>> > however that's more code in the call sites at the expense of less checking.
>> > I don't think the extra NULL check logic in cpuid_count() is that bad.
>> >
>> > Overall the solution proposed in this patch is safer going forward, as it
>> > prevent issues like this from being introduced in the first place.
>> 
>> Might be worth moving this same extra checks onto Xen's cpuid. There's
>> no shortage of `junk` variables at the callsites.
>> 
>> > ---
>> >  tools/firmware/hvmloader/util.h | 11 +++++++++++
>> >  1 file changed, 11 insertions(+)
>> >
>> > diff --git a/tools/firmware/hvmloader/util.h 
>> > b/tools/firmware/hvmloader/util.h
>> > index 644450c51ceb..765a013ddd9e 100644
>> > --- a/tools/firmware/hvmloader/util.h
>> > +++ b/tools/firmware/hvmloader/util.h
>> > @@ -190,6 +190,17 @@ static inline void cpuid_count(
>> >      uint32_t *ecx,
>> >      uint32_t *edx)
>> >  {
>> > +    uint32_t tmp;
>> > +
>> > +    if ( !eax )
>> > +        eax = &tmp;
>> > +    if ( !ebx )
>> > +        ebx = &tmp;
>> > +    if ( !ecx )
>> > +        ecx = &tmp;
>> > +    if ( !edx )
>> > +        edx = &tmp;
>> > +
>> 
>> A somewhat more compact alternative that doesn't require tmp would be:
>> 
>>   eax = eax ?: &leaf;
>>   ebx = ebx ?: &leaf;
>>   ecx = ecx ?: &leaf;
>>   edx = edx ?: &leaf;
>
> But that performs the write unconditionally?  It might be more compact
> code-wise, but might incur in an unneeded store?

Pretty sure it would all optimise to very similar, if not identical code.

>
>> It clobbers `leaf`, but only after it's no longer relevant.
>
> My preference was to use a explicitly tmp variable, but I could switch
> to using leaf if that's the preference.  Given that Andrew has already
> Acked the current version I'm tempted to just go with what has already
> been Acked.

That's perfectly fine. It was merely a cosmetic nit. LGTM as it is too.

>
> Thanks, Roger.

Cheers,
Alejandro



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.