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

[xen stable-4.11] tools/xenstore: introduce node_perms structure



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

    tools/xenstore: introduce node_perms structure
    
    There are several places in xenstored using a permission array and the
    size of that array. Introduce a new struct node_perms containing both.
    
    This is part of XSA-115.
    
    Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
    Acked-by: Julien Grall <jgrall@xxxxxxxxxx>
    Reviewed-by: Paul Durrant <paul@xxxxxxx>
---
 tools/xenstore/xenstored_core.c   | 79 +++++++++++++++++++--------------------
 tools/xenstore/xenstored_core.h   |  8 +++-
 tools/xenstore/xenstored_domain.c | 12 +++---
 3 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index fcc3798328..f95f44d594 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -401,14 +401,14 @@ static struct node *read_node(struct connection *conn, 
const void *ctx,
        /* Datalen, childlen, number of permissions */
        hdr = (void *)data.dptr;
        node->generation = hdr->generation;
-       node->num_perms = hdr->num_perms;
+       node->perms.num = hdr->num_perms;
        node->datalen = hdr->datalen;
        node->childlen = hdr->childlen;
 
        /* Permissions are struct xs_permissions. */
-       node->perms = hdr->perms;
+       node->perms.p = hdr->perms;
        /* Data is binary blob (usually ascii, no nul). */
-       node->data = node->perms + node->num_perms;
+       node->data = node->perms.p + node->perms.num;
        /* Children is strings, nul separated. */
        node->children = node->data + node->datalen;
 
@@ -425,7 +425,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, 
struct node *node,
        struct xs_tdb_record_hdr *hdr;
 
        data.dsize = sizeof(*hdr)
-               + node->num_perms*sizeof(node->perms[0])
+               + node->perms.num * sizeof(node->perms.p[0])
                + node->datalen + node->childlen;
 
        if (!no_quota_check && domain_is_unprivileged(conn) &&
@@ -437,12 +437,13 @@ int write_node_raw(struct connection *conn, TDB_DATA 
*key, struct node *node,
        data.dptr = talloc_size(node, data.dsize);
        hdr = (void *)data.dptr;
        hdr->generation = node->generation;
-       hdr->num_perms = node->num_perms;
+       hdr->num_perms = node->perms.num;
        hdr->datalen = node->datalen;
        hdr->childlen = node->childlen;
 
-       memcpy(hdr->perms, node->perms, node->num_perms*sizeof(node->perms[0]));
-       p = hdr->perms + node->num_perms;
+       memcpy(hdr->perms, node->perms.p,
+              node->perms.num * sizeof(*node->perms.p));
+       p = hdr->perms + node->perms.num;
        memcpy(p, node->data, node->datalen);
        p += node->datalen;
        memcpy(p, node->children, node->childlen);
@@ -468,8 +469,7 @@ static int write_node(struct connection *conn, struct node 
*node,
 }
 
 static enum xs_perm_type perm_for_conn(struct connection *conn,
-                                      struct xs_permissions *perms,
-                                      unsigned int num)
+                                      const struct node_perms *perms)
 {
        unsigned int i;
        enum xs_perm_type mask = XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
@@ -478,16 +478,16 @@ static enum xs_perm_type perm_for_conn(struct connection 
*conn,
                mask &= ~XS_PERM_WRITE;
 
        /* Owners and tools get it all... */
-       if (!domain_is_unprivileged(conn) || perms[0].id == conn->id
-                || (conn->target && perms[0].id == conn->target->id))
+       if (!domain_is_unprivileged(conn) || perms->p[0].id == conn->id
+                || (conn->target && perms->p[0].id == conn->target->id))
                return (XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER) & mask;
 
-       for (i = 1; i < num; i++)
-               if (perms[i].id == conn->id
-                        || (conn->target && perms[i].id == conn->target->id))
-                       return perms[i].perms & mask;
+       for (i = 1; i < perms->num; i++)
+               if (perms->p[i].id == conn->id
+                        || (conn->target && perms->p[i].id == 
conn->target->id))
+                       return perms->p[i].perms & mask;
 
-       return perms[0].perms & mask;
+       return perms->p[0].perms & mask;
 }
 
 /*
@@ -534,7 +534,7 @@ static int ask_parents(struct connection *conn, const void 
*ctx,
                return 0;
        }
 
-       *perm = perm_for_conn(conn, node->perms, node->num_perms);
+       *perm = perm_for_conn(conn, &node->perms);
        return 0;
 }
 
@@ -580,8 +580,7 @@ struct node *get_node(struct connection *conn,
        node = read_node(conn, ctx, name);
        /* If we don't have permission, we don't have node. */
        if (node) {
-               if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
-                   != perm) {
+               if ((perm_for_conn(conn, &node->perms) & perm) != perm) {
                        errno = EACCES;
                        node = NULL;
                }
@@ -757,16 +756,15 @@ const char *onearg(struct buffered_data *in)
        return in->buffer;
 }
 
-static char *perms_to_strings(const void *ctx,
-                             struct xs_permissions *perms, unsigned int num,
+static char *perms_to_strings(const void *ctx, const struct node_perms *perms,
                              unsigned int *len)
 {
        unsigned int i;
        char *strings = NULL;
        char buffer[MAX_STRLEN(unsigned int) + 1];
 
-       for (*len = 0, i = 0; i < num; i++) {
-               if (!xs_perm_to_string(&perms[i], buffer, sizeof(buffer)))
+       for (*len = 0, i = 0; i < perms->num; i++) {
+               if (!xs_perm_to_string(&perms->p[i], buffer, sizeof(buffer)))
                        return NULL;
 
                strings = talloc_realloc(ctx, strings, char,
@@ -945,13 +943,13 @@ static struct node *construct_node(struct connection 
*conn, const void *ctx,
                goto nomem;
 
        /* Inherit permissions, except unprivileged domains own what they 
create */
-       node->num_perms = parent->num_perms;
-       node->perms = talloc_memdup(node, parent->perms,
-                                   node->num_perms * sizeof(node->perms[0]));
-       if (!node->perms)
+       node->perms.num = parent->perms.num;
+       node->perms.p = talloc_memdup(node, parent->perms.p,
+                                     node->perms.num * sizeof(*node->perms.p));
+       if (!node->perms.p)
                goto nomem;
        if (domain_is_unprivileged(conn))
-               node->perms[0].id = conn->id;
+               node->perms.p[0].id = conn->id;
 
        /* No children, no data */
        node->children = node->data = NULL;
@@ -1228,7 +1226,7 @@ static int do_get_perms(struct connection *conn, struct 
buffered_data *in)
        if (!node)
                return errno;
 
-       strings = perms_to_strings(node, node->perms, node->num_perms, &len);
+       strings = perms_to_strings(node, &node->perms, &len);
        if (!strings)
                return errno;
 
@@ -1239,13 +1237,12 @@ static int do_get_perms(struct connection *conn, struct 
buffered_data *in)
 
 static int do_set_perms(struct connection *conn, struct buffered_data *in)
 {
-       unsigned int num;
-       struct xs_permissions *perms;
+       struct node_perms perms;
        char *name, *permstr;
        struct node *node;
 
-       num = xs_count_strings(in->buffer, in->used);
-       if (num < 2)
+       perms.num = xs_count_strings(in->buffer, in->used);
+       if (perms.num < 2)
                return EINVAL;
 
        /* First arg is node name. */
@@ -1256,21 +1253,21 @@ static int do_set_perms(struct connection *conn, struct 
buffered_data *in)
                return errno;
 
        permstr = in->buffer + strlen(in->buffer) + 1;
-       num--;
+       perms.num--;
 
-       perms = talloc_array(node, struct xs_permissions, num);
-       if (!perms)
+       perms.p = talloc_array(node, struct xs_permissions, perms.num);
+       if (!perms.p)
                return ENOMEM;
-       if (!xs_strings_to_perms(perms, num, permstr))
+       if (!xs_strings_to_perms(perms.p, perms.num, permstr))
                return errno;
 
        /* Unprivileged domains may not change the owner. */
-       if (domain_is_unprivileged(conn) && perms[0].id != node->perms[0].id)
+       if (domain_is_unprivileged(conn) &&
+           perms.p[0].id != node->perms.p[0].id)
                return EPERM;
 
        domain_entry_dec(conn, node);
        node->perms = perms;
-       node->num_perms = num;
        domain_entry_inc(conn, node);
 
        if (write_node(conn, node, false))
@@ -1545,8 +1542,8 @@ static void manual_node(const char *name, const char 
*child)
                barf_perror("Could not allocate initial node %s", name);
 
        node->name = name;
-       node->perms = &perms;
-       node->num_perms = 1;
+       node->perms.p = &perms;
+       node->perms.num = 1;
        node->children = (char *)child;
        if (child)
                node->childlen = strlen(child) + 1;
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
index ee312378f7..a43bb55530 100644
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -111,6 +111,11 @@ struct connection
 };
 extern struct list_head connections;
 
+struct node_perms {
+       unsigned int num;
+       struct xs_permissions *p;
+};
+
 struct node {
        const char *name;
 
@@ -122,8 +127,7 @@ struct node {
 #define NO_GENERATION ~((uint64_t)0)
 
        /* Permissions. */
-       unsigned int num_perms;
-       struct xs_permissions *perms;
+       struct node_perms perms;
 
        /* Contents. */
        unsigned int datalen;
diff --git a/tools/xenstore/xenstored_domain.c 
b/tools/xenstore/xenstored_domain.c
index e25d2c2e53..433732b926 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -665,12 +665,12 @@ void domain_entry_inc(struct connection *conn, struct 
node *node)
        if (!conn)
                return;
 
-       if (node->perms && node->perms[0].id != conn->id) {
+       if (node->perms.p && node->perms.p[0].id != conn->id) {
                if (conn->transaction) {
                        transaction_entry_inc(conn->transaction,
-                               node->perms[0].id);
+                               node->perms.p[0].id);
                } else {
-                       d = find_domain_by_domid(node->perms[0].id);
+                       d = find_domain_by_domid(node->perms.p[0].id);
                        if (d)
                                d->nbentry++;
                }
@@ -691,12 +691,12 @@ void domain_entry_dec(struct connection *conn, struct 
node *node)
        if (!conn)
                return;
 
-       if (node->perms && node->perms[0].id != conn->id) {
+       if (node->perms.p && node->perms.p[0].id != conn->id) {
                if (conn->transaction) {
                        transaction_entry_dec(conn->transaction,
-                               node->perms[0].id);
+                               node->perms.p[0].id);
                } else {
-                       d = find_domain_by_domid(node->perms[0].id);
+                       d = find_domain_by_domid(node->perms.p[0].id);
                        if (d && d->nbentry)
                                d->nbentry--;
                }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.11



 


Rackspace

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