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

Re: [PATCH] x86/PV: address odd UB in I/O emulation


  • To: Jan Beulich <jbeulich@xxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • Date: Thu, 8 Jul 2021 12:15:47 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LMXIU9hE9xko+HDwqxD9aIlaGPvtgEvYN145lL8FbHE=; b=cIXyDIAAwalTLVfkU/Tr9MzOJuW2Xt0xnF/CEiKNQREiIGECeUDhGZjRr249vfhOfycbn699+JuLj/7SIR1qyyjoRlr6Q6eSVvwmqwA7ddZ7YAl/4XqySDShUCpM7p/sM0+Ktboo4YNpDNKKW69gDhgTwyR9KNA9KhTHbVUeS8obqz72YgBCpfn0FduDAV4iGaBQS5BwanxZSwtuK4Di0ir8ocWdYElIO43imHiWs4bx4u8hp3Hf26bcBACmhwBSIe2foaABnlGDELr56acK9A9h91SES3QdFbD1ySOdXILVU25RzLmxKPgRMgpOQMSRINIp5rhesHIzDMdJyOBm0A==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=O6wkGa03wHH7gREupybBkjWTnXnT9/sI23REKdNEoVG2UFH2URc4C3Dzw/adLIW0Ue7X8KzVGXuYM0JuPAR+N84sqwRFz+y7M+BcrE2vm6vPmHrL11e93pcPwB9LmNuddmLFQ9IqUb9YLZ1WnHOg7o/HqOrRCXCldzS8k5bEAmdZsAkWnIvicO5ee+W+vXWwtXa2Ncln81SyBs4ssry8O2kSkMonufaly6UjWOg1H0+7CiQEcvuVwEhbiav3dBqcjoAoXA0Rgk5tXtqVPcC8Rm0qbnxY9KnShmfw8XwSGUJQmh/y7MKJya3NivqUesQ4/CYuSQmzzdod3Z7qNi744g==
  • Authentication-results: esa2.hc3370-68.iphmx.com; dkim=pass (signature verified) header.i=@citrix.onmicrosoft.com
  • Cc: Wei Liu <wl@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Franklin Shen <2284696125@xxxxxx>
  • Delivery-date: Thu, 08 Jul 2021 11:16:05 +0000
  • Ironport-hdrordr: A9a23:Jw/46KhPaG4CSKi+6dNkfGwnlHBQXtcji2hC6mlwRA09TyX4ra 6TdZEgvyMc5wx/ZJhNo6HkBED4ewK5yXYxjLNhXotKPzOGhILLFu1fBOLZqlXd8kbFh4xgPM lbHpSWWOeaMbAW5/yb3DWF
  • Ironport-sdr: f+3oZqNBqUMQxF0l7ib9xgyqd/HNdPryT3Z9K1M3ciz2xRKRsEx/q71OWwUAowthWznGJ983kM Mhk/qbFlGZrZtXivihZtrrxuZdcmoK0oYu6xEb6XafCGlGZy+4kDS2DR/shcbhFtgW5lnm9YrQ GPrd6F3GAcRr8kU2DHKljgOnnJUKKJypvq42m+jLb4bRevnBDsixi83rdYCnEm0TV9oWYCoFfP uC4O3qjdK94WK50FBfCu8u3UYi0G/x+YKHXzxH06oPvOXoKHzz9zHlrYnLw+uNkRNAA0mDu2gh qd8=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 08/07/2021 08:21, Jan Beulich wrote:
> Compilers are certainly right in detecting UB here, given that fully
> parenthesized (to express precedence) the original offending expression
> was (((stub_va + p) - ctxt->io_emul_stub) + 5), which in fact exhibits
> two overflows in pointer calculations. We really want to calculate
> (p - ctxt->io_emul_stub) first, which is guaranteed to not overflow.

I agree that avoiding this overflow is an improvement, but as I said in
my original analysis, (f) - (expr) also underflows and results in a
negative displacement.

This is specifically why I did the cast the other way around, so we're
subtracting integers not pointers.

It appears that we don't use -fwrapv so in any case, the only way of
doing this without UB is to use unsigned long's everywhere.

> The issue was observed with clang 9 on 4.13.
>
> The oddities are
> - the issue was detected on APPEND_CALL(save_guest_gprs), despite the
>   earlier similar APPEND_CALL(load_guest_gprs),
> - merely casting the original offending expression to long was reported
>   to also help.

Further to the above, that was also so didn't have an expression of
(ptr) - (unsigned long).

>
> While at it also avoid converting guaranteed (with our current address
> space layout) negative values to unsigned long (which has implementation
> defined behavior):

?  Converting between signed and unsigned representations has explicitly
well defined behaviour.

>  Have stub_va be of pointer type. And since it's on an
> immediately adjacent line, also constify this_stubs.
>
> Fixes: d89e5e65f305 ("x86/ioemul: Rewrite stub generation to be shadow stack 
> compatible")
> Reported-by: Franklin Shen <2284696125@xxxxxx>
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> ---
> I'm not going to insist on the part avoiding implementation defined
> behavior here. If I am to drop that, it is less clear whether
> constifying this_stubs would then still be warranted.

You're implicitly casting away const now at the return, which is
something you object to in other peoples patches.

>
> --- a/xen/arch/x86/pv/emul-priv-op.c
> +++ b/xen/arch/x86/pv/emul-priv-op.c
> @@ -89,8 +89,8 @@ static io_emul_stub_t *io_emul_stub_setu
>          0xc3,       /* ret       */
>      };
>  
> -    struct stubs *this_stubs = &this_cpu(stubs);
> -    unsigned long stub_va = this_stubs->addr + STUB_BUF_SIZE / 2;
> +    const struct stubs *this_stubs = &this_cpu(stubs);
> +    const void *stub_va = (void *)this_stubs->addr + STUB_BUF_SIZE / 2;
>      unsigned int quirk_bytes = 0;
>      char *p;
>  
> @@ -98,7 +98,7 @@ static io_emul_stub_t *io_emul_stub_setu
>  #define APPEND_BUFF(b) ({ memcpy(p, b, sizeof(b)); p += sizeof(b); })
>  #define APPEND_CALL(f)                                                  \
>      ({                                                                  \
> -        long disp = (long)(f) - (stub_va + p - ctxt->io_emul_stub + 5); \
> +        long disp = (void *)(f) - (stub_va + (p - ctxt->io_emul_stub) + 5); \

The only version of this which is UB-free is

long disp = (unsigned long)(f) - (stub_va + (p - ctxt->io_emul_stub) + 5);

As long as (p - ctxt->io_emul_stub) doesn't overflow (which it doesn't),
every other piece of that expression is well defined when stub_va stays
as its original type.

~Andrew




 


Rackspace

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