|
|
24e155b |
From e92f3dfeaae21a335e666c9247954424e34e5c56 Mon Sep 17 00:00:00 2001
|
|
|
24e155b |
From: Juergen Gross <jgross@suse.com>
|
|
|
24e155b |
Date: Thu, 11 Jun 2020 16:12:37 +0200
|
|
|
24e155b |
Subject: [PATCH 01/10] tools/xenstore: allow removing child of a node
|
|
|
24e155b |
exceeding quota
|
|
|
24e155b |
|
|
|
24e155b |
An unprivileged user of Xenstore is not allowed to write nodes with a
|
|
|
24e155b |
size exceeding a global quota, while privileged users like dom0 are
|
|
|
24e155b |
allowed to write such nodes. The size of a node is the needed space
|
|
|
24e155b |
to store all node specific data, this includes the names of all
|
|
|
24e155b |
children of the node.
|
|
|
24e155b |
|
|
|
24e155b |
When deleting a node its parent has to be modified by removing the
|
|
|
24e155b |
name of the to be deleted child from it.
|
|
|
24e155b |
|
|
|
24e155b |
This results in the strange situation that an unprivileged owner of a
|
|
|
24e155b |
node might not succeed in deleting that node in case its parent is
|
|
|
24e155b |
exceeding the quota of that unprivileged user (it might have been
|
|
|
24e155b |
written by dom0), as the user is not allowed to write the updated
|
|
|
24e155b |
parent node.
|
|
|
24e155b |
|
|
|
24e155b |
Fix that by not checking the quota when writing a node for the
|
|
|
24e155b |
purpose of removing a child's name only.
|
|
|
24e155b |
|
|
|
24e155b |
The same applies to transaction handling: a node being read during a
|
|
|
24e155b |
transaction is written to the transaction specific area and it should
|
|
|
24e155b |
not be tested for exceeding the quota, as it might not be owned by
|
|
|
24e155b |
the reader and presumably the original write would have failed if the
|
|
|
24e155b |
node is owned by the reader.
|
|
|
24e155b |
|
|
|
24e155b |
This is part of XSA-115.
|
|
|
24e155b |
|
|
|
24e155b |
Signed-off-by: Juergen Gross <jgross@suse.com>
|
|
|
24e155b |
Reviewed-by: Julien Grall <jgrall@amazon.com>
|
|
|
24e155b |
Reviewed-by: Paul Durrant <paul@xen.org>
|
|
|
24e155b |
---
|
|
|
24e155b |
tools/xenstore/xenstored_core.c | 20 +++++++++++---------
|
|
|
24e155b |
tools/xenstore/xenstored_core.h | 3 ++-
|
|
|
24e155b |
tools/xenstore/xenstored_transaction.c | 2 +-
|
|
|
24e155b |
3 files changed, 14 insertions(+), 11 deletions(-)
|
|
|
24e155b |
|
|
|
24e155b |
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
|
|
|
24e155b |
index 97ceabf9642d..b43e1018babd 100644
|
|
|
24e155b |
--- a/tools/xenstore/xenstored_core.c
|
|
|
24e155b |
+++ b/tools/xenstore/xenstored_core.c
|
|
|
24e155b |
@@ -417,7 +417,8 @@ static struct node *read_node(struct connection *conn, const void *ctx,
|
|
|
24e155b |
return node;
|
|
|
24e155b |
}
|
|
|
24e155b |
|
|
|
24e155b |
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
|
|
|
24e155b |
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
|
|
|
24e155b |
+ bool no_quota_check)
|
|
|
24e155b |
{
|
|
|
24e155b |
TDB_DATA data;
|
|
|
24e155b |
void *p;
|
|
|
24e155b |
@@ -427,7 +428,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
|
|
|
24e155b |
+ node->num_perms*sizeof(node->perms[0])
|
|
|
24e155b |
+ node->datalen + node->childlen;
|
|
|
24e155b |
|
|
|
24e155b |
- if (domain_is_unprivileged(conn) &&
|
|
|
24e155b |
+ if (!no_quota_check && domain_is_unprivileged(conn) &&
|
|
|
24e155b |
data.dsize >= quota_max_entry_size) {
|
|
|
24e155b |
errno = ENOSPC;
|
|
|
24e155b |
return errno;
|
|
|
24e155b |
@@ -455,14 +456,15 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node)
|
|
|
24e155b |
return 0;
|
|
|
24e155b |
}
|
|
|
24e155b |
|
|
|
24e155b |
-static int write_node(struct connection *conn, struct node *node)
|
|
|
24e155b |
+static int write_node(struct connection *conn, struct node *node,
|
|
|
24e155b |
+ bool no_quota_check)
|
|
|
24e155b |
{
|
|
|
24e155b |
TDB_DATA key;
|
|
|
24e155b |
|
|
|
24e155b |
if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
|
|
|
24e155b |
return errno;
|
|
|
24e155b |
|
|
|
24e155b |
- return write_node_raw(conn, &key, node);
|
|
|
24e155b |
+ return write_node_raw(conn, &key, node, no_quota_check);
|
|
|
24e155b |
}
|
|
|
24e155b |
|
|
|
24e155b |
static enum xs_perm_type perm_for_conn(struct connection *conn,
|
|
|
24e155b |
@@ -999,7 +1001,7 @@ static struct node *create_node(struct connection *conn, const void *ctx,
|
|
|
24e155b |
/* We write out the nodes down, setting destructor in case
|
|
|
24e155b |
* something goes wrong. */
|
|
|
24e155b |
for (i = node; i; i = i->parent) {
|
|
|
24e155b |
- if (write_node(conn, i)) {
|
|
|
24e155b |
+ if (write_node(conn, i, false)) {
|
|
|
24e155b |
domain_entry_dec(conn, i);
|
|
|
24e155b |
return NULL;
|
|
|
24e155b |
}
|
|
|
24e155b |
@@ -1039,7 +1041,7 @@ static int do_write(struct connection *conn, struct buffered_data *in)
|
|
|
24e155b |
} else {
|
|
|
24e155b |
node->data = in->buffer + offset;
|
|
|
24e155b |
node->datalen = datalen;
|
|
|
24e155b |
- if (write_node(conn, node))
|
|
|
24e155b |
+ if (write_node(conn, node, false))
|
|
|
24e155b |
return errno;
|
|
|
24e155b |
}
|
|
|
24e155b |
|
|
|
24e155b |
@@ -1115,7 +1117,7 @@ static int remove_child_entry(struct connection *conn, struct node *node,
|
|
|
24e155b |
size_t childlen = strlen(node->children + offset);
|
|
|
24e155b |
memdel(node->children, offset, childlen + 1, node->childlen);
|
|
|
24e155b |
node->childlen -= childlen + 1;
|
|
|
24e155b |
- return write_node(conn, node);
|
|
|
24e155b |
+ return write_node(conn, node, true);
|
|
|
24e155b |
}
|
|
|
24e155b |
|
|
|
24e155b |
|
|
|
24e155b |
@@ -1254,7 +1256,7 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
|
|
|
24e155b |
node->num_perms = num;
|
|
|
24e155b |
domain_entry_inc(conn, node);
|
|
|
24e155b |
|
|
|
24e155b |
- if (write_node(conn, node))
|
|
|
24e155b |
+ if (write_node(conn, node, false))
|
|
|
24e155b |
return errno;
|
|
|
24e155b |
|
|
|
24e155b |
fire_watches(conn, in, name, false);
|
|
|
24e155b |
@@ -1514,7 +1516,7 @@ static void manual_node(const char *name, const char *child)
|
|
|
24e155b |
if (child)
|
|
|
24e155b |
node->childlen = strlen(child) + 1;
|
|
|
24e155b |
|
|
|
24e155b |
- if (write_node(NULL, node))
|
|
|
24e155b |
+ if (write_node(NULL, node, false))
|
|
|
24e155b |
barf_perror("Could not create initial node %s", name);
|
|
|
24e155b |
talloc_free(node);
|
|
|
24e155b |
}
|
|
|
24e155b |
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
|
|
|
24e155b |
index 56a279cfbb47..3cb1c235a101 100644
|
|
|
24e155b |
--- a/tools/xenstore/xenstored_core.h
|
|
|
24e155b |
+++ b/tools/xenstore/xenstored_core.h
|
|
|
24e155b |
@@ -149,7 +149,8 @@ void send_ack(struct connection *conn, enum xsd_sockmsg_type type);
|
|
|
24e155b |
char *xenstore_canonicalize(struct connection *conn, const void *ctx, const char *node);
|
|
|
24e155b |
|
|
|
24e155b |
/* Write a node to the tdb data base. */
|
|
|
24e155b |
-int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node);
|
|
|
24e155b |
+int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
|
|
|
24e155b |
+ bool no_quota_check);
|
|
|
24e155b |
|
|
|
24e155b |
/* Get this node, checking we have permissions. */
|
|
|
24e155b |
struct node *get_node(struct connection *conn,
|
|
|
24e155b |
diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
|
|
|
24e155b |
index 2824f7b359b8..e87897573469 100644
|
|
|
24e155b |
--- a/tools/xenstore/xenstored_transaction.c
|
|
|
24e155b |
+++ b/tools/xenstore/xenstored_transaction.c
|
|
|
24e155b |
@@ -276,7 +276,7 @@ int access_node(struct connection *conn, struct node *node,
|
|
|
24e155b |
i->check_gen = true;
|
|
|
24e155b |
if (node->generation != NO_GENERATION) {
|
|
|
24e155b |
set_tdb_key(trans_name, &local_key);
|
|
|
24e155b |
- ret = write_node_raw(conn, &local_key, node);
|
|
|
24e155b |
+ ret = write_node_raw(conn, &local_key, node, true);
|
|
|
24e155b |
if (ret)
|
|
|
24e155b |
goto err;
|
|
|
24e155b |
i->ta_node = true;
|
|
|
24e155b |
--
|
|
|
24e155b |
2.17.1
|
|
|
24e155b |
|