|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 4/4] tools/xenstored: remove permissions related to dead domain
Wit unprivileged domains now capable to use the @releaseDomain watch,
there is no reason not to remove any node permissions which relate to
a domain which has been removed.
This resolves a complex scenario where a new domain could inherit the
permissions of an old one with the same domid.
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
tools/xenstored/domain.c | 61 ++++++++++++++++++++++++----------------
1 file changed, 36 insertions(+), 25 deletions(-)
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 0bd2a1891a..6fbb5c061a 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -569,24 +569,10 @@ static int domain_tree_remove_sub(const void *ctx, struct
connection *conn,
struct node *node, void *arg)
{
struct domain *domain = arg;
- int ret = WALK_TREE_OK;
-
- if (node->perms[0].id != domain->domid)
- return WALK_TREE_OK;
+ bool node_changed = false;
+ unsigned int i;
- if (keep_orphans) {
- domain_nbentry_dec(NULL, domain->domid);
- node->perms[0].id = priv_domid;
- node->acc.memory = 0;
- domain_nbentry_inc(NULL, priv_domid);
- if (write_node_raw(NULL, node->name, node, NODE_MODIFY, true)) {
- /* That's unfortunate. We only can try to continue. */
- syslog(LOG_ERR,
- "error when moving orphaned node %s to dom0\n",
- node->name);
- } else
- trace("orphaned node %s moved to dom0\n", node->name);
- } else {
+ if (node->perms[0].id == domain->domid && !keep_orphans) {
if (rm_node(NULL, ctx, node->name)) {
/* That's unfortunate. We only can try to continue. */
syslog(LOG_ERR,
@@ -596,10 +582,38 @@ static int domain_tree_remove_sub(const void *ctx, struct
connection *conn,
trace("orphaned node %s deleted\n", node->name);
/* Skip children in all cases in order to avoid more errors. */
- ret = WALK_TREE_SKIP_CHILDREN;
+ return WALK_TREE_SKIP_CHILDREN;
}
- return domain->acc_val[ACC_NODES] ? ret : WALK_TREE_SUCCESS_STOP;
+ if (node->perms[0].id == domain->domid) {
+ domain_nbentry_dec(NULL, domain->domid);
+ node->perms[0].id = priv_domid;
+ node->acc.memory = 0;
+ domain_nbentry_inc(NULL, priv_domid);
+ trace("moving orphaned node %s to dom0\n", node->name);
+ node_changed = true;
+ }
+
+ for (i = 1; i < node->hdr.num_perms; i++) {
+ if (node->perms[i].id != domain->domid)
+ continue;
+ memmove(node->perms + i, node->perms + i + 1,
+ sizeof(*node->perms) * (node->hdr.num_perms - i - 1));
+ node->hdr.num_perms--;
+ i--;
+ node_changed = true;
+ }
+
+ if (node_changed) {
+ if (write_node_raw(NULL, node->name, node, NODE_MODIFY, true)) {
+ /* That's unfortunate. We only can try to continue. */
+ syslog(LOG_ERR,
+ "error when writing modified node %s\n",
+ node->name);
+ }
+ }
+
+ return WALK_TREE_OK;
}
static void domain_tree_remove(struct domain *domain)
@@ -607,12 +621,9 @@ static void domain_tree_remove(struct domain *domain)
int ret;
struct walk_funcs walkfuncs = { .enter = domain_tree_remove_sub };
- if (domain->acc_val[ACC_NODES]) {
- ret = walk_node_tree(domain, NULL, "/", &walkfuncs, domain);
- if (ret == WALK_TREE_ERROR_STOP)
- syslog(LOG_ERR,
- "error when looking for orphaned nodes\n");
- }
+ ret = walk_node_tree(domain, NULL, "/", &walkfuncs, domain);
+ if (ret == WALK_TREE_ERROR_STOP)
+ syslog(LOG_ERR, "error when looking for orphaned nodes\n");
walk_node_tree(domain, NULL, "@releaseDomain", &walkfuncs, domain);
walk_node_tree(domain, NULL, "@introduceDomain", &walkfuncs, domain);
--
2.53.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |