All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rahul Singh <rahul.singh@arm.com>
To: xen-devel@lists.xenproject.org
Cc: bertrand.marquis@arm.com, rahul.singh@arm.com,
	Julien Grall <jgrall@amazon.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	George Dunlap <george.dunlap@citrix.com>,
	Jan Beulich <jbeulich@suse.com>, Julien Grall <julien@xen.org>,
	Stefano Stabellini <sstabellini@kernel.org>, Wei Liu <wl@xen.org>
Subject: [PATCH v2 1/7] xen/evtchn: Make sure all buckets below d->valid_evtchns are allocated
Date: Fri, 19 Aug 2022 11:02:38 +0100	[thread overview]
Message-ID: <710e9e6477270212136d6f2047fd15a033fa7d71.1660902588.git.rahul.singh@arm.com> (raw)
In-Reply-To: <cover.1660902588.git.rahul.singh@arm.com>

From: Julien Grall <jgrall@amazon.com>

Since commit 01280dc19cf3 "evtchn: simplify port_is_valid()", the event
channels code assumes that all the buckets below d->valid_evtchns are
always allocated.

This assumption hold in most of the situation because a guest is not
allowed to chose the port. Instead, it will be the first free from port
0.

When using Guest Transparent Migration and LiveUpdate, we will only
preserve ports that are currently in use. As a guest can open/close
event channels, this means the ports may be sparse.

The existing implementation of evtchn_allocate_port() is not able to
deal with such situation and will end up to override bucket or/and leave
some bucket unallocated. The latter will result to a droplet crash if
the event channel belongs to an unallocated bucket.

This can be solved by making sure that all the buckets below
d->valid_evtchns are allocated. There should be no impact for most of
the situation but LM/LU as only one bucket would be allocated. For
LM/LU, we may end up to allocate multiple buckets if ports in use are
sparse.

A potential alternative is to check that the bucket is valid in
is_port_valid(). This should still possible to do it without taking
per-domain lock but will result a couple more of memory access.

Signed-off-by: Julien Grall <jgrall@amazon.com>
Signed-off-by: Rahul Singh <rahul.singh@arm.com>
---
Changes in v2:
 - new patch in this version to fix the security issue
---
---
 xen/common/event_channel.c | 56 ++++++++++++++++++++++++--------------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index c2c6f8c151..dbe0a27311 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -193,6 +193,15 @@ static struct evtchn *alloc_evtchn_bucket(struct domain *d, unsigned int port)
     return NULL;
 }
 
+/*
+ * Allocate a given port and ensure all the buckets up to that ports
+ * have been allocated.
+ *
+ * The last part is important because the rest of the event channel code
+ * relies on all the buckets up to d->valid_evtchns to be valid. However,
+ * event channels may be sparsed when restoring a domain during Guest
+ * Transparent Migration and Live Update.
+ */
 int evtchn_allocate_port(struct domain *d, evtchn_port_t port)
 {
     if ( port > d->max_evtchn_port || port >= max_evtchns(d) )
@@ -207,30 +216,35 @@ int evtchn_allocate_port(struct domain *d, evtchn_port_t port)
     }
     else
     {
-        struct evtchn *chn;
-        struct evtchn **grp;
-
-        if ( !group_from_port(d, port) )
+        do
         {
-            grp = xzalloc_array(struct evtchn *, BUCKETS_PER_GROUP);
-            if ( !grp )
-                return -ENOMEM;
-            group_from_port(d, port) = grp;
-        }
+            struct evtchn *chn;
+            struct evtchn **grp;
+            unsigned int alloc_port = read_atomic(&d->valid_evtchns);
 
-        chn = alloc_evtchn_bucket(d, port);
-        if ( !chn )
-            return -ENOMEM;
-        bucket_from_port(d, port) = chn;
+            if ( !group_from_port(d, alloc_port) )
+            {
+                grp = xzalloc_array(struct evtchn *, BUCKETS_PER_GROUP);
+                if ( !grp )
+                    return -ENOMEM;
+                group_from_port(d, alloc_port) = grp;
+            }
 
-        /*
-         * d->valid_evtchns is used to check whether the bucket can be
-         * accessed without the per-domain lock. Therefore,
-         * d->valid_evtchns should be seen *after* the new bucket has
-         * been setup.
-         */
-        smp_wmb();
-        write_atomic(&d->valid_evtchns, d->valid_evtchns + EVTCHNS_PER_BUCKET);
+            chn = alloc_evtchn_bucket(d, alloc_port);
+            if ( !chn )
+                return -ENOMEM;
+            bucket_from_port(d, alloc_port) = chn;
+
+            /*
+             * d->valid_evtchns is used to check whether the bucket can be
+             * accessed without the per-domain lock. Therefore,
+             * d->valid_evtchns should be seen *after* the new bucket has
+             * been setup.
+             */
+            smp_wmb();
+            write_atomic(&d->valid_evtchns,
+                         d->valid_evtchns + EVTCHNS_PER_BUCKET);
+        } while ( port >= read_atomic(&d->valid_evtchns) );
     }
 
     write_atomic(&d->active_evtchns, d->active_evtchns + 1);
-- 
2.25.1



  reply	other threads:[~2022-08-19 10:03 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-19 10:02 [PATCH v2 0/7] xen/evtchn: implement static event channel signaling Rahul Singh
2022-08-19 10:02 ` Rahul Singh [this message]
2022-08-22 13:08   ` [PATCH v2 1/7] xen/evtchn: Make sure all buckets below d->valid_evtchns are allocated Jan Beulich
2022-08-23  8:14     ` Julien Grall
2022-08-23 13:37     ` Rahul Singh
2022-08-19 10:02 ` [PATCH v2 2/7] xen/evtchn: Add an helper to reserve/allocate a port Rahul Singh
2022-08-22 13:45   ` Jan Beulich
2022-08-23  9:14     ` Rahul Singh
2022-08-19 10:02 ` [PATCH v2 3/7] xen/evtchn: restrict the maximum number of evtchn supported for domUs Rahul Singh
2022-08-22 13:49   ` Jan Beulich
2022-08-23  7:56     ` Julien Grall
2022-08-23  8:29       ` Jan Beulich
2022-08-23 10:39         ` Rahul Singh
2022-08-23 11:35           ` Jan Beulich
2022-08-23 11:44             ` Bertrand Marquis
2022-08-23 12:48             ` Julien Grall
2022-08-23 14:01               ` Rahul Singh
2022-08-23  9:41       ` Rahul Singh
2022-08-19 10:02 ` [PATCH v2 4/7] xen/evtchn: modify evtchn_bind_interdomain to support static evtchn Rahul Singh
2022-08-22 13:53   ` Jan Beulich
2022-08-23  8:23   ` Julien Grall
2022-08-23  9:23     ` Rahul Singh
2022-08-19 10:02 ` [PATCH v2 5/7] xen/evtchn: modify evtchn_alloc_unbound to allocate specified port Rahul Singh
2022-08-22 13:57   ` Jan Beulich
2022-08-23  9:25     ` Rahul Singh
2022-08-23  8:31   ` Julien Grall
2022-08-23  9:27     ` Rahul Singh
2022-08-19 10:02 ` [PATCH v2 6/7] xen: introduce xen-evtchn dom0less property Rahul Singh
2022-08-23  9:32   ` Julien Grall
2022-08-24 14:52     ` Rahul Singh
2022-08-19 10:02 ` [PATCH v2 7/7] xen/arm: introduce new xen,enhanced property value Rahul Singh
2022-08-23 10:05   ` Julien Grall
2022-08-24 12:15     ` Rahul Singh
2022-08-24 12:59       ` Julien Grall
2022-08-24 14:42         ` Rahul Singh
2022-08-24 15:36           ` Julien Grall
2022-08-24 16:35             ` Rahul Singh
2022-08-24 21:59               ` Stefano Stabellini
2022-08-24 22:42                 ` Julien Grall
2022-08-25  1:10                   ` Stefano Stabellini
2022-08-25  7:39                     ` Bertrand Marquis
2022-08-25  9:37                       ` Julien Grall
2022-08-25  9:48                         ` Bertrand Marquis
2022-08-25 17:44                           ` Stefano Stabellini
2022-08-31  9:52                             ` Bertrand Marquis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=710e9e6477270212136d6f2047fd15a033fa7d71.1660902588.git.rahul.singh@arm.com \
    --to=rahul.singh@arm.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=bertrand.marquis@arm.com \
    --cc=george.dunlap@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=jgrall@amazon.com \
    --cc=julien@xen.org \
    --cc=sstabellini@kernel.org \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.