public inbox for pve-devel@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal