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

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


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Thu, 8 Jul 2021 09:21:26 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.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=ZZpAvKtmohzarK4azDYvQ9FxhhTmCdU3uZXkZyb9qg8=; b=YVYGn3YSiYodBqUUtLQyxUBQ8zdaMlZoHpfva+yseyWG7m1J6b83Sm4oWI6zCR/WDX8axS2jqBu76OBK6vVidLxEDF68YkbWSuAmBezpGauNZ7wDaSeRU44r4gYj0r++rdSFCOAOosv3WhHrTVliSXbCFrdAuT5tCLsA6TJ/bXCeNQk2nMfvzlTUHuKV1XfAl5XmMuUymakHs6pAo6JrBIvTjybSOvsCqSKJSCe+6B3dTXOo89lMMNq+v8nIvooeUoEKfAsjtpuGpTuYyD4bxQ6oS+2ueo4h6RA48yf+zeM8KUpSJ8Gf0+69rJ6rlOMgrEWV7UYFNhIGNIKLL8ZWzw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Wva8rqJuInerYX0AeSLayJeRQRyYIOLXF5AcUGZ6CH7By6UE3RcIIDTcaLjWrT1HhTd0Rx8Cj2sWvNf/oKzwaVsb2xG9HLBfu3EOvAV9p79l5R6wka9CWsKRzmWwbrRZSTAGSUGyiLcYMC8W8bjmQOEBS2MQv3Jwd/BvNkzI3hPgH+88N3FcRpRkJojcZwemOLr9dlR52YX5Dq0e2OAkzGvhPoPiSxCy4pRVLhKmTIuXgNOmYAJJtpYJWNV8s8Z4r3wNVsL/RtYK4IEB8QYFx3p0NeLv2LgNllEuE61WmJAvERAXXW6walyvR3CV5Z1PwYP6TY6ZWjgX4WgJ3d/FnQ==
  • Authentication-results: qq.com; dkim=none (message not signed) header.d=none;qq.com; dmarc=none action=none header.from=suse.com;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Rroach <2284696125@xxxxxx>
  • Delivery-date: Thu, 08 Jul 2021 07:21:41 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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.

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.

While at it also avoid converting guaranteed (with our current address
space layout) negative values to unsigned long (which has implementation
defined behavior): 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.

--- 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); \
         BUG_ON((int32_t)disp != disp);                                  \
         *p++ = 0xe8;                                                    \
         *(int32_t *)p = disp; p += 4;                                   \
@@ -106,7 +106,7 @@ static io_emul_stub_t *io_emul_stub_setu
 
     if ( !ctxt->io_emul_stub )
         ctxt->io_emul_stub =
-            map_domain_page(_mfn(this_stubs->mfn)) + (stub_va & ~PAGE_MASK);
+            map_domain_page(_mfn(this_stubs->mfn)) + PAGE_OFFSET(stub_va);
 
     p = ctxt->io_emul_stub;
 
@@ -141,7 +141,7 @@ static io_emul_stub_t *io_emul_stub_setu
     block_speculation(); /* SCSB */
 
     /* Handy function-typed pointer to the stub. */
-    return (void *)stub_va;
+    return stub_va;
 
 #undef APPEND_CALL
 #undef APPEND_BUFF




 


Rackspace

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