summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '0096-tools-xenstore-add-memory-accounting-for-responses.patch')
-rw-r--r--0096-tools-xenstore-add-memory-accounting-for-responses.patch82
1 files changed, 82 insertions, 0 deletions
diff --git a/0096-tools-xenstore-add-memory-accounting-for-responses.patch b/0096-tools-xenstore-add-memory-accounting-for-responses.patch
new file mode 100644
index 0000000..6174433
--- /dev/null
+++ b/0096-tools-xenstore-add-memory-accounting-for-responses.patch
@@ -0,0 +1,82 @@
+From 0113aacb3d791600668cd7703f6f12ed94fc6d03 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Tue, 13 Sep 2022 07:35:09 +0200
+Subject: [PATCH 096/126] tools/xenstore: add memory accounting for responses
+
+Add the memory accounting for queued responses.
+
+In case adding a watch event for a guest is causing the hard memory
+quota of that guest to be violated, the event is dropped. This will
+ensure that it is impossible to drive another guest past its memory
+quota by generating insane amounts of events for that guest. This is
+especially important for protecting driver domains from that attack
+vector.
+
+This is part of XSA-326 / CVE-2022-42315.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Julien Grall <jgrall@amazon.com>
+(cherry picked from commit f6d00133643a524d2138c9e3f192bbde719050ba)
+---
+ tools/xenstore/xenstored_core.c | 22 +++++++++++++++++++---
+ 1 file changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
+index eeb0d893e8c3..2e02b577c912 100644
+--- a/tools/xenstore/xenstored_core.c
++++ b/tools/xenstore/xenstored_core.c
+@@ -260,6 +260,8 @@ static void free_buffered_data(struct buffered_data *out,
+ }
+ }
+
++ domain_memory_add_nochk(conn->id, -out->hdr.msg.len - sizeof(out->hdr));
++
+ if (out->hdr.msg.type == XS_WATCH_EVENT) {
+ req = out->pend.req;
+ if (req) {
+@@ -904,11 +906,14 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
+ bdata->timeout_msec = 0;
+ bdata->watch_event = false;
+
+- if (len <= DEFAULT_BUFFER_SIZE)
++ if (len <= DEFAULT_BUFFER_SIZE) {
+ bdata->buffer = bdata->default_buffer;
+- else {
++ /* Don't check quota, path might be used for returning error. */
++ domain_memory_add_nochk(conn->id, len + sizeof(bdata->hdr));
++ } else {
+ bdata->buffer = talloc_array(bdata, char, len);
+- if (!bdata->buffer) {
++ if (!bdata->buffer ||
++ domain_memory_add_chk(conn->id, len + sizeof(bdata->hdr))) {
+ send_error(conn, ENOMEM);
+ return;
+ }
+@@ -973,6 +978,11 @@ void send_event(struct buffered_data *req, struct connection *conn,
+ }
+ }
+
++ if (domain_memory_add_chk(conn->id, len + sizeof(bdata->hdr))) {
++ talloc_free(bdata);
++ return;
++ }
++
+ if (timeout_watch_event_msec && domain_is_unprivileged(conn)) {
+ bdata->timeout_msec = get_now_msec() + timeout_watch_event_msec;
+ if (!conn->timeout_msec)
+@@ -2940,6 +2950,12 @@ static void add_buffered_data(struct buffered_data *bdata,
+ */
+ if (bdata->hdr.msg.type != XS_WATCH_EVENT)
+ domain_outstanding_inc(conn);
++ /*
++ * We are restoring the state after Live-Update and the new quota may
++ * be smaller. So ignore it. The limit will be applied for any resource
++ * after the state has been fully restored.
++ */
++ domain_memory_add_nochk(conn->id, len + sizeof(bdata->hdr));
+ }
+
+ void read_state_buffered_data(const void *ctx, struct connection *conn,
+--
+2.37.4
+