From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ot1-f69.google.com (mail-ot1-f69.google.com [209.85.210.69]) (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 D26E838B7A5 for ; Sat, 7 Mar 2026 10:33:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.69 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772879587; cv=none; b=uBPwpavZDBTJ64QS7HCR4qUAAv76xcPQiWAxsn3J1eryneBwfDL3Zecr3+iuecQF8eEy167e3JK4vLq9AYAqbhkX0g5lBJvm7qgOg7ds0dN/d1kPxCJKgq8o5Cdsp5rAxWevpOQlfwLlXbrjv+D1WkthB/hp0QDt7ybH1o3cyDU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772879587; c=relaxed/simple; bh=j87evvjOapRRc/wLEhcr75l30j8C4Sl3toa3rd5n3Zs=; h=MIME-Version:Date:In-Reply-To:Message-ID:Subject:From:To: Content-Type; b=XziPPlDF2y104oYjwkas5OGuvKYmMFmDrXirTbUhRSaah3GCBvdaZkQw3B5lCk04UOGne74pwavwK992eW62Vwp2m9G7CGtDa7XhimfmT5nIbFNKJvFVA6SV/dmpfCr3NyZLmVifZil5JWVpdzutoCGN+3JURh1D9MnctWPK3og= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com; arc=none smtp.client-ip=209.85.210.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com Received: by mail-ot1-f69.google.com with SMTP id 46e09a7af769-7d73a9553bfso3174541a34.2 for ; Sat, 07 Mar 2026 02:33:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772879585; x=1773484385; h=content-transfer-encoding:to:from:subject:message-id:in-reply-to :date:mime-version:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Hgkp9T1ipxfhpsv9yyk9c5xUAZuvAJboExz6bde3dsY=; b=kllBMKR7SLZHyygArHRF4QPZWPSPt9MLjEqPBWxGjI5ktsdAzRMS3CyXpFzWCux8Aa 21Fn7KssI+5hZPKatE1LEZ+l9hCWUuUaNWE5SCc7vRfAILJe6rBZkM9Y/IxW0iBk7Xwd Bu2L2iFxhmMv0zOYifMP9+qkT2/gcyXupYxEOAx/D3arQm0sjQsvY0wXddLg5tJnIikk 4oNSnztj6y/8EJsyzNlH0bGnb6TIlGpmQKev+K4EpHC6ng+VnFr608g+XZKvAlABAgIL VCjyzYW38uHzBUdTrRV1iWd000txgs9fsMnp53bivJEvMuKzzIh9hq6koOhcFTl1SotR RrMw== X-Gm-Message-State: AOJu0YypTDtfa6vobR2HbhiSek98XeVaLyPzyZuyF/OC/d6LoyGqFgED Jz7AkfTh163JBiBZnuHHiX8uF9GSEnujwteR8Kbv8VvzzzDerOOPfmhKJCj11Z84lfImg3DUrPb AxzV1R/NpBsKOHji50XH8fesAd8Tyy/IPhsDLHiM0aA+Ng26wY6NHfrGd6+4= Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Received: by 2002:a05:6820:1890:b0:679:9392:ddfd with SMTP id 006d021491bc7-67b9bca1df6mr2957097eaf.30.1772879584805; Sat, 07 Mar 2026 02:33:04 -0800 (PST) Date: Sat, 07 Mar 2026 02:33:04 -0800 In-Reply-To: <67251e01.050a0220.529b6.0162.GAE@google.com> X-Google-Appengine-App-Id: s~syzkaller X-Google-Appengine-App-Id-Alias: syzkaller Message-ID: <69abfee0.050a0220.13f275.004a.GAE@google.com> Subject: Forwarded: Re: [RESEND] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user From: syzbot To: linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: Re: [RESEND] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregis= ter_user Author: pav@iki.fi la, 2026-03-07 kello 11:45 +0200, Pauli Virtanen kirjoitti: > la, 2026-03-07 kello 10:59 +0200, Pauli Virtanen kirjoitti: > > pe, 2026-03-06 kello 16:04 -0500, Luiz Augusto von Dentz kirjoitti: > > > From: Shaurya Rane > > >=20 > > > After commit ab4eedb790ca ("Bluetooth: L2CAP: Fix corrupted list in > > > hci_chan_del"), l2cap_conn_del() uses conn->lock to protect access to > > > conn->users and conn->hchan. However, l2cap_register_user() and > > > l2cap_unregister_user() still use hci_dev_lock(), creating a race > > > condition where these functions can access conn->users and conn->hcha= n > > > concurrently with l2cap_conn_del(). > >=20 > > AFAIK the above text from the original submitter is a bit inaccurate, > > as l2cap_conn_del()=C2=A0is called with hdev lock held, so conn->users/= hchan > > should be safe. > >=20 > > However, using conn->mutex should fix the use-after-free in > >=20 > > conn->hcon->hdev > > hci_dev_lock(hdev); > > hci_dev_unlock(hdev); > >=20 > > by making l2cap_unregister_user() safe to call after the hcon/hdev are > > no longer alive. > >=20 > > The change looks OK to me, but probably worth to double check with > > syzbot it fixes the original issue >=20 > syzbot seems to have hit some internal error, another try on upstream > branch instead >=20 No luck, test the patch setting session->conn =3D NULL; in case it fixes the syzcaller failure. If that passes, maybe the conn->mutex locking overlooks something that I don't see right now, #syz test > > > This can lead to use-after-free and list corruption bugs, as reported > > > by syzbot. > > >=20 > > > Fix this by changing l2cap_register_user() and l2cap_unregister_user(= ) > > > to use conn->lock instead of hci_dev_lock(), ensuring consistent lock= ing > > > for the l2cap_conn structure. > > > Reported-by: syzbot+14b6d57fb728e27ce23c@syzkaller.appspotmail.com > > > Closes: https://syzkaller.appspot.com/bug?extid=3D14b6d57fb728e27ce23= c > > > Fixes: ab4eedb790ca ("Bluetooth: L2CAP: Fix corrupted list in hci_cha= n_del") > > > Signed-off-by: Shaurya Rane > > > Signed-off-by: Luiz Augusto von Dentz > > > --- > > > net/bluetooth/l2cap_core.c | 20 ++++++++------------ > > > 1 file changed, 8 insertions(+), 12 deletions(-) > > >=20 > > > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c > > > index 14131e427efd..6606d7f12534 100644 > > > --- a/net/bluetooth/l2cap_core.c > > > +++ b/net/bluetooth/l2cap_core.c > > > @@ -1678,17 +1678,15 @@ static void l2cap_info_timeout(struct work_st= ruct *work) > > > =20 > > > int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *= user) > > > { > > > - struct hci_dev *hdev =3D conn->hcon->hdev; > > > int ret; > > > =20 > > > /* We need to check whether l2cap_conn is registered. If it is not,= we > > > - * must not register the l2cap_user. l2cap_conn_del() is unregister= s > > > - * l2cap_conn objects, but doesn't provide its own locking. Instead= , it > > > - * relies on the parent hci_conn object to be locked. This itself r= elies > > > - * on the hci_dev object to be locked. So we must lock the hci devi= ce > > > - * here, too. */ > > > + * must not register the l2cap_user. l2cap_conn_del() unregisters > > > + * l2cap_conn objects under conn->lock, and we use the same lock he= re > > > + * to protect access to conn->users and conn->hchan. > > > + */ > > > =20 > > > - hci_dev_lock(hdev); > > > + mutex_lock(&conn->lock); > > > =20 > > > if (!list_empty(&user->list)) { > > > ret =3D -EINVAL; > > > @@ -1709,16 +1707,14 @@ int l2cap_register_user(struct l2cap_conn *co= nn, struct l2cap_user *user) > > > ret =3D 0; > > > =20 > > > out_unlock: > > > - hci_dev_unlock(hdev); > > > + mutex_unlock(&conn->lock); > > > return ret; > > > } > > > EXPORT_SYMBOL(l2cap_register_user); > > > =20 > > > void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_use= r *user) > > > { > > > - struct hci_dev *hdev =3D conn->hcon->hdev; > > > - > > > - hci_dev_lock(hdev); > > > + mutex_lock(&conn->lock); > > > =20 > > > if (list_empty(&user->list)) > > > goto out_unlock; > > > @@ -1727,7 +1723,7 @@ void l2cap_unregister_user(struct l2cap_conn *c= onn, struct l2cap_user *user) > > > user->remove(conn, user); > > > =20 > > > out_unlock: > > > - hci_dev_unlock(hdev); > > > + mutex_unlock(&conn->lock); > > > } > > > EXPORT_SYMBOL(l2cap_unregister_user); > > > =20