From: Julien Grall Date: Mon, 27 Apr 2020 07:28:21 +0000 (+0200) Subject: guest_access: harden *copy_to_guest_offset() to prevent const dest operand X-Git-Tag: archive/raspbian/4.14.0+80-gd101b417b7-1+rpi1^2~63^2~351 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=4bdf6b5a7fec876e9bbd70ebe605828ad0fb12a4;p=xen.git guest_access: harden *copy_to_guest_offset() to prevent const dest operand At the moment, *copy_to_guest_offset() will allow the hypervisor to copy data to guest handle marked const. Thankfully, no users of the helper will do that. Rather than hoping this can be caught during review, harden copy_to_guest_offset() so the build will fail if such users are introduced. There is no easy way to check whether a const is NULL in C99. The approach used is to introduce an unused variable that is non-const and assign the handle. If the handle were const, this would fail at build because without an explicit cast, it is not possible to assign a const variable to a non-const variable. Suggested-by: Jan Beulich Signed-off-by: Julien Grall Reviewed-by: Jan Beulich Acked-by: Stefano Stabellini --- diff --git a/xen/include/asm-arm/guest_access.h b/xen/include/asm-arm/guest_access.h index 8997a1cbfe..3b8d4ec322 100644 --- a/xen/include/asm-arm/guest_access.h +++ b/xen/include/asm-arm/guest_access.h @@ -78,6 +78,8 @@ int access_guest_memory_by_ipa(struct domain *d, paddr_t ipa, void *buf, #define copy_to_guest_offset(hnd, off, ptr, nr) ({ \ const typeof(*(ptr)) *_s = (ptr); \ char (*_d)[sizeof(*_s)] = (void *)(hnd).p; \ + /* Check that the handle is not for a const type */ \ + void *__maybe_unused _t = (hnd).p; \ ((void)((hnd).p == (ptr))); \ raw_copy_to_guest(_d+(off), _s, sizeof(*_s)*(nr)); \ }) @@ -127,6 +129,8 @@ int access_guest_memory_by_ipa(struct domain *d, paddr_t ipa, void *buf, #define __copy_to_guest_offset(hnd, off, ptr, nr) ({ \ const typeof(*(ptr)) *_s = (ptr); \ char (*_d)[sizeof(*_s)] = (void *)(hnd).p; \ + /* Check that the handle is not for a const type */ \ + void *__maybe_unused _t = (hnd).p; \ ((void)((hnd).p == (ptr))); \ __raw_copy_to_guest(_d+(off), _s, sizeof(*_s)*(nr));\ }) diff --git a/xen/include/asm-x86/guest_access.h b/xen/include/asm-x86/guest_access.h index ca700c959a..a22745ceb4 100644 --- a/xen/include/asm-x86/guest_access.h +++ b/xen/include/asm-x86/guest_access.h @@ -87,6 +87,8 @@ #define copy_to_guest_offset(hnd, off, ptr, nr) ({ \ const typeof(*(ptr)) *_s = (ptr); \ char (*_d)[sizeof(*_s)] = (void *)(hnd).p; \ + /* Check that the handle is not for a const type */ \ + void *__maybe_unused _t = (hnd).p; \ ((void)((hnd).p == (ptr))); \ raw_copy_to_guest(_d+(off), _s, sizeof(*_s)*(nr)); \ }) @@ -137,6 +139,8 @@ #define __copy_to_guest_offset(hnd, off, ptr, nr) ({ \ const typeof(*(ptr)) *_s = (ptr); \ char (*_d)[sizeof(*_s)] = (void *)(hnd).p; \ + /* Check that the handle is not for a const type */ \ + void *__maybe_unused _t = (hnd).p; \ ((void)((hnd).p == (ptr))); \ __raw_copy_to_guest(_d+(off), _s, sizeof(*_s)*(nr));\ })