mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v3] Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready
@ 2026-08-18 11:33 Hang Nan
  2026-08-18 18:08 ` Luiz Augusto von Dentz
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Hang Nan @ 2026-08-18 11:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, luiz.dentz, linux-kernel, stable, pav

iso_conn_ready() looks up the BIS listener socket with iso_get_sock(),
which takes a reference, and then, without re-checking its state,
creates a child socket from it:

    parent = iso_get_sock(hdev, ...);
    if (!parent)
        return;

    lock_sock(parent);
    sk = iso_sock_alloc(sock_net(parent), NULL, BTPROTO_ISO, ...);
    ...
    iso_chan_add(conn, sk, parent);
    ...
    release_sock(parent);
    sock_put(parent);

If the listener socket is closed concurrently, between iso_get_sock()
and lock_sock(), the reference taken by iso_get_sock() may be the last
one: the close path drops the link-list reference, and once
iso_conn_ready() drops its own reference at the end of the function the
socket is freed.  The child socket, however, is already linked to the
freed parent, and a later disconnect of the child runs iso_chan_del()
-> bt_accept_unlink(), which dereferences the dangling parent pointer
into the freed accept queue (a use-after-free).  The same dangling
pointer is also dereferenced through parent->***() in
iso_chan_del().

Fix it the same way the connected (non-BIS) path was fixed in commit
0d255e63fcf3 ("Bluetooth: ISO: hold sk properly in iso_conn_ready"):
after taking the socket lock, re-check that the parent is still a
listening, alive socket, and bail out otherwise.

Fixes: ccf74f2390d60 ("Bluetooth: Add BTPROTO_ISO socket type")
Cc: stable@vger.kernel.org
Signed-off-by: Hang Nan <2122295973@qq.com>
---
Changes in v3:
- Move the changelog below the "---" separator so it is not part
  of the commit message
- Shorten the comment in iso_conn_ready()

Changes in v2:
- Fix GitLint B3: replace hard tabs with spaces in the commit
  message code snippet (no functional change)

 net/bluetooth/iso.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index aa2ce78f56a2..069fc87a4e18 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -2277,6 +2277,14 @@ static void iso_conn_ready(struct iso_conn *conn)
 
 		lock_sock(parent);
 
+		/* The listener may have been closed concurrently. */
+		if (parent->sk_state != BT_LISTEN ||
+		    (parent, SOCK_ZAPPED)) {
+			release_sock_flagsock(parent);
+			sock_put(parent);
+			return;
+		}
+
 		sk = iso_sock_alloc(sock_net(parent), NULL,
 				    BTPROTO_ISO, GFP_ATOMIC, 0);
 		if (!sk) {


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3] Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready
  2026-08-18 11:33 [PATCH v3] Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready Hang Nan
@ 2026-08-18 18:08 ` Luiz Augusto von Dentz
  2026-08-24 19:48 ` kernel test robot
  2026-08-24 21:19 ` kernel test robot
  2 siblings, 0 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2026-08-18 18:08 UTC (permalink / raw)
  To: Hang Nan; +Cc: linux-bluetooth, marcel, linux-kernel, stable, pav

Hi Hang,

On Tue, Aug 18, 2026 at 7:33 AM Hang Nan <2122295973@qq.com> wrote:
>
> iso_conn_ready() looks up the BIS listener socket with iso_get_sock(),
> which takes a reference, and then, without re-checking its state,
> creates a child socket from it:
>
>     parent = iso_get_sock(hdev, ...);
>     if (!parent)
>         return;
>
>     lock_sock(parent);
>     sk = iso_sock_alloc(sock_net(parent), NULL, BTPROTO_ISO, ...);
>     ...
>     iso_chan_add(conn, sk, parent);
>     ...
>     release_sock(parent);
>     sock_put(parent);
>
> If the listener socket is closed concurrently, between iso_get_sock()
> and lock_sock(), the reference taken by iso_get_sock() may be the last
> one: the close path drops the link-list reference, and once
> iso_conn_ready() drops its own reference at the end of the function the
> socket is freed.  The child socket, however, is already linked to the
> freed parent, and a later disconnect of the child runs iso_chan_del()
> -> bt_accept_unlink(), which dereferences the dangling parent pointer
> into the freed accept queue (a use-after-free).  The same dangling
> pointer is also dereferenced through parent->***() in
> iso_chan_del().
>
> Fix it the same way the connected (non-BIS) path was fixed in commit
> 0d255e63fcf3 ("Bluetooth: ISO: hold sk properly in iso_conn_ready"):
> after taking the socket lock, re-check that the parent is still a
> listening, alive socket, and bail out otherwise.
>
> Fixes: ccf74f2390d60 ("Bluetooth: Add BTPROTO_ISO socket type")
> Cc: stable@vger.kernel.org
> Signed-off-by: Hang Nan <2122295973@qq.com>
> ---
> Changes in v3:
> - Move the changelog below the "---" separator so it is not part
>   of the commit message
> - Shorten the comment in iso_conn_ready()
>
> Changes in v2:
> - Fix GitLint B3: replace hard tabs with spaces in the commit
>   message code snippet (no functional change)
>
>  net/bluetooth/iso.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
> index aa2ce78f56a2..069fc87a4e18 100644
> --- a/net/bluetooth/iso.c
> +++ b/net/bluetooth/iso.c
> @@ -2277,6 +2277,14 @@ static void iso_conn_ready(struct iso_conn *conn)
>
>                 lock_sock(parent);
>
> +               /* The listener may have been closed concurrently. */
> +               if (parent->sk_state != BT_LISTEN ||
> +                   (parent, SOCK_ZAPPED)) {
> +                       release_sock_flagsock(parent);
> +                       sock_put(parent);
> +                       return;
> +               }

Looks like there is a typo and this should have been release_sock
rather than release_sock_flagsock (or there is a new function called
that introduced via some other tree?)

>                 sk = iso_sock_alloc(sock_net(parent), NULL,
>                                     BTPROTO_ISO, GFP_ATOMIC, 0);
>                 if (!sk) {
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3] Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready
  2026-08-18 11:33 [PATCH v3] Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready Hang Nan
  2026-08-18 18:08 ` Luiz Augusto von Dentz
@ 2026-08-24 19:48 ` kernel test robot
  2026-08-24 21:19 ` kernel test robot
  2 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2026-08-24 19:48 UTC (permalink / raw)
  To: Hang Nan, linux-bluetooth
  Cc: llvm, oe-kbuild-all, marcel, luiz.dentz, linux-kernel, stable, pav

Hi Hang,

kernel test robot noticed the following build errors:

[auto build test ERROR on bluetooth/master]
[also build test ERROR on linus/master v7.2]
[cannot apply to bluetooth-next/master next-20260821]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Hang-Nan/Bluetooth-ISO-fix-use-after-free-of-listener-socket-in-iso_conn_ready/20260818-193343
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git master
patch link:    https://lore.kernel.org/r/tencent_1E12CBD7417A4019FF058EFD19B1DB930006%40qq.com
patch subject: [PATCH v3] Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready
config: loongarch-defconfig (https://download.01.org/0day-ci/archive/20260825/202608250307.IiUVBpTP-lkp@intel.com/config)
compiler: clang version 24.0.0git (https://github.com/llvm/llvm-project 935bfc708590c60147a79c7df145bb6e68b1d388)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260825/202608250307.IiUVBpTP-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608250307.IiUVBpTP-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

>> net/bluetooth/iso.c:2267:4: error: call to undeclared function 'release_sock_flagsock'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2267 |                         release_sock_flagsock(parent);
         |                         ^
>> net/bluetooth/iso.c:2266:8: warning: left operand of comma operator has no effect [-Wunused-value]
    2266 |                     (parent, SOCK_ZAPPED)) {
         |                      ^~~~~~
   1 warning and 1 error generated.


vim +/release_sock_flagsock +2267 net/bluetooth/iso.c

  2156	
  2157	static void iso_conn_ready(struct iso_conn *conn)
  2158	{
  2159		struct sock *parent = NULL;
  2160		struct sock *sk;
  2161		struct hci_ev_le_big_sync_established *ev = NULL;
  2162		struct hci_ev_le_pa_sync_established *ev2 = NULL;
  2163		struct hci_ev_le_per_adv_report *ev3 = NULL;
  2164		struct hci_conn *hcon;
  2165		struct hci_dev *hdev;
  2166	
  2167		BT_DBG("conn %p", conn);
  2168	
  2169		iso_conn_lock(conn);
  2170		sk = iso_sock_hold(conn);
  2171		iso_conn_unlock(conn);
  2172	
  2173		if (sk) {
  2174			lock_sock(sk);
  2175	
  2176			/* conn->sk may have become NULL if racing with sk close, but
  2177			 * due to held hdev->lock, it can't become different sk.
  2178			 */
  2179			if (!conn->sk) {
  2180				release_sock(sk);
  2181				sock_put(sk);
  2182				return;
  2183			}
  2184	
  2185			/* Attempt to update source address in case of BIS Sender if
  2186			 * the advertisement is using a random address.
  2187			 */
  2188			if (conn->hcon->type == BIS_LINK &&
  2189			    conn->hcon->role == HCI_ROLE_MASTER &&
  2190			    !bacmp(&conn->hcon->dst, BDADDR_ANY)) {
  2191				struct hci_conn *bis = conn->hcon;
  2192				struct adv_info *adv;
  2193	
  2194				adv = hci_find_adv_instance(bis->hdev,
  2195							    bis->iso_qos.bcast.bis);
  2196				if (adv && bacmp(&adv->random_addr, BDADDR_ANY)) {
  2197					iso_pi(sk)->src_type = BDADDR_LE_RANDOM;
  2198					bacpy(&iso_pi(sk)->src, &adv->random_addr);
  2199				}
  2200			}
  2201	
  2202			iso_sock_ready(sk);
  2203	
  2204			release_sock(sk);
  2205			sock_put(sk);
  2206		} else {
  2207			hcon = conn->hcon;
  2208			if (!hcon)
  2209				return;
  2210	
  2211			hdev = hcon->hdev;
  2212	
  2213			if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags)) {
  2214				/* A BIS slave hcon is notified to the ISO layer
  2215				 * after the Command Complete for the LE Setup
  2216				 * ISO Data Path command is received. Get the
  2217				 * parent socket that matches the hcon BIG handle.
  2218				 */
  2219				parent = iso_get_sock(hdev, &hcon->src, &hcon->dst,
  2220						      BT_LISTEN, iso_match_big_hcon,
  2221						      hcon);
  2222			} else if (test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
  2223				ev = hci_recv_event_data(hcon->hdev,
  2224							 HCI_EVT_LE_BIG_SYNC_ESTABLISHED);
  2225	
  2226				/* Get reference to PA sync parent socket, if it exists */
  2227				parent = iso_get_sock(hdev, &hcon->src, &hcon->dst,
  2228						      BT_LISTEN,
  2229						      iso_match_pa_sync_flag,
  2230						      NULL);
  2231				if (!parent && ev)
  2232					parent = iso_get_sock(hdev, &hcon->src,
  2233							      &hcon->dst,
  2234							      BT_LISTEN,
  2235							      iso_match_big, ev);
  2236			} else if (test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) {
  2237				ev2 = hci_recv_event_data(hcon->hdev,
  2238							  HCI_EV_LE_PA_SYNC_ESTABLISHED);
  2239				if (ev2)
  2240					parent = iso_get_sock(hdev, &hcon->src,
  2241							      &hcon->dst,
  2242							      BT_LISTEN,
  2243							      iso_match_sid, ev2);
  2244			} else if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
  2245				ev3 = hci_recv_event_data(hcon->hdev,
  2246							  HCI_EV_LE_PER_ADV_REPORT);
  2247				if (ev3)
  2248					parent = iso_get_sock(hdev, &hcon->src,
  2249							      &hcon->dst,
  2250							      BT_LISTEN,
  2251							      iso_match_sync_handle_pa_report,
  2252							      ev3);
  2253			}
  2254	
  2255			if (!parent)
  2256				parent = iso_get_sock(hdev, &hcon->src, BDADDR_ANY,
  2257						      BT_LISTEN, iso_match_dst, BDADDR_ANY);
  2258	
  2259			if (!parent)
  2260				return;
  2261	
  2262			lock_sock(parent);
  2263	
  2264			/* The listener may have been closed concurrently. */
  2265			if (parent->sk_state != BT_LISTEN ||
> 2266			    (parent, SOCK_ZAPPED)) {
> 2267				release_sock_flagsock(parent);
  2268				sock_put(parent);
  2269				return;
  2270			}
  2271	
  2272			sk = iso_sock_alloc(sock_net(parent), NULL,
  2273					    BTPROTO_ISO, GFP_ATOMIC, 0);
  2274			if (!sk) {
  2275				release_sock(parent);
  2276				return;
  2277			}
  2278	
  2279			iso_sock_init(sk, parent);
  2280	
  2281			bacpy(&iso_pi(sk)->src, &hcon->src);
  2282	
  2283			/* Convert from HCI to three-value type */
  2284			if (hcon->src_type == ADDR_LE_DEV_PUBLIC)
  2285				iso_pi(sk)->src_type = BDADDR_LE_PUBLIC;
  2286			else
  2287				iso_pi(sk)->src_type = BDADDR_LE_RANDOM;
  2288	
  2289			/* If hcon has no destination address (BDADDR_ANY) it means it
  2290			 * was created by HCI_EV_LE_BIG_SYNC_ESTABILISHED or
  2291			 * HCI_EV_LE_PA_SYNC_ESTABLISHED so we need to initialize using
  2292			 * the parent socket destination address.
  2293			 */
  2294			if (!bacmp(&hcon->dst, BDADDR_ANY)) {
  2295				bacpy(&hcon->dst, &iso_pi(parent)->dst);
  2296				hcon->dst_type = le_addr_type(iso_pi(parent)->dst_type);
  2297			}
  2298	
  2299			if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
  2300				iso_pi(sk)->qos = iso_pi(parent)->qos;
  2301				hcon->iso_qos = iso_pi(sk)->qos;
  2302				iso_pi(sk)->bc_sid = iso_pi(parent)->bc_sid;
  2303				iso_pi(sk)->bc_num_bis = iso_pi(parent)->bc_num_bis;
  2304				memcpy(iso_pi(sk)->bc_bis, iso_pi(parent)->bc_bis,
  2305				       ISO_MAX_NUM_BIS);
  2306				set_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags);
  2307			}
  2308	
  2309			bacpy(&iso_pi(sk)->dst, &hcon->dst);
  2310	
  2311			/* Convert from HCI to three-value type */
  2312			if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
  2313				iso_pi(sk)->dst_type = BDADDR_LE_PUBLIC;
  2314			else
  2315				iso_pi(sk)->dst_type = BDADDR_LE_RANDOM;
  2316	
  2317			iso_pi(sk)->sync_handle = iso_pi(parent)->sync_handle;
  2318			memcpy(iso_pi(sk)->base, iso_pi(parent)->base, iso_pi(parent)->base_len);
  2319			iso_pi(sk)->base_len = iso_pi(parent)->base_len;
  2320	
  2321			hci_conn_hold(hcon);
  2322			iso_chan_add(conn, sk, parent);
  2323	
  2324			if ((ev && ((struct hci_evt_le_big_sync_established *)ev)->status) ||
  2325			    (ev2 && ev2->status)) {
  2326				/* Trigger error signal on child socket */
  2327				sk->sk_err = ECONNREFUSED;
  2328				sk->sk_error_report(sk);
  2329			}
  2330	
  2331			if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
  2332				sk->sk_state = BT_CONNECT2;
  2333			else
  2334				sk->sk_state = BT_CONNECTED;
  2335	
  2336			/* Wake up parent */
  2337			parent->sk_data_ready(parent);
  2338	
  2339			release_sock(parent);
  2340			sock_put(parent);
  2341		}
  2342	}
  2343	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3] Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready
  2026-08-18 11:33 [PATCH v3] Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready Hang Nan
  2026-08-18 18:08 ` Luiz Augusto von Dentz
  2026-08-24 19:48 ` kernel test robot
@ 2026-08-24 21:19 ` kernel test robot
  2 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2026-08-24 21:19 UTC (permalink / raw)
  To: Hang Nan, linux-bluetooth
  Cc: oe-kbuild-all, marcel, luiz.dentz, linux-kernel, stable, pav

Hi Hang,

kernel test robot noticed the following build errors:

[auto build test ERROR on bluetooth/master]
[also build test ERROR on linus/master v7.2]
[cannot apply to bluetooth-next/master next-20260821]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Hang-Nan/Bluetooth-ISO-fix-use-after-free-of-listener-socket-in-iso_conn_ready/20260818-193343
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git master
patch link:    https://lore.kernel.org/r/tencent_1E12CBD7417A4019FF058EFD19B1DB930006%40qq.com
patch subject: [PATCH v3] Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready
config: nios2-allmodconfig (https://download.01.org/0day-ci/archive/20260825/202608250515.cLzFz5iN-lkp@intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260825/202608250515.cLzFz5iN-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608250515.cLzFz5iN-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   net/bluetooth/iso.c: In function 'iso_conn_ready':
>> net/bluetooth/iso.c:2266:28: warning: left-hand operand of comma expression has no effect [-Wunused-value]
    2266 |                     (parent, SOCK_ZAPPED)) {
         |                            ^
>> net/bluetooth/iso.c:2267:25: error: implicit declaration of function 'release_sock_flagsock' [-Werror=implicit-function-declaration]
    2267 |                         release_sock_flagsock(parent);
         |                         ^~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +/release_sock_flagsock +2267 net/bluetooth/iso.c

  2156	
  2157	static void iso_conn_ready(struct iso_conn *conn)
  2158	{
  2159		struct sock *parent = NULL;
  2160		struct sock *sk;
  2161		struct hci_ev_le_big_sync_established *ev = NULL;
  2162		struct hci_ev_le_pa_sync_established *ev2 = NULL;
  2163		struct hci_ev_le_per_adv_report *ev3 = NULL;
  2164		struct hci_conn *hcon;
  2165		struct hci_dev *hdev;
  2166	
  2167		BT_DBG("conn %p", conn);
  2168	
  2169		iso_conn_lock(conn);
  2170		sk = iso_sock_hold(conn);
  2171		iso_conn_unlock(conn);
  2172	
  2173		if (sk) {
  2174			lock_sock(sk);
  2175	
  2176			/* conn->sk may have become NULL if racing with sk close, but
  2177			 * due to held hdev->lock, it can't become different sk.
  2178			 */
  2179			if (!conn->sk) {
  2180				release_sock(sk);
  2181				sock_put(sk);
  2182				return;
  2183			}
  2184	
  2185			/* Attempt to update source address in case of BIS Sender if
  2186			 * the advertisement is using a random address.
  2187			 */
  2188			if (conn->hcon->type == BIS_LINK &&
  2189			    conn->hcon->role == HCI_ROLE_MASTER &&
  2190			    !bacmp(&conn->hcon->dst, BDADDR_ANY)) {
  2191				struct hci_conn *bis = conn->hcon;
  2192				struct adv_info *adv;
  2193	
  2194				adv = hci_find_adv_instance(bis->hdev,
  2195							    bis->iso_qos.bcast.bis);
  2196				if (adv && bacmp(&adv->random_addr, BDADDR_ANY)) {
  2197					iso_pi(sk)->src_type = BDADDR_LE_RANDOM;
  2198					bacpy(&iso_pi(sk)->src, &adv->random_addr);
  2199				}
  2200			}
  2201	
  2202			iso_sock_ready(sk);
  2203	
  2204			release_sock(sk);
  2205			sock_put(sk);
  2206		} else {
  2207			hcon = conn->hcon;
  2208			if (!hcon)
  2209				return;
  2210	
  2211			hdev = hcon->hdev;
  2212	
  2213			if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags)) {
  2214				/* A BIS slave hcon is notified to the ISO layer
  2215				 * after the Command Complete for the LE Setup
  2216				 * ISO Data Path command is received. Get the
  2217				 * parent socket that matches the hcon BIG handle.
  2218				 */
  2219				parent = iso_get_sock(hdev, &hcon->src, &hcon->dst,
  2220						      BT_LISTEN, iso_match_big_hcon,
  2221						      hcon);
  2222			} else if (test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
  2223				ev = hci_recv_event_data(hcon->hdev,
  2224							 HCI_EVT_LE_BIG_SYNC_ESTABLISHED);
  2225	
  2226				/* Get reference to PA sync parent socket, if it exists */
  2227				parent = iso_get_sock(hdev, &hcon->src, &hcon->dst,
  2228						      BT_LISTEN,
  2229						      iso_match_pa_sync_flag,
  2230						      NULL);
  2231				if (!parent && ev)
  2232					parent = iso_get_sock(hdev, &hcon->src,
  2233							      &hcon->dst,
  2234							      BT_LISTEN,
  2235							      iso_match_big, ev);
  2236			} else if (test_bit(HCI_CONN_PA_SYNC_FAILED, &hcon->flags)) {
  2237				ev2 = hci_recv_event_data(hcon->hdev,
  2238							  HCI_EV_LE_PA_SYNC_ESTABLISHED);
  2239				if (ev2)
  2240					parent = iso_get_sock(hdev, &hcon->src,
  2241							      &hcon->dst,
  2242							      BT_LISTEN,
  2243							      iso_match_sid, ev2);
  2244			} else if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
  2245				ev3 = hci_recv_event_data(hcon->hdev,
  2246							  HCI_EV_LE_PER_ADV_REPORT);
  2247				if (ev3)
  2248					parent = iso_get_sock(hdev, &hcon->src,
  2249							      &hcon->dst,
  2250							      BT_LISTEN,
  2251							      iso_match_sync_handle_pa_report,
  2252							      ev3);
  2253			}
  2254	
  2255			if (!parent)
  2256				parent = iso_get_sock(hdev, &hcon->src, BDADDR_ANY,
  2257						      BT_LISTEN, iso_match_dst, BDADDR_ANY);
  2258	
  2259			if (!parent)
  2260				return;
  2261	
  2262			lock_sock(parent);
  2263	
  2264			/* The listener may have been closed concurrently. */
  2265			if (parent->sk_state != BT_LISTEN ||
> 2266			    (parent, SOCK_ZAPPED)) {
> 2267				release_sock_flagsock(parent);
  2268				sock_put(parent);
  2269				return;
  2270			}
  2271	
  2272			sk = iso_sock_alloc(sock_net(parent), NULL,
  2273					    BTPROTO_ISO, GFP_ATOMIC, 0);
  2274			if (!sk) {
  2275				release_sock(parent);
  2276				return;
  2277			}
  2278	
  2279			iso_sock_init(sk, parent);
  2280	
  2281			bacpy(&iso_pi(sk)->src, &hcon->src);
  2282	
  2283			/* Convert from HCI to three-value type */
  2284			if (hcon->src_type == ADDR_LE_DEV_PUBLIC)
  2285				iso_pi(sk)->src_type = BDADDR_LE_PUBLIC;
  2286			else
  2287				iso_pi(sk)->src_type = BDADDR_LE_RANDOM;
  2288	
  2289			/* If hcon has no destination address (BDADDR_ANY) it means it
  2290			 * was created by HCI_EV_LE_BIG_SYNC_ESTABILISHED or
  2291			 * HCI_EV_LE_PA_SYNC_ESTABLISHED so we need to initialize using
  2292			 * the parent socket destination address.
  2293			 */
  2294			if (!bacmp(&hcon->dst, BDADDR_ANY)) {
  2295				bacpy(&hcon->dst, &iso_pi(parent)->dst);
  2296				hcon->dst_type = le_addr_type(iso_pi(parent)->dst_type);
  2297			}
  2298	
  2299			if (test_bit(HCI_CONN_PA_SYNC, &hcon->flags)) {
  2300				iso_pi(sk)->qos = iso_pi(parent)->qos;
  2301				hcon->iso_qos = iso_pi(sk)->qos;
  2302				iso_pi(sk)->bc_sid = iso_pi(parent)->bc_sid;
  2303				iso_pi(sk)->bc_num_bis = iso_pi(parent)->bc_num_bis;
  2304				memcpy(iso_pi(sk)->bc_bis, iso_pi(parent)->bc_bis,
  2305				       ISO_MAX_NUM_BIS);
  2306				set_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags);
  2307			}
  2308	
  2309			bacpy(&iso_pi(sk)->dst, &hcon->dst);
  2310	
  2311			/* Convert from HCI to three-value type */
  2312			if (hcon->dst_type == ADDR_LE_DEV_PUBLIC)
  2313				iso_pi(sk)->dst_type = BDADDR_LE_PUBLIC;
  2314			else
  2315				iso_pi(sk)->dst_type = BDADDR_LE_RANDOM;
  2316	
  2317			iso_pi(sk)->sync_handle = iso_pi(parent)->sync_handle;
  2318			memcpy(iso_pi(sk)->base, iso_pi(parent)->base, iso_pi(parent)->base_len);
  2319			iso_pi(sk)->base_len = iso_pi(parent)->base_len;
  2320	
  2321			hci_conn_hold(hcon);
  2322			iso_chan_add(conn, sk, parent);
  2323	
  2324			if ((ev && ((struct hci_evt_le_big_sync_established *)ev)->status) ||
  2325			    (ev2 && ev2->status)) {
  2326				/* Trigger error signal on child socket */
  2327				sk->sk_err = ECONNREFUSED;
  2328				sk->sk_error_report(sk);
  2329			}
  2330	
  2331			if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
  2332				sk->sk_state = BT_CONNECT2;
  2333			else
  2334				sk->sk_state = BT_CONNECTED;
  2335	
  2336			/* Wake up parent */
  2337			parent->sk_data_ready(parent);
  2338	
  2339			release_sock(parent);
  2340			sock_put(parent);
  2341		}
  2342	}
  2343	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-08-24 21:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-18 11:33 [PATCH v3] Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready Hang Nan
2026-08-18 18:08 ` Luiz Augusto von Dentz
2026-08-24 19:48 ` kernel test robot
2026-08-24 21:19 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®