{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2025-22102","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","state":"PUBLISHED","assignerShortName":"Linux","dateReserved":"2024-12-29T08:45:45.819Z","datePublished":"2025-04-16T14:12:51.482Z","dateUpdated":"2026-08-05T11:56:47.440Z"},"containers":{"cna":{"providerMetadata":{"orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux","dateUpdated":"2026-08-05T11:56:47.440Z"},"descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nBluetooth: btnxpuart: Fix kernel panic during FW release\n\nThis fixes a kernel panic seen during release FW in a stress test\nscenario where WLAN and BT FW download occurs simultaneously, and due to\na HW bug, chip sends out only 1 bootloader signatures.\n\nWhen driver receives the bootloader signature, it enters FW download\nmode, but since no consequtive bootloader signatures seen, FW file is\nnot requested.\n\nAfter 60 seconds, when FW download times out, release_firmware causes a\nkernel panic.\n\n[ 2601.949184] Unable to handle kernel paging request at virtual address 0000312e6f006573\n[ 2601.992076] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000111802000\n[ 2601.992080] [0000312e6f006573] pgd=0000000000000000, p4d=0000000000000000\n[ 2601.992087] Internal error: Oops: 0000000096000021 [#1] PREEMPT SMP\n[ 2601.992091] Modules linked in: algif_hash algif_skcipher af_alg btnxpuart(O) pciexxx(O) mlan(O) overlay fsl_jr_uio caam_jr caamkeyblob_desc caamhash_desc caamalg_desc crypto_engine authenc libdes crct10dif_ce polyval_ce snd_soc_fsl_easrc snd_soc_fsl_asoc_card imx8_media_dev(C) snd_soc_fsl_micfil polyval_generic snd_soc_fsl_xcvr snd_soc_fsl_sai snd_soc_imx_audmux snd_soc_fsl_asrc snd_soc_imx_card snd_soc_imx_hdmi snd_soc_fsl_aud2htx snd_soc_fsl_utils imx_pcm_dma dw_hdmi_cec flexcan can_dev\n[ 2602.001825] CPU: 2 PID: 20060 Comm: hciconfig Tainted: G         C O       6.6.23-lts-next-06236-gb586a521770e #1\n[ 2602.010182] Hardware name: NXP i.MX8MPlus EVK board (DT)\n[ 2602.010185] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)\n[ 2602.010191] pc : _raw_spin_lock+0x34/0x68\n[ 2602.010201] lr : free_fw_priv+0x20/0xfc\n[ 2602.020561] sp : ffff800089363b30\n[ 2602.020563] x29: ffff800089363b30 x28: ffff0000d0eb5880 x27: 0000000000000000\n[ 2602.020570] x26: 0000000000000000 x25: ffff0000d728b330 x24: 0000000000000000\n[ 2602.020577] x23: ffff0000dc856f38\n[ 2602.033797] x22: ffff800089363b70 x21: ffff0000dc856000\n[ 2602.033802] x20: ff00312e6f006573 x19: ffff0000d0d9ea80 x18: 0000000000000000\n[ 2602.033809] x17: 0000000000000000 x16: 0000000000000000 x15: 0000aaaad80dd480\n[ 2602.083320] x14: 0000000000000000 x13: 00000000000001b9 x12: 0000000000000002\n[ 2602.083326] x11: 0000000000000000 x10: 0000000000000a60 x9 : ffff800089363a30\n[ 2602.083333] x8 : ffff0001793d75c0 x7 : ffff0000d6dbc400 x6 : 0000000000000000\n[ 2602.083339] x5 : 00000000410fd030 x4 : 0000000000000000 x3 : 0000000000000001\n[ 2602.083346] x2 : 0000000000000000 x1 : 0000000000000001 x0 : ff00312e6f006573\n[ 2602.083354] Call trace:\n[ 2602.083356]  _raw_spin_lock+0x34/0x68\n[ 2602.083364]  release_firmware+0x48/0x6c\n[ 2602.083370]  nxp_setup+0x3c4/0x540 [btnxpuart]\n[ 2602.083383]  hci_dev_open_sync+0xf0/0xa34\n[ 2602.083391]  hci_dev_open+0xd8/0x178\n[ 2602.083399]  hci_sock_ioctl+0x3b0/0x590\n[ 2602.083405]  sock_do_ioctl+0x60/0x118\n[ 2602.083413]  sock_ioctl+0x2f4/0x374\n[ 2602.091430]  __arm64_sys_ioctl+0xac/0xf0\n[ 2602.091437]  invoke_syscall+0x48/0x110\n[ 2602.091445]  el0_svc_common.constprop.0+0xc0/0xe0\n[ 2602.091452]  do_el0_svc+0x1c/0x28\n[ 2602.091457]  el0_svc+0x40/0xe4\n[ 2602.091465]  el0t_64_sync_handler+0x120/0x12c\n[ 2602.091470]  el0t_64_sync+0x190/0x194"}],"metrics":[{"cvssV3_1":{"version":"3.1","vectorString":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","baseScore":7.8,"baseSeverity":"HIGH"},"scenarios":[{"lang":"en","value":"AV:L - The vulnerable state machine parses bootloader traffic on the local UART between the SoC and the NXP chip; it is entered from local syscalls (`hci_sock_ioctl(HCIDEVUP)` → `hci_dev_open_sync` → `nxp_setup`, per the reported oops stack, plus the `HCI_NXP_IND_RESET` vendor opcode and driver unbind). No remote or over-the-air Bluetooth peer can reach `nxp_download_firmware()`, since the bug occurs before any radio link exists.\nAC:L - The attacker controls both halves of the trigger — bringing the BT adapter up/down and driving the WLAN combo interface so the two firmware downloads collide, in an unbounded cheap loop until the chip emits the single bootloader signature — and the abort variant (`BTNXPUART_FW_DOWNLOAD_ABORT` set by driver removal, which wakes `fw_dnld_done_wait_q` early) hits the stale `release_firmware()` deterministically inside a 60-second window the attacker chooses. Nothing here depends on state the attacker cannot influence, and heap grooming of the 24-byte `kmalloc-32` object is under their control.\nPR:L - `hci_sock.c` gates HCIDEVUP on `capable(CAP_NET_ADMIN)`, but on the affected hardware class (i.MX8 boards, Android/IoT combo chips) adapter power-cycling and Wi-Fi bring-up are routinely exposed to any local unprivileged user through the privileged BT/mgmt and Wi-Fi daemons, so an ordinary user reproduces the exact concurrent WLAN+BT download stress described in the commit without holding any capability itself. No credential beyond basic local access is required.\nUI:N - The attacker drives the entire sequence — repeated adapter and WLAN bring-up/down cycles, or a vendor IND_RESET followed by an abort — with no victim action, mount, or file open involved.\nS:U - The freed `struct firmware` and the corrupted `fw_priv`/`firmware_cache` structures all live in kernel slab memory, and the resulting compromise stays inside the kernel's own security authority with no VM, IOMMU, or sandbox boundary crossed.\nC:H - `release_firmware()` on the dangling pointer reads `fw->priv` and then `fw_priv->fwc`, `fw_priv->data` and `fw_priv->fw_name` out of a reclaimed `kmalloc-32` object — the reported oops shows the slot already refilled with ASCII string data (`x0 = ff00312e6f006573`), proving reclamation with attacker-influenceable content. Chaining the UAF read into `kfree_const(fw_priv->fw_name)` and the unlink gives an arbitrary kernel read/disclosure primitive.\nI:H - The stale release yields multiple write primitives: `spin_lock(&fwc->lock)` writes through a reclaimed pointer, `list_del(&fw_priv->list)` in `__free_fw_priv()` is a classic unlink arbitrary write, and `vfree(fw->data)`/`kfree(fw_priv)` plus the final `kfree(fw)` double-free of the highly sprayable kmalloc-32 slot enable standard slab-corruption escalation to control-flow hijack.\nA:H - The reported failure is an immediate unrecoverable kernel panic — \"Unable to handle kernel paging request\" / \"Internal error: Oops\" in `_raw_spin_lock` under `free_fw_priv` — and the underlying double-free corrupts the slab allocator even when it does not fault instantly, so the attacker can crash the system at will."}]}],"affected":[{"product":"Linux","vendor":"Linux","defaultStatus":"unaffected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/bluetooth/btnxpuart.c"],"versions":[{"version":"689ca16e523278470c38832a3010645a78c544d8","lessThan":"a0a736d9857cadd87ae48b151d787e28954ea831","status":"affected","versionType":"git"},{"version":"689ca16e523278470c38832a3010645a78c544d8","lessThan":"d22496de5049d9b8f5b6d8623682a56b3c3d7e18","status":"affected","versionType":"git"},{"version":"689ca16e523278470c38832a3010645a78c544d8","lessThan":"6749cf49eff7ce6dadcb603c5c8db70b28079a5d","status":"affected","versionType":"git"},{"version":"689ca16e523278470c38832a3010645a78c544d8","lessThan":"1f77c05408c96bc0b58ae476a9cadc9e5b9cfd0f","status":"affected","versionType":"git"}]},{"product":"Linux","vendor":"Linux","defaultStatus":"affected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/bluetooth/btnxpuart.c"],"versions":[{"version":"6.4","status":"affected"},{"version":"0","lessThan":"6.4","status":"unaffected","versionType":"semver"},{"version":"6.6.92","lessThanOrEqual":"6.6.*","status":"unaffected","versionType":"semver"},{"version":"6.12.30","lessThanOrEqual":"6.12.*","status":"unaffected","versionType":"semver"},{"version":"6.14.2","lessThanOrEqual":"6.14.*","status":"unaffected","versionType":"semver"},{"version":"6.15","lessThanOrEqual":"*","status":"unaffected","versionType":"original_commit_for_fix"}]}],"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.4","versionEndExcluding":"6.6.92"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.4","versionEndExcluding":"6.12.30"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.4","versionEndExcluding":"6.14.2"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.4","versionEndExcluding":"6.15"}]}]}],"references":[{"url":"https://git.kernel.org/stable/c/a0a736d9857cadd87ae48b151d787e28954ea831"},{"url":"https://git.kernel.org/stable/c/d22496de5049d9b8f5b6d8623682a56b3c3d7e18"},{"url":"https://git.kernel.org/stable/c/6749cf49eff7ce6dadcb603c5c8db70b28079a5d"},{"url":"https://git.kernel.org/stable/c/1f77c05408c96bc0b58ae476a9cadc9e5b9cfd0f"}],"title":"Bluetooth: btnxpuart: Fix kernel panic during FW release","x_generator":{"engine":"bippy-1.2.0"}}}}