From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-dl1-f45.google.com (mail-dl1-f45.google.com [74.125.82.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB84A40BCD3 for ; Thu, 11 Jun 2026 16:27:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.45 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781195226; cv=none; b=H3F7yr++doj6vMC5uc/LvO3HtVddErrokBKOf+DNia/qZWugfI9GtMKjK75U+B2y6CA8XP/RQC5dKQQzjrVA+dInEHYV0pux6WPzr5Zl5XY11JxJ/n3DCqgCNYTYq97orcCGrrcwrCkvReSGpfXYiViGlz1B8kty5CSvEpCtiBw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781195226; c=relaxed/simple; bh=cAbqpXtpBfIChkS2icEuZxRztc3RLiCrmte818eDwgQ=; h=Mime-Version:Content-Type:Date:Message-Id:Cc:Subject:From:To: References:In-Reply-To; b=J0a1HHTVT6f6ZRhwenhsjD+/lZgZ1pbiSvQWPUjGRv2eLEdV2wf7/Ja4oZ+3I5NxZAd8xzhht92bn9xauZwW6xgacqdnhyqeeLJdKwgknlXJ0D97MfuD1wtFWuo0lV36ekZ4RsFDjuM40f8f4qSoroNBgBidZAWJSoTPWIcUPOA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=XPwrEJuq; arc=none smtp.client-ip=74.125.82.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XPwrEJuq" Received: by mail-dl1-f45.google.com with SMTP id a92af1059eb24-13807d2f898so5844c88.0 for ; Thu, 11 Jun 2026 09:27:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781195224; x=1781800024; darn=vger.kernel.org; h=in-reply-to:references:to:from:subject:cc:message-id:date :content-transfer-encoding:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=XIQ0zMQkILDWGcn93CGMgKvcLA3VvTscsfQrUNo9JBI=; b=XPwrEJuqu8by+5Qd5ei1ZDQwCmKRjusfSFtBVvubpEfrBtSB5NZz0PymgQlW2hlZPx 0wH2Bm9oLudfcJAkTjVxuy2Ee0L5nUMadpv9p2AhTj3140u2oEqs8P9R3+zKC6b37bU0 xLNelLPBJeEM4G7ZlU04/0yXZv7mScvd6gbVof+Bqz0WYuG1UZeUm2Iu54V0basueBcr +gp17KwVB93h2zFnvwtFDYeFWlJxWN5tR5rSFQvxv6O9rSYEsospZc9iKH6BfGFZ1dTm kyy5PWBbIU433ydMqUxkz1rK91dbX8TX66oF6efBXTVU7oHKcBAcySAWQ1lFlDdM+vZ+ rjkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781195224; x=1781800024; h=in-reply-to:references:to:from:subject:cc:message-id:date :content-transfer-encoding:mime-version:x-gm-gg:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=XIQ0zMQkILDWGcn93CGMgKvcLA3VvTscsfQrUNo9JBI=; b=RXk67FntSpPVS7eK/dGLsbNhSKJ/ha7fRK/2odIrjdQsep1lztssTfZmTHJOVyH0Gr i62Rl0LOfyw8K+iGqp9UOZMjT1jgyXbIRDImUciV0chIm2b7O/V6EGHvXs1Ank9+DQYa 9AUozVp5OH0lmpdZLV3cBW0oIue8jYMpgJHip7xk0V9oRdiGMxcdQkOyz2bUxz8eteD+ RLdpo27E0HGthw4cbL8LurT0zOc9gEBcPmICiKUHJZZj2EGG/4QkQTbWzHfFKSwuWMEY h79P7ENSWvRJI2/grwyWIpfagpRiV7ahKCxUmKx34yFKlSEue8iNAfCZAwAqrK2LLbCu Wudw== X-Forwarded-Encrypted: i=1; AFNElJ+QJfP8OWUxcMw6woWCVlcAv9oKigDk/erucKjJGOyPiuOLJIL40oqB+fBcE1n+Ap2XC6xNQ4AKuFIGwuo=@vger.kernel.org X-Gm-Message-State: AOJu0YyQXJFlk1mS2/qrLHcZH7vQovAZfJWphefus4kMRFoc1Quold8e YvAxGTYXOwGe/obDbErSnWxDAmheG0IRqFTbyGvVJsrwSUys0cVPxz4l X-Gm-Gg: Acq92OGf4f3xOIRb8Tt0Lv/e3ydhgcUHgdE7Z5k+FfV923M6sJIyExLSY0aAl1uQaH3 lWFL10r+/OUz69gsAzioGot216rsRLbFjc1zJuleF5C0Bbea2ROZESh4t98k1S914oysVyzfhkR /dhpZUK0j+uczKW+qiU7VHbjDwhImjeNF6jbYhqKlMnAp9teHIFKb0EVbkvb9PIhdvOzpQcxAS8 Wo72q82jFGEcnRrzUaoyd/NY42B0Z4haAnsCEQhEJyzaEtC7rvdlFtmkfJmK/NCVORSIyvlotSU 9oADlMIqjrsevW//X+l29BitDT9+cKKr7y1m7sDjpjFrlKSumqCOkwT9d++VE1Yfez4WNAAiufp HRsbAozec42rMbSiZXVfpxTKhmt60GzUieaV1DSSw6puAruv6bWFX4AIH1mb/eU5DpoZ1Q7Na15 IFbveDm92Van8nbaQjeaQEFnwl8Fh9/zZVkJYYjN4+Rx632S5J+vM= X-Received: by 2002:a05:7022:fd08:b0:130:7246:10aa with SMTP id a92af1059eb24-1384218087fmr1769445c88.12.1781195223900; Thu, 11 Jun 2026 09:27:03 -0700 (PDT) Received: from localhost ([198.176.50.157]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-138430452a2sm2275834c88.14.2026.06.11.09.27.00 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 11 Jun 2026 09:27:03 -0700 (PDT) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Fri, 12 Jun 2026 00:26:58 +0800 Message-Id: Cc: "Simon Horman" , , , , "Xiang Mei" Subject: Re: [PATCH v2] atm: fix use-after-free in sigd_put_skb() From: "Weiming Shi" To: "Weiming Shi" , "Chas Williams" <3chas3@gmail.com>, "David S . Miller" , "Eric Dumazet" , "Jakub Kicinski" , "Paolo Abeni" X-Mailer: aerc 0.21.0 References: <20260609162107.2865310-2-bestswngs@gmail.com> In-Reply-To: <20260609162107.2865310-2-bestswngs@gmail.com> On Wed Jun 10, 2026 at 12:21 AM CST, Weiming Shi wrote: > sigd_put_skb() delivers a signalling message to the daemon socket named > by the global @sigd pointer, ending in a call to sk_data_ready(). It > reads @sigd with no synchronisation, so it can race with a close of the > daemon socket: sigd_close() clears @sigd and the socket is then torn > down and freed. > > Holding a reference on the socket is not enough to make this safe. The > daemon fd close runs __sock_release(), which frees the struct socket -- > and the wait queue that sk->sk_wq points at -- via iput() once > ->release() has returned. sk_data_ready() (sock_def_readable()) then > dereferences a freed sk_wq: > > KASAN: null-ptr-deref in range [0x0000000000000188-0x000000000000018f] > RIP: 0010:sigd_put_skb (net/atm/signaling.c:65) > sigd_enq2 (net/atm/signaling.c:228) > sigd_enq (net/atm/signaling.c:237) > svc_bind (net/atm/svc.c:135) > __sys_bind > __x64_sys_bind > do_syscall_64 > > Fix it on both sides. sigd_close() now calls sock_orphan(), which under > sk_callback_lock sets SOCK_DEAD and clears sk_wq before the socket is > freed. sigd_put_skb() latches @sigd with READ_ONCE(), pins the socket > with find_get_vcc(), and then takes sk_callback_lock; it delivers only > while the socket is still the signalling daemon and not yet SOCK_DEAD, > otherwise it drops the skb. sk_callback_lock is used rather than > lock_sock() because sigd_put_skb() can be reached from vcc_sendmsg() -> > sigd_send(), which already holds lock_sock() on the daemon socket. > > The READ_ONCE(sigd) !=3D vcc check also rejects a reused VCC: a caller > preempted between latching @sigd and validating it in find_get_vcc() > could otherwise match a freed-and-reallocated, live (non-SOCK_DEAD) VCC. > This needs a concurrent (privileged) daemon teardown, so it is hardening. > > Triggering the use-after-free requires CAP_NET_ADMIN and CAP_SYS_RAWIO > to attach the daemon. > > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") > Reported-by: Xiang Mei > Assisted-by: Claude:claude-opus-4-8 > Signed-off-by: Weiming Shi > --- > v2: > - Also bail when READ_ONCE(sigd) !=3D vcc, rejecting a reused VCC that a > preempted caller could match in find_get_vcc() (hardening, no stable). > > net/atm/signaling.c | 29 +++++++++++++++++++++++++---- > 1 file changed, 25 insertions(+), 4 deletions(-) > > diff --git a/net/atm/signaling.c b/net/atm/signaling.c > index 358fbe5e4d1d0..346fb969166e8 100644 > --- a/net/atm/signaling.c > +++ b/net/atm/signaling.c > @@ -54,14 +54,32 @@ static struct atm_vcc *find_get_vcc(struct atm_vcc *v= cc) > =20 > static void sigd_put_skb(struct sk_buff *skb) > { > - if (!sigd) { > + struct atm_vcc *vcc; > + struct sock *sk; > + > + vcc =3D find_get_vcc(READ_ONCE(sigd)); > + if (!vcc) { > pr_debug("atmsvc: no signaling daemon\n"); > kfree_skb(skb); > return; > } > - atm_force_charge(sigd, skb->truesize); > - skb_queue_tail(&sk_atm(sigd)->sk_receive_queue, skb); > - sk_atm(sigd)->sk_data_ready(sk_atm(sigd)); > + sk =3D sk_atm(vcc); > + > + /* Pairs with sock_orphan() in sigd_close(). */ > + read_lock_bh(&sk->sk_callback_lock); > + /* Bail if torn down, or if the slot was reused by another VCC. */ > + if (sock_flag(sk, SOCK_DEAD) || READ_ONCE(sigd) !=3D vcc) { > + read_unlock_bh(&sk->sk_callback_lock); > + sock_put(sk); > + kfree_skb(skb); > + return; > + } > + atm_force_charge(vcc, skb->truesize); > + skb_queue_tail(&sk->sk_receive_queue, skb); > + sk->sk_data_ready(sk); > + read_unlock_bh(&sk->sk_callback_lock); > + > + sock_put(sk); > } > =20 > static void modify_qos(struct atm_vcc *vcc, struct atmsvc_msg *msg) > @@ -257,6 +275,9 @@ static void sigd_close(struct atm_vcc *vcc) > pr_err("closing with requests pending\n"); > skb_queue_purge(&sk_atm(vcc)->sk_receive_queue); > =20 > + /* Make a concurrent sigd_put_skb() observe SOCK_DEAD and bail. */ > + sock_orphan(sk_atm(vcc)); > + > read_lock(&vcc_sklist_lock); > for (i =3D 0; i < VCC_HTABLE_SIZE; ++i) { > struct hlist_head *head =3D &vcc_hash[i];