]> xenbits.xensource.com Git - xen.git/commitdiff
tools/xenstore: add memory accounting for watches
authorJuergen Gross <jgross@suse.com>
Tue, 13 Sep 2022 05:35:10 +0000 (07:35 +0200)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 1 Nov 2022 15:25:15 +0000 (15:25 +0000)
Add the memory accounting for registered watches.

When a socket connection is destroyed, the associated watches are
removed, too. In order to keep memory accounting correct the watches
must be removed explicitly via a call of conn_delete_all_watches() from
destroy_conn().

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 7f9978a2cc37aaffab2fb09593bc598c0712a69b)

tools/xenstore/xenstored_core.c
tools/xenstore/xenstored_watch.c

index 4f29439ad8250ae987ad11196461c5790f531a6f..eca04e734a8348be143f850e7e4d7fd5f1c1bdc4 100644 (file)
@@ -404,6 +404,7 @@ static int destroy_conn(void *_conn)
        }
 
        conn_free_buffered_data(conn);
+       conn_delete_all_watches(conn);
        list_for_each_entry(req, &conn->ref_list, list)
                req->on_ref_list = false;
 
index c50c0575f0f1f3091481f3e7cb41973b7e34fb34..7118c30e8c3238433e2eac90b85a89ef288d717d 100644 (file)
@@ -224,7 +224,8 @@ int do_watch(struct connection *conn, struct buffered_data *in)
                return ENOMEM;
        watch->node = talloc_strdup(watch, vec[0]);
        watch->token = talloc_strdup(watch, vec[1]);
-       if (!watch->node || !watch->token) {
+       if (!watch->node || !watch->token ||
+           domain_memory_add_chk(conn->id, strlen(vec[0]) + strlen(vec[1]))) {
                talloc_free(watch);
                return ENOMEM;
        }
@@ -265,6 +266,8 @@ int do_unwatch(struct connection *conn, struct buffered_data *in)
        list_for_each_entry(watch, &conn->watches, list) {
                if (streq(watch->node, node) && streq(watch->token, vec[1])) {
                        list_del(&watch->list);
+                       domain_memory_add_nochk(conn->id, -strlen(watch->node) -
+                                                         strlen(watch->token));
                        talloc_free(watch);
                        domain_watch_dec(conn);
                        send_ack(conn, XS_UNWATCH);
@@ -280,6 +283,8 @@ void conn_delete_all_watches(struct connection *conn)
 
        while ((watch = list_top(&conn->watches, struct watch, list))) {
                list_del(&watch->list);
+               domain_memory_add_nochk(conn->id, -strlen(watch->node) -
+                                                 strlen(watch->token));
                talloc_free(watch);
                domain_watch_dec(conn);
        }