mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
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 f6d0013364)
This commit is contained in:
1 parent
03889b6716
commit
cc289061d9
1 file changed
+13
-3
@@ -257,6 +257,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) {
|
||||
@@ -845,11 +847,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;
|
||||
}
|
||||
@@ -914,6 +919,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)
|
||||
|
||||