From nobody Sun Nov 16 02:28:11 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1762644604; cv=none; d=zohomail.com; s=zohoarc; b=D2l5ZzPy5DV5Aa4O03B9op9xuysuMIop1ase84qQr+dENPQ4twsAvhCkW2OMgtsBAPwK8+ZFb1nYHdM9AU3nya/aINR8+8tR7lHkVsbdZiWBDELoZqa+a8YGLB1fPNd7JqfUg0eCqpYAWdSTydm1vqeRWLZ+qguv3w1TedbFkB4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1762644604; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=udpGvb6GsLzY8Nzx5SVU1xxaApckb0eWOKbbFMkxDfw=; b=F0miKecYcpyiwS7EwdnOHlY9geEs8UYmy6ijGBiG1OLar2x3H/+15nMFFyIElwjzRqILJzPvGROkmYc/SuugkBlFCJRJbeknYD5dik/JAZsoctvzQaQzujS2pe42V5u3KA6fB/jqp718TLorua+n9VaJgmIBZkNLzS7jU9T1tuw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1762644604893270.12157764495976; Sat, 8 Nov 2025 15:30:04 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vHs0H-0005bT-Ac; Sat, 08 Nov 2025 18:05:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vHs07-0005Ox-LM for qemu-devel@nongnu.org; Sat, 08 Nov 2025 18:05:43 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vHs06-0001fT-4s for qemu-devel@nongnu.org; Sat, 08 Nov 2025 18:05:43 -0500 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-553-x1Lfxzr8Oi6Jm7BI3CxTQQ-1; Sat, 08 Nov 2025 18:05:37 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4BD7A1800451; Sat, 8 Nov 2025 23:05:36 +0000 (UTC) Received: from green.redhat.com (unknown [10.2.16.2]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E422619560A7; Sat, 8 Nov 2025 23:05:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762643141; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=udpGvb6GsLzY8Nzx5SVU1xxaApckb0eWOKbbFMkxDfw=; b=S4Rz407wGY78MsDJiwJ3ICcvktUvSnXWiScOuzJXP3wAt5NQKqDkJ7KIDCQ9t0iufK9ndq CIz6nkorbHYvVUNeT/kId2gkOpg4SZU9vSv1240cmtVnTd8JYKnL3RgqvMPA6vvn8g0Mde kuyKpyL2G2DYXU9XxYoXd7hhJHYvvKg= X-MC-Unique: x1Lfxzr8Oi6Jm7BI3CxTQQ-1 X-Mimecast-MFC-AGG-ID: x1Lfxzr8Oi6Jm7BI3CxTQQ_1762643136 From: Eric Blake To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, berrange@redhat.com, kwolf@redhat.com, qemu-stable@nongnu.org Subject: [PATCH v2 03/12] qio: Unwatch before notify in QIONetListener Date: Sat, 8 Nov 2025 16:59:24 -0600 Message-ID: <20251108230525.3169174-17-eblake@redhat.com> In-Reply-To: <20251108230525.3169174-14-eblake@redhat.com> References: <20251108230525.3169174-14-eblake@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1762644608169158500 Content-Type: text/plain; charset="utf-8" When changing the callback registered with QIONetListener, the code was calling notify on the old opaque data prior to actually removing the old GSource objects still pointing to that data. Similarly, during finalize, it called notify before tearing down the various GSource objects tied to the data. In practice, a grep of the QEMU code base found that every existing client of QIONetListener passes in a NULL notifier (the opaque data, if non-NULL, outlives the NetListener and so does not need cleanup when the NetListener is torn down), so this patch has no impact. And even if a caller had passed in a reference-counted object with a notifier of object_unref but kept its own reference on the data, then the early notify would merely reduce a refcount from (say) 2 to 1, but not free the object. However, it is a latent bug waiting to bite any future caller that passes in data where the notifier actually frees the object, because the GSource could then trigger a use-after-free if it loses the race on a last-minute client connection resulting in the data being passed to one final use of the async callback. Better is to delay the notify call until after all GSource that have been given a copy of the opaque data are torn down. CC: qemu-stable@nongnu.org Fixes: 530473924d "io: introduce a network socket listener API", v2.12.0 Signed-off-by: Eric Blake Reviewed-by: Daniel P. Berrang=C3=A9 --- v2: new patch, split out from 4/8 to leave that one as just pure refactoring, and call attention to this being a latent bug fix --- io/net-listener.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/io/net-listener.c b/io/net-listener.c index 007acbd5b18..d71b65270e0 100644 --- a/io/net-listener.c +++ b/io/net-listener.c @@ -148,13 +148,6 @@ void qio_net_listener_set_client_func_full(QIONetListe= ner *listener, trace_qio_net_listener_unwatch(listener, listener->io_func, "set_client_func"); - if (listener->io_notify) { - listener->io_notify(listener->io_data); - } - listener->io_func =3D func; - listener->io_data =3D data; - listener->io_notify =3D notify; - for (i =3D 0; i < listener->nsioc; i++) { if (listener->io_source[i]) { g_source_destroy(listener->io_source[i]); @@ -163,6 +156,13 @@ void qio_net_listener_set_client_func_full(QIONetListe= ner *listener, } } + if (listener->io_notify) { + listener->io_notify(listener->io_data); + } + listener->io_func =3D func; + listener->io_data =3D data; + listener->io_notify =3D notify; + trace_qio_net_listener_watch(listener, listener->io_func, "set_client_func"); if (listener->io_func !=3D NULL) { @@ -300,10 +300,10 @@ static void qio_net_listener_finalize(Object *obj) QIONetListener *listener =3D QIO_NET_LISTENER(obj); size_t i; + qio_net_listener_disconnect(listener); if (listener->io_notify) { listener->io_notify(listener->io_data); } - qio_net_listener_disconnect(listener); for (i =3D 0; i < listener->nsioc; i++) { object_unref(OBJECT(listener->sioc[i])); --=20 2.51.1