all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Dominik Csapak <d.csapak@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH qemu-server] fix #7654: prevent use after free
Date: Mon,  1 Jun 2026 14:16:29 +0200	[thread overview]
Message-ID: <20260601121654.2421101-1-d.csapak@proxmox.com> (raw)

to prevent a use after free on a client struct, instead of freeing it
inline in 'cleanup_client', only set a boolean flag 'pending_free'
and free it in the main 'handle_client' function.

the call graphs look like this:

handle_client
`-> cleanup_client
`-> handle_qmp_handshake
    `-> cleanup_client
    `-> send_qmp_cmd
        `-> cleanup_client
`-> handle_qmp_event
    `-> terminate_check
        `-> cleanup_client
`-> handle_qmp_return
    `-> terminate_check
        `-> cleanup_client

In addition, if we cleanup a 'vzdump' client, the corresponding vm wll
be looked up and 'terminate_check' will be called for it. If that
resulted in a cleanup, we have to free that immediately.

cleanup_client will not be called in other paths, so handling the
freeing in handle_client should suffice.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/qmeventd/qmeventd.c | 17 ++++++++++++++++-
 src/qmeventd/qmeventd.h |  1 +
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/qmeventd/qmeventd.c b/src/qmeventd/qmeventd.c
index 1d9eb74a..5c873e88 100644
--- a/src/qmeventd/qmeventd.c
+++ b/src/qmeventd/qmeventd.c
@@ -405,6 +405,13 @@ void cleanup_client(struct Client *client) {
             VERBOSE_PRINT("%s: backup ended\n", client->vzdump.vmid);
             vmc->qemu.backup = false;
             terminate_check(vmc);
+
+            // we cleaned up a vm client while handling a vzdump client, so we
+            // have to free it here directly. the nested cleanup call must have
+            // removed it from the vm_clients hash table already in that case.
+            if (vmc->pending_free) {
+                free(vmc);
+            }
         }
         break;
 
@@ -418,7 +425,7 @@ void cleanup_client(struct Client *client) {
     }
     VERBOSE_PRINT("removing %s from forced cleanups\n", client->qemu.vmid);
     forced_cleanups = g_slist_remove(forced_cleanups, client);
-    free(client);
+    client->pending_free = true;
 }
 
 void terminate_client(struct Client *client) {
@@ -478,11 +485,13 @@ void handle_client(struct Client *client) {
         if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
             log_neg((int)len, "read");
             cleanup_client(client);
+            free(client);
         }
         return;
     } else if (len == 0) {
         VERBOSE_PRINT("pid%d: got EOF\n", client->pid);
         cleanup_client(client);
+        free(client);
         return;
     }
 
@@ -530,6 +539,12 @@ void handle_client(struct Client *client) {
             break;
         }
         json_object_put(jobj);
+
+        // if the client was cleaned up, we have to free it here
+        if (client->pending_free) {
+            free(client);
+            break;
+        }
     }
     json_tokener_free(tok);
 }
diff --git a/src/qmeventd/qmeventd.h b/src/qmeventd/qmeventd.h
index bb372077..6a293b84 100644
--- a/src/qmeventd/qmeventd.h
+++ b/src/qmeventd/qmeventd.h
@@ -66,6 +66,7 @@ struct Client {
     pid_t pid;
     int pidfd;
     time_t timeout;
+    bool pending_free;
 
     ClientType type;
     ClientState state;
-- 
2.47.3





             reply	other threads:[~2026-06-01 12:17 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-01 12:16 Dominik Csapak [this message]
2026-06-02 11:39 ` [PATCH qemu-server] fix #7654: prevent use after free Fiona Ebner
2026-06-02 12:17 ` superseded: " Dominik Csapak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260601121654.2421101-1-d.csapak@proxmox.com \
    --to=d.csapak@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal