Look up another CVE · open CVE-2026-90224 in the interactive tracker
CVE-2026-90224
nfc: nci: fix double completion race in nci_data_exchange_complete
Published 2026-09-17 (31 days ago) by the Linux kernel CNA. Subsystem net/nfc. Debian urgency: not yet assigned.
What to do, per Debian release
Debian's own status for CVE-2026-90224 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source
| Release | Status | Version | What this means |
|---|---|---|---|
| Debian 12bookworm | fixedDLA-4841-1 · 2026-10-17 · text | 6.1.190-1 | Update the kernel and reboot. DLA-4841-1 shipped the fix on 2026-10-17, in 6.1.190-1. A running kernel keeps the old code until the machine restarts. |
| Debian 13trixie | fixedDSA-6528-1 · 2026-09-29 · text | 6.12.111-1 | Update the kernel and reboot. DSA-6528-1 shipped the fix on 2026-09-29, in 6.12.111-1. A running kernel keeps the old code until the machine restarts. |
| Debian 14forky | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
| Debian unstablesid | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
| Debian 12bookworm · linux-6.12 | fixedDLA-4817-1 · 2026-10-04 · text | 6.12.111-1~deb12u1 | Update the kernel and reboot. DLA-4817-1 shipped the fix on 2026-10-04, in 6.12.111-1~deb12u1. A running kernel keeps the old code until the machine restarts. |
The vulnerability
What the bug is
nci_close_device() and nci_rx_work can both call nci_data_exchange_complete() concurrently. After commit 4527025d440ce8 ("nfc: nci: fix circular locking dependency in nci_close_device") moved flush_workqueue(ndev->rx_wq) after mutex_unlock(&ndev->req_lock), rx_work is no longer serialized with the explicit completion call in the close path. Both callers read the non-NULL callback pointer and invoke rawsock_data_exchange_complete(), which calls sock_put() -- but only one sock_hold() was taken, so the second sock_put() underflows the refcount and frees the socket while it is still in use. Replace the bare clear_bit(NCI_DATA_EXCHANGE) with test_and_clear_bit() so that only the first caller proceeds to invoke the callback.
Where it lives
The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.
net/nfc/nci/data.c
- What this is
- NFC SUBSYSTEMMAINTAINERS section matched on net/nfc/ · oe-linux-nfc@lists.linux.dev · Maintained
- Kernel module
- nci
Check it on the machine
grep -wE 'CONFIG_NFC|CONFIG_NFC_NCI' /boot/config-$(uname -r)Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.
lsmod | grep -w nciPrints a line if that module is loaded right now, and nothing if it is not. One that is not loaded can still be loaded later by anything that needs it.
Show whether Debian builds this, per release
Debian builds this, but not on every flavour. At least one release below builds the code on some of its kernel flavours and not on others, so the answer depends on the architecture and flavour installed.
- bookworm, trixie, forky, sid, bookworm · linux-6.12Mnot built on amd64/cloud-amd64, arm64/cloud-arm64
- M
- a module where it is built at all; some flavours do not build it
- Build switches
- CONFIG_NFC, CONFIG_NFC_NCI
- Reads as
- all on means the file is compiled; any one off means it is not.
From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages
Signals
- Published
- 2026-09-17 (31 days ago)source
- CVSS
- 7.5 high
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:Hsource recompute it - Attack vector
- adjacent network (AV:A)source
- EPSS
- 0.36%, higher than 27.8% of all CVEssource
- CISA KEV
- not listedthe KEV catalogue
- Debian urgency
- not yet assignedsource
- Subsystem
- net/nfc
Upstream fixes
The versions the CNA records as introducing and fixing this, and the commit for each. source
| Introduced | Fixed in | Commit |
|---|---|---|
| 5.10.253 | 5.10.270 | 3f0758327340 |
| 5.15.203 | 5.15.221 | 588ccd19a6e6 |
| 6.1.168 | 6.1.188 | cf646a9f5554 |
| 6.6.131 | 6.6.157 | 9030a1bbe2c6 |
| 6.12.80 | 6.12.110 | bfdf412208fe |
| 6.18.21 | 6.18.52 | ba4c776af3dc |
| 7.0 | 7.2.6 | ee08414d78b8 |
| 7.0 | 7.3 | 8265a626cc14 |
| 6.19.11 | 0 | 0 |
Debian advisories
| Advisory | Date | Shipped to | Debian |
|---|---|---|---|
| DLA-4841-1 | 2026-10-17 | bookworm 6.1.190-1 | tracker |
| DLA-4817-1 | 2026-10-04 | bookworm 6.12.111-1~deb12u1 | tracker |
| DSA-6528-1 | 2026-09-29 | trixie 6.12.111-1 | tracker |
Why the CNA scored it this way
Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source
- AV:AAttack vector, adjacent network
- One completion is nci_rx_work() handling an NCI_MT_DATA_PKT (nci_rx_data_packet()→nci_add_rx_data_frag()→nci_data_exchange_complete()), with that skb queued by nci_recv_frame() from the NFC controller as NFC RF traffic; NFC radio range is Adjacent, not a routable IP transport.
- AC:HAttack complexity, high
- The bug is nci_close_device() and nci_rx_work() both invoking nci_data_exchange_complete() after flush_workqueue(ndev->rx_wq) moved past mutex_unlock(&ndev->req_lock). An NFC peer can drive rx_work but cannot start that close: nfc_dev_down() returns -EBUSY while active_target is set, and nci_unregister_device() is driver teardown the peer cannot initiate.
- PR:NPrivileges required, none
- nci_recv_frame()→nci_rx_work() processes NCI frames with no capability or authentication check, so an in-range NFC peer needs no host account. GENL_ADMIN_PERM on nfc_genl_dev_down()/NFC_CMD_DEV_DOWN is only the victim-side close gate, not a privilege the adjacent attacker must hold.
- UI:NUser interaction, none
- With NFC already up and nci_transceive() having set NCI_DATA_EXCHANGE (normal for a polling reader or in-progress tag session), the peer's DATA packet completes via nci_rx_work with no further click, mount, or prompt; concurrent nci_close_device() is an AC condition, not a required victim action.
- S:UScope, unchanged
- The extra sock_put() in rawsock_data_exchange_complete() frees a host kernel struct sock; impact stays in the same kernel authority with no VM escape, IOMMU bypass, or sandbox crossing.
- C:HConfidentiality impact, high
- nci_close_device() and nci_rx_work() both read conn_info->data_exchange_cb and call rawsock_data_exchange_complete(), which sock_put()s the sk held once by sock_hold() in rawsock_tx_work(); the second put underflows that refcount and frees the socket while still referenced, a UAF read primitive.
- I:HIntegrity impact, high
- The same double sock_put() of the PF_NFC SOCK_SEQPACKET socket is a kernel UAF on struct sock, and the second callback runs against that freed object, giving a heap write/control-flow hijack primitive.
- A:HAvailability impact, high
- Refcount underflow and the second rawsock_data_exchange_complete() on the already-freed sk (or __sk_destruct racing the second put, the path that also hit nci_close_device lockdep) cause a kernel oops or panic.