aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore/xenstored_core.c
diff options
context:
space:
mode:
authorEwan Mellor <ewan@xensource.com>2006-11-13 10:43:29 +0000
committerEwan Mellor <ewan@xensource.com>2006-11-13 10:43:29 +0000
commitdb34d2aaa5f5eb5826a939fe8eacb91432a87d42 (patch)
tree3ca8ca28a68e078e67ac2c9e39b539b0fb06a99c /tools/xenstore/xenstored_core.c
parentede7828af2f265d3a40abe8905611861c0f88867 (diff)
downloadxen-db34d2aaa5f5eb5826a939fe8eacb91432a87d42.tar.gz
xen-db34d2aaa5f5eb5826a939fe8eacb91432a87d42.tar.bz2
xen-db34d2aaa5f5eb5826a939fe8eacb91432a87d42.zip
Fix handling of the entries-per-domain quota. Entries which are created by
the guest but deleted by dom0 were remaining accounted against the guest, which meant that the guest would eventually run out of quota. This patch also prevents unprivileged domains from changing the owner of a node. One guest could attack another by creating nodes and then transferring them to the ownership of another, and though the accounting could be made to work properly in this case, domains should never be transferring nodes in any case, so it seems safer just to disallow the operation entirely. Signed-off-by: Ewan Mellor <ewan@xensource.com>
Diffstat (limited to 'tools/xenstore/xenstored_core.c')
-rw-r--r--tools/xenstore/xenstored_core.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 3f304b0e41..5ac4dd3b0f 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -791,7 +791,7 @@ static void delete_node_single(struct connection *conn, struct node *node)
corrupt(conn, "Could not delete '%s'", node->name);
return;
}
- domain_entry_dec(conn);
+ domain_entry_dec(conn, node);
}
/* Must not be / */
@@ -842,7 +842,7 @@ static struct node *construct_node(struct connection *conn, const char *name)
node->children = node->data = NULL;
node->childlen = node->datalen = 0;
node->parent = parent;
- domain_entry_inc(conn);
+ domain_entry_inc(conn, node);
return node;
}
@@ -878,7 +878,7 @@ static struct node *create_node(struct connection *conn,
* something goes wrong. */
for (i = node; i; i = i->parent) {
if (!write_node(conn, i)) {
- domain_entry_dec(conn);
+ domain_entry_dec(conn, i);
return NULL;
}
talloc_set_destructor(i, destroy_node);
@@ -1108,6 +1108,7 @@ static void do_get_perms(struct connection *conn, const char *name)
static void do_set_perms(struct connection *conn, struct buffered_data *in)
{
unsigned int num;
+ struct xs_permissions *perms;
char *name, *permstr;
struct node *node;
@@ -1129,12 +1130,24 @@ static void do_set_perms(struct connection *conn, struct buffered_data *in)
return;
}
- node->perms = talloc_array(node, struct xs_permissions, num);
- node->num_perms = num;
- if (!xs_strings_to_perms(node->perms, num, permstr)) {
+ perms = talloc_array(node, struct xs_permissions, num);
+ if (!xs_strings_to_perms(perms, num, permstr)) {
send_error(conn, errno);
return;
}
+
+ /* Unprivileged domains may not change the owner. */
+ if (domain_is_unprivileged(conn) &&
+ perms[0].id != node->perms[0].id) {
+ send_error(conn, EPERM);
+ return;
+ }
+
+ domain_entry_dec(conn, node);
+ node->perms = perms;
+ node->num_perms = num;
+ domain_entry_inc(conn, node);
+
if (!write_node(conn, node)) {
send_error(conn, errno);
return;