x86/PV: address odd UB in I/O emulation
authorJan Beulich <jbeulich@suse.com>
Mon, 18 Oct 2021 12:23:29 +0000 (14:23 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 18 Oct 2021 12:23:29 +0000 (14:23 +0200)
commitc11b8d25fbe9c0155e91409594ea6701008409ed
tree9fafa36bb07fdb7e5117eb85b583e965dfca5474
parentc8ac573c238308dbaa31fa6acb571c91b587714f
x86/PV: address odd UB in I/O emulation

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@qq.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
xen/arch/x86/pv/emul-priv-op.c