mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
v7.4-rc1
5929 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
734bef548a |
Networking changes for 7.4.
Core & protocols
----------------
- Continue the work on removing rtnl_lock dependencies:
- per-netns ARP and ND neighbour tables, with the default settings
now configurable per netns (inheritance from init_net is
controlled by the new net.core.neigh_inherit_init_net sysctl)
- RCU-protected configuration and rtnl_lock-less fill_info() for
hsr, netkit, sit, vlan and vxlan devices
- per-netns device unregistration for ip tunnel and gre devices
- use the netdev instance lock instead of rtnl_lock when reading
speed and duplex via sysfs
- batch the flushing of uncached routes at device unregistration
time, relieving rtnl_lock contention on netns dismantle.
- Add hardware pacing offload support, admin-controlled via a new
rtnetlink attribute, with sch_fq integration (implemented in idpf).
- Re-segment BIG TCP GSO packets into GSO packets fitting the
egress device limits instead of plain MSS-sized segments,
improving throughput for mixed BIG TCP / non-BIG TCP paths
by up to 70%.
- Generate RSS keys that spread flows over all the RX queues; the
previous random keys could leave some queues unused.
- Optimize the bridge VLAN forwarding paths: cache the port-VLAN in fdb
entries and consider only VLAN members when flooding, for ~10% more
Mpps in the fdb forwarding path.
- A few TCP/IP performance improvements aimed at efficient cache
usage and reducing contention.
- Add the TCP ROCCET congestion control, a CUBIC variant aimed at
avoiding bufferbloat in cellular networks.
- Continue the conversion of getsockopt callbacks to sockopt_t.
- Add an ethtool command to list the front-facing ports of an
interface, including SFP cages and modules, using the phy_port
representation.
- Enable BIG TCP support for bareudp tunnels.
- Remove the IPV6_ADDRFORM socket option and disallow buggy TCP state
transitions (listen() + shutdown() + connect() and connect() +
connect(AF_UNSPEC) + listen()).
- Remove most BUG_ON()s from core packet processing, replacing them
with error paths.
Wireless
--------
- Latency improvements, including lockless station get/dump and beacon
updates, plus RTNL reduction and locking cleanups.
- Infrastructure for non-station TX/RX with MLO.
- NAN (Wi-Fi Aware) Instant Communication support and other NAN
improvements.
- Control frame Integrity Protocol (CIP) and protected TWT support.
- Improvements for AP regulatory checks.
Netfilter
---------
- Disable br_netfilter in user namespaces and schedule it for removal
in 2027.
- Restrict the raw table in nft_compat to the specific family, hook and
priority.
- Prepare the flowtable for mixed IPv4-over-IPv6 tunneling (and
vice versa).
- Use GFP_KERNEL_ACCOUNT for most netfilter allocations, for better
integration with memcg.
- Allow discovering conntrack zone filtering support in ctnetlink
dumps, and fix nfnetlink_hook handling of large dumps.
Deletions
---------
- Move the LLC type 2 sockets out of tree. There are no known users and
the code attracts a never-ending stream of LLM-driven fixes.
Device drivers
--------------
- New drivers:
- Meta Platforms NIC (mpnic), the second-generation NIC from Meta
- initial skeleton of the Nebula-matrix NICs driver (nbl)
- X-Powers AC200/AC300 Fast Ethernet PHYs
- Ethernet high-speed NICs:
- Intel:
- i40e: XDP metadata support for RX hash and VLAN tag
- ice: expose the E825 TSPLL state via the DPLL subsystem
- nVidia/Mellanox:
- move the data direct infrastructure from IB to core, in
preparation for netdev support.
- reduce the memory used per offloaded TC rule
- Meta (fbnic):
- support large io_uring zero-copy RX buffers
- Microsoft vNIC (mana):
- add BQL support
- Ethernet NICs consumer, and embedded:
- Airoha:
- LRO offload support
- Cadence (macb):
- context swapping for ringparam and MTU changes, avoiding
buffer loss under memory pressure
- Mucse (rnpgbe):
- TX/RX and link status support
- NXP (enetc):
- SR-IOV improvements and VF support for ENETC v4
- Qualcomm (ppe):
- IPQ5424 support
- Realtek PCI (r8169):
- phylink support
- RSS support for RTL8127
- Renesas (ravb):
- gPTP support for R-Car Gen4
- Synopsys (stmmac):
- XDP multi-buffer support on the TX side
- tc mqprio hw queue priority offload
- support for RK3568 SGMII, Allwinner H616 EMAC1, UltraRISC
DP1000 and Qualcomm sa8255p
- Ethernet switches:
- Mediatek (mt7530):
- fast age and change conduit support
- Microchip (ksz):
- support for KSZ8995XA/KS8995XA
- Microchip (lan966x):
- PCIe FDMA support, ~20x throughput increase in PCIe endpoint
- Microchip (sparx5):
- Time Aware Shaper (taprio) offload
- Motorcomm (yt921x):
- LED and SerDes PCS support
- Realtek (rtl8365mb):
- EEE support
- Ethernet PHYs:
- Broadcom:
- enable jumbo frames on BCM54xx
- Realtek:
- support for RTL8261CE_CG and RTL8261D_VM
- MDIO support for RTL838x and RTL839x
- WiFi drivers:
- Broadcom (brcmfmac):
- FT/OKC roaming offload
- Intel (iwlwifi):
- UHR sniffer support
- support for newer UEFI/BIOS tables
- MediaTek (mt76):
- mt7925 NAN improvements
- offchannel/scan improvements and MLO fixes
- Morse Micro (mm81x):
- monitor mode support
- Qualcomm (ath12k):
- IPQ5332 platform infrastructure
- Realtek (rtw88):
- RTL8723BS support
- SDIO TX performance improvements
- Realtek (rtw89):
- P2P_DEVICE support
- BT-coex updates for RTL8922D
- Bluetooth:
- move H:4 reassembly into the Bluetooth core
- add generic support for vendor packets
- MGMT: add security level changed event
- Bluetooth drivers:
- btusb: support Bulk Serialization Mode
- Intel: support Draco and Titan Lake, allow unsigned firmware
- Mediatek: MT7928 support
- Qualcomm: QCC2072 support
- Broadcom: Synaptics 4384 support
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-----BEGIN PGP SIGNATURE-----
iQJKBAABCgA0FiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmraNIAWHHBhb2xvLmFi
ZW5pQGdtYWlsLmNvbQAKCRApJHmNzI8TpBaeD/9iBxxaZzworKk3v+RalWo4noIC
QsZ8E0Du7vDruS2nESbZpUpf0lKxNxJVnXEj/q0acObzUuGFJBaqZ8Uzn337w6WK
nuM1YppPE9lIMNAgDhxKUIMGeVLHuQd3wQPsOs0nlywNehzrKYAfCUtcB3xD2H+I
xaUdTRooop5l6GpSS0CP7li/kzHb5GagVI2VmoOFCb+0BPl6tr+ITW8s0/Z/oyZC
Lx4Fl0Hhj0li4eHr0DS3vgS7jqmPFYOxo4zhGzXqCYaagPpvazR9RfFhP16BfJ/D
TPI3oIkqcyvttrTtgwYhLDJjw1+m+r1vmhel7Tp5XLHQJ4WXuunPBGrq9w7Xd+IF
JLd8VbUiXB2A/+fNSD3Q1nzukjRjlEsR2ZyRqAWqXWDhXYbAd0D/vptJJwem1ozm
RRoe9Gk2N+iSsqvfAq6coTRPEKrlsh27v36uWQZgQ2jA2SnrNsTuJwlhiET0Jc6T
kTEM0yjLDiUxsefOgGs5s10EnfLa2sL/0NWow0s83x6Dm3f3x2fvm2e0UlI3gLNI
43AgMaNO1IsNOWEiJC/O81pt/6FuF8cX+cJXtlLBW1ZTJnEnVtNlafJVnyfblblx
TXyzGtM0cUXyJsaS8/Qx1GUQO9N9MiWI4mCtDUWthBxvdpkn93G0pNXwnjybcnAH
0nX3+pVqFZCrG/PmvQ==
=ZOCE
-----END PGP SIGNATURE-----
Merge tag 'net-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Paolo Abeni:
"This includes a significant number of low-priority fixes - especially
in the NIC drivers area - that we deferred from the last few RCs in
the previous cycle, which can't be easily outlined in the synopsis
below.
Core & protocols:
- Continue the work on removing rtnl_lock dependencies:
- per-netns ARP and ND neighbour tables, with the default settings
now configurable per netns (inheritance from init_net is
controlled by the new net.core.neigh_inherit_init_net sysctl)
- RCU-protected configuration and rtnl_lock-less fill_info() for
hsr, netkit, sit, vlan and vxlan devices
- per-netns device unregistration for ip tunnel and gre devices
- use the netdev instance lock instead of rtnl_lock when reading
speed and duplex via sysfs
- batch the flushing of uncached routes at device unregistration
time, relieving rtnl_lock contention on netns dismantle.
- Add hardware pacing offload support, admin-controlled via a new
rtnetlink attribute, with sch_fq integration (implemented in idpf).
- Re-segment BIG TCP GSO packets into GSO packets fitting the egress
device limits instead of plain MSS-sized segments, improving
throughput for mixed BIG TCP / non-BIG TCP paths by up to 70%.
- Generate RSS keys that spread flows over all the RX queues; the
previous random keys could leave some queues unused.
- Optimize the bridge VLAN forwarding paths: cache the port-VLAN in
fdb entries and consider only VLAN members when flooding, for ~10%
more Mpps in the fdb forwarding path.
- A few TCP/IP performance improvements aimed at efficient cache
usage and reducing contention.
- Add the TCP ROCCET congestion control, a CUBIC variant aimed at
avoiding bufferbloat in cellular networks.
- Continue the conversion of getsockopt callbacks to sockopt_t.
- Add an ethtool command to list the front-facing ports of an
interface, including SFP cages and modules, using the phy_port
representation.
- Enable BIG TCP support for bareudp tunnels.
- Remove the IPV6_ADDRFORM socket option and disallow buggy TCP state
transitions (listen() + shutdown() + connect() and connect() +
connect(AF_UNSPEC) + listen()).
- Remove most BUG_ON()s from core packet processing, replacing them
with error paths.
Wireless:
- Latency improvements, including lockless station get/dump and
beacon updates, plus RTNL reduction and locking cleanups.
- Infrastructure for non-station TX/RX with MLO.
- NAN (Wi-Fi Aware) Instant Communication support and other NAN
improvements.
- Control frame Integrity Protocol (CIP) and protected TWT support.
- Improvements for AP regulatory checks.
Netfilter:
- Disable br_netfilter in user namespaces and schedule it for removal
in 2027.
- Restrict the raw table in nft_compat to the specific family, hook
and priority.
- Prepare the flowtable for mixed IPv4-over-IPv6 tunneling (and vice
versa).
- Use GFP_KERNEL_ACCOUNT for most netfilter allocations, for better
integration with memcg.
- Allow discovering conntrack zone filtering support in ctnetlink
dumps, and fix nfnetlink_hook handling of large dumps.
Deletions:
- Move the LLC type 2 sockets out of tree. There are no known users
and the code attracts a never-ending stream of LLM-driven fixes.
Device drivers:
- New drivers:
- Meta Platforms NIC (mpnic), the second-generation NIC from Meta
- initial skeleton of the Nebula-matrix NICs driver (nbl)
- X-Powers AC200/AC300 Fast Ethernet PHYs
- Ethernet high-speed NICs:
- Intel:
- i40e: XDP metadata support for RX hash and VLAN tag
- ice: expose the E825 TSPLL state via the DPLL subsystem
- nVidia/Mellanox:
- move the data direct infrastructure from IB to core, in
preparation for netdev support.
- reduce the memory used per offloaded TC rule
- Meta (fbnic):
- support large io_uring zero-copy RX buffers
- Microsoft vNIC (mana):
- add BQL support
- Ethernet NICs consumer, and embedded:
- Airoha:
- LRO offload support
- Cadence (macb):
- context swapping for ringparam and MTU changes, avoiding
buffer loss under memory pressure
- Mucse (rnpgbe):
- TX/RX and link status support
- NXP (enetc):
- SR-IOV improvements and VF support for ENETC v4
- Qualcomm (ppe):
- IPQ5424 support
- Realtek PCI (r8169):
- phylink support
- RSS support for RTL8127
- Renesas (ravb):
- gPTP support for R-Car Gen4
- Synopsys (stmmac):
- XDP multi-buffer support on the TX side
- tc mqprio hw queue priority offload
- support for RK3568 SGMII, Allwinner H616 EMAC1, UltraRISC
DP1000 and Qualcomm sa8255p
- Ethernet switches:
- Mediatek (mt7530):
- fast age and change conduit support
- Microchip (ksz):
- support for KSZ8995XA/KS8995XA
- Microchip (lan966x):
- PCIe FDMA support, ~20x throughput increase in PCIe endpoint
- Microchip (sparx5):
- Time Aware Shaper (taprio) offload
- Motorcomm (yt921x):
- LED and SerDes PCS support
- Realtek (rtl8365mb):
- EEE support
- Ethernet PHYs:
- Broadcom:
- enable jumbo frames on BCM54xx
- Realtek:
- support for RTL8261CE_CG and RTL8261D_VM
- MDIO support for RTL838x and RTL839x
- WiFi drivers:
- Broadcom (brcmfmac):
- FT/OKC roaming offload
- Intel (iwlwifi):
- UHR sniffer support
- support for newer UEFI/BIOS tables
- MediaTek (mt76):
- mt7925 NAN improvements
- offchannel/scan improvements and MLO fixes
- Morse Micro (mm81x):
- monitor mode support
- Qualcomm (ath12k):
- IPQ5332 platform infrastructure
- Realtek (rtw88):
- RTL8723BS support
- SDIO TX performance improvements
- Realtek (rtw89):
- P2P_DEVICE support
- BT-coex updates for RTL8922D
- Bluetooth:
- move H:4 reassembly into the Bluetooth core
- add generic support for vendor packets
- MGMT: add security level changed event
- Bluetooth drivers:
- btusb: support Bulk Serialization Mode
- Intel: support Draco and Titan Lake, allow unsigned firmware
- Mediatek: MT7928 support
- Qualcomm: QCC2072 support
- Broadcom: Synaptics 4384 support"
* tag 'net-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2126 commits)
Bluetooth: btusb: disable by default Qualcomm multi-subsystem
tipc: fix broadcast sender hang on last acker departure
tipc: fix use-after-free of broadcast reception link at node release
r8169: clear TX LPI on RTL8168h at link up after phylink conversion
tun: Require CAP_NET_ADMIN to attach to an ownerless device
net/sched/sch_cake: drop dead nla_nest_end() error check
net/sched/sch_cake: widen buffer_used to u64
net/sched/sch_cake: reduce parent backlog when clearing a tin
net/sched/sch_cake: serialize reconfiguration with the datapath
tg3: Add Datto SIRIS 5 1U Server to restart AER quirk table
net/mlx5e: Stop asserting for RTNL when closing channels
net: shrink the payload-only part of skb dataref to one bit
net: wwan: iosm: validate msg_head before indexing msg_ring
net: bgmac: rate limit RX error messages
selftests: net: veth: test XDP_TX to a peer with GRO enabled
veth: schedule the peer's NAPI after XDP_TX when only GRO is enabled
pppoe: delete session hash entries by pointer match
net: lan969x: don't disable hardirqs in fdma tx clear
net: sparx5/lan969x: do not clobber the PSFP cycle timer update period
net: lan969x: fix DSM calendar for empty taxis
...
|
||
|
|
258c3ae4a4 |
net: rename skb_unshare() to skb_unclone_full()
skb_unshare() only copies cloned skbs. A shared skb that is not a clone comes back unchanged, which the name doesn't suggest. The loopback selftest hooks got caught by this and hit BUG_ON(skb_shared()). Rename it to skb_unclone_full(). Like skb_unclone() it only acts on clones, but it copies the whole skb, not just the head. Suggested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de> Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com> # dpaa2 Link: https://patch.msgid.link/20261015-nb-skb-unclone-full-v1-1-0dfbf01f60f2@tipi-net.de Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
397464709a |
Bluetooth: hci_sync: scan unfiltered for host-resolved RPAs
Restore unfiltered scanning for pending IRK peers when the controller
cannot resolve private addresses. Keep accept-list filtering while
suspended and when forced by periodic advertising synchronization.
Fixes:
|
||
|
|
5874f8d032 |
Bluetooth: Fix the LE Read Connection Interval response layout
The response to HCI_OP_LE_READ_CONN_INTERVAL carries a
Minimum_Supported_Connection_Interval octet between the status and
Num_Groups, which was missing from the structure. Without it the minimum
interval was read as the number of groups, and every group after it
from one octet off.
Take the minimum interval used to clamp the default rate parameters from
that field rather than the smallest group minimum, as the number of
groups can be zero, which left it unset.
Fixes:
|
||
|
|
76a7545451 |
Bluetooth: L2CAP: Remove dead configuration state code
CONF_EWS_RECV has not been set since commit
|
||
|
|
a518b9a9ef |
Bluetooth: L2CAP: Only accept connection responses to outstanding requests
An outgoing channel waits in BT_CONNECT until security
and the feature mask exchange complete, and only then
sends its connection request. A peer can answer it
before that with a connection response matching our
source CID. The channel then moves to BT_CONFIG,
completes configuration and becomes connected before
security has completed. If security then fails,
l2cap_security_cfm() leaves the connected channel
alone, so it stays up on a link that did not reach
the required security level.
A connection response with a zero source CID is
matched by identifier. Another channel can hold the
same identifier for a response it still has to send,
so the lookup can pick the wrong channel.
Only accept a connection response while our request
is outstanding, and only look at such channels when
matching by identifier.
Fixes:
|
||
|
|
226fa3b676 |
Bluetooth: L2CAP: Use default TxWindow for zero socket option
L2CAP_OPTIONS accepts a txwin_size of zero and
stores it in tx_win. The zero is then sent to the
peer in our configuration request, and if the
channel ends up in ERTM mode it is passed to
l2cap_seq_list_init().
Use the default TxWindow instead, as the mode can
still be changed to ERTM during configuration.
Fixes:
|
||
|
|
c5ebb0245f |
Bluetooth: L2CAP: Reject invalid TxWindow in configuration requests
A peer can send an ERTM RFC option with a TxWindow
of zero, which is out of spec. It is stored in
remote_tx_win unchanged and later passed to
l2cap_seq_list_init(), where roundup_pow_of_two(0)
is undefined. On some architectures this results in
a ZERO_SIZE_PTR list and a remote kernel oops.
A TxWindow above 63 is out of spec as well. With
6-bit sequence numbers we would then send more
unacknowledged frames than the sequence space can
tell apart.
Reply with L2CAP_CONF_UNACCEPT and propose the
default TxWindow instead of accepting the value, so
remote_tx_win always stays within 1 to 63. Keep the
parameters of an earlier request then, and do not
treat the request as done because an earlier one was.
Also refuse a zero size in l2cap_seq_list_init(), so
any other path that reaches it with a zero TxWindow
fails the channel instead of the kernel.
Fixes:
|
||
|
|
6320736af7 |
Bluetooth: L2CAP: Reject signalling responses in invalid states
A peer can send configuration messages while an
incoming channel is in BT_CONNECT2, before the
security or deferred accept gate has completed. A
configuration response can then promote the channel
to BT_CONNECTED. Configuration responses can also
act on channels that are closing, and a late connection
response can move a disconnecting channel back to
BT_CONFIG.
Accept connection responses only while waiting in
BT_CONNECT. Answer configuration requests in
BT_CONNECT2, but defer our own request until
BT_CONFIG so configuration cannot complete before
the gate. Ignore configuration responses outside
BT_CONFIG and BT_CONNECTED, and only complete
configuration in BT_CONFIG.
Fixes:
|
||
|
|
c1398cf11b |
Bluetooth: L2CAP: Reject mode changes on connected channels
A peer can send a configuration response with an RFC
option for another mode to a connected channel, for
example to switch it from Streaming to ERTM mode.
l2cap_parse_conf_rsp() then changes chan->mode, but
l2cap_ertm_init() is not called again, so the ERTM
sequence lists are never allocated. The next
out-of-sequence I-frame makes l2cap_seq_list_clear()
write through the NULL srej_list.list.
Refuse the channel when a response tries to change
the mode of a connected channel.
Fixes:
|
||
|
|
91638f53ff |
Bluetooth: hci_event: Fix LE link drop on remote features command status
When the local controller supports peripheral-initiated features
exchange, the LE Read Remote Features procedure also runs for incoming
connections, and it fails with Unsupported Remote Feature (0x1a) if the
central does not support that feature. hci_le_remote_feat_complete_evt()
and hci_le_read_all_remote_features_evt() handle this and let the
connection transition into connected state.
A controller can also return that error in the Command Status event
instead. An Intel controller does so for a central that does not
support peripheral-initiated features exchange, presumably because it
already has the features of the central. hci_cs_le_read_remote_features()
and hci_cs_le_read_all_remote_features() then confirm the connection as
failed while it is still in BT_CONFIG, and the hci_conn_drop() in
le_read_features_complete() disconnects it right away:
> HCI Event: LE Meta Event (0x3e) plen 31
LE Enhanced Connection Complete (0x0a)
Status: Success (0x00)
Role: Peripheral (0x01)
< HCI Command: LE Read Remote Used Features (0x08|0x0016) plen 2
> HCI Event: Command Status (0x0f) plen 4
LE Read Remote Used Features (0x08|0x0016) ncmd 1
Status: Unsupported Remote Feature / Unsupported LMP Feature (0x1a)
< HCI Command: Disconnect (0x01|0x0006) plen 3
Reason: Remote User Terminated Connection (0x13)
Data the central sends afterwards is reported as:
Bluetooth: hci0: ACL packet for unknown connection handle 3585
Handle Unsupported Remote Feature in the command status the same way as
in the complete events.
Fixes:
|
||
|
|
56e20c3d8a |
Bluetooth: MSFT: Serialize handle map cleanup with event processing
MSFT monitor handle mappings must remain valid while vendor events look
up and use them under hdev->lock. msft_do_close() removes and frees the
mappings without that lock.
hci_dev_close_sync() clears HCI_UP and drains the RX workqueue before
MSFT cleanup. However, a transport callback that already passed
hci_recv_frame()'s state check can queue a vendor event after the drain
returns, if no earlier shutdown callback has quiesced reception. The
driver close callback runs after MSFT cleanup, so event processing can
overlap the unlocked removal. msft_monitor_device_evt() can then
traverse freed list entries or read handle_data->mgmt_handle after it is
freed.
Take hdev->lock while resetting monitor states and removing handle
mappings in msft_do_close(), as normal monitor cancellation already
does. An active event reader then finishes before its mapping is freed,
and later lookups see an empty handle map.
An instrumented kernel produced this KASAN report (timestamps removed
and unrelated frames omitted):
BUG: KASAN: slab-use-after-free in msft_vendor_evt+0x1906/0x1990
Read of size 2 at addr ffff888104df3602 by task kworker/u17:2/502
Workqueue: hci0 hci_rx_work
Call Trace:
[...]
msft_vendor_evt+0x1906/0x1990
hci_vendor_evt+0x6f/0x90
hci_event_packet+0x894/0xc70
[...]
hci_rx_work+0x3f8/0xfa0
[...]
Allocated by task 499:
[...]
msft_add_monitor_sync+0x6a8/0x10a0
msft_add_monitor_pattern+0x7f/0xb0
hci_add_adv_monitor+0x1fa/0x2e0
[...]
Freed by task 499:
[...]
kfree+0x307/0x580
msft_do_close+0x238/0x750
hci_dev_close_sync+0x546/0x1380
[...]
The buggy address belongs to the object at ffff888104df3600
which belongs to the cache kmalloc-32 of size 32
The buggy address is located 2 bytes inside of
freed 32-byte region [ffff888104df3600, ffff888104df3620)
[...]
Fixes:
|
||
|
|
47493e62e8 |
Bluetooth: MGMT: Allow connection rate request as peripheral
Load Connection Subrate only issues the LE Connection Rate Request when
connected as central, but either role can initiate the Connection Rate
Update procedure, e.g. a HID device, which is the peripheral, does it
once the HID host requests a HID SCI mode with the HID Control Point.
Issue it regardless of the role.
Fixes:
|
||
|
|
64aabf94ec |
Bluetooth: selftest: Pin module for selftest debugfs file operations
An open debugfs file retains its file_operations pointer in the debugfs proxy state. However, test_smp_fops in net/bluetooth/smp.c and test_ecdh_fops in net/bluetooth/selftest.c have no .owner set to THIS_MODULE. As a result, full_proxy_open_regular() calls fops_get() which succeeds without taking a reference to the bluetooth module. When CONFIG_BT=m and selftests are enabled, a userspace process can open either /sys/kernel/debug/bluetooth/selftest_smp or /sys/kernel/debug/bluetooth/selftest_ecdh and keep the file descriptor open while the module is unloaded (rmmod bluetooth). When the userspace process subsequently closes the descriptor, full_proxy_release() accesses the already unmapped file_operations structure, triggering a kernel oops in full_proxy_release(): BUG: unable to handle page fault for address: fffffbfff8056f03 #PF: supervisor read access in kernel mode Oops: 0000 [#1] SMP KASAN NOPTI RIP: 0010:full_proxy_release+0x8e/0x140 Call Trace: <TASK> __fput+0x39f/0xa60 fput_close_sync+0xff/0x200 __x64_sys_close+0x8c/0xf0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> The issue was discovered via manual code audit of net/bluetooth/smp.c and net/bluetooth/selftest.c. Set .owner = THIS_MODULE on test_smp_fops and test_ecdh_fops so that debugfs keeps the module pinned until the file descriptors are closed. Fixes: |
||
|
|
4020751fd0 |
Bluetooth: L2CAP: Hold the listener while notifying child teardown
A pending child's listener must remain alive until the child's teardown
callback finishes notifying it. l2cap_sock_teardown_cb() saves the raw
bt_sk(sk)->parent pointer, calls bt_accept_unlink(), then invokes
parent->sk_data_ready(). The accept queue holds a reference to the
child, but the callback takes no reference to the listener across
unlink.
When an incoming child has not been accepted, HCI disconnection can
reach l2cap_conn_del() and the child's teardown callback while another
task closes the listener. The listener channel has no connection, so the
child's connection and channel locks do not serialize listener release.
The following ordering is possible:
HCI child teardown Listener release
lock the child socket
save parent
bt_accept_unlink(sk)
drain the empty accept queue
bt_sock_unlink()
shut down the listener channel
sock_orphan()
l2cap_sock_kill()
parent->sk_data_ready(parent)
If no other reference delays freeing the listener, the final
notification reads sk_data_ready through freed socket storage. The child
lock cannot stop listener release once the child is no longer on the
accept queue.
Take a listener socket reference before unlinking the child and release
it after sk_data_ready() returns. While the child remains queued, its
socket lock prevents listener cleanup from completing the dequeue, so
the listener is still alive when the reference is acquired. The
reference then protects the notification after unlink without changing
lock order or the ordering of queue removal and wakeup.
KASAN report as below:
==================================================================
BUG: KASAN: slab-use-after-free in l2cap_sock_teardown_cb+0x467/0x490
Read of size 8 at addr ffff88810b99b188 by task kworker/u17:3/516
Workqueue: hci1 hci_rx_work
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
? l2cap_sock_teardown_cb+0x467/0x490
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20d/0x410
? l2cap_sock_teardown_cb+0x467/0x490
kasan_report+0xe0/0x110
? l2cap_sock_teardown_cb+0x467/0x490
l2cap_sock_teardown_cb+0x467/0x490
l2cap_chan_del+0x123/0x8f0
l2cap_conn_del+0x31b/0x740
? hci_cmd_sync_submit+0x264/0x320
? __pfx_l2cap_disconn_cfm+0x10/0x10
l2cap_disconn_cfm+0x87/0xd0
hci_disconn_complete_evt+0x30f/0x990
? srso_alias_return_thunk+0x5/0xfbef5
hci_event_packet+0x894/0xc70
? __pfx_hci_disconn_complete_evt+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_hci_event_packet+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? free_zapped_rcu+0xd0/0x1e0
? srso_alias_return_thunk+0x5/0xfbef5
? lockdep_hardirqs_on_prepare+0xea/0x1a0
? __pfx_hci_cmd_sync_complete+0x10/0x10
? trace_hardirqs_on+0x18/0x160
? srso_alias_return_thunk+0x5/0xfbef5
hci_rx_work+0x367/0xf00
? srso_alias_return_thunk+0x5/0xfbef5
process_one_work+0x908/0x19c0
? __pfx_process_one_work+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? lock_is_held_type+0x8f/0x100
? srso_alias_return_thunk+0x5/0xfbef5
worker_thread+0x65c/0xe40
? __pfx_worker_thread+0x10/0x10
kthread+0x34f/0x460
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_kthread+0x10/0x10
ret_from_fork+0x659/0x940
? __pfx_ret_from_fork+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __switch_to+0x74f/0xf80
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Allocated by task 502:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0xaa/0xb0
__kmalloc_noprof+0x2d7/0x770
sk_prot_alloc+0x13e/0x260
sk_alloc+0x37/0xb40
bt_sock_alloc+0x40/0x3b0
l2cap_sock_create+0x116/0x310
bt_sock_create+0x171/0x330
__sock_create+0x2c4/0x730
__sys_socket+0x141/0x210
__x64_sys_socket+0x77/0xc0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 502:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
kfree+0x307/0x580
__sk_destruct+0x64f/0x790
sk_destruct+0xb3/0xd0
__sk_free+0xdd/0x370
sk_free+0x51/0x80
l2cap_sock_kill+0x17a/0x2a0
l2cap_sock_release+0x1d0/0x310
__sock_release+0xb8/0x270
sock_close+0x21/0x30
__fput+0x39f/0xa60
fput_close_sync+0xff/0x200
__x64_sys_close+0x8c/0xf0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff88810b99b000
which
belongs to the cache kmalloc-2k of size
2048
The buggy address is located 392 bytes inside of
freed
2048-byte region [ffff88810b99b000,
ffff88810b99b800)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0
pfn:0x10b998
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x200000000000040(head|node=0|zone=2)
page_type: f5(slab)
raw: 0200000000000040 ffff888100042f00 dead000000000100
dead000000000122
raw: 0000000000000000 0000000000080008 00000000f5000000
0000000000000000
head: 0200000000000040 ffff888100042f00 dead000000000100
dead000000000122
head: 0000000000000000 0000000000080008 00000000f5000000
0000000000000000
head: 0200000000000003 fffffffffffffe01 00000000ffffffff
00000000ffffffff
head: 0000000000000000 0000000000000000 00000000ffffffff
0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88810b99b080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88810b99b100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff88810b99b180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff88810b99b200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88810b99b280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
||
|
|
4b76fa3621 |
Bluetooth: hci_sync: Protect IRK identity reads with RCU
hci_le_set_privacy_mode_sync() needs the IRK returned by
hci_find_irk_by_addr() to remain allocated until its identity address
and type have been copied into the command. The finder drops its RCU
read lock before returning this borrowed pointer, leaving the later
field reads unprotected.
When a privacy-capable controller has a pending peer with address
resolution and device privacy enabled, accept-list programming can
reach this helper while management reloads the IRKs. The request
worker holds hdev->req_lock, whereas load_irks() takes hdev->lock,
allowing the following ordering:
Request worker Management / RCU reclaim
hci_le_set_privacy_mode_sync()
hci_find_irk_by_addr()
rcu_read_lock()
find matching IRK
rcu_read_unlock()
return borrowed IRK
load_irks()
hci_dev_lock(hdev)
hci_smp_irks_clear()
list_del_rcu()
kfree_rcu()
hci_dev_unlock(hdev)
RCU grace period and IRK free
read irk->addr_type
copy irk->bdaddr
The request then accesses a freed IRK. KASAN reports a one-byte
use-after-free read of addr_type on this path.
Keep an outer RCU read-side critical section across the lookup and
both identity-field copies. The finder's nested unlock then leaves
the IRK protected until the caller finishes copying it. Release RCU
on a lookup miss and after copying the fields, before the synchronous
HCI command can sleep.
KASAN report as below:
==================================================================
BUG: KASAN: slab-use-after-free in
hci_le_add_accept_list_sync+0x90f/0x940
Read of size 1 at addr ffff88810aa6072c by task kworker/u17:0/493
Workqueue: hci0 hci_cmd_sync_work
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
? hci_le_add_accept_list_sync+0x90f/0x940
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20d/0x410
? hci_le_add_accept_list_sync+0x90f/0x940
kasan_report+0xe0/0x110
? hci_le_add_accept_list_sync+0x90f/0x940
hci_le_add_accept_list_sync+0x90f/0x940
? __pfx_hci_le_add_accept_list_sync+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? conn_params_copy+0x3a0/0x650
hci_passive_scan_sync+0x8c9/0x1e80
? __pfx_hci_passive_scan_sync+0x10/0x10
? find_held_lock+0x2b/0x80
? hci_lookup_le_connect+0x181/0x3c0
? srso_alias_return_thunk+0x5/0xfbef5
? find_held_lock+0x2b/0x80
? hci_update_passive_scan_sync+0x437/0x950
? srso_alias_return_thunk+0x5/0xfbef5
? lock_release+0xc8/0x280
hci_update_passive_scan_sync+0x461/0x950
hci_cmd_sync_work+0x1b3/0x450
? srso_alias_return_thunk+0x5/0xfbef5
process_one_work+0x908/0x19c0
? __pfx_process_one_work+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? lock_is_held_type+0x8f/0x100
? srso_alias_return_thunk+0x5/0xfbef5
worker_thread+0x65c/0xe40
? __pfx_worker_thread+0x10/0x10
kthread+0x34f/0x460
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_kthread+0x10/0x10
ret_from_fork+0x659/0x940
? __pfx_ret_from_fork+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __switch_to+0x74f/0xf80
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Allocated by task 507:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0xaa/0xb0
__kmalloc_cache_noprof+0x251/0x610
hci_add_irk+0xb6/0x220
load_irks+0x5ef/0x7e0
hci_sock_sendmsg+0x128b/0x22e0
__sys_sendto+0x425/0x470
__x64_sys_sendto+0xe5/0x1c0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 0:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
__rcu_free_sheaf_prepare+0x65/0x2a0
rcu_free_sheaf+0x1f/0xe0
rcu_core+0x661/0x1d10
handle_softirqs+0x201/0x930
__irq_exit_rcu+0x110/0x1e0
irq_exit_rcu+0xe/0x20
sysvec_apic_timer_interrupt+0x6c/0x80
asm_sysvec_apic_timer_interrupt+0x1a/0x20
The buggy address belongs to the object at ffff88810aa60700
which belongs to the cache kmalloc-64 of size 64
The buggy address is located 44 bytes inside of
freed 64-byte region [ffff88810aa60700, ffff88810aa60740)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0
pfn:0x10aa60
flags: 0x200000000000000(node=0|zone=2)
page_type: f5(slab)
raw: 0200000000000000 ffff8881000428c0 dead000000000100
dead000000000122
raw: 0000000000000000 0000000000200020 00000000f5000000
0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88810aa60600: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
ffff88810aa60680: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>ffff88810aa60700: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
^
ffff88810aa60780: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
ffff88810aa60800: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
==================================================================
Disabling lock debugging due to kernel taint
Fixes:
|
||
|
|
2a3e228787 |
Bluetooth: hci_debugfs: Pin module for debugfs file operations
An open debugfs file retains its file_operations pointer in the
debugfs proxy state. However, the file_operations defined in
hci_debugfs.c (use_debug_keys_fops, sc_only_mode_fops,
ssp_debug_mode_fops, force_bredr_smp_fops, force_static_address_fops,
force_no_mitm_fops, dut_mode_fops, vendor_diag_fops, and the
DEFINE_QUIRK_ATTRIBUTE macro) have no .owner set to THIS_MODULE.
As a result, full_proxy_open_regular() calls fops_get() which succeeds
without taking a reference to the bluetooth module. When a userspace
process opens any of these debugfs files, a subsequent controller removal
and module unload (rmmod bluetooth) can succeed while the file descriptor
remains open.
When the userspace process subsequently closes the descriptor,
full_proxy_release() accesses the already unmapped file_operations
structure, triggering a kernel oops in full_proxy_release():
BUG: unable to handle page fault for address: fffffbfff8056f03
#PF: supervisor read access in kernel mode
Oops: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:full_proxy_release+0x8e/0x140
Call Trace:
<TASK>
__fput+0x39f/0xa60
fput_close_sync+0xff/0x200
__x64_sys_close+0x8c/0xf0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
The issue was discovered via manual code audit of
net/bluetooth/hci_debugfs.c and verified on a Linux 7.3-rc6 test VM
with CONFIG_BT=m.
Set .owner = THIS_MODULE on all debugfs file_operations tables in
hci_debugfs.c so that debugfs keeps the module loaded until close has
finished.
Fixes:
|
||
|
|
8368f0c2cd |
Bluetooth: 6lowpan: Pin module for 6lowpan_control debugfs file
An open debugfs file retains lowpan_control_fops in the debugfs proxy
state. However, lowpan_control_fops has no .owner set to THIS_MODULE.
As a result, full_proxy_open_regular() calls fops_get() which succeeds
without taking a reference to the bluetooth_6lowpan module.
With CONFIG_BT_6LOWPAN=m, a userspace process can keep the debugfs file
descriptor for 6lowpan_control open across module unload
(delete_module / rmmod bluetooth_6lowpan). When the process subsequently
closes the file descriptor, full_proxy_release() accesses the already
freed and unmapped lowpan_control_fops table, causing a kernel page fault
or oops.
The issue was discovered via manual code audit of
net/bluetooth/6lowpan.c.
Set .owner = THIS_MODULE on lowpan_control_fops so that debugfs pins
the module until all open file descriptors have finished.
Fixes:
|
||
|
|
ebba800d14 |
Bluetooth: 6lowpan: Drain RCU readers on registration failure
A lowpan_btle_dev is embedded in its net_device allocation and must
remain alive until readers of bt_6lowpan_devices have left their RCU
sections. setup_netdev() publishes it before registration, but its
error path only unlinks it before calling free_netdev().
If a second controller's registration fails while multicast is sent
on an existing 6LoWPAN interface, send_mcast_pkt() can already have
selected the new entry. It reads entry->netdev before checking which
interface owns it. An early failure, such as allocating the device's
name node, leaves NETREG_UNINITIALIZED, so free_netdev() releases the
storage immediately.
The following ordering frees the selected entry before the reader
loads its netdev field:
Adapter creation (controller B) Multicast on controller A
setup_netdev()
list_add_rcu()
rcu_read_lock()
select B's entry
lowpan_register_netdev() fails
list_del_rcu()
free_netdev()
read entry->netdev
rcu_read_unlock()
Removing the list node does not wait for that reader, and
devices_lock does not serialize the multicast reader. The subsequent
field load is a use-after-free, reported by KASAN in bt_xmit().
Wait for an RCU grace period after dropping devices_lock and before
free_netdev(). This keeps the failed adapter allocated until traversals
that could have selected it complete. The callback is already sleepable,
and the wait happens outside the list spinlock.
KASAN report as below:
==================================================================
BUG: KASAN: slab-use-after-free in bt_xmit+0x1d06/0x21e0
Read of size 8 at addr ffff88810ef45030 by task python3/556
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
? bt_xmit+0x1d06/0x21e0
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20d/0x410
? bt_xmit+0x1d06/0x21e0
kasan_report+0xe0/0x110
? bt_xmit+0x1d06/0x21e0
bt_xmit+0x1d06/0x21e0
? __pfx_bt_xmit+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? lock_acquire+0x17b/0x2f0
? srso_alias_return_thunk+0x5/0xfbef5
? lock_is_held_type+0x8f/0x100
? dev_hard_start_xmit+0x187/0x660
? __pfx_bt_xmit+0x10/0x10
dev_hard_start_xmit+0x187/0x660
sch_direct_xmit+0x153/0x850
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_sch_direct_xmit+0x10/0x10
? do_raw_spin_lock+0x130/0x270
? __pfx_do_raw_spin_lock+0x10/0x10
? lock_is_held_type+0x8f/0x100
__dev_queue_xmit+0x3111/0x3aa0
? srso_alias_return_thunk+0x5/0xfbef5
? look_up_lock_class+0x59/0x130
? register_lock_class+0x41/0x790
? __pfx___dev_queue_xmit+0x10/0x10
? __lock_acquire+0x466/0x2260
? find_held_lock+0x2b/0x80
? ___neigh_create+0x1690/0x2540
? __local_bh_enable_ip+0xa6/0x120
? srso_alias_return_thunk+0x5/0xfbef5
? lockdep_hardirqs_on_prepare+0xea/0x1a0
? srso_alias_return_thunk+0x5/0xfbef5
? lock_acquire+0x17b/0x2f0
? srso_alias_return_thunk+0x5/0xfbef5
? find_held_lock+0x2b/0x80
? ip6_finish_output2+0x8be/0x1840
? srso_alias_return_thunk+0x5/0xfbef5
? neigh_connected_output+0x39f/0x4e0
? srso_alias_return_thunk+0x5/0xfbef5
neigh_connected_output+0x33f/0x4e0
ip6_finish_output2+0x8be/0x1840
ip6_finish_output+0x424/0xd50
ip6_output+0x210/0x640
? __pfx_ip6_mr_output+0x10/0x10
ip6_local_out+0x193/0x1c0
ip6_send_skb+0xfb/0x3e0
udp_v6_send_skb+0x6e1/0x1180
udpv6_sendmsg+0x1f9b/0x2a00
? get_random_u32+0xaf/0x640
? __pfx_udpv6_sendmsg+0x10/0x10
? lock_release+0xc8/0x280
? srso_alias_return_thunk+0x5/0xfbef5
? lockdep_hardirqs_on_prepare+0xea/0x1a0
? srso_alias_return_thunk+0x5/0xfbef5
? trace_hardirqs_on+0x18/0x160
? srso_alias_return_thunk+0x5/0xfbef5
? __local_bh_enable_ip+0xa6/0x120
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_udpv6_sendmsg+0x10/0x10
? inet6_sendmsg+0xff/0x140
inet6_sendmsg+0xff/0x140
__sys_sendto+0x320/0x470
? __pfx___sys_sendto+0x10/0x10
? exc_page_fault+0x5c/0xc0
? srso_alias_return_thunk+0x5/0xfbef5
? lock_release+0xc8/0x280
? handle_mm_fault+0x12e/0x580
__x64_sys_sendto+0xe5/0x1c0
? lockdep_hardirqs_on_prepare+0xea/0x1a0
? srso_alias_return_thunk+0x5/0xfbef5
? trace_hardirqs_on+0x18/0x160
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Allocated by task 502:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0xaa/0xb0
__kvmalloc_node_noprof+0x353/0x930
alloc_netdev_mqs+0xa0/0x1250
chan_ready_cb+0x198/0x1110
l2cap_recv_frame+0x6dc0/0x8830
l2cap_recv_acldata+0xe9f/0x10e0
hci_rx_work+0x5a6/0xf00
process_one_work+0x908/0x19c0
worker_thread+0x65c/0xe40
kthread+0x34f/0x460
ret_from_fork+0x659/0x940
ret_from_fork_asm+0x1a/0x30
Freed by task 502:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
kfree+0x307/0x580
free_netdev+0x6ca/0x8f0
chan_ready_cb+0xd91/0x1110
l2cap_recv_frame+0x6dc0/0x8830
l2cap_recv_acldata+0xe9f/0x10e0
hci_rx_work+0x5a6/0xf00
process_one_work+0x908/0x19c0
worker_thread+0x65c/0xe40
kthread+0x34f/0x460
ret_from_fork+0x659/0x940
ret_from_fork_asm+0x1a/0x30
The buggy address belongs to the object at ffff88810ef44000
which
belongs to the cache kmalloc-8k of size
8192
The buggy address is located 4144 bytes inside of
freed
8192-byte region [ffff88810ef44000,
ffff88810ef46000)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0
pfn:0x10ef40
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x200000000000040(head|node=0|zone=2)
page_type: f5(slab)
raw: 0200000000000040 ffff888100043180 dead000000000100
dead000000000122
raw: 0000000000000000 0000000000020002 00000000f5000000
0000000000000000
head: 0200000000000040 ffff888100043180 dead000000000100
dead000000000122
head: 0000000000000000 0000000000020002 00000000f5000000
0000000000000000
head: 0200000000000003 fffffffffffffe01 00000000ffffffff
00000000ffffffff
head: ffff88810ef41a80 0000000000000000 00000000ffffffff
0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88810ef44f00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88810ef44f80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff88810ef45000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff88810ef45080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88810ef45100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
Disabling lock debugging due to kernel taint
Fixes:
|
||
|
|
21895f20fe |
Bluetooth: msft: Lock failed probe cleanup against feature readers
The MSFT data must remain allocated while msft_get_features() reads
its features. read_adv_mon_features() protects that access with
hdev->lock, but msft_do_open() clears hdev->msft_data and frees the
object without that lock when read_supported_features() fails.
After a successful probe, the data survives a normal close. A later
open can fail the probe while a management feature request is running.
hci_mgmt_cmd() permits requests during HCI_INIT, and the opener's
hdev->req_lock does not serialize the management reader:
Management feature request HCI open
hold hdev->req_lock
msft_do_open()
hold hdev->lock
msft_get_features(): save msft
read_supported_features() fails
hdev->msft_data = NULL
kfree(msft)
read msft->features
release hdev->lock release hdev->req_lock
The saved pointer then refers to freed memory, causing a use-after-free
read. Advertisement reporting through mgmt_device_found() also reads
the features with hdev->lock held.
Take hdev->lock around clearing and freeing msft_data in the failure
branch. An existing feature reader finishes before the free, while a
reader starting after cleanup sees NULL. Keep the synchronous probe
outside this critical section, following the existing req_lock to
hdev->lock ordering.
KASAN report as below:
==================================================================
BUG: KASAN: slab-use-after-free in msft_monitor_supported+0xa9/0xb0
Read of size 8 at addr ffff88811573ee00 by task mgmt-read-adv-m/532
CPU: 2 UID: 0 PID: 532 Comm: mgmt-read-adv-m Not tainted
7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy)
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps
fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
? msft_monitor_supported+0xa9/0xb0
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20d/0x410
? msft_monitor_supported+0xa9/0xb0
kasan_report+0xe0/0x110
? msft_monitor_supported+0xa9/0xb0
msft_monitor_supported+0xa9/0xb0
read_adv_mon_features+0xdf/0x640
? trace_hardirqs_on+0x18/0x160
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_read_adv_mon_features+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? do_raw_read_unlock+0x49/0xe0
? srso_alias_return_thunk+0x5/0xfbef5
? _raw_read_unlock+0x23/0x40
hci_sock_sendmsg+0x12b5/0x2270
? __pfx_hci_sock_sendmsg+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? selinux_socket_sendmsg+0x160/0x280
__sys_sendto+0x425/0x470
? __pfx_hci_sock_sendmsg+0x10/0x10
? __pfx___sys_sendto+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? __sys_setsockopt+0x119/0x180
__x64_sys_sendto+0xe5/0x1c0
? lockdep_hardirqs_on_prepare+0xea/0x1a0
? srso_alias_return_thunk+0x5/0xfbef5
? trace_hardirqs_on+0x18/0x160
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f9ceb04a687
Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48
83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b>
c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
RSP: 002b:00007ffe6ab96a70 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
RAX: ffffffffffffffda RBX: 00007f9ceafb8780 RCX: 00007f9ceb04a687
RDX: 0000000000000006 RSI: 00007ffe6ab96aea RDI: 0000000000000003
RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000003
R13: 00007ffe6ab96d50 R14: 00007f9ceb1f6000 R15: 00005625e427dd68
</TASK>
Allocated by task 506:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0xaa/0xb0
__kmalloc_cache_noprof+0x251/0x610
msft_register+0x54/0x260
hci_register_dev+0x6b7/0xc80
__vhci_create_device+0x330/0x840
vhci_write+0x287/0x440
vfs_write+0x637/0x1010
ksys_write+0x111/0x200
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 529:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
kfree+0x307/0x580
msft_do_open+0x604/0x9e0
hci_dev_open_sync+0x94a/0x2110
hci_dev_do_open+0x2f/0xb0
hci_dev_open+0x17d/0x300
hci_sock_ioctl+0x3c6/0x710
sock_do_ioctl+0x120/0x2b0
sock_ioctl+0x41b/0x670
__x64_sys_ioctl+0x163/0x1d0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff88811573ee00
which belongs to the cache kmalloc-256 of size 256
The buggy address is located 0 bytes inside of
freed 256-byte region [ffff88811573ee00, ffff88811573ef00)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0
pfn:0x11573e
head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x200000000000040(head|node=0|zone=2)
page_type: f5(slab)
raw: 0200000000000040 ffff888100042b40 dead000000000100
dead000000000122
raw: 0000000000000000 0000000000100010 00000000f5000000
0000000000000000
head: 0200000000000040 ffff888100042b40 dead000000000100
dead000000000122
head: 0000000000000000 0000000000100010 00000000f5000000
0000000000000000
head: 0200000000000001 ffffffffffffff81 00000000ffffffff
00000000ffffffff
head: 0000000000000000 0000000000000000 00000000ffffffff
0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88811573ed00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88811573ed80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff88811573ee00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff88811573ee80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88811573ef00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================
Fixes:
|
||
|
|
213e7a99be |
Bluetooth: MGMT: Reject quality report requests during unregister
A quality report request must not call a driver callback after its
module text has been released. hci_mgmt_cmd() holds an hci_dev reference
through set_exp_feature(), but that reference only preserves the device
allocation. set_quality_report_func() takes req_lock and invokes
hdev->set_quality_report without checking HCI_UNREGISTER.
This is unsafe when a SET_EXP_FEATURE request for an Intel controller
would change HCI_QUALITY_REPORT and is delayed before taking req_lock
while the controller is removed. With btintel_pcie and btintel built as
modules and no other btintel dependents, the following order is
possible:
Management request Removal and module unload
------------------ -------------------------
hci_mgmt_cmd(): retain hdev
hci_unregister_dev():
set HCI_UNREGISTER
remove hdev from lookup
close under req_lock
release req_lock
btintel_pcie_remove(): return
unload btintel_pcie, then btintel
set_quality_report_func():
take req_lock
call hdev->set_quality_report
When the request resumes after btintel unload, the indirect call targets
released module text and can cause an instruction-fetch page fault. The
close operation serializes with a running callback but does not prevent
a delayed management handler from invoking it afterwards.
Check HCI_UNREGISTER immediately after acquiring the existing req_lock
and return MGMT_STATUS_INVALID_INDEX via the common unlock path. If
unregister passed its close section first, the request now rejects the
removed controller before accessing the callback. If the request passes
the check first, hci_dev_do_close() must wait for req_lock until the
callback has returned, so unregister cannot finish before the use.
Oops report as below:
BUG: unable to handle page fault for address: ffffffffc0408e10
#PF: supervisor instruction fetch in kernel mode
#PF: error_code(0x0010) - not-present page
PGD 80a9067 P4D 80a9067 PUD 80ab067 PMD 0
Oops: Oops: 0010 [#1] SMP KASAN NOPTI
CPU: 1 UID: 0 PID: 439 Comm: btmgmt Tainted: G O 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy)
Tainted: [O]=OOT_MODULE
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
RIP: 0010:0xffffffffc0408e10
Code: Unable to access opcode bytes at 0xffffffffc0408de6.
RSP: 0018:ffff888110927838 EFLAGS: 00010293
RAX: 0000000000000000 RBX: 1ffff11022124f0c RCX: ffffffff85b1a1b6
RDX: ffff888117511d00 RSI: 0000000000000001 RDI: ffff888117598000
RBP: ffff888110927950 R08: 0000000000000001 R09: 0000000000000001
R10: ffffffff893d3057 R11: ffff888117511d00 R12: ffff888117598000
R13: 0000000000000001 R14: ffffffffc0408e10 R15: ffff888117599970
FS: 00007f15453f2040(0000) GS:ffff8881fd852000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffffc0408de6 CR3: 000000010b832005 CR4: 0000000000770ef0
PKRU: 55555554
Call Trace:
<TASK>
? set_quality_report_func+0x232/0x660
? __pfx_set_quality_report_func+0x10/0x10
? pmbd_gate_maybe+0x47/0x60
? srso_alias_return_thunk+0x5/0xfbef5
? pmbd_probe_hit_cookie+0xe7/0x1c0
? srso_alias_return_thunk+0x5/0xfbef5
? pmbd_probe_hit_cookie+0xee/0x1c0
set_exp_feature+0xf7/0x260
? set_exp_feature+0xf7/0x260
? hci_sock_sendmsg+0x12b2/0x2400
? __pfx_hci_sock_sendmsg+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? selinux_socket_sendmsg+0x160/0x280
? sock_write_iter+0x4c0/0x550
? __pfx_hci_sock_sendmsg+0x10/0x10
? __pfx_sock_write_iter+0x10/0x10
? __file_has_perm+0x25e/0x420
? __pfx___file_has_perm+0x10/0x10
? do_iter_readv_writev+0x59c/0x860
? __pfx_do_iter_readv_writev+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? security_file_permission+0x26/0x80
? vfs_writev+0x30e/0xc10
? __pfx_vfs_writev+0x10/0x10
? __pfx_do_epoll_wait+0x10/0x10
? __pfx_do_epoll_ctl+0x10/0x10
? do_writev+0x241/0x2f0
? srso_alias_return_thunk+0x5/0xfbef5
? do_writev+0x241/0x2f0
? __pfx_do_writev+0x10/0x10
? irqentry_exit+0xbe/0x820
? do_syscall_64+0x115/0x6a0
? entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
Modules linked in: [last unloaded: btintel(O)]
CR2: ffffffffc0408e10
---[ end trace 0000000000000000 ]---
RIP: 0010:0xffffffffc0408e10
Code: Unable to access opcode bytes at 0xffffffffc0408de6.
RSP: 0018:ffff888110927838 EFLAGS: 00010293
RAX: 0000000000000000 RBX: 1ffff11022124f0c RCX: ffffffff85b1a1b6
RDX: ffff888117511d00 RSI: 0000000000000001 RDI: ffff888117598000
RBP: ffff888110927950 R08: 0000000000000001 R09: 0000000000000001
R10: ffffffff893d3057 R11: ffff888117511d00 R12: ffff888117598000
R13: 0000000000000001 R14: ffffffffc0408e10 R15: ffff888117599970
FS: 00007f15453f2040(0000) GS:ffff8881fd852000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffffc0408de6 CR3: 000000010b832005 CR4: 0000000000770ef0
PKRU: 55555554
Kernel panic - not syncing: Fatal exception
Kernel Offset: disabled
Rebooting in 1 seconds..
Fixes:
|
||
|
|
b4a00dedc5 |
Bluetooth: ISO: Hold the listener during disconnect notification
An ISO listener must remain alive until a queued child's disconnect
notification completes. bt_accept_enqueue() retains only the child and
stores a raw parent pointer; iso_conn_ready() drops its temporary
listener reference after setup. iso_chan_del() saves that pointer,
unlinks the child and then calls parent->sk_data_ready() without holding
a listener reference.
With an incoming CIS child still queued, disconnect and listener release
can proceed in this order:
HCI disconnect Listener release
iso_conn_del(): lock child
iso_chan_del(): save parent
bt_accept_unlink(child)
iso_sock_cleanup_listen():
drain empty accept queue
iso_sock_release():
orphan and kill listener
final sock_put(listener)
parent->sk_data_ready(parent)
After unlink, listener cleanup no longer has to take the child socket
lock. The listener can therefore be freed before iso_chan_del() reads
sk_data_ready, causing a use-after-free.
Take a temporary parent reference before bt_accept_unlink() and drop it
after the notification. The child lock excludes accept dequeue while the
child is still queued, so listener cleanup cannot complete before
sock_hold(). The reference then keeps the listener alive across unlink
and through the callback without changing lock order.
KASAN report as below:
==================================================================
BUG: KASAN: slab-use-after-free in iso_chan_del+0x302/0x320
Read of size 8 at addr ffff888105ca2188 by task kworker/2:1/50
CPU: 2 UID: 0 PID: 50 Comm: kworker/2:1 Not tainted
7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy)
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps
fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: events iso_fixture_disconnect_work
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
? iso_chan_del+0x302/0x320
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20d/0x410
? iso_chan_del+0x302/0x320
kasan_report+0xe0/0x110
? iso_chan_del+0x302/0x320
iso_chan_del+0x302/0x320
iso_conn_del+0x19d/0x3c0
? __pfx_iso_disconn_cfm+0x10/0x10
iso_disconn_cfm+0x78/0x120
hci_disconn_complete_evt+0x319/0xa30
? find_held_lock+0x2b/0x80
hci_test_iso_disconn_event+0x85/0xb0
? __pfx_hci_test_iso_disconn_event+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? _raw_read_unlock+0x23/0x40
? srso_alias_return_thunk+0x5/0xfbef5
? __hci_dev_get+0x15d/0x280
iso_fixture_disconnect_work+0x67/0x290
process_one_work+0x908/0x19c0
? __pfx_process_one_work+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? lock_is_held_type+0x8f/0x100
? srso_alias_return_thunk+0x5/0xfbef5
worker_thread+0x65c/0xe40
? srso_alias_return_thunk+0x5/0xfbef5
? __kthread_parkme+0x175/0x220
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_worker_thread+0x10/0x10
kthread+0x34f/0x460
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_kthread+0x10/0x10
ret_from_fork+0x659/0x940
? __pfx_ret_from_fork+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __switch_to+0x74f/0xf80
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Allocated by task 521:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0xaa/0xb0
__kmalloc_noprof+0x2d7/0x770
sk_prot_alloc+0x13e/0x260
sk_alloc+0x37/0xb40
bt_sock_alloc+0x40/0x3b0
iso_sock_alloc.constprop.0+0x3a/0x360
iso_sock_create+0xc7/0x160
bt_sock_create+0x171/0x330
__sock_create+0x2c4/0x730
__sys_socket+0x141/0x210
__x64_sys_socket+0x77/0xc0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 521:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
kfree+0x307/0x580
__sk_destruct+0x64f/0x790
sk_destruct+0xb3/0xd0
__sk_free+0xdd/0x370
sk_free+0x51/0x80
iso_sock_release+0x46d/0x5b0
__sock_release+0xb8/0x270
sock_close+0x21/0x30
__fput+0x39f/0xa60
task_work_run+0x144/0x230
do_exit+0x834/0x2830
do_group_exit+0xc7/0x280
get_signal+0x20a9/0x2400
arch_do_signal_or_restart+0x94/0x6f0
exit_to_user_mode_loop+0xcf/0x570
do_syscall_64+0x4f0/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff888105ca2000
which
belongs to the cache kmalloc-2k of size
2048
The buggy address is located 392 bytes inside of
freed
2048-byte region [ffff888105ca2000,
ffff888105ca2800)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000
index:0xffff888105ca5000 pfn:0x105ca0
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x200000000000240(workingset|head|node=0|zone=2)
page_type: f5(slab)
raw: 0200000000000240 ffff888100042f00 ffffea00042cd010
ffffea00042c9210
raw: ffff888105ca5000 0000000000080005 00000000f5000000
0000000000000000
head: 0200000000000240 ffff888100042f00 ffffea00042cd010
ffffea00042c9210
head: ffff888105ca5000 0000000000080005 00000000f5000000
0000000000000000
head: 0200000000000003 fffffffffffffe01 00000000ffffffff
00000000ffffffff
head: ffff888105ca1000 0000000000000000 00000000ffffffff
0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff888105ca2080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888105ca2100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff888105ca2180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff888105ca2200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888105ca2280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
Fixes:
|
||
|
|
6d91353f6d |
Bluetooth: hci_sync: Serialize devcoredump reset during device open
An ACTIVE devcoredump's buffer cursors must remain valid from the
packet handler's state check through its copy. hci_devcd_rx() holds
hdev->lock across that interval, and hci_devcd_reset() requires the
same lock. However, hci_dev_open_sync() invokes reset without taking
it.
A registered VHCI controller can collect a dump through its debugfs
interface while the controller is down. If a successful open overlaps
with handling a nonempty dump packet, reset can run after the receiver's
ACTIVE check and before its copy:
hci_devcd_rx() hci_dev_open_sync()
dequeue nonempty skb
hci_dev_lock(hdev)
handler observes ACTIVE
hdev->open(hdev) succeeds
hci_devcd_reset(hdev)
dump.tail = NULL
dump.state = IDLE
hci_devcd_copy()
compare against old dump.end
memcpy(NULL, ..., skb->len)
hci_dev_unlock(hdev)
Reset leaves dump.end pointing at the old buffer and purges only queued
packets, so it cannot discard the skb already dequeued by the receiver.
The bounds check can pass with a NULL tail, leading to a nonempty copy
to address zero. KASAN reported a 24-byte NULL write in hci_devcd_rx().
Take hdev->lock around the open-time reset. The receiver then finishes
its state check and copy using valid cursors before reset, or observes
IDLE after reset and skips the copy.
KASAN report as below:
BUG: KASAN: null-ptr-deref in hci_devcd_rx+0x5d5/0x1a80
Write of size 24 at addr 0000000000000000 by task kworker/u17:0/496
CPU: 0 UID: 0 PID: 496 Comm: kworker/u17:0 Not tainted
7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy)
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps
fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: hci0 hci_devcd_rx
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
kasan_report+0xe0/0x110
? hci_devcd_rx+0x5d5/0x1a80
kasan_check_range+0x105/0x1b0
__asan_memcpy+0x3c/0x60
hci_devcd_rx+0x5d5/0x1a80
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_hci_devcd_rx+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? lock_release+0xc8/0x280
? srso_alias_return_thunk+0x5/0xfbef5
process_one_work+0x908/0x19c0
? __pfx_process_one_work+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? lock_is_held_type+0x8f/0x100
? srso_alias_return_thunk+0x5/0xfbef5
worker_thread+0x65c/0xe40
? __pfx_worker_thread+0x10/0x10
kthread+0x34f/0x460
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_kthread+0x10/0x10
ret_from_fork+0x659/0x940
? __pfx_ret_from_fork+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __switch_to+0x74f/0xf80
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
==================================================================
Disabling lock debugging due to kernel taint
Fixes:
|
||
|
|
817cbcab91 |
Bluetooth: hci_core: Keep RCU protection through LTK filtering
The LTK selected by hci_find_ltk() must remain allocated while its
value is checked against the blocked-key list. The finder releases RCU
before passing k->val to hci_is_blocked_key(). The helper's own RCU
section protects the blocked-key list, but the selected LTK may already
have been reclaimed before that section starts.
An LE ATT socket security request can reach smp_ltk_encrypt() without
holding hdev->lock. With a matching stored LTK and an LTK-type
blocked-key entry present, a concurrent MGMT_OP_LOAD_LONG_TERM_KEYS can
remove the selected LTK in the following order:
Socket security Management / RCU reclamation
hci_find_ltk()
rcu_read_lock()
select k
rcu_read_unlock()
load_long_term_keys()
hci_dev_lock(hdev)
hci_smp_ltks_clear(hdev)
list_del_rcu(&k->list)
kfree_rcu(k, rcu)
grace period ends; k is freed
hci_is_blocked_key(..., k->val)
memcmp(b->val, val, ...)
The final comparison reads freed LTK bytes. Entering a new RCU section
in hci_is_blocked_key() cannot protect a pointer obtained before the
completed grace period.
Keep the finder's RCU read-side section active through the blocked-key
comparison and the warning that reads k->bdaddr. Release it before
returning on either matched-key path. This delays reclamation until the
finder has finished using the selected record, following the existing
IRK lookup pattern.
KFENCE report as below:
==================================================================
BUG: KFENCE: use-after-free read in hci_is_blocked_key+0xdf/0x240
Use-after-free read at 0x00000000b9ee38e4 (in kfence-#249):
hci_is_blocked_key+0xdf/0x240
blocked_key_wrapper+0xc5/0x140 [pmbd_ltk_probe]
hci_find_ltk+0x1aa/0x3e0
smp_ltk_encrypt.isra.0+0xad/0x340
smp_conn_security+0x3b8/0x8c0
l2cap_sock_setsockopt+0x1c4b/0x2270
do_sock_setsockopt+0x1fb/0x430
__sys_setsockopt+0x106/0x180
__x64_sys_setsockopt+0xc2/0x160
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
kfence-#249: 0x00000000121f2ad9-0x000000005b5bfb3d, size=72, cache=kmalloc-96
allocated by task 495 on cpu 0 at 36.722380s (2.603973s ago):
hci_add_ltk+0x1f5/0x3a0
load_long_term_keys+0x6d0/0x860
hci_sock_sendmsg+0x128b/0x22e0
__sys_sendto+0x425/0x470
__x64_sys_sendto+0xe5/0x1c0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
freed by task 533 on cpu 0 at 36.993097s (2.339769s ago):
__rcu_free_sheaf_prepare+0x261/0x2a0
rcu_free_sheaf+0x1f/0xe0
rcu_core+0x661/0x1d10
handle_softirqs+0x201/0x930
__irq_exit_rcu+0x110/0x1e0
irq_exit_rcu+0xe/0x20
sysvec_apic_timer_interrupt+0x6c/0x80
asm_sysvec_apic_timer_interrupt+0x1a/0x20
srso_alias_return_thunk+0x0/0xfbef5
__asan_memcpy+0x23/0x60
create_monitor_ctrl_event+0x1a2/0x460
mgmt_cmd_complete+0x2da/0x580
load_long_term_keys+0x741/0x860
hci_sock_sendmsg+0x128b/0x22e0
__sys_sendto+0x425/0x470
__x64_sys_sendto+0xe5/0x1c0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
CPU: 1 UID: 0 PID: 495 Comm: python3 Tainted: G O 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy)
Tainted: [O]=OOT_MODULE
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
==================================================================
Fixes:
|
||
|
|
8c27d7d06e |
Bluetooth: 6LoWPAN: Use RCU-safe device list removal
RCU readers of bt_6lowpan_devices must be able to follow an adapter's
forward link until their read-side critical section ends. The entries
are published with list_add_rcu(), but device_event() removes an entry
on NETDEV_UNREGISTER with list_del(), poisoning that link.
When an adapter is being unregistered and 6LoWPAN is enabled, a
6lowpan_control debugfs write with an existing LE L2CAP connection can
enter lookup_peer() after unregister's first synchronize_net(). If the
connection has no peer on that adapter, the reader must advance to the
next list entry. Neither RTNL nor devices_lock excludes this RCU reader.
The last peer's chan_close_cb() schedules delete_netdev(), which reaches
unregister_netdevice_many_notify() through unregister_dev() and
lowpan_unregister_netdev(). The following ordering is possible:
Unregister worker Control writer
----------------- --------------
synchronize_net() returns
lowpan_control_write()
lookup_peer(): rcu_read_lock()
reach adapter; no matching peer
device_event(): devices_lock
list_del(&entry->list)
spin_unlock(&devices_lock)
follow poisoned next link
read invalid adapter address
post-notifier synchronize_net()
waits for the reader
This invalid pointer access can fault in lookup_peer(). The first grace
period drains existing readers but permits new ones to start, and the
later grace period cannot prevent the intervening poisoned-link access.
Use list_del_rcu() under the existing devices_lock to preserve the
forward link for readers that already reached the adapter. The existing
post-notifier synchronize_net() waits for those readers before netdevice
teardown frees the private storage containing lowpan_btle_dev.
KASAN report as below:
[...]
[ 45.867526] Oops: general protection fault, probably for non-canonical address 0xfbd59c0000000023: 0000 [#1] SMP KASAN NOPTI
[ 45.869489] KASAN: maybe wild-memory-access in range [0xdead000000000118-0xdead00000000011f]
[ 45.870981] CPU: 1 UID: 0 PID: 646 Comm: sh Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #4 PREEMPT(lazy)
[ 45.872609] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 45.874380] RIP: 0010:lookup_peer+0x1ba/0x320
[ 45.875067] Code: 48 89 d9 ba 04 00 00 00 4c 89 fe bf a0 06 00 00 e8 2b e8 ad fb e9 56 ff ff ff e8 01 1e c3 fb 49 8d 7f 18 48 89 f8 48 c1 e8 03 <80> 3c 28 00 0f 85 4a 01 00 00 4d 8b 47 18 4c 89 f1 ba 04 00 00 00
[ 45.878206] RSP: 0018:ffff888114d67b90 EFLAGS: 00010212
[ 45.879106] RAX: 1bd5a00000000023 RBX: 0000000000000000 RCX: ffffffff85c1d19f
[ 45.880334] RDX: ffff88810dc35700 RSI: 0000000000000000 RDI: dead000000000118
[ 45.881455] RBP: dffffc0000000000 R08: 0000000000000001 R09: 0000000000000001
[ 45.882546] R10: ffffffff893d3057 R11: ffff88810dc35700 R12: ffff88810a690000
[ 45.883839] R13: ffff888115451038 R14: ffff88810a690000 R15: dead000000000100
[ 45.885186] FS: 00007fa889bac780(0000) GS:ffff8881fd852000(0000) knlGS:0000000000000000
[ 45.886539] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 45.887527] CR2: 00007ffe304f2f80 CR3: 0000000104f64005 CR4: 0000000000770ef0
[ 45.888687] PKRU: 55555554
[ 45.889183] Call Trace:
[ 45.889666] <TASK>
[ 45.890061] lowpan_control_write+0x445/0x9e0
[ 45.890854] ? __pfx_lowpan_control_write+0x10/0x10
[ 45.891738] ? srso_alias_return_thunk+0x5/0xfbef5
[ 45.892603] ? srso_alias_return_thunk+0x5/0xfbef5
[ 45.893383] ? __debugfs_file_get+0x1bd/0x7f0
[ 45.894057] ? srso_alias_return_thunk+0x5/0xfbef5
[ 45.894902] ? lock_acquire+0x17b/0x2f0
[ 45.895593] ? ksys_write+0x111/0x200
[ 45.896290] full_proxy_write+0x11f/0x180
[ 45.896991] vfs_write+0x25a/0x1010
[ 45.897642] ? __pfx_full_proxy_write+0x10/0x10
[ 45.898440] ? __pfx_vfs_write+0x10/0x10
[ 45.899178] ? lock_release+0x11f/0x280
[ 45.899855] ksys_write+0x111/0x200
[ 45.900435] ? __pfx_ksys_write+0x10/0x10
[ 45.901074] ? irqentry_exit+0xbe/0x820
[ 45.901722] ? srso_alias_return_thunk+0x5/0xfbef5
[ 45.902489] do_syscall_64+0x115/0x6a0
[ 45.903064] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 45.903813] RIP: 0033:0x7fa889c3e687
[ 45.904359] Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
[ 45.906981] RSP: 002b:00007ffd7651b960 EFLAGS: 00000202 ORIG_RAX: 0000000000000001
[ 45.908070] RAX: ffffffffffffffda RBX: 00007fa889bac780 RCX: 00007fa889c3e687
[ 45.909102] RDX: 000000000000001c RSI: 00005570f25e8d10 RDI: 0000000000000001
[ 45.910133] RBP: 00005570f25e8d10 R08: 0000000000000000 R09: 0000000000000000
[ 45.911162] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000001
[ 45.912190] R13: 000000000000001c R14: 0000000000000000 R15: 00005570f25e8a78
[ 45.913208] </TASK>
[ 45.913530] Modules linked in:
[ 45.914022] ---[ end trace 0000000000000000 ]---
[ 45.914709] RIP: 0010:lookup_peer+0x1ba/0x320
[ 45.915436] Code: 48 89 d9 ba 04 00 00 00 4c 89 fe bf a0 06 00 00 e8 2b e8 ad fb e9 56 ff ff ff e8 01 1e c3 fb 49 8d 7f 18 48 89 f8 48 c1 e8 03 <80> 3c 28 00 0f 85 4a 01 00 00 4d 8b 47 18 4c 89 f1 ba 04 00 00 00
[ 45.919191] RSP: 0018:ffff888114d67b90 EFLAGS: 00010212
[ 45.920046] RAX: 1bd5a00000000023 RBX: 0000000000000000 RCX: ffffffff85c1d19f
[ 45.921129] RDX: ffff88810dc35700 RSI: 0000000000000000 RDI: dead000000000118
[ 45.922553] RBP: dffffc0000000000 R08: 0000000000000001 R09: 0000000000000001
[ 45.923653] R10: ffffffff893d3057 R11: ffff88810dc35700 R12: ffff88810a690000
[ 45.925119] R13: ffff888115451038 R14: ffff88810a690000 R15: dead000000000100
[ 45.926180] FS: 00007fa889bac780(0000) GS:ffff8881fd852000(0000) knlGS:0000000000000000
[ 45.927817] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 45.928726] CR2: 00007ffe304f2f80 CR3: 0000000104f64005 CR4: 0000000000770ef0
[ 45.930069] PKRU: 55555554
[ 45.930456] Kernel panic - not syncing: Fatal exception
[ 45.931542] Kernel Offset: disabled
[ 45.932040] Rebooting in 1 seconds..
Fixes:
|
||
|
|
f7f0d0a9eb |
Bluetooth: MGMT: Fix leaking instance on Add Extended Advertising Parameters
If queueing the command fails the instance is never removed, despite it
having already been added or modified by hci_add_adv_instance, so remove
it as it is done by add_ext_adv_params_complete on failure, signaling
it has been removed if it was previously added.
Fixes:
|
||
|
|
5548fb51aa |
Bluetooth: MGMT: Fix pending state of instances added without HCI traffic
When Add Advertising completes without HCI communication, e.g. when the
device is not powered or the instance is overridden by Global
Advertising, the instance is left marked as pending, so a subsequent
failure in add_adv_complete would remove it despite it having been
successfully added.
Fix this by clearing the pending state before completing the command.
Fixes:
|
||
|
|
1bfecdbd03 |
Bluetooth: HCI: Fix tracking of instances sharing handle 0x00
When the controller supports a single advertising set, instance 1 uses
handle 0x00 which is the same handle used by instance 0 (Global
Advertising), but hci_cc_le_set_ext_adv_enable would lookup the instance
using the handle as instance identifier, marking instance 0 as
enabled/disabled instead of instance 1, leaving its state out of sync.
Fix this by matching instances by handle and, for handle 0x00, using
hdev->cur_adv_instance, now set when enabling an instance, to determine
which instance owns the set. Also disable the instance sharing the
advertising set of instance 0 before overriding it.
Fixes:
|
||
|
|
0ad48c88a2 |
Bluetooth: MGMT: Fix advertising instances with Global Advertising
Global Advertising, enabled with MGMT_OP_SET_ADVERTISING, uses instance
0 and with extended advertising it has its own advertising set, but
instances were still being treated as if they shared the same set:
- Add Advertising and Add Extended Advertising Data would return
success without ever enabling the instance.
- Removing the last instance would disable all advertising sets,
stopping Global Advertising while leaving its setting enabled.
- Disabling Global Advertising would disable all sets, including
active instances.
Fix this by only overriding instances that share the advertising set of
Global Advertising, and by tracking HCI_LE_ADV_0 rather than HCI_LE_ADV
to determine the state of Global Advertising.
Fixes:
|
||
|
|
3d9526b171 |
Bluetooth: make hdev->adv_instance_timeout a boolean
Mesh uses millisecond time units for advertisements instead of seconds as normally. These values go to hdev->adv_instance_timeout, which then has mixed units. hdev->adv_instance_timeout is however only used as a true/false flag. Make hdev->adv_instance_timeout boolean flag, to avoid possible future problems with its mixed-units values. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
8a8d51eeed |
Bluetooth: hci_sync: fix mesh adv timeout units
Mesh adv instance timeout and duration are in milliseconds, see
mesh_send_sync, hci_add_adv_instance. hci_schedule_adv_instance_sync()
and hci_enable_ext_advertising_sync() ignore this, and scale the timeout
wrong.
Fix for mesh instances by using msecs_to_jiffies() in
hci_schedule_adv_instance_sync and fixing the scaling in
hci_enable_ext_advertising_sync.
Fixes BlueZ "Mesh - Send cancel" test failures.
Fixes:
|
||
|
|
1b723bd294 |
Bluetooth: MGMT: Add management security level changed event
Add an event on device security level or encryption type change to let user space know which level is currently in use. Reset security level to 0 on disconnection so further connections will correctly report security level changes. This will be used for BlueZ qualification automation. Assisted-by: GPT:GPT-5.3-Codex Assisted-by: Copilot:claude-sonnet-5 Signed-off-by: Frédéric Danis <frederic.danis@collabora.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
c4154fc347 |
Bluetooth: use assign_bit() where applicable
Convert open-coded if/else with set_bit/clear_bit the assign_bit API.
Done with Coccinelle semantic patch:
// set_bit -> clear_bit => assign_bit
@@
expression cond, bit, addr;
@@
-if (cond)
- set_bit(bit, addr);
-else
- clear_bit(bit, addr);
+assign_bit(bit, addr, cond);
@@
expression cond, bit, addr;
@@
-if (cond)
- clear_bit(bit, addr);
-else
- set_bit(bit, addr);
+assign_bit(bit, addr, !cond);
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
||
|
|
366cdec7fe |
Bluetooth: Add generic support for vendor packets
The virtual HCI_VENDOR_PKT (0xff) has been defined but never used by
the BT core. Now, there is a requirement to implement it, as follows:
For Qualcomm multi-subsystem BT chips, the transport wire carries both
BT-HCI and PERI-HCI packets, where PERI is a subsystem in the chip, take
the upcoming QCC2072 as an example:
Packet type BT-HCI indicator PERI-HCI indicator
-----------------------------------------------------------------
CMD (Host -> Controller) 0x01 0x31
ACL Data (bidirectional) 0x02 0x32
EVENT (Controller -> Host) 0x04 0x34
There are also BT ACL packets with vendor-reserved handles found in
existing device drivers, as shown below:
+--------+--------+---------------------------+
| Vendor | Handle | Purpose |
+--------+--------+---------------------------+
| QCOM | 0xEDD | Firmware coredump |
| | 0xEDC | Firmware enhanced logging |
+--------+--------+---------------------------+
| MTK | 0xFC6F | Firmware coredump |
| | 0x05FF | Firmware debug logging 1 |
| | 0x05FE | Firmware debug logging 2 |
+--------+--------+---------------------------+
| NXP | 0xFFF | Firmware coredump |
+--------+--------+---------------------------+
Implement HCI_VENDOR_PKT to generically support such vendor packets,
which don't follow BT SIG's vendor-extension framework:
- Log them in btmon as they appear on the wire.
- Add hdev->recv_vendor_pkt() to handle them in hci_rx_work().
- Add hci_send_vendor_frame() to send them to the device driver.
- Allow them to flow over HCI_CHANNEL_USER, nested inside HCI_VENDOR_PKT.
Also solve the same issues that the commit below fixes for
HCI_EV_VENDOR, which follows BT SIG's vendor-extension framework:
commit
|
||
|
|
51589ddae3 |
Bluetooth: hci_event: Use 252 as max CC event payload length in hci_cc_table[]
hci_cc_func() validates skb->len against cc->max_len from the entry in hci_cc_table[], But By then, the HCI event and CC headers have already been stripped by skb_pull(). So the max CC payload is 252, but hci_cc_table[] still uses HCI_MAX_EVENT_SIZE (260) for it, which is imprecise. Fix by defining HCI_MAX_CC_PLEN (252) and using it instead. Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
9822887f0d |
Bluetooth: hci_event: Use 254 as max LE Meta subevent payload length in hci_le_ev_table[]
hci_le_meta_evt() validates skb->len against subev->max_len from the entry in hci_le_ev_table[], By then, the HCI event header and LE Meta subevent header have already been stripped by skb_pull(), So the max LE Meta subevent payload is 254, but hci_le_ev_table[] still uses HCI_MAX_EVENT_SIZE (260) for it, which is imprecise. Fix by defining HCI_MAX_LE_SUBEVT_PLEN (254) and using it instead. Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
c930a69fec |
Bluetooth: SMP: Zeroize raw key data on the stack in smp_e()
smp_e() already clears the AES key in its "struct aes_enckey aes" on the stack before leaving the function - but the very same information is also available as raw key data in the tmp[] array, so this should get cleared, too. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
9cc144d95e |
Bluetooth: bnep: linearize skb before sending
kernel_sendmsg expects contiguous data. Linearize the skb in the bnep_session() loop, before bnep_tx_frame builds its kvec, so it is not split across non-linear pages. Drop the dead block and FIXME. Signed-off-by: Adriano Cordova <adrianox@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
3889a5fcd0 |
Bluetooth: forget a peer's RPA once it advertises its identity address
hci_connect_le() dials the RPA cached in the peer's IRK whenever one is set, on the assumption that a peer holding an IRK is on air with a resolvable private address. A peer that stops using privacy breaks that assumption: it advertises its identity address, the cached RPA keeps the value it had before the change, and the host aims at an address the peer has abandoned. Nothing clears the cache. hci_find_irk_by_rpa() refreshes irk->rpa each time an advertisement resolves, so it tracks rotation, but a peer that stops sending RPAs stops producing the reports that would update it, and the stale address then survives until the adapter is powered off. On the path that creates the connection object this is currently masked: __hci_conn_add() resolves the cached RPA back to the identity address, so that is what goes on air. It is not masked on the reuse branch, which copies the swapped address straight into an existing conn->dst, and the next patch removes the conversion for the case where the controller cannot translate an identity address, so the stale RPA would be dialled there too. Clear the cached RPA when the peer is seen on its identity address. hci_find_irk_by_addr() only matches public and static random addresses, so an unresolved RPA belonging to some other device cannot reach this path. Assisted-by: Claude:claude-opus-5 Signed-off-by: Radek Podgorny <radek@podgorny.cz> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
5299db91df |
Bluetooth: Move H:4 reassembly into the Bluetooth core
h4_recv_buf() is currently implemented in hci_h4.c which is only built as part of the hci_uart module, and only when CONFIG_BT_HCIUART_H4 is enabled. That makes the H:4 reassembly logic unusable by drivers which do not depend on hci_uart, e.g. btusb which needs it to implement Bulk Serialization Mode. Move the transport agnostic part into the Bluetooth core as h4_recv_skb(), which takes a struct hci_dev instead of a struct hci_uart, along with struct h4_recv_pkt and the H4_RECV_* helpers, and keep h4_recv_buf() as a thin wrapper for the hci_uart protocols. Since every Bluetooth driver already depends on the bluetooth module this introduces no new module dependency and no new Kconfig symbol. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
86b55991d3 |
Bluetooth: L2CAP: refuse __l2cap_chan_add if chan already has conn
l2cap_chan may be linked to l2cap_conn at most once. This is assumed in
several places, eg l2cap_chan_del cleanup.
There is a TOCTOU race where the invariant is violated:
[Task 1] [Task 2]
l2cap_chan_connect l2cap_sock_bind
l2cap_chan_lock lock_sock
l2cap_state_change if (sk->sk_state != BT_OPEN)
chan->state = BT_CONNECT
l2cap_sock_state_change_cb chan->state = BT_BOUND
sk->sk_state = BT_BOUND
lock_sock <------------------ release_sock
sk->sk_state = BT_CONNECT
l2cap_sock_connect() does not check sk->sk_state, so since chan->state
is now BT_BOUND, subsequent connect() ends up with second
__l2cap_chan_add.
Explicitly document and check the invariant in __l2cap_chan_add with
WARN_ON_ONCE. The only callsite where it could be hit is
l2cap_chan_connect, so add pre-check there to avoid relying on
chan->state. chan->state read/write is not properly guarded currently so
there can be other TOCTOUC problems.
Add l2cap_lock_chan in l2cap_sock_bind() to guard chan->state write.
Fixes:
|
||
|
|
a0c672c410 |
Bluetooth: L2CAP: annotate locking for l2cap_ops callbacks
Annotate current locking context for l2cap_ops callbacks. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
0e4d951a2f |
Bluetooth: L2CAP: annotate locking for l2cap_chan_del()
Add context analysis annotations for chan->lock and chan->conn->lock involving l2cap_chan_del() usage. Add necessary annotations and related lockdep_assert_held to callers. Move struct l2cap_ops definition after struct l2cap_conn, so that the callbacks can be annotated. In l2cap_chan_close_unlocked() we consider chan->conn->lock as locked even if chan->conn == NULL, to avoid needing to define separate __l2cap_chan_close/del for this NULL case. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
dc1ddc65f0 |
Bluetooth: L2CAP: take lock for l2cap_chan_del in l2cap_ecred_rsp_defer
l2cap_ecred_rsp_defer() calls l2cap_chan_del without holding chan->lock, which ends up calling ops->teardown() with wrong lock context. Fix by taking chan->lock in l2cap_ecred_rsp_defer(). AB-BA deadlocks between sibling l2cap_chan are avoided here via requiring l2cap_conn::lock to serialize all nested l2cap_chan locking on same nesting level. In current code, there is no nested l2cap_chan locking on same nesting level, so we can add this new requirement. Also return early from __l2cap_ecred_conn_rsp_defer() if chan did not have FLAG_DEFER_SETUP, as then no RSP shall be sent for it, to make sure SMP channels are excluded. Also hold chan reference over l2cap_chan_del(), in case chan_l reference was the last. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
6098ed784e |
Bluetooth: L2CAP: remove conditional locking from l2cap_connect()
Context analysis does not understand conditional locking. Restructure l2cap_connect() by removing conditional locking at the cost of some code duplication, so that static analysis can see its content. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
b508a2a2d8 |
Bluetooth: L2CAP: hold chan in l2cap_ecred_conn_rsp()
l2cap_chan_del() calls l2cap_chan_put() to drop the conn->chan_l
reference. If this was the last reference, UAF follows.
l2cap_ecred_conn_rsp() iterates chan_l list and calls l2cap_chan_del()
on some members, without holding chan reference.
Fix by holding refcount while using chan after l2cap_chan_del().
Since orig is looked up by dcid provided by remote, it's also possible
orig == chan, so reference needs to be held also after orig use.
Fixes:
|
||
|
|
889dfdde79 |
Bluetooth: L2CAP: add annotations for l2cap_chan list locking
Add context analysis annotations for l2cap_conn::chan_l and chan_list locking. Add corresponding required annotations to accessors and callers. This is not complete chan_l annotation, l2cap_chan::list and l2cap_chan_del() locking is currently not fully correct, and needs separate fix + annotations. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
115e6a21c8 |
Bluetooth: L2CAP: hold l2cap_conn::lock in l2cap_connect_cfm()
l2cap_new_connection() -> __l2cap_chan_add() modifies
l2cap_conn::chan_l, which is guarded by l2cap_conn::lock. The lock is
not held in l2cap_connect_cfm().
Fix by holding conn->lock in l2cap_connect_cfm() to make the locking
systematic.
Fixes:
|
||
|
|
32d86e048d |
Bluetooth: L2CAP: hold conn->lock for __l2cap_ecred_conn_rsp_defer
__l2cap_ecred_conn_rsp_defer() > __l2cap_chan_list_id() accesses
conn->chan_l which is guarded by conn->lock. The lock fails to be held
when calling from l2cap_sock.c.
Fix by using l2cap_chan_conn_lock(), and taking the locks in required
order l2cap_conn::lock > l2cap_chan::lock > sk. Leave fast path with
sk->sk_state precheck. Move the L2CAP defer handling to
l2cap_sock_defer().
The code should also take l2cap_chan_lock() for sibling channels, but
that needs separate fix due to lock nesting.
Fixes:
|
||
|
|
df5175dfcf |
Bluetooth: 6lowpan: avoid concurrent peer_del() in bt_6lowpan_disconnect
bt_6lowpan_disconnect() looks up and accesses peer->chan, without
holding locks guaranteeing peer_del() cannot free the peer concurrently.
Take devices_lock to ensure peer can be dereferenced safely.
Fixes:
|