Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP7:GA
xen.22544
xsa115-1.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa115-1.patch of Package xen.22544
From e92f3dfeaae21a335e666c9247954424e34e5c56 Mon Sep 17 00:00:00 2001 From: Juergen Gross <jgross@suse.com> Date: Thu, 11 Jun 2020 16:12:37 +0200 Subject: [PATCH 01/10] tools/xenstore: allow removing child of a node exceeding quota An unprivileged user of Xenstore is not allowed to write nodes with a size exceeding a global quota, while privileged users like dom0 are allowed to write such nodes. The size of a node is the needed space to store all node specific data, this includes the names of all children of the node. When deleting a node its parent has to be modified by removing the name of the to be deleted child from it. This results in the strange situation that an unprivileged owner of a node might not succeed in deleting that node in case its parent is exceeding the quota of that unprivileged user (it might have been written by dom0), as the user is not allowed to write the updated parent node. Fix that by not checking the quota when writing a node for the purpose of removing a child's name only. The same applies to transaction handling: a node being read during a transaction is written to the transaction specific area and it should not be tested for exceeding the quota, as it might not be owned by the reader and presumably the original write would have failed if the node is owned by the reader. This is part of XSA-115. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Julien Grall <jgrall@amazon.com> Reviewed-by: Paul Durrant <paul@xen.org> --- tools/xenstore/xenstored_core.c | 20 +++++++++++--------- tools/xenstore/xenstored_core.h | 3 ++- tools/xenstore/xenstored_transaction.c | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) --- xen-4.11.4-testing.orig/tools/xenstore/xenstored_core.c +++ xen-4.11.4-testing/tools/xenstore/xenstored_core.c @@ -417,7 +417,8 @@ static struct node *read_node(struct con return node; } -int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node) +int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node, + bool no_quota_check) { TDB_DATA data; void *p; @@ -427,7 +428,7 @@ int write_node_raw(struct connection *co + node->num_perms*sizeof(node->perms[0]) + node->datalen + node->childlen; - if (domain_is_unprivileged(conn) && + if (!no_quota_check && domain_is_unprivileged(conn) && data.dsize >= quota_max_entry_size) { errno = ENOSPC; return errno; @@ -455,14 +456,15 @@ int write_node_raw(struct connection *co return 0; } -static int write_node(struct connection *conn, struct node *node) +static int write_node(struct connection *conn, struct node *node, + bool no_quota_check) { TDB_DATA key; if (access_node(conn, node, NODE_ACCESS_WRITE, &key)) return errno; - return write_node_raw(conn, &key, node); + return write_node_raw(conn, &key, node, no_quota_check); } static enum xs_perm_type perm_for_conn(struct connection *conn, @@ -999,7 +1001,7 @@ static struct node *create_node(struct c /* We write out the nodes down, setting destructor in case * something goes wrong. */ for (i = node; i; i = i->parent) { - if (write_node(conn, i)) { + if (write_node(conn, i, false)) { domain_entry_dec(conn, i); return NULL; } @@ -1039,7 +1041,7 @@ static int do_write(struct connection *c } else { node->data = in->buffer + offset; node->datalen = datalen; - if (write_node(conn, node)) + if (write_node(conn, node, false)) return errno; } @@ -1115,7 +1117,7 @@ static int remove_child_entry(struct con size_t childlen = strlen(node->children + offset); memdel(node->children, offset, childlen + 1, node->childlen); node->childlen -= childlen + 1; - return write_node(conn, node); + return write_node(conn, node, true); } @@ -1254,7 +1256,7 @@ static int do_set_perms(struct connectio node->num_perms = num; domain_entry_inc(conn, node); - if (write_node(conn, node)) + if (write_node(conn, node, false)) return errno; fire_watches(conn, in, name, false); @@ -1514,7 +1516,7 @@ static void manual_node(const char *name if (child) node->childlen = strlen(child) + 1; - if (write_node(NULL, node)) + if (write_node(NULL, node, false)) barf_perror("Could not create initial node %s", name); talloc_free(node); } --- xen-4.11.4-testing.orig/tools/xenstore/xenstored_core.h +++ xen-4.11.4-testing/tools/xenstore/xenstored_core.h @@ -151,7 +151,8 @@ void send_ack(struct connection *conn, e char *canonicalize(struct connection *conn, const void *ctx, const char *node); /* Write a node to the tdb data base. */ -int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node); +int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node, + bool no_quota_check); /* Get this node, checking we have permissions. */ struct node *get_node(struct connection *conn, --- xen-4.11.4-testing.orig/tools/xenstore/xenstored_transaction.c +++ xen-4.11.4-testing/tools/xenstore/xenstored_transaction.c @@ -276,7 +276,7 @@ int access_node(struct connection *conn, i->check_gen = true; if (node->generation != NO_GENERATION) { set_tdb_key(trans_name, &local_key); - ret = write_node_raw(conn, &local_key, node); + ret = write_node_raw(conn, &local_key, node, true); if (ret) goto err; i->ta_node = true;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor