From: Juergen Gross Date: Tue, 13 Sep 2022 05:35:10 +0000 (+0200) Subject: tools/xenstore: add memory accounting for watches X-Git-Tag: RELEASE-4.14.6~105 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=3a7c46a94454aa48f6e247ed91773d96b4b70afb;p=xen.git tools/xenstore: add memory accounting for watches 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 Reviewed-by: Julien Grall (cherry picked from commit 7f9978a2cc37aaffab2fb09593bc598c0712a69b) --- diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 4322d3cf63..0f589a1f63 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -407,6 +407,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; diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index c50c0575f0..7118c30e8c 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -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); }