File xsa115-5.patch of Package xen.27494
From c625fae44aedc246776b52eb1173cf847a3d4d80 Mon Sep 17 00:00:00 2001
From: Juergen Gross <jgross@suse.com>
Date: Thu, 11 Jun 2020 16:12:41 +0200
Subject: [PATCH 05/10] tools/xenstore: check privilege for
XS_IS_DOMAIN_INTRODUCED
The Xenstore command XS_IS_DOMAIN_INTRODUCED should be possible for
privileged domains only (the only user in the tree is the xenpaging
daemon).
Instead of having the privilege test for each command introduce a
per-command flag for that purpose.
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 | 24 ++++++++++++++++++------
tools/xenstore/xenstored_domain.c | 7 ++-----
2 files changed, 20 insertions(+), 11 deletions(-)
--- xen-4.12.4-testing.orig/tools/xenstore/xenstored_core.c
+++ xen-4.12.4-testing/tools/xenstore/xenstored_core.c
@@ -1283,8 +1283,10 @@ static struct {
int (*func)(struct connection *conn, struct buffered_data *in);
unsigned int flags;
#define XS_FLAG_NOTID (1U << 0) /* Ignore transaction id. */
+#define XS_FLAG_PRIV (1U << 1) /* Privileged domain only. */
} const wire_funcs[XS_TYPE_COUNT] = {
- [XS_CONTROL] = { "CONTROL", do_control },
+ [XS_CONTROL] =
+ { "CONTROL", do_control, XS_FLAG_PRIV },
[XS_DIRECTORY] = { "DIRECTORY", send_directory },
[XS_READ] = { "READ", do_read },
[XS_GET_PERMS] = { "GET_PERMS", do_get_perms },
@@ -1294,8 +1296,10 @@ static struct {
{ "UNWATCH", do_unwatch, XS_FLAG_NOTID },
[XS_TRANSACTION_START] = { "TRANSACTION_START", do_transaction_start },
[XS_TRANSACTION_END] = { "TRANSACTION_END", do_transaction_end },
- [XS_INTRODUCE] = { "INTRODUCE", do_introduce },
- [XS_RELEASE] = { "RELEASE", do_release },
+ [XS_INTRODUCE] =
+ { "INTRODUCE", do_introduce, XS_FLAG_PRIV },
+ [XS_RELEASE] =
+ { "RELEASE", do_release, XS_FLAG_PRIV },
[XS_GET_DOMAIN_PATH] = { "GET_DOMAIN_PATH", do_get_domain_path },
[XS_WRITE] = { "WRITE", do_write },
[XS_MKDIR] = { "MKDIR", do_mkdir },
@@ -1304,9 +1308,11 @@ static struct {
[XS_WATCH_EVENT] = { "WATCH_EVENT", NULL },
[XS_ERROR] = { "ERROR", NULL },
[XS_IS_DOMAIN_INTRODUCED] =
- { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced },
- [XS_RESUME] = { "RESUME", do_resume },
- [XS_SET_TARGET] = { "SET_TARGET", do_set_target },
+ { "IS_DOMAIN_INTRODUCED", do_is_domain_introduced, XS_FLAG_PRIV },
+ [XS_RESUME] =
+ { "RESUME", do_resume, XS_FLAG_PRIV },
+ [XS_SET_TARGET] =
+ { "SET_TARGET", do_set_target, XS_FLAG_PRIV },
[XS_RESET_WATCHES] = { "RESET_WATCHES", do_reset_watches },
[XS_DIRECTORY_PART] = { "DIRECTORY_PART", send_directory_part },
};
@@ -1334,6 +1340,12 @@ static void process_message(struct conne
return;
}
+ if ((wire_funcs[type].flags & XS_FLAG_PRIV) &&
+ domain_is_unprivileged(conn)) {
+ send_error(conn, EACCES);
+ return;
+ }
+
trans = (wire_funcs[type].flags & XS_FLAG_NOTID)
? NULL : transaction_lookup(conn, in->hdr.msg.tx_id);
if (IS_ERR(trans)) {
--- xen-4.12.4-testing.orig/tools/xenstore/xenstored_domain.c
+++ xen-4.12.4-testing/tools/xenstore/xenstored_domain.c
@@ -385,7 +385,7 @@ int do_introduce(struct connection *conn
if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
return EINVAL;
- if (domain_is_unprivileged(conn) || !conn->can_write)
+ if (!conn->can_write)
return EACCES;
domid = atoi(vec[0]);
@@ -453,7 +453,7 @@ int do_set_target(struct connection *con
if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec))
return EINVAL;
- if (domain_is_unprivileged(conn) || !conn->can_write)
+ if (!conn->can_write)
return EACCES;
domid = atoi(vec[0]);
@@ -488,9 +488,6 @@ static struct domain *onearg_domain(stru
if (!domid)
return ERR_PTR(-EINVAL);
- if (domain_is_unprivileged(conn))
- return ERR_PTR(-EACCES);
-
return find_connected_domain(domid);
}