[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 Monne <roger.pau@xxxxxxxxxx>, <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Alejandro Vallejo <agarciav@xxxxxxx>
  • Date: Fri, 25 Apr 2025 13:23:30 +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=/pGcYbRi0Ea7ULYgSqcSRAcuX2/Qs5vWBI6vB5qWo/M=; b=iEhzQdqbUhgfwa22p9k5DCfNqvS7QI6gusNO/4tM5tlvh+x4gYtBcwh52V0FNHhvqNwGZlJZYCni6qDtFCRUu8llB9B3p73gyKFOthlKxPHozTgrKxZvZJ1WHx9v4r7sYGliYhj2m7wL/TGccKAqdEkV9mq+xa6uVjE/fk2AnVp5ny+MwlxGV1GCvfbWG1NqLVvIPiSQgZGk1SO5nPK1BzEQ5Knfov0xPUUnhCyGOdaSHafxnu9peoDm6MpmZx8NHbwLuJrMMTbx7EgJVY3SJyVC3Heeq1SDI5KUaF5XJkzACGPE52htgvcriL2V1Z7P/eeDNqGOiybziFTBrhIj1Q==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=XryCHQ9lcLbJ2a8GyBfOuLhRYmKoCBDhrIELnrsJnsNSUT0oFZSGeOwis9gW3o+WUZknSuMe13qTPnnH95CWYaE7h+Q5G9IdaREM4q/0zvRe3VmFG5Q/AREouWB4wXvQe/cy/0vxf5Rw/fhHlJxIkYr4Yvk1D6k2FaY0GrkaL6uyskFJkQZYC6sf2kVCcE/pfVY9Ay9lUs0aeJkmtIWavFt0cLaqqf2R4IvZUqZN/jG9drskgxLqTxORYUWljzOoUK0pen5NvQ5osA9lGBOOTJm9Z3H1WLtnsu7apUIelmdf8ekKj6w/39+YlCi5oZXibo24kgJX4MyE8o9JAi19Zw==
  • Cc: 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:24:02 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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;

It clobbers `leaf`, but only after it's no longer relevant.

>      asm volatile ( "cpuid"
>                     : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
>                     : "a" (leaf), "c" (subleaf) );

Cheers,
Alejandro



 


Rackspace

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