* [PATCH qemu-server] fix #7654: prevent use after free
@ 2026-06-01 12:16 Dominik Csapak
2026-06-02 11:39 ` Fiona Ebner
2026-06-02 12:17 ` superseded: " Dominik Csapak
0 siblings, 2 replies; 3+ messages in thread
From: Dominik Csapak @ 2026-06-01 12:16 UTC (permalink / raw)
To: pve-devel
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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH qemu-server] fix #7654: prevent use after free
2026-06-01 12:16 [PATCH qemu-server] fix #7654: prevent use after free Dominik Csapak
@ 2026-06-02 11:39 ` Fiona Ebner
2026-06-02 12:17 ` superseded: " Dominik Csapak
1 sibling, 0 replies; 3+ messages in thread
From: Fiona Ebner @ 2026-06-02 11:39 UTC (permalink / raw)
To: Dominik Csapak, pve-devel
Am 01.06.26 um 2:16 PM schrieb Dominik Csapak:
> 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
Nit: there's an additional `-> send_qmp_cmd here (terminate_check() does
not call cleanup_client() directly).
> `-> cleanup_client
> `-> handle_qmp_return
> `-> terminate_check
Nit: same here
> `-> cleanup_client
>
> In addition, if we cleanup a 'vzdump' client, the corresponding vm wll
s/vm wll/VM client will/
> 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>
Reviewed-by: Fiona Ebner <f.ebner@proxmox.com>
Thanks!
^ permalink raw reply [flat|nested] 3+ messages in thread
* superseded: [PATCH qemu-server] fix #7654: prevent use after free
2026-06-01 12:16 [PATCH qemu-server] fix #7654: prevent use after free Dominik Csapak
2026-06-02 11:39 ` Fiona Ebner
@ 2026-06-02 12:17 ` Dominik Csapak
1 sibling, 0 replies; 3+ messages in thread
From: Dominik Csapak @ 2026-06-02 12:17 UTC (permalink / raw)
To: pve-devel
superseded by v2:
https://lore.proxmox.com/pve-devel/20260602121659.2497188-1-d.csapak@proxmox.com/T/#u
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-06-02 12:17 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-01 12:16 [PATCH qemu-server] fix #7654: prevent use after free Dominik Csapak
2026-06-02 11:39 ` Fiona Ebner
2026-06-02 12:17 ` superseded: " Dominik Csapak
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.