[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging-4.13] tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED



commit 1819c9dbe8f93e832a18db61390948e35f5862c5
Author:     Juergen Gross <jgross@xxxxxxxx>
AuthorDate: Thu Jun 11 16:12:41 2020 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Dec 15 14:18:44 2020 +0100

    tools/xenstore: check privilege for XS_IS_DOMAIN_INTRODUCED
    
    The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
    privileged domains only (the only user in the tree is the xenpaging
    daemon).
    
    Instead of having the privilege test for each command introduce a
    per-command flag for that purpose.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
    Reviewed-by: Julien Grall <jgrall@xxxxxxxxxx>
    Reviewed-by: Paul Durrant <paul@xxxxxxx>
---
 tools/xenstore/xenstored_core.c   | 24 ++++++++++++++++++------
 tools/xenstore/xenstored_domain.c |  7 ++-----
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index db9b9ca795..6afd584311 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -1283,8 +1283,10 @@ static struct {
        int (*func)(struct connection *conn, struct buffered_data *in);
        unsigned int flags;
 #define XS_FLAG_NOTID          (1U << 0)       /* Ignore transaction id. */
+#define XS_FLAG_PRIV           (1U << 1)       /* Privileged domain only. */
 } const wire_funcs[XS_TYPE_COUNT] = {
-       [XS_CONTROL]           = { "CONTROL",           do_control },
+       [XS_CONTROL]           =
+           { "CONTROL",       do_control,      XS_FLAG_PRIV },
        [XS_DIRECTORY]         = { "DIRECTORY",         send_directory },
        [XS_READ]              = { "READ",              do_read },
        [XS_GET_PERMS]         = { "GET_PERMS",         do_get_perms },
@@ -1294,8 +1296,10 @@ static struct {
            { "UNWATCH",       do_unwatch,      XS_FLAG_NOTID },
        [XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
        [XS_TRANSACTION_END]   = { "TRANSACTION_END",   do_transaction_end },
-       [XS_INTRODUCE]         = { "INTRODUCE",         do_introduce },
-       [XS_RELEASE]           = { "RELEASE",           do_release },
+       [XS_INTRODUCE]         =
+           { "INTRODUCE",     do_introduce,    XS_FLAG_PRIV },
+       [XS_RELEASE]           =
+           { "RELEASE",       do_release,      XS_FLAG_PRIV },
        [XS_GET_DOMAIN_PATH]   = { "GET_DOMAIN_PATH",   do_get_domain_path },
        [XS_WRITE]             = { "WRITE",             do_write },
        [XS_MKDIR]             = { "MKDIR",             do_mkdir },
@@ -1304,9 +1308,11 @@ static struct {
        [XS_WATCH_EVENT]       = { "WATCH_EVENT",       NULL },
        [XS_ERROR]             = { "ERROR",             NULL },
        [XS_IS_DOMAIN_INTRODUCED] =
-                       { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
-       [XS_RESUME]            = { "RESUME",            do_resume },
-       [XS_SET_TARGET]        = { "SET_TARGET",        do_set_target },
+           { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+       [XS_RESUME]            =
+           { "RESUME",        do_resume,       XS_FLAG_PRIV },
+       [XS_SET_TARGET]        =
+           { "SET_TARGET",    do_set_target,   XS_FLAG_PRIV },
        [XS_RESET_WATCHES]     = { "RESET_WATCHES",     do_reset_watches },
        [XS_DIRECTORY_PART]    = { "DIRECTORY_PART",    send_directory_part },
 };
@@ -1334,6 +1340,12 @@ static void process_message(struct connection *conn, 
struct buffered_data *in)
                return;
        }
 
+       if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+           domain_is_unprivileged(conn)) {
+               send_error(conn, EACCES);
+               return;
+       }
+
        trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
                ? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
        if (IS_ERR(trans)) {
diff --git a/tools/xenstore/xenstored_domain.c 
b/tools/xenstore/xenstored_domain.c
index 1eae703ef6..0e2926e2a3 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -377,7 +377,7 @@ int do_introduce(struct connection *conn, struct 
buffered_data *in)
        if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
                return EINVAL;
 
-       if (domain_is_unprivileged(conn) || !conn->can_write)
+       if (!conn->can_write)
                return EACCES;
 
        domid = atoi(vec[0]);
@@ -445,7 +445,7 @@ int do_set_target(struct connection *conn, struct 
buffered_data *in)
        if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
                return EINVAL;
 
-       if (domain_is_unprivileged(conn) || !conn->can_write)
+       if (!conn->can_write)
                return EACCES;
 
        domid = atoi(vec[0]);
@@ -480,9 +480,6 @@ static struct domain *onearg_domain(struct connection *conn,
        if (!domid)
                return ERR_PTR(-EINVAL);
 
-       if (domain_is_unprivileged(conn))
-               return ERR_PTR(-EACCES);
-
        return find_connected_domain(domid);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.13



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.