[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] tools/xenstore: add memory accounting for responses



commit f6d00133643a524d2138c9e3f192bbde719050ba
Author:     Juergen Gross <jgross@xxxxxxxx>
AuthorDate: Tue Sep 13 07:35:09 2022 +0200
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Tue Nov 1 13:05:44 2022 +0000

    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@xxxxxxxx>
    Reviewed-by: Julien Grall <jgrall@xxxxxxxxxx>
---
 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 f03ad93b43..009eaa8e5f 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -256,6 +256,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) {
@@ -934,11 +936,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;
                }
@@ -1003,6 +1008,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)
@@ -3012,6 +3022,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,
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.