evtchn/FIFO: add 2nd smp_rmb() to evtchn_fifo_word_from_port()
authorJan Beulich <jbeulich@suse.com>
Fri, 11 Dec 2020 21:09:54 +0000 (22:09 +0100)
committerHans van Kranenburg <hans@knorrie.org>
Fri, 11 Dec 2020 21:10:09 +0000 (21:10 +0000)
Besides with add_page_to_event_array() the function also needs to
synchronize with evtchn_fifo_init_control() setting both d->evtchn_fifo
and (subsequently) d->evtchn_port_ops.

This is XSA-359 / CVE-2020-29571.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
Gbp-Pq: Name 0076-evtchn-FIFO-add-2nd-smp_rmb-to-evtchn_fifo_word_from.patch

xen/common/event_fifo.c

index ab9e496696fd8b273653cd9a6bb16c5f1251cffc..454ca40743655e9828f940379dfcb4381cb14eb5 100644 (file)
@@ -34,6 +34,13 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
 {
     unsigned int p, w;
 
+    /*
+     * Callers aren't required to hold d->event_lock, so we need to synchronize
+     * with evtchn_fifo_init_control() setting d->evtchn_port_ops /after/
+     * d->evtchn_fifo.
+     */
+    smp_rmb();
+
     if ( unlikely(port >= d->evtchn_fifo->num_evtchns) )
         return NULL;
 
@@ -590,6 +597,10 @@ int evtchn_fifo_init_control(struct evtchn_init_control *init_control)
         if ( rc < 0 )
             goto error;
 
+        /*
+         * This call, as a side effect, synchronizes with
+         * evtchn_fifo_word_from_port().
+         */
         rc = map_control_block(v, gfn, offset);
         if ( rc < 0 )
             goto error;