On 7/22/26 10:36, Denis V. Lunev wrote:
> This email originated from an IP that might not be authorized by the domain
> it was sent from.
> Do not click links or open attachments unless it is an email you expected to
> receive.
> daemonStreamHandleWrite() snapshots status from msg->header.status
> before dispatching to the per-type handler, then reuses that stale
> snapshot afterwards to decide whether to send a fake release reply.
> A stale snapshot lets it send that reply twice for the same 'msg',
> linking the message to itself and deadlooping the event loop thread
> in virNetMessageQueuePush()'s tail-walk loop.
>
> Remove the 'status' variable and read msg->header.status directly
> at the point of use instead. Commit 411cbe7199c ("remote: fix
> stream use-after-free") introduced it alongside its real fix: it
> also moved virNetMessageQueueServe() to dequeue 'msg' from
> stream->rx before dispatch instead of after, which is what actually
> prevents corrupting stream->rx's linkage and remains unchanged
> here. The variable itself was never load-bearing: no dispatch
> handler frees 'msg' on the path that reaches this check, so reading
> msg->header.status straight from 'msg' cannot go stale.
>
> Fixes: 411cbe7199ce ("remote: fix stream use-after-free")
> Signed-off-by: Denis V. Lunev <[email protected]>
> ---
> src/remote/remote_daemon_stream.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/src/remote/remote_daemon_stream.c
> b/src/remote/remote_daemon_stream.c
> index 3777c8e684..437cec374f 100644
> --- a/src/remote/remote_daemon_stream.c
> +++ b/src/remote/remote_daemon_stream.c
> @@ -736,7 +736,6 @@ static int
> daemonStreamHandleWrite(virNetServerClient *client,
> daemonClientStream *stream)
> {
> - virNetMessageStatus status = VIR_NET_OK;
> VIR_DEBUG("client=%p, stream=%p", client, stream);
>
> while (stream->rx && !stream->closed) {
> @@ -748,10 +747,8 @@ daemonStreamHandleWrite(virNetServerClient *client,
> * Otherwise just carry on with processing stream
> * data. */
> ret = daemonStreamHandleHole(client, stream, msg);
> - status = msg->header.status;
> } else if (msg->header.type == VIR_NET_STREAM) {
> - status = msg->header.status;
> - switch (status) {
> + switch (msg->header.status) {
> case VIR_NET_OK:
> ret = daemonStreamHandleFinish(client, stream, msg);
> break;
> @@ -791,7 +788,7 @@ daemonStreamHandleWrite(virNetServerClient *client,
> * onto the wire, but this causes the client to reset
> * its active request count / throttling
> */
> - if (status == VIR_NET_CONTINUE) {
> + if (msg->header.status == VIR_NET_CONTINUE) {
> virNetMessageClear(msg);
> msg->header.type = VIR_NET_REPLY;
> if (virNetServerClientSendMessage(client, msg) < 0) {
ping