diff options
Diffstat (limited to '0096-tools-xenstore-add-memory-accounting-for-responses.patch')
-rw-r--r-- | 0096-tools-xenstore-add-memory-accounting-for-responses.patch | 82 |
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 + |