mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
master
5836 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
801fb950ca |
Bluetooth: RFCOMM: avoid socket lock inversion in listener cleanup
rfcomm_sock_cleanup_listen() closes unaccepted child sockets through
rfcomm_sock_close(), which takes the child socket lock before
rfcomm_dlc_close() acquires rfcomm_mutex. The RFCOMM worker takes these
locks in reverse order while handling connections and DLC state changes,
so lockdep reports a possible deadlock.
Close dequeued children without taking their socket lock. The accept queue
owns a reference to each child, and bt_accept_dequeue() locks the child
while unlinking it and clearing its parent pointer.
Dropping the child lock makes it important to prevent a concurrent
rfcomm_connect_ind() from enqueueing a new child after cleanup observes an
empty queue. Set a listening socket to BT_CLOSED while its lock is still
held, before dropping the lock and draining the queue. The state check in
rfcomm_connect_ind() then rejects new children once cleanup starts.
Reported-by: syzbot+0cece8fa7d83523f47a3@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=0cece8fa7d83523f47a3
Fixes:
|
||
|
|
555cd2bd86 |
Bluetooth: keep dst_type with dst when reusing an LE connection
hci_connect_le() swaps the caller's identity address for the peer's
cached RPA when one is known, and stamps the matching
ADDR_LE_DEV_RANDOM on the local dst_type. On the conn-reuse path only
the address is copied into the connection:
if (conn) {
bacpy(&conn->dst, dst);
so conn->dst ends up holding an RPA while conn->dst_type still names the
identity it was resolved from, and hci_le_create_conn_sync() puts that
pair on air unchanged. An RPA declared as a public address is not
something any peer can answer.
Measured on a CYW43438 against a peer advertising an RPA the host holds
the IRK for, connecting to the identity address over a raw L2CAP socket.
The first attempt creates the connection, the second takes the reuse
path:
LE Create Connection 3C:78:95:78:37:C3 type public
LE Create Connection 5B:75:A2:26:D6:18 type public
LE Connection Complete: Unknown Connection Identifier (0x02)
The second address is the peer's RPA. btmon annotates it with an OUI
lookup rather than "(Resolvable)" precisely because the command declares
it public; the same bit pattern annotates as resolvable once the type is
right.
The mistyped pair is also why nothing downstream repairs it.
hci_bdaddr_is_rpa() tests the type before the address, so an RPA carrying
a public type is not recognised as one, and hci_find_irk_by_addr() then
searches for an identity address that does not match it either.
Copy the type along with the address.
The assignment used to be unconditional just below this block and covered
both paths; it moved into hci_conn_add_unset(), which the reuse path does
not go through.
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
296e7f3c50 |
Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync
A BIS connection is matched to its parent socket by looking for a
socket in BT_LISTEN state with the same BIG handle:
iso_conn_ready()
if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags))
parent = iso_get_sock(hdev, &hcon->src, &hcon->dst,
BT_LISTEN, iso_match_big_hcon, hcon);
The socket was only moved to BT_LISTEN after iso_conn_big_sync()
returned, while the LE BIG Create Sync command has already been queued
by then. If the BIG sync is established before the state is updated,
which is easy to hit with an emulated controller as the command may
complete in a few hundred microseconds, no parent is found and the BIS
connections are never notified to the listening socket.
The user space is then left waiting for connections that never arrive,
e.g. bluetoothd never completes a MediaTransport1.Acquire of a
Broadcast Sink transport.
Move the socket to BT_LISTEN before requesting the BIG sync, so the
state is visible by the time the command is queued, and restore the
previous state if the request could not be started. Since the socket is
briefly visible as a listening socket, child sockets may have been
queued in the meantime, so drain the accept queue before restoring the
state: the cleanup paths of BT_CONNECT2/BT_CONNECTED don't do it and the
children would be left with a dangling parent pointer.
Fixes:
|
||
|
|
ca18ee413a |
Bluetooth: ISO: Fix parent socket leak in iso_conn_ready()
iso_get_sock() returns the parent socket with a reference held, which is
dropped by sock_put() once the child socket has been set up. The error
path taken when iso_sock_alloc() fails only calls release_sock() and
returns, leaking the reference and thus the parent socket itself.
Drop the reference on that path as well.
Fixes:
|
||
|
|
9a10987a2f |
Bluetooth: hci_sync: Serialize local codec list cleanup
hci_dev_close_sync() clears hdev->local_codecs after releasing hdev->lock.
Codec list additions and both traversals in sco_sock_getsockopt() use that
lock, but the close path does not. A close and BT_CODEC query can therefore
interleave as follows:
hci_dev_close_sync() sco_sock_getsockopt()
hci_dev_lock()
fetch codec entry
hci_codec_list_clear()
kfree(entry)
read entry->id
The reader then accesses an entry which the close path has freed. KASAN
reported:
BUG: KASAN: slab-use-after-free in sco_sock_getsockopt+0xfa0/0xfe0
Read of size 1 at addr ffff8881001c3450
Call Trace:
sco_sock_getsockopt+0xfa0/0xfe0
do_sock_getsockopt+0x537/0x7b0
__sys_getsockopt+0xf2/0x170
Allocated by task 92:
hci_codec_list_add.isra.0+0x2c/0x440
hci_read_codec_capabilities+0x224/0x590
hci_read_supported_codecs+0x2c2/0x640
Freed by task 92:
kfree+0x131/0x3c0
hci_codec_list_clear+0xd8/0x160
hci_dev_close_sync+0x92a/0xfa0
Take hdev->lock around the clear operation at its existing point in the
close path. This makes the clear wait for active readers and prevents a new
traversal until the list is empty without changing teardown ordering.
Fixes:
|
||
|
|
d0795cfd6f |
Bluetooth: hci_codec: validate vendor codec count length
The Read Local Supported Codecs parsers consume the variable-sized standard codec array before parsing the vendor codec count. Although the initial reply-size check includes a vendor count byte in the fixed layout, it does not guarantee that the byte remains after the standard codec array. If a controller reply ends immediately after that array, calculating the vendor codec array size reads vnd_codecs->num beyond the skb data. Use skb_pull_data() to validate and consume each codec header before using its count in both command variants. Fixes: |
||
|
|
4914c49989 |
Bluetooth: put the peer's on-air address on air when we cannot resolve
An identity address only reaches a peer that is advertising an RPA if the
controller resolves it on our behalf. Where it cannot, the host has to put
the peer's on-air address on air itself.
hci_connect_le() still swaps the caller's identity address for the peer's
cached RPA before creating the connection, but __hci_conn_add() resolves
the RPA back to the identity address when it stores it, so the identity is
what goes out. Storing the identity is right when the controller
translates it on the way to the radio; without LL Privacy, or with this
peer absent from the resolving list, nothing does.
A peer advertising an RPA cannot answer its identity address, so the
attempt burns a full create-connection timeout. That is not merely a slow
connect: a controller without extended scanning cannot scan while it is
initiating, so every dead attempt also takes the scanner off the air for
the whole timeout.
Measured on a CYW43438, which reports neither LL Privacy nor extended
advertising (LE features 3f 00 00 08 00 00 00 00), against a peer
advertising a resolvable private address the host holds the IRK for, with
the connection requested on the peer's identity address:
before: LE Create Connection to the identity address, public type
1.61s -> 22.07s, then LE Create Connection Cancel
LE Connection Complete: Unknown Connection Identifier (0x02)
after: LE Create Connection to the peer's RPA, random type
LE Connection Complete: Success
Advertising reports reaching the host per second, same window, same five
unrelated devices on the adapter:
before 1s:2 [nothing from 2s through 21s] 22s:5 23s:3
after 0s:11 1s:5 2s:2 3s:5 4s:3 5s:4 ... 21s:2 22s:1 23s:2
One dead connect costs twenty seconds of scanning for every device on the
adapter, not just the one being dialled.
Keep the RPA in conn->dst unless the controller will translate the
identity address: address resolution enabled and the peer's identity
actually programmed into the resolving list. Testing ll_privacy_capable()
alone would not be enough: it reports the feature bit, not whether
resolution is switched on and not whether this peer is in the list.
Resolution is cleared with the other volatile flags on power-off and
switched off again while suspend pauses scanning, and a peer's IRK is only
programmed along the accept list path, so a direct-connect target, a peer
without HCI_CONN_FLAG_ADDRESS_RESOLUTION, and one that did not fit in a
full list are all absent from it.
With the peer programmed, the identity address stays in conn->dst and the
controller translates it: measured on an Intel controller, the host dials
the identity and LE Enhanced Connection Complete reports Resolved Public
with the peer's RPA in the separate peer resolvable private address field.
With the peer absent from the list the same setup dials the RPA itself.
Everything downstream already copes with an RPA in conn->dst: it is what
every outgoing LE connection stored before
|
||
|
|
d236517c26 |
Bluetooth: coredump: Quiesce dump work on unregister
hci_devcd_handle_pkt_init() arms dump_timeout and coredump producers
queue dump_rx without holding an hdev reference. Unregister leaves both
works live, so disconnecting during an active dump lets them access hdev
after hci_release_dev() frees it.
Shut down coredump processing during unregister. Close the producer gate
under dump_q.lock before disabling both works, then free the active buffer
and queued packets under hci_dev_lock. Serializing the gate with enqueue
prevents controller-specific workers from adding packets after the final
purge.
Fixes:
|
||
|
|
6610c6fe4b |
Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained
hci_send_acl(), hci_send_sco() and hci_send_iso() queue hdev->tx_work
unconditionally. They can run from the L2CAP/SCO/ISO socket send path
while hci_dev_close_sync() is draining hdev->workqueue (HCIDEVDOWN
racing with a socket write). Since that queue_work() is not chained
work from the tx_work worker itself, __queue_work() sees the queue
marked __WQ_DRAINING, warns "cannot queue %ps on wq %s", and drops
the work:
WARNING: CPU: 1 PID: 5985 at kernel/workqueue.c:2352 __queue_work
Call Trace:
queue_work_on
l2cap_chan_send
l2cap_sock_sendmsg
...
hci_dev_close_sync() already sets HCI_CMD_DRAIN_WORKQUEUE before
draining, but only hci_cmd_work() and handle_cmd_cnt_and_timer()
check it before queuing. Route the tx_work producers through the
same guard via a shared hci_sched_tx() helper.
Fixes:
|
||
|
|
e824176679 |
Bluetooth: eir: validate service data length before reading UUID
eir_get_service_data() reads a 16-bit UUID from the service data using
get_unaligned_le16() without first checking that the data is long enough
to hold a UUID16 (2 bytes). If a malformed EIR entry has a service data
field with only 1 byte of payload (field_len=2), eir_get_data() returns
dlen=1. The subsequent get_unaligned_le16() then reads 1 byte past the
field boundary.
Additionally, if the corrupted UUID happens to match, the length
calculation "dlen - 2" underflows to SIZE_MAX since dlen is size_t.
Current callers either pass NULL for the length parameter or bounds-check
the returned length, but future callers may not.
Add a check that dlen >= sizeof(u16) and skip fields that are too short
to contain a valid UUID16.
Fixes:
|
||
|
|
7844502343 |
Nothing too exciting, usual stream of fixes.
Including fixes from Netfilter, Bluetooth and WPAN.
Current release - new code bugs:
- Bluetooth: hci_sync: fix not setting CE length properly
- eth: enic: match mailbox replies to request numbers
Previous releases - regressions:
- tunnels: drop stale dst when building an ICMP error for PMTUD
- ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings()
(bug in the rtnl_lock -> RCU conversion)
- eth: bnxt_en: fix crashes on Thor2 due to OOB coalescing buffer accesses
- eth: bnxt_en: prevent queue stop with deferred completions
Previous releases - always broken:
- eth: ice: don't dereference pointers from TP_printk()
- eth: fix OOB writes on ethtool flow rule dump in 3 drivers
- eth: mlx5: fix FEC configuration with RS_544_514_INTERLEAVED_QUAD
- dsa: tag_brcm: legacy FCS: request needed tailroom
Misc:
- net: cap tx_queue_len at S16_MAX to prevent oversized ring alloc
- ipv6: flowlabel: cap duplicate leases per socket
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmqi3pQACgkQMUZtbf5S
IrvUIg//X9nIxY2F5PzJ5jD9p5ccXrQMLe7kT5AW2tP5PDC8d5PIv4Q5XzFKQPU7
XElAUKvBxmofwU2lqILYGi8AeUpqHZtKPY7XzKeqd6i72KOD6mGzzYNijqttBXcM
vFVtIeKExXjAwvNc2as1SeXVEAAAkBtrCFuMNHMq0C56yK4md/XVkCDHaJkomNit
geke1U8gut3rZddWKxp4WDbL8Wmx9yM0uDMBznO/+cwITObA0Hme3IgRndglzz7n
n4Ih+EG4tRrD3kUf6oePzKQ47cd+qnSVlVTCZUwB5E/HKqWJFXxSN4Sv+mez0sAS
rrI5hl+luNKUYrZ8/jiNlvajgAL4+AYpCKPDJbXrOW+z+x4BC2VYZBAHLoUr5ZAq
Z5OYU9SgD1oGntqkI8mAEiRTEu+4gjhIEhjENHEzqdjUogaBIp7MWwCrNBAnFWvs
2McmNfZZMVhxKpyYnndUStsVQySVPASb0CXeqTIO6PJsAp/HBjoMYKYKPhhwk0Gp
lE8zHjEnPVofRfXfT+oZnbS8is2nC9FjBy9ksIGcC7vyTOdPsoIBoB8JY0x/INRM
SOJvyxrdnVkMjiBejkdOa5X9HbD1cA/NVyzT2WEaZBGPmIqfNBgUIOxnXD4CShuy
9zX8qtHsUmmYxPteF30Uhfe0kyLQ9OnjUz2Bl++EruxpIE3+i48=
=f9J9
-----END PGP SIGNATURE-----
Merge tag 'net-7.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski:
"Nothing too exciting, usual stream of fixes. Including fixes from
Netfilter, Bluetooth and WPAN.
Current release - new code bugs:
- Bluetooth: hci_sync: fix not setting CE length properly
- eth: enic: match mailbox replies to request numbers
Previous releases - regressions:
- tunnels: drop stale dst when building an ICMP error for PMTUD
- ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings()
(bug in the rtnl_lock -> RCU conversion)
- eth: bnxt_en:
- fix crashes on Thor2 due to OOB coalescing buffer accesses
- prevent queue stop with deferred completions
Previous releases - always broken:
- eth:
- ice: don't dereference pointers from TP_printk()
- fix OOB writes on ethtool flow rule dump in 3 drivers
- mlx5: fix FEC configuration with RS_544_514_INTERLEAVED_QUAD
- dsa: tag_brcm: legacy FCS: request needed tailroom
Misc:
- net: cap tx_queue_len at S16_MAX to prevent oversized ring alloc
- ipv6: flowlabel: cap duplicate leases per socket"
* tag 'net-7.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (164 commits)
selftests: tc-testing: test action batch failure cleanup
net/sched: act_api: release all action references on NEWACTION failure
openvswitch: fix wrong flag value in get_ipv6_ext_hdrs()
ipmr: account multicast table and route memory
net: phy: dp83td510: handle the active-high LED polarity mode
net: macb: initialize PTP state before registering clock
net: hsr: enable promiscuous mode on interlink port with fwd offload
ipv6: fix fib6 walker UAF on seq stop
net: stmmac: fix TX descriptor availability check for TSO traffic
net/rds: fix tcp stream corruption with large pages
net: mana: restore the XDP program pointer when pre-allocation fails
net: phy: dp83867: handle the active-high LED polarity mode
octeontx2-af: fix PF/CGX debugfs PCI bus lookup
net: net_failover: Fix the deadlock in net_failover_slave_name_change()
net: phy: mediatek-ge: disable EEE on the MT7530 PHY
tcp: reject non zerocopy devmem tx
net: ethernet: mtk_eth_soc: populate lpi_interfaces to fix EEE support
net: dsa: mt7530: populate lpi_interfaces to fix EEE support
net: hinic: fix mailbox segment buffer overflow
net: sun4i-emac: fix missing of_node_put() for phy_node
...
|
||
|
|
9b851b09b3 |
Bluetooth: hci_sysfs: Fix NULL pointer dereference in device_del()
A NULL pointer dereference in klist_put() occurs when a child device (such as a BNEP network device in bnep_session) is concurrently being unregistered while hci_conn_del_sysfs() reparents child devices. This is caused by a race condition between hci_conn_del_sysfs() and concurrent child device unregistration (e.g. bnep_session calling unregister_netdev()). During device unregistration, device_del() snapshots a non-NULL parent pointer. Concurrently, hci_conn_del_sysfs() finds the child device using device_find_any_child() and calls device_move() to reparent it to NULL, which removes the node from its parent's klist and clears knode_parent. Subsequently, device_del() calls klist_del(&dev->p->knode_parent) using the stale parent snapshot, causing klist_put() to dereference knode_klist(n)->put on an already removed node, resulting in a NULL pointer dereference. This race was introduced by commit |
||
|
|
3621f78d43 |
Bluetooth: hci_sync: Fix not setting CE length properly
Both hci_le_set_def_rate_sync() and hci_le_conn_rate_request_sync() were
leaving Min_CE_Length and Max_CE_Length set to 0x0000, but the connection
event length recommended in requests by a Peripheral has a valid range of
0x0001 to 0x7CFF (Time = N * 125 us, Time Range: 0.125 ms to 3.999875 s),
so 0x0000 cannot be used.
Set both to the minimum valid value, which is safe since the Controller
is not required to use these values:
BLUETOOTH CORE SPECIFICATION Version 6.2 | Vol 4, Part E
7.8.157. LE Connection Rate Request command
7.8.158. LE Set Default Rate Parameters command
The Min_CE_Length and Max_CE_Length parameters provide the Controller
with the expected minimum and maximum length of the connection events.
The Controller is not required to use these values.
Fixes:
|
||
|
|
3a2c4d55e3 |
treewide: refresh kmalloc_obj() conversions
This is another run of the Coccinelle script for converting kmalloc() family of allocations to kmalloc_obj() via the existing rules in scripts/coccinelle/api/kmalloc_objs.cocci This catches both the set of kmalloc() uses added since the first kmalloc_obj() conversions in v7.0 and adds a large group missed in the first pass due to Coccinelle not interacting well with the cleanup.h scoped_...() family of macros[1]. I worked around this with spatch's "--macro-file" argument to a file with all the scoped_...() macros mapped to Coccinelle's YACFE_ITERATOR[2] as that was the closest viable control flow indicator I could find. Build tested allmodconfig on x86, arm64, arm, loongarch, mips, powerpc, riscv, and s390 with no new warnings. Link: https://lore.kernel.org/lkml/202609021314.8A9C0B8@keescook/ [1] Link: https://github.com/coccinelle/coccinelle/blob/master/standard.h [2] Signed-off-by: Kees Cook <kees+treewide@kernel.org> |
||
|
|
0d77683237 |
Bluetooth: L2CAP: clear FLAG_DEFER_SETUP only for same PID/PSM
l2cap_ecred_defer_connect() clears FLAG_DEFER_SETUP also for channels
with different PID/PSM, which will not be added to the same
ECRED_CONN_REQ in any case. Consequently, only one ECRED connection
group can work at a time although it appears intended they would be
separate for each PID/PSM combination.
Fix by clearing FLAG_DEFER_SETUP only for the connections that could be
added in the request. Retain test_bit(FLAG_DEFER_SETUP) before calling
get_peer_pid as it may be NULL otherwise.
Fixes:
|
||
|
|
56c2b5831d |
Bluetooth: L2CAP: fix out-of-bounds write in l2cap_ecred_connect
l2cap_chan_connect() tries to ensure there are no more than
L2CAP_ECRED_CONN_SCID_MAX pending ECRED channels, so they fit in the
same L2CAP_ECRED_CONN_REQ that l2cap_ecred_connect() constructs.
However, the check only counts deferred channels. If 6 L2CAP sockets
are connected at the same time in order DDDDND (D=deferred,
N=non-deferred), the last can bump the total to max+1. It results to
one __le16 written out of bounds of the scid array, and an invalid
ECRED_CONN_REQ being sent.
Fix by leaving room for the non-deferred pending ECRED channels in the
counting in l2cap_chan_connect(), so the limit can't be exceeded.
Move counting under same critical section where the channel is added.
Although race conditions involving this appear unreachable, it's easier
to see.
Also add WARN_ON_ONCE check in l2cap_ecred_defer_connect() to make this
less brittle.
Fixes:
|
||
|
|
4ef05db5b0 |
Bluetooth: L2CAP: fix chan mode for LE_CONN_REQ + EXT_FLOWCTL pchan
l2cap_new_connection() sets default value of channel mode to match the
parent channel. l2cap_le_connect_req() left this at the default, and
created L2CAP_MODE_EXT_FLOWCTL channels if listening pchan has that
mode. This causes FLAG_DEFER_SETUP channels to reply to
L2CAP_LE_CONN_REQ with L2CAP_ECRED_CONN_RSP, which is incorrect.
It can also result to stack OOB write (of l2cap_alloc_cid determined
values) in l2cap_ecred_rsp_defer(), as l2cap_le_connect_req() does not
limit maximum number of deferred channels or check for duplicate ident.
Fix by setting chan->mode correctly in l2cap_le_connect_req().
Also check channel mode in l2cap_ecred_rsp_defer(), and do WARN_ON_ONCE
instead of OOB write to make it less brittle.
Fixes:
|
||
|
|
57938bbdb9 |
Bluetooth: hci_core: Fix race condition during device registration
In hci_register_dev(), the power_on work item is queued to
hdev->req_workqueue before initializing hdev->adv_monitors_idr and
registering the MSFT extension via msft_register(). For devices marked with
quirks such as HCI_QUIRK_RAW_DEVICE, the HCI_UNCONFIGURED flag is set on
the device. When the power_on work item runs concurrently on another CPU,
hci_power_on() detects that the device is unconfigured and immediately
invokes hci_dev_do_close(), which calls msft_do_close().
Concurrently, msft_register() allocates the msft structure and exposes it
to hdev->msft_data prior to calling mutex_init(&msft->filter_lock). If
msft_do_close() executes while hdev->msft_data is already assigned but the
mutex has not yet been initialized, mutex_lock(&msft->filter_lock) operates
on an uninitialized mutex, triggering a DEBUG_LOCKS warning:
DEBUG_LOCKS_WARN_ON(lock->magic != lock)
WARNING: kernel/locking/mutex.c:625 at __mutex_lock_common
kernel/locking/mutex.c:625 [inline]
WARNING: kernel/locking/mutex.c:625 at __mutex_lock+0x12d8/0x1550
kernel/locking/mutex.c:821
...
Call Trace:
<TASK>
msft_do_close+0x308/0x7b0 net/bluetooth/msft.c:693
hci_dev_close_sync+0x86b/0x10a0 net/bluetooth/hci_sync.c:5522
hci_dev_do_close net/bluetooth/hci_core.c:499 [inline]
hci_power_on+0x32c/0x750 net/bluetooth/hci_core.c:937
process_one_work kernel/workqueue.c:3322 [inline]
process_scheduled_works+0xa8e/0x14e0 kernel/workqueue.c:3405
worker_thread+0x92d/0xe10 kernel/workqueue.c:3486
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Fix this by moving the queue_work() call in hci_register_dev() to after
idr_init(&hdev->adv_monitors_idr) and msft_register(hdev) so that device
structures and extensions are fully initialized before asynchronous tasks
can access them. Additionally, assign hdev->msft_data in msft_register()
only after mutex_init(&msft->filter_lock) has completed.
Fixes:
|
||
|
|
ebe6674292 |
Bluetooth: RFCOMM: serialize session teardown
rfcomm_kill_listener() walks session_list and deletes every session
without holding rfcomm_mutex, unlike the normal session processing and
connect error paths.
Under normal operation, an open RFCOMM socket pins rfcomm.ko, so
rfcomm_kill_listener() does not run concurrently with rfcomm_dlc_open().
However, forced module unload via delete_module(O_TRUNC) can stop
krfcommd while a failed connect is still unwinding.
connect task forced unload / krfcommd
------------ ------------------------
rfcomm_lock()
rfcomm_session_add()
delete_module("rfcomm", O_TRUNC)
rfcomm_kill_listener()
fetch session from session_list
kernel_connect() fails
rfcomm_session_del()
remove and free session
rfcomm_session_del(session)
The final call then reads the freed session and may corrupt the list.
KASAN reported with mdelay() to enlarge critical window:
BUG: KASAN: slab-use-after-free in rfcomm_run+0x3802/0x3f00 [rfcomm]
Read of size 8 at addr ffff888111058d40 by task krfcommd/79
Tainted: [R]=FORCED_RMMOD
Allocated by task 86:
rfcomm_session_add+0xa1/0x300 [rfcomm]
rfcomm_dlc_open+0x8b2/0xf30 [rfcomm]
rfcomm_sock_connect+0x34c/0x530 [rfcomm]
Freed by task 86:
kfree+0x121/0x3c0
rfcomm_dlc_open+0xab7/0xf30 [rfcomm]
rfcomm_sock_connect+0x34c/0x530 [rfcomm]
Hold rfcomm_mutex across the teardown traversal so every reachable
session_list walk uses the same serialization.
Reviewed-by: Ali Ahmet Memis <ali@iusegentoo.com>
Tested-by: Ali Ahmet Memis <ali@iusegentoo.com>
Reviewed-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
||
|
|
7e1e404720 |
Bluetooth: do not leak an hci_conn when a second LE connect is rejected
create_le_conn_complete() decides whether the failed connection is
still pending by comparing it against hci_lookup_le_connect(), which
returns the first LE connection in BT_CONNECT. That is the same
connection only while at most one is pending.
Two can be pending. Connections created on the passive scan path sit
in BT_CONNECT with HCI_CONN_SCANNING set and are invisible to
hci_lookup_le_connect() until hci_le_create_conn_sync() clears the
flag when their command is issued, so the -EBUSY guard in
hci_connect_le() does not prevent a second connection from being
queued while the first is still on the scan path. Whenever two
connections are in BT_CONNECT at once, the lookup may return one
connection while create_le_conn_complete() is reporting the failure
of the other; the early exit then drops the error and hci_conn_failed()
never runs on the connection that failed.
The controller also rejects a second HCI_OP_LE_CREATE_CONN issued
while another connection creation is still outstanding, per Core Spec
Vol 4, Part E. The spec calls for Command Disallowed there; the
bcm43438 observed here answers with an LMP/LL error code instead,
which bt_to_errno() maps to the -EPROTO (-71) in the log below.
The leaked connection stays in BT_CONNECT forever, and because
hci_connect_le() refuses to dial while hci_lookup_le_connect() finds
anything, every subsequent attempt to reach any peer fails with
-EBUSY and no command reaches the controller at all.
Seen on a bcm43438 with two BLE peers polled on the same interval
(state 5 is BT_CONNECT; both handles are UNSET ones, allocated from
the ida above HCI_CONN_HANDLE_MAX):
Bluetooth: hci1: Opcode 0x2013 failed: -71
# hcitool con
< LE 14:9C:EF:03:68:81 handle 3840 state 5 lm CENTRAL
< LE C4:D3:6A:8C:B5:38 handle 3841 state 5 lm CENTRAL
A btmon capture across the next ten minutes of connect attempts
contains no HCI_OP_LE_CREATE_CONN at all; outgoing LE connections
do not recover until the adapter is reset. With this change the same
scenario fails the rejected connection cleanly and further connects
to both peers go through.
Ask about the connection itself instead of about the device.
Fixes:
|
||
|
|
759c185d0b |
Bluetooth: RFCOMM: serialize security confirmation handling
rfcomm_security_cfm() looks up a session on session_list and then walks
its DLC list without holding rfcomm_mutex. Since RFCOMM session teardown
uses rfcomm_mutex, krfcommd can close and free the same session and DLCs
concurrently:
hci_rx_work krfcommd
----------- ---------
rfcomm_session_get()
rfcomm_lock()
rfcomm_session_close()
rfcomm_dlc_unlink()
rfcomm_session_del()
kfree(s)
rfcomm_unlock()
walk s->dlcs
The callback can then read a freed session list head and touch freed DLCs
while updating their flags or timers.
Serialize the session lookup and DLC traversal in rfcomm_security_cfm()
with rfcomm_mutex. This matches the existing RFCOMM session lifetime
rules and prevents concurrent rfcomm_session_del() / rfcomm_dlc_unlink()
from tearing the objects down while the callback is using them.
KASAN reported:
BUG: KASAN: slab-use-after-free in rfcomm_security_cfm+0x41c/0x440
Read of size 8 at addr ffff888111fb3960 by task kworker/u17:1/89
Workqueue: hci0 hci_rx_work
Call Trace:
rfcomm_security_cfm+0x41c/0x440
hci_encrypt_cfm+0x139/0x590
hci_encrypt_change_evt+0x37b/0xc40
hci_event_packet+0x71b/0xb20
hci_rx_work+0x293/0x730
Allocated by task 69:
rfcomm_session_add+0x9e/0x2f0
rfcomm_run+0x44b/0x41e0
Freed by task 69:
kfree+0x131/0x3c0
rfcomm_session_del+0x188/0x220
rfcomm_run+0x1985/0x41e0
Fixes:
|
||
|
|
44c98fd082 |
Bluetooth: RFCOMM: Validate MTU in rfcomm_apply_pn() to prevent infinite loop
rfcomm_apply_pn() accepts the MTU value from a remote PN (Parameter
Negotiation) frame without checking for zero. When the remote peer
sends an MTU of zero, d->mtu is set to 0. This causes the sendmsg
path to enter an infinite loop when fragmenting data, as each fragment
has size == min_t(size_t, len, 0) == 0, so the remaining length never
decreases. The infinite allocation of zero-length skbs exhausts all
system memory.
Fix by clamping d->mtu to RFCOMM_DEFAULT_MTU when the negotiated
value is zero, consistent with the initial value assigned in
rfcomm_dlc_alloc().
Fixes:
|
||
|
|
560bef609f |
Bluetooth: ISO: fix use-after-free of listener socket in iso_conn_ready
iso_conn_ready() looks up the BIS listener socket with iso_get_sock(),
which takes a reference, and then, without re-checking its state,
creates a child socket from it:
parent = iso_get_sock(hdev, ...);
if (!parent)
return;
lock_sock(parent);
sk = iso_sock_alloc(sock_net(parent), NULL, BTPROTO_ISO, ...);
...
iso_chan_add(conn, sk, parent);
...
release_sock(parent);
sock_put(parent);
If the listener socket is closed concurrently, between iso_get_sock()
and lock_sock(), the reference taken by iso_get_sock() may be the last
one: the close path drops the link-list reference, and once
iso_conn_ready() drops its own reference at the end of the function the
socket is freed. The child socket, however, is already linked to the
freed parent, and a later disconnect of the child runs iso_chan_del()
-> bt_accept_unlink(), which dereferences the dangling parent pointer
into the freed accept queue (a use-after-free). The same dangling
pointer is also dereferenced through parent->***() in
iso_chan_del().
Fix it the same way the connected (non-BIS) path was fixed in commit
|
||
|
|
f5afdff569 |
Bluetooth: hci_core: use skb_get() instead of skb_clone() for req_skb
BT enable fails intermittently with -ETIMEDOUT (-110). The kernel log
shows the HCI Read Local Version command was sent and the firmware
replied with status 0x00 (logged by hci_req_cmd_complete() BT_DBG),
but the waiter in __hci_cmd_sync_sk() never woke up and timed out
after 10 s:
bluetooth hci0: Opcode 0xfc00 // __hci_cmd_sync_sk
bluetooth hci0: opcode 0xfc00 plen 1 // hci_cmd_sync_add
bluetooth hci0: skb len 4 // hci_cmd_sync_alloc
bluetooth hci0: length 1 // hci_req_sync_run
Bluetooth: hci0 cmd_cnt 1 cmd queued 1 // hci_cmd_work
Bluetooth: hci0 type 1 len 4 // hci_send_frame
Bluetooth: opcode 0xfc00 status 0x00 // hci_req_cmd_complete
<-- req_skb NULL: req_complete_skb not set,
hci_cmd_sync_complete() never called,
req_status stays HCI_REQ_PEND -->
<-- 10 s later: wait_event_interruptible_timeout expires -->
bluetooth hci0: end: err -110 // __hci_cmd_sync_sk
The root cause is that hci_send_cmd_sync() clones the sent command
into hdev->req_skb so that hci_req_cmd_complete() can locate the
registered completion callback. Under memory pressure this
skb_clone() fails, leaving hdev->req_skb NULL. The firmware reply
is received and processed, but hci_req_cmd_complete() finds NULL
req_skb, so hci_cmd_sync_complete() is never called, req_status
stays HCI_REQ_PEND, and the waiter times out with -ETIMEDOUT.
req_skb is only used to read bt_cb(skb)->hci callbacks and opcode --
it is never modified. Replace skb_clone() with skb_get(), which
simply increments the reference count of hdev->sent_cmd without
allocating new memory and therefore cannot fail.
This issue was first observed as a use-after-free in ttyport_close()
when ttyport_open() failed, which was investigated in an earlier
patch series [1]. That investigation led to the discovery of the
true root cause described above.
[1] https://lore.kernel.org/all/20250430111617.1151390-1-quic_cxin@quicinc.com/
Fixes:
|
||
|
|
941929abe5 |
Bluetooth: hci_event: clear HCI_LE_ADV only on a created connection
le_conn_complete_evt() clears HCI_LE_ADV before looking at the event
status, on the premise stated in its comment that all controllers stop
advertising when a connection is created.
That premise only holds when a connection was actually created. On a
non-zero status none was, and the controller is still advertising: after
the host issues LE Create Connection Cancel the event arrives with
Unknown Connection Identifier (0x02), and a connection timeout behaves
the same way. Clearing the flag there leaves the host believing
advertising is off while the controller has it on.
It is also wrong for extended advertising, where several sets can be
advertising at once. hci_cc_le_set_ext_adv_enable() is careful about
this - on disabling one set it walks hdev->adv_instances and only clears
HCI_LE_ADV once no instance is still enabled. The unconditional clear
here discards that bookkeeping, so one set connecting drops the flag
while the others keep advertising.
The direction of the error matters. A flag left set is self-correcting:
hci_disable_advertising_sync() sends LE Set Advertising Enable(0) and
the command complete puts the state back. A flag left clear is not,
because that same function returns early without sending anything while
the flag is clear:
- LE Set Advertising Parameters is then sent to a controller that is
still advertising, and is correctly rejected with Command Disallowed
(0x0c);
- hci_enable_advertising_sync() returns at that point, before the
LE Set Advertising Enable that would set HCI_LE_ADV again.
On a controller without LE Extended Advertising that is reachable from
here: hci_schedule_adv_instance_sync() re-arms adv_instance_expire every
HCI_DEFAULT_ADV_DURATION (2 s) and its "already advertising" shortcut
tests HCI_LE_ADV, which can no longer become true, so the parameter
write is retried for as long as advertising is configured:
Bluetooth: hci0: Opcode 0x2006 failed: -16
Only clear the flag when a connection was established.
Note this is not on its own sufficient to stop that retry loop - the
redundant enable queued by hci_le_conn_failed() clears HCI_LE_ADV itself
and recreates the same mismatch, which patch 1 addresses. This patch
fixes the event handler reporting a state the controller is not in.
Verified on the affected device (BCM43455, legacy advertising only) with
this patch and patch 1 applied. A 221 s btmon capture with an out-of-range
peer at -90 dBm contains two outgoing connection attempts that the host
cancelled, each producing exactly the event this patch changes:
< LE Set Advertising Parameters 0x2006 Success
< LE Set Advertising Enable 0x200a Success
< LE Create Connection Cancel 0x200e Success
> LE Connection Complete Unknown Connection Identifier (0x02), central
Nothing follows either one; the next command is an unrelated scan restart
70 ms later. Over the whole capture: 7 LE Set Advertising Parameters sent,
all Success; 10 LE Set Advertising Enable, all Success; no Command
Disallowed of any opcode, and no 2 s cadence anywhere. Two central
connections to other peers completed normally afterwards, with feature
exchange and a connection parameter update, so advertising was still live
across the cancelled attempts.
The extended advertising case above is a code argument, not a measurement:
this controller has no LE Extended Advertising, so that path is not
exercised by the capture.
Fixes:
|
||
|
|
ed5fb41d3b |
Bluetooth: hci_conn: re-enable advertising only for peripheral role
hci_le_conn_failed() unconditionally calls hci_enable_advertising(), although its own comment states advertising should be re-enabled only when the failed attempt was made as a peripheral. hci_le_conn_failed() is reached from hci_conn_failed() for every failed LE connection, including outgoing central connections. For a central attempt this enable is redundant: hci_le_create_conn_sync() already restores advertising via hci_resume_advertising_sync() in its done: block. Because hci_enable_advertising() only queues the work on cmd_sync_work, it runs *after* that resume has already succeeded and set HCI_LE_ADV. The resulting HCI sequence, captured on a BCM43455 (no LE Extended Advertising, so legacy advertising is used): LE Create Connection Status Success ... 13.8 s, peer never answers ... LE Set Advertising Parameters (0x2006) Success <- done: resume, LE Set Advertising Enable (0x200a) Success HCI_LE_ADV set LE Create Connection Cancel (0x200e) Success LE Connection Complete Unknown Conn Id LE Set Advertising Parameters (0x2006) Command Disallowed (0x0c) The last command is the queued enable from hci_le_conn_failed() running as a second hci_enable_advertising_sync() pass. It clears HCI_LE_ADV (hci_sync.c, "Clear the HCI_LE_ADV bit temporarily"), then sends LE Set Advertising Parameters while the controller is still advertising, which the controller correctly rejects with Command Disallowed. The disable-first call at the top of hci_enable_advertising_sync() cannot prevent this: hci_disable_advertising_sync() returns early without sending anything when HCI_LE_ADV is clear, so it is a no-op exactly when the flag is wrong. hci_enable_advertising_sync() then returns without sending LE Set Advertising Enable, so HCI_LE_ADV is never set again. The legacy software rotation loop re-arms hci_schedule_adv_instance_sync() every HCI_DEFAULT_ADV_DURATION (2 s), and its "already advertising" shortcut tests HCI_LE_ADV, which can no longer become true. The command is therefore retried every 2 s indefinitely: Bluetooth: hci0: Opcode 0x2006 failed: -16 Observed on a gateway as 5326 occurrences over 3 hours, ending only when bluetoothd was restarted. Connection attempts that succeed do not call hci_le_conn_failed() and never trigger this. Add the role test the comment already describes. Both other hci_enable_advertising() call sites reached from a failed/closed LE connection (hci_cs_disconnect() and hci_disconn_complete_evt()) already guard on conn->role == HCI_ROLE_SLAVE; this one was missed. Reproducing needs legacy advertising (ext_adv_capable() false, so the software rotation loop is used), simultaneous peripheral advertising and outgoing central connects, and a central connect that times out rather than failing fast. The Fixes tag points at the commit that introduced the advertising restart into this path for the directed-advertising (peripheral) case; the role test that the later commit |
||
|
|
4beb198bc5 |
Bluetooth: eir: Fix OOB read in eir_get_service_data()
eir_get_service_data() walks the advertising data for a Service Data
field with a matching UUID. On a mismatch it advances:
eir += dlen;
eir_len -= dlen;
eir_get_data() reports dlen as the field's data length, but the field
spans dlen + 2 bytes once its length and type bytes count, and more
when non-Service-Data fields were skipped to reach it. The pointer
lands correctly on the next field. eir_len does not, and the shortfall
compounds across fields until eir_get_data() reads the length and type
bytes of a "field" past the end of the buffer.
For an ISO broadcast sink that buffer is hcon->le_per_adv_data[], filled
from the periodic advertising reports of a remote broadcaster. A PA
payload packed with mismatching Service Data fields walks off the array
into the rest of struct hci_conn. A drifted field that matches the BAA
UUID puts those bytes in iso_pi(sk)->base, where user space reads them
back with getsockopt(BT_ISO_BASE).
Recompute eir_len from the end of the buffer each iteration.
Fixes:
|
||
|
|
5b9b68abb5 |
Bluetooth: hci_sync: add conditional locking annotations
Add context analysis annotations to functions doing conditional locking,
to suppress analysis warnings.
Fixes:
|
||
|
|
66d6ef1854 |
Bluetooth: L2CAP: fix race l2cap_sock_cleanup_listen() vs. put_chan
For L2CAP sockets without owning sk->sk_socket, reading
l2cap_pi(sk)->chan may race against concurrent l2cap_sock_kill() ->
l2cap_sock_put_chan(). This excludes simultaneous proto_ops callbacks,
but access in l2cap_sock_cleanup_listen() has unsafe lockless read.
[Task 1] [Task 2 (hdev->workqueue)]
l2cap_sock_release(parent) l2cap_disconn_cfm
l2cap_sock_cleanup_listen l2cap_conn_del
bt_accept_dequeue l2cap_chan_del
lock_sock(sk) l2cap_sock_teardown_cb
bt_accept_unlink
bt_sk(sk)->parent = NULL
release_sock(sk) ----------------> lock_sock(sk)
parent = /* NULL */
lock_sock(sk) <--------------------- release_sock(sk)
sock_set_flag(sk, SOCK_ZAPPED)
l2cap_sock_close_cb
l2cap_sock_kill(sk)
l2cap_sock_put_chan
chan = READ l2cap_pi(sk)->chan l2cap_pi(sk)->chan = NULL
l2cap_chan_hold_unless_zero l2cap_put_chan(chan)
kref_get_unless_zero(&chan->ref)
Task 1 may observe NULL which causes null-ptr-deref.
Fix the race by taking lock_sock() in l2cap_sock_kill() to
synchronize with l2cap_sock_cleanup_listen(). hold_unless_zero() is not
needed here, l2cap_pi(sk)->chan owns reference if it is non-NULL.
Clarify code comments vs. locking.
Fixes:
|
||
|
|
59eecbe2f2 |
Bluetooth: mgmt: fix 'hdev->discovery.uuids' NULL dereference
'uuid_count' member of struct 'discovery_state' is assigned and read
without any locks, so there is a chance of situation when
uuid_count != 0, but uuids is NULL and there will be NULL pointer
dereference.
Possible race:
'hci_update_passive_scan_sync'
'hci_discovery_filter_clear'
hdev->discovery.uuid_count = 0;
<----------------------preempted----------------------------->
'start_service_discovery'
// Set uuid_count to value != 0
hdev->discovery.uuid_count = uuid_count;
hdev->discovery.uuids = kmemdup(...);
<----------------------preempted----------------------------->
spin_lock(&hdev->discovery.lock);
kfree(hdev->discovery.uuids);
hdev->discovery.uuids = NULL;
spin_unlock(&hdev->discovery.lock);
Now uuids == NULL and uuid_count != 0.
So 'mgmt_device_found' -> 'is_filter_match' -> 'eir_has_uuids' receives
non consistent discovery state, where NULL dereference of uuids happens.
To fix it let's add discovery.lock around every read/write of uuid_count,
uuids pair of struct members. It is also important to assign uuid_count
value only after success kmemdup() allocation in
start_service_discovery(), otherwise uuids is NULL, because kmemdup failed,
but uuid_count is already assigned to non zero value.
The following panic happens:
[ ] ------------[ cut here ]------------
[ ] Unable to handle kernel NULL pointer dereference at virtual
address 0000000000000000
[ ] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
[ ] CPU: 0 PID: 15056 Comm: kworker/u9:2
[ ] Workqueue: hci0 hci_rx_work
[ ] pstate: 10400009 (nzcV daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ ] pc : eir_has_uuids+0x2d8/0x590
[ ] lr : is_filter_match+0x258/0x320
...
[ ] Call trace:
[ ] eir_has_uuids+0x2d8/0x590
[ ] is_filter_match+0x258/0x320
[ ] mgmt_device_found+0x5b0/0xafc
[ ] process_adv_report.part.0+0x8c8/0xf14
[ ] hci_le_adv_report_evt+0x338/0x3f0
[ ] hci_le_meta_evt+0x1f0/0x4c8
[ ] hci_event_packet+0x440/0xc9c
[ ] hci_rx_work+0x44c/0xaf8
[ ] process_one_work+0x54c/0x103c
[ ] worker_thread+0x6c4/0x10c4
[ ] kthread+0x274/0x2ec
[ ] ret_from_fork+0x10/0x20
[ ] Code: 14000004 91004021 eb14003f 54000180 (f9400024)
[ ] ---[ end trace 0000000000000000 ]---
Fixes:
|
||
|
|
d4bfa78fd6 |
Bluetooth: L2CAP: reject accept queue add unless BT_LISTEN
New sk should not be added to parent socket accept queue after last
l2cap_sock_cleanup_listen() has run in l2cap_sock_teardown_cb() and
state set to BT_CLOSED, as that can result to UAF on dereferencing the
dangling parent reference.
l2cap_sock_new_connection_cb() may race with parent l2cap_chan teardown,
due to chan->state accessed without consistent locking:
[Task 1] [Task 2]
l2cap_sock_release(parent) l2cap_connect
l2cap_sock_shutdown pchan = l2cap_global_chan_by_psm
l2cap_chan_lock(pchan)
l2cap_chan_close
l2cap_sock_teardown_cb
pchan->state = BT_CLOSED
l2cap_chan_unlock(pchan) ------> l2cap_chan_lock(pchan)
l2cap_new_connection
l2cap_sock_new_connection_cb
l2cap_chan_lock(pchan) <-------- l2cap_chan_unlock(pchan)
l2cap_sock_kill(parent) /* bt_sk(sk)->parent dangling */
Fix by adding check for sk_state == BT_LISTEN after acquiring sk lock in
l2cap_sock_new_connection_cb(). Add lock_sock() around sk_state writes
where missing, to avoid data races.
Although the data races on pchan->state should be fixed too, this
defensive sk_state check probably makes sense in any case.
Fixes:
|
||
|
|
ca2c4c2649 |
Bluetooth: L2CAP: access chan->conn safely in get/setsockopt
Since commit |
||
|
|
cb19774faa |
Bluetooth: hci_sync: Clear HCI_CMD_PENDING when dropping the last request
A synchronous HCI command that never receives a response leaves
HCI_CMD_PENDING set: hci_req_cmd_complete() is the only place that clears
it, and it only runs when a response matching the last command sent
arrives.
hci_send_cmd_sync() populates hdev->req_skb only when the flag transitions
from clear to set, while hci_dev_open_sync() and hci_dev_close_sync() drop
req_skb without clearing the flag. After a timeout followed by either, the
two disagree: the flag claims a request is outstanding while req_skb is
NULL. Subsequent synchronous commands are then sent with no req_skb, so
hci_event_packet() has nothing to match an arriving event against, and the
caller times out even though the controller answered.
Commands answered by Command Complete recover on their own, since
hci_req_cmd_complete() clears the flag as a side effect. Drivers using
__hci_cmd_sync_ev() with a custom event do not, because a vendor event
never reaches that path. On a WCN3988 (hci_qca over UART) this makes a
controller firmware hang unrecoverable: the driver injects a hardware
error and re-runs qca_setup(), qca_read_soc_version() waits for
HCI_EV_VENDOR, the reply arrives within 4 ms and is discarded, and every
retry fails the same way. The adapter is left down until the driver is
unbound and rebound, or power is removed.
Clear the flag wherever the last request is dropped, restoring the
invariant that req_skb is non-NULL exactly when HCI_CMD_PENDING is set.
Verified on hardware by forcing a command timeout: without this change
setup fails on every attempt, with it setup succeeds on the first.
Fixes:
|
||
|
|
91ec203513 |
Networking changes for 7.3.
Core & protocols
----------------
- A few steps lowering rtnl_lock dependence:
- per-netns netdev unregistration for select SW drivers
(e.g. veth, ipvlan, tunnels)
- rtnl_lock-less FIB rule changes (RTM_NEWRULE and RTM_DELRULE)
- prepare software drivers and TC qdiscs for rtnl_lock-less GET
- Support BIG TCP (>64kB TSO) in UDP tunnels (vxlan, geneve).
- Support buffers larger than PAGE_SIZE in devmem zero-copy API.
- Improve MPTCP handling of extreme memory pressure handling,
when out-of-order queue had to be pruned.
- Report the per-group user count via RTM_GETMULTICAST.
- Expose the route deletion reason in RTM_DELROUTE.
- Add a SO_RIGHTS_NOTRUNC option to UNIX sockets to enable more useful
handling of LSM denials when receiving SCM_RIGHTS messages: instead
of truncating the message at the first blocked fd, keep every fd slot
and store the LSM errno in the blocked slot.
- IPv6 Segment Routing - support looking up the post-encap SID
(address) in a different/specified routing table.
- Support PRP RedBox (interlink) creation.
- Support per-nexthop UDP dst port in VXLAN.
- Continue converting getsockopt callbacks in a number of protocols
to iov_iter.
Ethernet
--------
- Marge initial CXL support for AMD/Solarflare NICs (shared branch
with the CXL tree).
- New drivers:
- ADIN1140 10BASE-T1S MACPHY
- Initial skeleton of Intel iXD and ZTE Dinghai drivers.
- High-speed NICs:
- AMD/Pensando:
- support firmware flashing
- Cisco (enic):
- SR-IOV V2 admin channel and MBOX protocol
- Huawei (hns3):
- support for ethtool pfc_prevention_tout
- nVidia/Mellanox:
- support sharing bandwidth control across interfaces of
the same device
- Marvell (octeontx2-pf):
- link RQ page pools to netdev for Netlink stats
- Google vNIC:
- XDP metadata support for DQ RDA
- Microsoft vNIC:
- support forcing full-page RX buffers
- Other NICs:
- Synopsys IP:
- eic7700: support for eth1
- Microchip (lan743x):
- support for RMII interface
- Wangxun:
- support for ethtool -G and -C for VFs
- add Tx timeout and PCIe error handling
- Intel (igb/igc):
- RSS key get/set support
- support for forcing link speed without auto-negotiation
- Switches:
- NXP (dpaa2):
- support bonding/LAG offload
- Mediatek:
- mt7530: EN7528 support
- initial support for MT7628
- Micrel (ksz8/9):
- refactoring work to move towards library model
- PTP support for KSZ8463
- nVidia/Mellanox:
- support rtnl-lock-less ethtool callbacks
- Realtek:
- rtl8366rb: use generic RTL83xx code
- support SGMII and HSGMII for RTL8367S
- PHYs:
- Airoha:
- EcoNet EN7528 PHY support
- DAPU Telecom
- DAPU Telecom DAP8211R(I) Gigabit PHY support
- Realtek:
- support RTL8261C_CG
- support RTL8261D
Wireless
--------
- nl80211: per-link statistics support for multi-link operation
- mac80211: AQL/airtime-fairness support for multicast
- Merge Peripheral Authentication Service (PAS) / TEE support
for ath12k (shared branch with the firmware/qcom tree).
- New drivers:
- mm81x for Morse Micro Long-Range S1G devices
- nxpwifi for NXP devices (mostly forked off from mwifiex)
- Driver changes:
- Broadcom (brcmfmac):
- DPP support, some Cypress part update
- MediaTek (mt76):
- mt7928 support
- mt7925 NAN support
- mt7996 AP powersave improvements
- Qualcomm (ath12k):
- much kernel infrastructure integration work
- AHB platform MultiPD support
- Realtek (rt89):
- LED support
- RTL8922DE support
- dual-BT coex for RTL8922D
- Intel:
- new FW version support
Bluetooth
---------
- HCI: add support for Shorter Connection Interval (SCI) feature.
- af_bluetooth: add minimal context analysis annotations.
- Driver changes:
- Intel:
- add Bluetooth SAR revision 2 support
- add vendor_reset PCI sysfs for PLDR
- Mediatek:
- add USB IDs for MT7902 and MT7922 devices
- Realtek:
- add USB IDs for 8761CU and 8852BE devices
- NXP:
- add M.2 Bluetooth device support using pwrseq
Misc
----
- DPLL support for manual/numerical oscillator control (NCO)
(implement in zl3073x).
- MCTP support for MCTP over USB v1.1 (DMTF DSP0283).
- Power-over-Ethernet: support Realtek PSE controllers.
- Remove the IBM EHEA driver.
- Remove tulip/xircom_cb driver.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmqEwJ4ACgkQMUZtbf5S
Irsegw//fmHJae525nxg3DHoXhrUz8EDDOVoLH6oyWyLQnh5bmbReAY/+oWA4m54
3KKKO0b2rtgRvmY/7rnjAt3bjecYgCSjvZT7I+NosB0QbbBYc14PtHfYig9HffYm
uCXfNJOk+aJ2QK4ncEvU2SjgE89Ya7cC+yARFBAwYx4zi/Qx24RB+ziOyvkQ8ksX
atvMOZrnhwqvYUFOwnOLNHTpvdxB/ZsNwWY6iXcx6EYp9xrtPusbh3FlushWkwxH
8cI/dNla44TcIKXAzRn0znRdgiEVmCMyHvOv7LKaOfy8P3I+knmuIf/mScYQqOEF
T143HdXhVSBZFRtLtFKXIja/KsvCjX9lCeMn/2ak0brQDUREcacXxYbuZKDsNAAK
zXt/+5qAcm/mO8W1gKR9Ulfli5bhFN4HKXgXMLjo5ucPtzfPxFN7HGxTiC3Cxv1v
lSXexKaj74pNBVFmADrb5jWbq7oG+GzIdjzx3ycvm2q39Fr4nJ2SzrSPPNwc/ItQ
IHv3tGLQKXlr8dl0+p2mDkRInmHXrawVNsB1UgN8E/jtcwT2QMwyWOV6s5G3uEDl
a+0U/XsrPvDYBTUCRs/KaOJQGB90QkzLe9DATt159mf+rPzAX2/oCDo8xIEe+kWV
aivP+YutFfMH/CSC9PMuvdLE2KmoPY4mibAeE4/4AYLKtJnc/yU=
=zDto
-----END PGP SIGNATURE-----
Merge tag 'net-next-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Jakub Kicinski:
"One of the 'small improvements all over the place' releases for us.
It's hard to draw any direct comparisons because summer vacations
disrupted our patch processing (and presumably - generation) quite a
bit.
Quick and dirty count suggests we (Paolo and I) merged a very similar
number of net (632) and net-next (648) patches. This is not telling
the full story either because 1/3 to 1/2 of the net-next patches also
*seem* like AI-driven low priority fixes, cleanups and clarifications.
We are completely overwhelmed, of course. The glimmer of hope is that
we secured sufficient LLM budget and access (thank you Meta!) to run
reviews with multiple frontier models on each patch. This eliminates
some hallucinations. That said, in terms of review, the LLMs can only
do so much.
The sad truth is that our APIs (especially for rare events like PCIe
errors, timeouts etc) have always been racy, and now LLMs don't let us
ignore that. I expect our direction for the next release will be to
tweak the reviews a little bit more, but start shifting focus to
letting the LLMs take care of the busy work - managing patchwork,
automating common process complaints, editing commit messages, and
maybe applying patches which already got "reviewed-by" tags from
people we trust...
Core & protocols:
- A few steps lowering rtnl_lock dependence:
- per-netns netdev unregistration for select SW drivers (e.g.
veth, ipvlan, tunnels)
- rtnl_lock-less FIB rule changes (RTM_NEWRULE and RTM_DELRULE)
- prepare software drivers and TC qdiscs for rtnl_lock-less GET
- Support BIG TCP (>64kB TSO) in UDP tunnels (vxlan, geneve)
- Support buffers larger than PAGE_SIZE in devmem zero-copy API
- Improve MPTCP handling of extreme memory pressure handling, when
out-of-order queue had to be pruned
- Report the per-group user count via RTM_GETMULTICAST
- Expose the route deletion reason in RTM_DELROUTE
- Add a SO_RIGHTS_NOTRUNC option to UNIX sockets to enable more
useful handling of LSM denials when receiving SCM_RIGHTS messages:
instead of truncating the message at the first blocked fd, keep
every fd slot and store the LSM errno in the blocked slot
- IPv6 Segment Routing - support looking up the post-encap SID
(address) in a different/specified routing table
- Support PRP RedBox (interlink) creation
- Support per-nexthop UDP dst port in VXLAN
- Continue converting getsockopt callbacks in a number of protocols
to iov_iter
Ethernet:
- Merge initial CXL support for AMD/Solarflare NICs (shared branch
with the CXL tree)
- New drivers:
- ADIN1140 10BASE-T1S MACPHY
- Initial skeleton of Intel iXD and ZTE Dinghai drivers
- High-speed NICs:
- AMD/Pensando:
- support firmware flashing
- Cisco (enic):
- SR-IOV V2 admin channel and MBOX protocol
- Huawei (hns3):
- support for ethtool pfc_prevention_tout
- nVidia/Mellanox:
- support sharing bandwidth control across interfaces
of the same device
- Marvell (octeontx2-pf):
- link RQ page pools to netdev for Netlink stats
- Google vNIC:
- XDP metadata support for DQ RDA
- Microsoft vNIC:
- support forcing full-page RX buffers
- Other NICs:
- Synopsys IP:
- eic7700: support for eth1
- Microchip (lan743x):
- support for RMII interface
- Wangxun:
- support for ethtool -G and -C for VFs
- add Tx timeout and PCIe error handling
- Intel (igb/igc):
- RSS key get/set support
- support for forcing link speed without auto-negotiation
- Switches:
- NXP (dpaa2):
- support bonding/LAG offload
- Mediatek:
- mt7530: EN7528 support
- initial support for MT7628
- Micrel (ksz8/9):
- refactoring work to move towards library model
- PTP support for KSZ8463
- nVidia/Mellanox:
- support rtnl-lock-less ethtool callbacks
- Realtek:
- rtl8366rb: use generic RTL83xx code
- support SGMII and HSGMII for RTL8367S
- PHYs:
- Airoha:
- EcoNet EN7528 PHY support
- DAPU Telecom
- DAPU Telecom DAP8211R(I) Gigabit PHY support
- Realtek:
- support RTL8261C_CG
- support RTL8261D
Wireless:
- nl80211: per-link statistics support for multi-link operation
- mac80211: AQL/airtime-fairness support for multicast
- Merge Peripheral Authentication Service (PAS) / TEE support for
ath12k (shared branch with the firmware/qcom tree)
- New drivers:
- mm81x for Morse Micro Long-Range S1G devices
- nxpwifi for NXP devices (mostly forked off from mwifiex)
- Driver changes:
- Broadcom (brcmfmac):
- DPP support, some Cypress part update
- MediaTek (mt76):
- mt7928 support
- mt7925 NAN support
- mt7996 AP powersave improvements
- Qualcomm (ath12k):
- much kernel infrastructure integration work
- AHB platform MultiPD support
- Realtek (rt89):
- LED support
- RTL8922DE support
- dual-BT coex for RTL8922D
- Intel:
- new FW version support
Bluetooth:
- HCI: add support for Shorter Connection Interval (SCI) feature
- af_bluetooth: add minimal context analysis annotations
- Driver changes:
- Intel:
- add Bluetooth SAR revision 2 support
- add vendor_reset PCI sysfs for PLDR
- Mediatek:
- add USB IDs for MT7902 and MT7922 devices
- Realtek:
- add USB IDs for 8761CU and 8852BE devices
- NXP:
- add M.2 Bluetooth device support using pwrseq
Misc:
- DPLL support for manual/numerical oscillator control (NCO)
(implement in zl3073x)
- MCTP support for MCTP over USB v1.1 (DMTF DSP0283)
- Power-over-Ethernet: support Realtek PSE controllers
- Remove the IBM EHEA driver
- Remove tulip/xircom_cb driver"
* tag 'net-next-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1433 commits)
net/mlx5e: do not HW-GRO coalesce small frames
net: openvswitch: fix nf_connlabels leak in ovs_ct_init
net: add missing ref_tracker_dir_exit() to alloc_netdev_mqs()
net: openvswitch: fix flow mask use-after-free on flow deletion
sctp: stop processing a packet once its association is deleted
dpll: zl3073x: add PTP clock support
dpll: zl3073x: add channel ToD, phase step and TIE operations
dpll: zl3073x: scale poll interval proportionally to timeout
ptp: vmclock: prevent read-only mappings from becoming writable
ipv4: reject undersized MTUs in ip_do_fragment()
bonding: initialize err for empty target lists
net: dsa: initial support for MT7628 embedded switch
net: dsa: initial MT7628 tagging driver
net: phy: mediatek: add phy driver for MT7628 built-in Fast Ethernet PHYs
dt-bindings: net: dsa: add MT7628 ESW
net: pse-pd: realtek-pse-mcu: add UART transport
net: pse-pd: realtek-pse-mcu: add I2C transport
net: pse-pd: add Realtek PSE MCU core
dt-bindings: net: pse-pd: add bindings for Realtek PSE MCU
vsock: use sock_error() to consume sk_err after a failed connect
...
|
||
|
|
d47db9bf50 |
Crypto library updates for 7.3
Add library APIs for most AES encryption modes that are used in the
kernel (ECB, CBC, CBC-CTS, CTR, XCTR, XTS, GCM, CCM).
These AES modes have many in-kernel users that are currently using the
crypto_skcipher or crypto_aead APIs. These existing APIs are difficult
to use and inefficient. Until now, the lack of proper library support
for these has been the main gap in the crypto library.
This set of changes is the next stage of addressing it:
- Implement the new APIs on top of the existing support for
single-block AES in the library.
- Fully document the new APIs.
- Migrate the only user of the old AES-GCM library API to the new,
more flexible API; then remove the old API and its implementation.
- Wire up the new APIs to the traditional crypto API by adding
crypto_skcipher and crypto_aead algorithms.
This makes the new APIs be covered by the traditional crypto API's
self-tests. It also makes them be already used for real on systems
that don't have architecture-optimized code for these modes.
But most importantly, this is a prerequisite for migrating the
architecture-optimized code for these AES modes (i.e.
arch/*/crypto/aes*) into the library, which as usual will
eliminate a lot of redundant "glue" code.
Note that unlike some of the other algorithms that have been migrated
to the library, e.g. SHA-512, for these AES modes there was too much
to get done in one cycle. Nor did it make sense to handle these modes
one at a time, because they tend to be coupled together or depend on
each other, especially in the architecture-optimized AES code.
Thus, most of the benefits (reductions in lines of code, performance
improvements, etc.) will follow in later cycles when
architecture-optimized code is migrated into the library and users of
crypto_skcipher and crypto_aead are updated to use the new APIs.
The design of the new APIs was informed by writing proof-of-concept
patches for many kernel subsystems currently accessing these same
algorithms via crypto_skcipher or crypto_aead (patches 18-33 of
https://lore.kernel.org/r/20260707053503.209874-1-ebiggers@kernel.org/).
While those patches will be resent for real later, the total diffstat
for them was negative 1905 lines. So clearly the new APIs are quite a
bit easier to use and align better with what users actually need.
Besides the new AES encryption APIs, there are also a few changes for
improved AES-CMAC key and context zeroization.
-----BEGIN PGP SIGNATURE-----
iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCaoEqhRQcZWJpZ2dlcnNA
a2VybmVsLm9yZwAKCRDzXCl4vpKOKy8YAP4o44z09KdugtigFIFX7qQnLk0uPAw+
sTPqmu+FA4jOGAD/Vy23hzAVpWmSBFhyo7HMK9W0ABK7cqj6x23I/N6JRgM=
=SLPT
-----END PGP SIGNATURE-----
Merge tag 'libcrypto-updates-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux
Pull crypto library updates from Eric Biggers:
"Add library APIs for most AES encryption modes that are used in the
kernel (ECB, CBC, CBC-CTS, CTR, XCTR, XTS, GCM, CCM).
These AES modes have many in-kernel users that are currently using the
crypto_skcipher or crypto_aead APIs. These existing APIs are difficult
to use and inefficient. Until now, the lack of proper library support
for these has been the main gap in the crypto library.
This set of changes is the next stage of addressing it:
- Implement the new APIs on top of the existing support for
single-block AES in the library.
- Fully document the new APIs.
- Migrate the only user of the old AES-GCM library API to the new,
more flexible API; then remove the old API and its implementation.
- Wire up the new APIs to the traditional crypto API by adding
crypto_skcipher and crypto_aead algorithms.
This makes the new APIs be covered by the traditional crypto API's
self-tests. It also makes them be already used for real on systems
that don't have architecture-optimized code for these modes.
But most importantly, this is a prerequisite for migrating the
architecture-optimized code for these AES modes (i.e.
arch/*/crypto/aes*) into the library, which as usual will eliminate
a lot of redundant "glue" code.
Note that unlike some of the other algorithms that have been migrated
to the library, e.g. SHA-512, for these AES modes there was too much
to get done in one cycle. Nor did it make sense to handle these modes
one at a time, because they tend to be coupled together or depend on
each other, especially in the architecture-optimized AES code.
Thus, most of the benefits (reductions in lines of code, performance
improvements, etc.) will follow in later cycles when
architecture-optimized code is migrated into the library and users of
crypto_skcipher and crypto_aead are updated to use the new APIs.
The design of the new APIs was informed by writing proof-of-concept
patches for many kernel subsystems currently accessing these same
algorithms via crypto_skcipher or crypto_aead (patches 18-33 of
https://lore.kernel.org/r/20260707053503.209874-1-ebiggers@kernel.org/).
While those patches will be resent for real later, the total diffstat
for them was negative 1905 lines. So clearly the new APIs are quite a
bit easier to use and align better with what users actually need.
Besides the new AES encryption APIs, there are also a few changes for
improved AES-CMAC key and context zeroization"
* tag 'libcrypto-updates-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux:
mac80211: fils_aead: Use __cleanup() instead of memzero_explicit()
Bluetooth: SMP: clear the aes_cmac_key when done
smb: clear the aes_cmac_key and aes_cmac_ctx when done
lib/crypto: aes-cmac: Add zeroization functions
lib/crypto: aesgcm: Remove old AES-GCM library
x86/sev: Remove obsolete virtual address check
x86/sev: Use new AES-GCM library
crypto: aes - Add CCM support using library
crypto: aes - Add GCM support using library
crypto: aes - Add XTS support using library
crypto: aes - Add CTR and XCTR support using library
crypto: aes - Add CBC and CBC-CTS support using library
crypto: aes - Add ECB support using library
lib/crypto: aes: Add CCM support
lib/crypto: aes: Add GCM support
lib/crypto: aes: Add XTS support
lib/crypto: aes: Add CTR and XCTR support
lib/crypto: aes: Add CBC and CBC-CTS support
lib/crypto: aes: Add ECB support
crypto: xts - Split out __xts_verify_key() helper
|
||
|
|
053baab47d |
Bluetooth: SMP: clear the aes_cmac_key when done
Clear the local aes_cmac_key structure via __cleanup() function when we're done with it to avoid that sensitive data could leak on the stack. While we're at it, also clear the tmp[] array here that is populated with a raw version of the original key and thus would leak the same information via the stack otherwise. Signed-off-by: Thomas Huth <thuth@redhat.com> Link: https://patch.msgid.link/20260807125845.1477067-5-thuth@redhat.com Signed-off-by: Eric Biggers <ebiggers@kernel.org> |
||
|
|
43a556b2fd |
Bluetooth: RFCOMM: take rfcomm_mutex for the deferred setup accept
rfcomm_sock_recvmsg() completes a deferred setup by calling
rfcomm_dlc_accept() without holding any RFCOMM lock:
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
rfcomm_dlc_accept(d);
return 0;
}
and rfcomm_dlc_accept() dereferences the session on its first line:
struct sock *sk = d->session->sock->sk;
Every other path that touches d->session runs under rfcomm_mutex:
rfcomm_dlc_open(), rfcomm_dlc_close(), rfcomm_dlc_exists(),
rfcomm_dlc_send_rpn(), and the RFCOMM thread through
rfcomm_process_sessions(). rfcomm_connect_ind() is even documented as
"called under rfcomm_lock()". This call site is the only one that skips
it.
The RFCOMM_DEFER_SETUP bit looks like it serialises the accept against
teardown, since __rfcomm_dlc_close() returns early when it wins the
test_and_clear. But rfcomm_recv_disc() forces the state first:
d->state = BT_CLOSED;
__rfcomm_dlc_close(d, err);
and the early return only covers BT_CONNECT, BT_CONFIG, BT_OPEN and
BT_CONNECT2. With the state already BT_CLOSED that switch does not
match, the bit is never consulted, and __rfcomm_dlc_close() falls
through to rfcomm_dlc_unlink(), which sets d->session = NULL.
So a remote DISC on a deferred dlc clears the session while leaving
RFCOMM_DEFER_SETUP set. The next recvmsg() then passes the
test_and_clear and dereferences a NULL session. No timing window is
needed: once the DISC has been processed, the dereference is
unconditional.
Give rfcomm_dlc_accept() the same shape as rfcomm_dlc_open() and
rfcomm_dlc_close(): an exported wrapper that takes rfcomm_mutex and
re-checks the session, around a __rfcomm_dlc_accept() that the two
in-core callers, which already hold the mutex, keep using.
Reproduced on a KASAN + PROVE_LOCKING kernel with a BR/EDR peer emulated
over /dev/vhci: the peer brings up an ACL link, opens L2CAP on the
RFCOMM PSM, starts a session, opens a dlc on a channel bound with
BT_DEFER_SETUP, and sends DISC after the socket is accepted. recv() on
the accepted socket then hits:
Oops: general protection fault
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
RIP: 0010:rfcomm_dlc_accept+0x54/0x350
Call Trace:
rfcomm_sock_recvmsg+0x1cd/0x230
sock_recvmsg+0x166/0x1c0
__sys_recvfrom+0x20d/0x300
0x10 is the offset of sock in struct rfcomm_session. With this patch the
same run completes with recv() returning 0 and no report, and lockdep
stays quiet, confirming rfcomm_mutex is still taken before lock_sock on
this path as it is on the thread side.
Fixes:
|
||
|
|
0079e1a944 |
Bluetooth: MSFT: validate evt_prefix_len against the response length
read_supported_features() only checks that the response covers the fixed
part of struct msft_rp_read_supported_features, which is 11 bytes:
if (skb->len < sizeof(*rp)) {
bt_dev_err(hdev, "MSFT supported features length mismatch");
goto failed;
}
evt_prefix[] is a flexible array member and rp->evt_prefix_len is an
unvalidated u8 taken straight out of that response, so
msft->evt_prefix = kmemdup(rp->evt_prefix, rp->evt_prefix_len,
GFP_KERNEL);
copies up to 255 bytes from a reply that may have carried none of them.
What is copied is data the controller never sent, and it is then used to
match incoming vendor events in msft_vendor_evt().
This is not an out-of-bounds access. An skb data allocation always has
at least SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) bytes past the
payload, which is more than the 255 byte maximum, so the read stays
inside the allocation and KASAN does not report it. It is still a read
of bytes the host was never given, with the length fully controlled by
the controller.
Reject a response that is too short for the prefix it declares.
Verified with an emulated controller over /dev/vhci on a KASAN kernel,
with vhci made to advertise an MSFT opcode the way btintel, btqca, btmtk
and btrtl do unconditionally. A reply of exactly 11 bytes declaring
evt_prefix_len = 255 reaches kmemdup and copies 255 bytes
("skb->len=11 evt_prefix_len=255", with the copied buffer dumped); since
the reply ends at the fixed part, all 255 come from past the end of the
response. No KASAN report is produced, as expected from the allocation
slack described above. With this patch the response is rejected with
"MSFT event prefix length mismatch" and msft->evt_prefix is left unset.
Fixes:
|
||
|
|
884cf2cc95 |
Bluetooth: ISO: zero the sockaddr before returning it in getname
iso_sock_getname() fills a struct sockaddr_iso in place and returns its
size without clearing it first, so bytes it does not write are copied to
user space from the kernel stack. The getsockname(2) and getpeername(2)
paths both run through do_getsockname(), which hands getname() an
uninitialized sockaddr_storage on the stack and copies back up to the
number of bytes getname() returns, so the driver has to initialize every
byte it accounts for.
Two ranges are left uninitialized:
- struct sockaddr_iso is 10 bytes but only 9 are written (family,
iso_bdaddr, iso_bdaddr_type), leaking the trailing pad byte on every
call.
- for a broadcast peer (BIS_LINK or PA_LINK) the returned length grows
by sizeof(struct sockaddr_iso_bc), but only bc_sid, bc_num_bis and
bc_bis are filled; bc_bdaddr and bc_bdaddr_type, the first 7 bytes of
that structure, are never written.
An unprivileged process can open a BTPROTO_ISO socket and reach the pad
leak with getsockname(); the broadcast leak needs an established BIS/PA
connection. l2cap and rfcomm already memset their sockaddr in getname
for the same reason; do the same here.
Fixes:
|
||
|
|
9838a80096 |
Bluetooth: ISO: do not force BT_LISTEN after a failed BIG sync
iso_sock_recvmsg() handles the deferred setup of a broadcast sink by
dropping the socket lock, calling iso_conn_big_sync() and taking the
lock again:
release_sock(sk);
iso_conn_big_sync(sk);
lock_sock(sk);
sk->sk_state = BT_LISTEN;
The state is written unconditionally, but iso_conn_big_sync() returns
void and has paths that do nothing at all: hci_get_route() may fail, and
after re-acquiring the socket lock the connection may already be gone,
in which case it bails out without ever issuing an LE BIG Create Sync.
While the lock is dropped the connection can be torn down, for example
when the controller reports HCI_EV_LE_PA_SYNC_LOST:
hci_le_pa_sync_lost_evt()
hci_disconn_cfm() -> iso_disconn_cfm() -> iso_conn_del()
iso_chan_del()
iso_pi(sk)->conn = NULL
sk->sk_state = BT_CLOSED
sock_set_flag(sk, SOCK_ZAPPED)
iso_conn_big_sync() then finds conn == NULL and returns, but the caller
still overwrites the BT_CLOSED that iso_chan_del() has just set. The
socket ends up marked BT_LISTEN with no connection, so recvmsg() reports
success for a setup that never happened and a later accept() waits for
BIS connections that can never arrive instead of failing.
A concurrent shutdown() reaches the same write by another route:
__iso_sock_close() takes the BT_CONNECT2 PA sync path to
iso_sock_disconn(), which sets BT_DISCONN but leaves conn and
conn->hcon in place, so iso_conn_big_sync() succeeds and BT_LISTEN is
written over BT_DISCONN. Both the BT_CONNECT2 and the BT_CONNECTED case
write the state the same way.
Let iso_conn_big_sync() report whether the BIG sync was started, and
only move the socket to BT_LISTEN when it was and when the state has not
changed while the lock was dropped, mirroring what the BT_CONNECT case
of the same switch already does with iso_connect_cis(). Both conditions
are needed, the error alone does not cover the shutdown() race.
This corrupts the socket state machine only, it is not a memory safety
issue. KASAN and lockdep stayed quiet in all of the runs below.
Reproduced with an emulated controller over /dev/vhci on a KASAN +
PROVE_LOCKING kernel. A PA sync broadcast sink socket is driven to
BT_CONNECT2 and recvmsg() on it is raced against teardown, with a debug
delay inside the lock-dropped section to widen the window:
- HCI_EV_LE_PA_SYNC_LOST injected: 64 of 64 rounds left the socket in
BT_LISTEN with the connection gone, recvmsg() returned 0 and accept()
on that fd returned EAGAIN, which iso_sock_accept() can only do while
the socket is BT_LISTEN. With this patch, 0 of 64, recvmsg() returns
an error and accept() returns EBADFD.
- shutdown() instead of a controller event: 24 of 32 rounds wedged in
BT_LISTEN, 0 of 32 with this patch. With only the error check in
place and a short window, one round still wedged while recvmsg()
returned 0, which is the case the state re-check covers.
An unraced control round behaves the same before and after: recvmsg()
returns 0, the socket reaches BT_LISTEN and an LE BIG Create Sync is
issued.
Fixes:
|
||
|
|
75722cde87 |
Bluetooth: hci_sync: Disable legacy instance's ext adv before setup snapshot
hci_setup_ext_adv_instance_sync(...) only disabled HCI_OP_LE_SET_EXT_ADV_ENABLE before setup snapshot in case of non-legacy instances (instance > 0) and never disabled the same for legacy instance (instance == 0). This would lead to failure in setting ext adv params with HCI_ERROR_COMMAND_DISALLOWED (0x0c) error like below, when toggling the discoverable/connectable property of a controller with advertising enabled. ``` $ btmgmt advertising off hci0 Set Advertising complete, settings: powered ssp br/edr le secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt connectable on hci0 Set Connectable complete, settings: powered connectable ssp br/edr le secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt connectable off hci0 Set Connectable complete, settings: powered ssp br/edr le secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt advertising on hci0 Set Advertising complete, settings: powered connectable ssp br/edr le advertising secure-conn wide-band-speech cis-central cis-peripheral $ btmgmt connectable on Set Connectable for hci0 failed with status 0x0a (Busy) $ btmgmt connectable off Set Connectable for hci0 failed with status 0x0a (Busy) $ dmesg ... [ 21.970527] hci0: Opcode 0x2036 [ 21.970529] hci0: opcode 0x2036 plen 25 [ 21.970537] hci0: skb len 28 [ 21.970539] hci0: length 1 [ 21.976099] hci0: result 0x0c [ 21.976105] hci0: end: err -16 [ 21.976114] Bluetooth: hci0: Opcode 0x2036 failed: -16 ``` Signed-off-by: Muhammad Saheed <muhammad.saheed.iam@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> |
||
|
|
e3643fbddb |
Bluetooth: hci_event: fix out-of-bounds read in LE PA report reassembly
hci_le_per_adv_report_evt() is dispatched with a minimum length of
sizeof(struct hci_ev_le_per_adv_report), which only covers the fixed
part of the event and not the trailing data[] array:
struct hci_ev_le_per_adv_report {
__le16 sync_handle;
__u8 tx_power;
__u8 rssi;
__u8 cte_type;
__u8 data_status;
__u8 length;
__u8 data[];
} __packed;
The handler notifies the ISO layer via hci_proto_connect_ind(), which
reaches iso_connect_ind(). That function retrieves the stored event with
hci_recv_event_data() and, while reassembling the periodic advertising
data, does:
memcpy(hcon->le_per_adv_data + hcon->le_per_adv_data_offset,
ev->data, ev->length);
ev->length is taken directly from the event and is never validated
against the amount of data the event actually carries. A controller
that reports a length larger than the received event therefore causes
the memcpy() to read past the end of the event buffer. The leaked bytes
are stored in hcon->le_per_adv_data and can subsequently be read back
from user space via getsockopt(BT_ISO_BASE).
Validate that the event contains ev->length data bytes before it is
consumed, mirroring the check already performed by
hci_le_ext_adv_report_evt() and hci_le_adv_report_evt().
Signed-off-by: Laxman Acharya <acharyalaxman8848@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
||
|
|
5d95286b6d |
Bluetooth: MGMT: reject HCI_CMD_SYNC params_len above 255
mgmt_hci_cmd_sync() checks that the message length agrees with params_len
but puts no upper bound on it. params_len is __le16 while the parameter
length in the HCI command header is a u8:
struct hci_command_hdr {
__le16 opcode;
__u8 plen;
} __packed;
hci_cmd_sync_alloc() assigns one to the other:
hdr->plen = plen;
if (plen)
skb_put_data(skb, param, plen);
so a params_len of 256 leaves plen at 0 while all 256 bytes are still
appended. The frame handed to the driver then declares no parameters and
carries 256 of them. On a length framed transport such as H:4 the
controller takes the trailing bytes as the start of the next packet.
The mgmt socket MTU is HCI_MAX_FRAME_SIZE, so params_len can reach about
1KB this way. Commit
|
||
|
|
414b365ece |
Bluetooth: MGMT: free the HCI command when it is cancelled
mgmt_hci_cmd_sync() queues the pending command with a NULL destroy
callback, so it is only freed if send_hci_cmd_sync() runs. A cancelled
entry is leaked, as _hci_cmd_sync_cancel_entry() does not release
entry->data when there is no destroy callback, and hci_cmd_sync_clear()
cancels every pending entry when the controller is unregistered. Nothing
else reclaims it either: mgmt_pending_new() does not put the command on
hdev->mgmt_pending.
The leak also pins the socket reference taken by mgmt_pending_new(), so
the mgmt socket is never released.
Free the command from a destroy callback. The now-empty done label is
replaced by a direct return.
Fixes:
|
||
|
|
3c742feda8 |
Bluetooth: MGMT: free the mesh send cancel command when it is cancelled
mesh_send_cancel() queues the pending command with a NULL destroy
callback, so it is only freed if send_cancel() runs. A cancelled entry is
leaked, as _hci_cmd_sync_cancel_entry() does not release entry->data when
there is no destroy callback, and hci_cmd_sync_clear() cancels every
pending entry when the controller is unregistered. Nothing else reclaims
it either: mgmt_pending_new() does not put the command on
hdev->mgmt_pending.
The leak also pins the socket reference taken by mgmt_pending_new(), so
the mgmt socket is never released.
Free the command from a destroy callback.
Fixes:
|
||
|
|
120d8dc042 |
Bluetooth: hci_sync: free the advertising instance on the failure and cancel paths
adv_timeout_expire() hands a kmalloc()ed instance byte to
hci_cmd_sync_queue() with a NULL destroy callback, and only
adv_timeout_expire_sync() frees it. That leaks on two paths:
- the return value is not checked, and hci_cmd_sync_queue() does not
take ownership when it fails (-ENETDOWN, -ENODEV, -ENOMEM);
- a cancelled entry is not released, as _hci_cmd_sync_cancel_entry()
does not free entry->data when there is no destroy callback.
hci_cmd_sync_clear() cancels every pending entry when the controller
is unregistered.
Free the buffer from a destroy callback, and in the caller when the entry
could not be queued at all.
Fixes:
|
||
|
|
42de40abe2 |
Bluetooth: hci_conn: fix the SCO setup context lifetime
hci_setup_sync() queues a conn_handle_t with a NULL destroy callback, so the context is only freed if hci_enhanced_setup_sync() actually runs. An entry that is cancelled instead is leaked, as _hci_cmd_sync_cancel_entry() does not release entry->data when there is no destroy callback, and hci_cmd_sync_clear() cancels every pending entry when the controller is unregistered. The context also stores a bare hci_conn pointer, so the connection can be freed while the work is queued. The dequeue in hci_conn_del() does not cover it either, as it matches on entry->data == conn and entry->data is the wrapper here. Same problem as commit |
||
|
|
f57b399c4f |
Bluetooth: hci_sync: Fix accept list UAF during suspend
hci_update_event_filter_sync() walks hdev->accept_list while sending a
synchronous HCI command for each remote-wakeup device. The suspend path
holds hdev->req_lock, but accept-list updates are serialized by hdev->lock.
Consequently, remove_device() can free the current list entry during the
controller wait.
The following interleaving causes the use-after-free:
hci_update_event_filter_sync() remove_device()
fetch accept-list entry
hci_set_event_filter_sync()
wait for controller response hci_dev_lock()
list_del()
kfree()
hci_dev_unlock()
read the freed list.next
KASAN reported:
BUG: KASAN: slab-use-after-free in hci_suspend_sync+0x835/0x910
Read of size 8 at addr ffff88810bec8440 by task kworker/0:1/10
Workqueue: events vhci_suspend_work
Call Trace:
hci_suspend_sync+0x835/0x910
hci_suspend_dev+0x182/0x450
process_one_work+0x661/0x1090
worker_thread+0x45b/0xd10
Allocated by task 86:
hci_bdaddr_list_add_with_flags+0x1a8/0x400
add_device+0x381/0x820
hci_sock_sendmsg+0x1033/0x1ea0
Freed by task 91:
kfree+0x131/0x3c0
remove_device+0x429/0xb70
hci_sock_sendmsg+0x1033/0x1ea0
Snapshot the remote-wakeup addresses under hdev->lock. Release the lock
before sending HCI commands. Clear the controller event filter before
building the snapshot, and skip allocation and the second list traversal
when there are no matching entries. This preserves the original filter
and scan-state updates without retaining an accept-list node across a
controller wait.
Fixes:
|
||
|
|
9a4fa3cddc |
Bluetooth: hci_event: Use 255 as max event payload length in hci_ev_table[]
hci_event_func() validates skb->len against ev->max_len from the entry in hci_ev_table[]. By then, the header has already been stripped by skb_pull(). So the max event payload is 255, but hci_ev_table[] still uses HCI_MAX_EVENT_SIZE (260) for it, which is imprecise. Fix by introducing HCI_MAX_EVENT_PLEN (255) 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> |
||
|
|
0bd606b31d |
Bluetooth: hci_event: Introduce handle_ev_vendor() for HCI_EV_VENDOR
Introduce the hook to solve issues below:
msft_vendor_evt(), the current handler for all VSEs, is unsuitable
since:
- many VSEs are not MSFT ones;
- it always corrupts the non-MSFT VSEs by calling skb_pull_data()
once the MSFT extension is enabled.
Several issues are caused by many transport drivers pre-processing
VSEs in their RX path, often an IRQ-disabled atomic context. Take
the two typical cases below as examples:
Case 1:
// no btmon log, no way to reach userspace
Step 1: handle and free @original_skb directly
Case 2:
// hurts performance and consumes GFP_ATOMIC memory
Step 1: cloned_skb = skb_clone(original_skb, GFP_ATOMIC);
// the VSE is handled here
Step 2: handle and free @cloned_skb
Step 3: hci_recv_frame(hdev, original_skb);
// already handled, but re-enters the stack's event-handling path
Step 4: hci_event_packet(hdev, original_skb);
Fix by introducing the hook with usage:
1) the transport driver registers the hook for VSEs of interest;
2) the stack calls it in process context, handling the VSE like any
other event:
- if interested, handle the VSE - no need to free it - and
return true;
- otherwise return false.
Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|