Mailing List Archive

[xen stable-4.13] xen: Check the alignment of the offset pased via VCPUOP_register_vcpu_info
commit 378321bb1fd5272653ae64f0306827614a3bd196
Author: Julien Grall <jgrall@amazon.com>
AuthorDate: Tue Jul 7 15:05:36 2020 +0200
Commit: Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Jul 7 15:05:36 2020 +0200

xen: Check the alignment of the offset pased via VCPUOP_register_vcpu_info

Currently a guest is able to register any guest physical address to use
for the vcpu_info structure as long as the structure can fits in the
rest of the frame.

This means a guest can provide an address that is not aligned to the
natural alignment of the structure.

On Arm 32-bit, unaligned access are completely forbidden by the
hypervisor. This will result to a data abort which is fatal.

On Arm 64-bit, unaligned access are only forbidden when used for atomic
access. As the structure contains fields (such as evtchn_pending_self)
that are updated using atomic operations, any unaligned access will be
fatal as well.

While the misalignment is only fatal on Arm, a generic check is added
as an x86 guest shouldn't sensibly pass an unaligned address (this
would result to a split lock).

This is XSA-327.

Reported-by: Julien Grall <jgrall@amazon.com>
Signed-off-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
master commit: 3fdc211b01b29f252166937238efe02d15cb5780
master date: 2020-07-07 14:41:00 +0200
---
xen/common/domain.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index 0902a15e8d..30b5f7f898 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -1300,10 +1300,20 @@ int map_vcpu_info(struct vcpu *v, unsigned long gfn, unsigned offset)
void *mapping;
vcpu_info_t *new_info;
struct page_info *page;
+ unsigned int align;

if ( offset > (PAGE_SIZE - sizeof(vcpu_info_t)) )
return -EINVAL;

+#ifdef CONFIG_COMPAT
+ if ( has_32bit_shinfo(d) )
+ align = alignof(new_info->compat);
+ else
+#endif
+ align = alignof(*new_info);
+ if ( offset & (align - 1) )
+ return -EINVAL;
+
if ( !mfn_eq(v->vcpu_info_mfn, INVALID_MFN) )
return -EINVAL;

--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.13