In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: dummy_hcd: prevent fifo_req reuse during giveback
dummy_hcd embeds a single shared usb_request (dum->fifo_req) that the
"emulated single-request FIFO" fast-path in dummy_queue() reuses for
small IN transfers: it copies the caller's request into it
(req->req = *_req) and queues it, treating list_empty(&fifo_req.queue)
as "the slot is free".
The completion side (dummy_timer/transfer/nuke/dummy_dequeue) follows
the standard pattern: list_del_init(&req->queue) unlinks the request,
then the lock is dropped and usb_gadget_giveback_request() invokes
req->complete(). But list_del_init() makes fifo_req.queue look empty
*before* the completion callback returns, so a concurrent dummy_queue()
on another CPU sees the slot as free, reuses fifo_req and runs
req->req = *_req -- overwriting req->complete while dummy_timer is
mid-calling it. The indirect call then jumps to a clobbered pointer,
causing a general protection fault / page fault in dummy_timer
(syzkaller extid faf3a6cf579fc65591ca). The clobbering write is an
in-bounds memcpy on a live shared object, so KASAN cannot flag it.
Add a fifo_req_busy bit covering the shared request's whole lifetime:
set it in dummy_queue() when the FIFO fast-path takes fifo_req (making
it the fast-path guard, replacing the list_empty(&fifo_req.queue)
test), and clear it after the completion callback has returned, via a
dummy_giveback() helper used at all four gadget-request giveback
sites. The shared slot can no longer be reused until its completion
callback has finished.
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: printer: fix infinite loop in printer_read()
printer_read() uses the same variable for the requested copy size and
the number of bytes actually copied to user space. copy_to_user()
returns the number of bytes not copied, so when it fails to copy
anything, the computed copied length becomes zero.
In that case len, buf, current_rx_bytes and current_rx_buf are left
unchanged. If RX data is available and the user buffer remains
unwritable, the read loop can repeat indefinitely.
Track the copied length separately and return -EFAULT, or the number of
bytes already copied, if an iteration makes no progress.
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: f_ncm: validate datagram bounds in ncm_unwrap_ntb()
When unpacking host-supplied NTBs, ncm_unwrap_ntb() checks datagram length
against frame_max but does not verify that the datagram fits within the
declared block length. Additionally, when decoding multiple NTBs from a
single socket buffer, subsequent block lengths are not checked against the
actual remaining buffer data.
With these checks missing, a malicious USB host can specify datagram
offsets and lengths that point beyond the block, or supply secondary NTB
headers declaring lengths larger than the buffer. skb_put_data() then
copies adjacent kernel memory from skb_shared_info into the network skb.
Fix this by verifying that sufficient buffer space remains for the NTB
header before parsing, handling zero-length block declarations, ensuring
that block lengths never exceed the remaining buffer space, and verifying
that each datagram payload stays strictly within the block boundary.
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: f_tcm: synchronize delayed set_alt with teardown
The f_tcm set_alt() path defers endpoint setup to a work item and
completes the delayed status response from process context. The delayed
work uses f_tcm private state and may complete the setup request after
disconnect or function teardown has already moved on.
Cancel and drain the delayed set_alt work when the function is unbound or
freed. For disable paths, which are reached under the composite device
lock, use a small state machine and a non-sleeping cancellation path
instead of cancel_work_sync(). If the work is already running, mark it
cancelled and let the worker own the cleanup; otherwise tcm_disable() can
cancel the queued work and clean up immediately.
Also serialize the final delayed-status completion with the cancellation
check while holding the composite device lock. This prevents a disconnect
from clearing delayed_status while the worker is about to complete the
control request.
Validation reproduced this kernel report:
BUG: KASAN: slab-use-after-free in tcm_delayed_set_alt+0x6c/0xef0
Call Trace:
<TASK>
dump_stack_lvl+0x66/0xa0
print_report+0xce/0x630
? tcm_delayed_set_alt+0x6c/0xef0
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x188/0x320
? tcm_delayed_set_alt+0x6c/0xef0
kasan_report+0xe0/0x110
? tcm_delayed_set_alt+0x6c/0xef0
tcm_delayed_set_alt+0x6c/0xef0
? __pfx_tcm_delayed_set_alt+0x10/0x10
? process_one_work+0x4cb/0xb90
? rcu_is_watching+0x20/0x50
? tcm_delayed_set_alt+0x9/0xef0
process_one_work+0x4d7/0xb90
? __pfx_process_one_work+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __list_add_valid_or_report+0x37/0xf0
? __pfx_tcm_delayed_set_alt+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
worker_thread+0x2d8/0x570
? __pfx_worker_thread+0x10/0x10
kthread+0x1ad/0x1f0
? __pfx_kthread+0x10/0x10
ret_from_fork+0x3c9/0x540
? __pfx_ret_from_fork+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __switch_to+0x2e9/0x730
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Allocated by task 544:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0x8f/0xa0
tcm_alloc+0x68/0x180
usb_get_function+0x36/0x60
config_usb_cfg_link+0x125/0x1b0
configfs_symlink+0x322/0x890
vfs_symlink+0xc2/0x270
filename_symlinkat+0x295/0x2f0
__x64_sys_symlinkat+0x62/0x90
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 661:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x43/0x70
kfree+0x2f9/0x530
config_usb_cfg_unlink+0x173/0x1e0
configfs_unlink+0x1fa/0x340
vfs_unlink+0x15c/0x510
filename_unlinkat+0x2ba/0x450
__x64_sys_unlinkat+0x63/0x90
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: uvc: clamp SEND_RESPONSE length to the response buffer
uvc_send_response() builds the UVC control response from a user-supplied
struct uvc_request_data:
req->length = min_t(unsigned int, uvc->event_length, data->length);
...
memcpy(req->buf, data->data, req->length);
req->length is clamped to uvc->event_length, which is taken from the
host control request wLength (up to UVC_MAX_REQUEST_SIZE, 64), and to
data->length, which comes from the UVCIOC_SEND_RESPONSE ioctl and is
only checked for being negative. The source buffer data->data is only
60 bytes, so a response with uvc->event_length and data->length both
greater than 60 makes memcpy() read past the end of data->data.
Clamp req->length to sizeof(data->data) as well.
In the Linux kernel, the following vulnerability has been resolved:
USB: serial: io_edgeport: cap received transmit credits
The interrupt-status packet reports transmit credits returned by the
device. edge_interrupt_callback() adds the 16-bit value to txCredits
without checking maxTxCredits.
edge_write() uses txCredits minus the software FIFO count as the amount
of data that fits. Since the FIFO is allocated with maxTxCredits bytes,
txCredits exceeding maxTxCredits can cause OOB write in ring buffer.
Cap accumulated credits at maxTxCredits. Conforming devices should never
hit the cap.
In the Linux kernel, the following vulnerability has been resolved:
drm/amd/display: Fix ISM dc_lock deadlock during suspend
[Why]
System hang observed during suspend/resume while video is playing.
amdgpu_dm_ism_disable() is called under dc_lock and waits for ISM
delayed work via disable_delayed_work_sync(). The work handlers
themselves take dc_lock, producing an ABBA deadlock when a worker is
in flight at suspend time.
[How]
Split the disable path into two phases with opposite locking
contracts:
1. amdgpu_dm_ism_disable() -- quiesces workers, must NOT hold
dc_lock.
2. amdgpu_dm_ism_force_full_power() (new) -- drives the ISM FSM
back to FULL_POWER_RUNNING, must hold dc_lock.
In the Linux kernel, the following vulnerability has been resolved:
wifi: ath9k: hif_usb: don't dereference hif_dev after re-arming firmware request
ath9k_hif_request_firmware() re-arms an asynchronous firmware load via
request_firmware_nowait(), passing hif_dev as the completion context, and
then still dereferences hif_dev:
dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n",
hif_dev->fw_name);
The re-armed callback ath9k_hif_usb_firmware_cb() runs on the "events"
workqueue and, when the firmware is missing, walks the retry chain into
ath9k_hif_usb_firmware_fail() -> complete_all(&hif_dev->fw_done). That
releases the wait_for_completion(&hif_dev->fw_done) in a concurrent
ath9k_hif_usb_disconnect(), which then kfree()s hif_dev. The trailing
dev_info() in the frame that re-armed the request can therefore read freed
memory (hif_dev->udev, the first field of struct hif_device_usb):
BUG: KASAN: slab-use-after-free in ath9k_hif_request_firmware
Read of size 8 ... by task kworker/...
ath9k_hif_request_firmware
ath9k_hif_usb_firmware_cb drivers/net/wireless/ath/ath9k/hif_usb.c:1247
request_firmware_work_func
Allocated by ...:
ath9k_hif_usb_probe drivers/net/wireless/ath/ath9k/hif_usb.c
Freed by ...:
ath9k_hif_usb_disconnect -> kfree drivers/net/wireless/ath/ath9k/hif_usb.c
The fw_done barrier only makes disconnect wait for the firmware chain to
*terminate*; it does not protect the outer ath9k_hif_request_firmware()
frame that re-armed the request and keeps touching hif_dev afterwards.
Drop the post-request dev_info(): it is the only use of hif_dev after the
async request is armed, and it is purely informational (the dev_err() on the
failure path runs only when request_firmware_nowait() did not arm a callback,
so hif_dev is still alive there).
This was first reported by syzbot as a single, non-reproduced crash that was
later auto-obsoleted, and was independently rediscovered by the reFuzz fuzzer,
which produced a C reproducer (USB-gadget connect/disconnect of an ath9k_htc
device whose firmware download fails). The vulnerable code is unchanged and
still present in v7.1-rc6, where the slab-use-after-free reproduces under KASAN
once the (sub-microsecond) race window is widened.
In the Linux kernel, the following vulnerability has been resolved:
wifi: ath11k: fix NULL pointer dereference in ath11k_hal_srng_access_begin
In ATH11K_QMI_EVENT_FW_READY, ATH11K_FLAG_REGISTERED is set
unconditionally even when ath11k_core_qmi_firmware_ready() fails.
This leaves the driver in an inconsistent state where
initialization is considered complete although the firmware ready
handling did not finish successfully. During the subsequent SSR,
the driver enters the restart path based on this incorrect state
and dereferences uninitialized srng members, resulting in a NULL
pointer dereference.
Call trace:
ath11k_hal_srng_access_begin+0xc/0x60 [ath11k] (P)
ath11k_ce_cleanup_pipes+0x17c/0x180 [ath11k]
ath11k_core_restart+0x40/0x168 [ath11k]
Fix this by:
- skipping firmware_ready if ATH11K_FLAG_REGISTERED is already set
- setting ATH11K_FLAG_REGISTERED only when firmware_ready succeeds
- setting ATH11K_FLAG_QMI_FAIL and aborting the FW_READY handling
on error
Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.2.0.c2-00204-QCAMSLSWPLZ-1
In the Linux kernel, the following vulnerability has been resolved:
hwmon: (corsair-psu) Stop device IO before calling hid_hw_stop
hid_hw_stop() does not stop the device IO.
This results in a race condition between hid_input_report() and the point
immediately following the execution of hid_device_io_start() within
corsairpsu_probe(). If the probe operation fails after "io start" has
been initiated, this race condition will result in a uaf vulnerability
[1].
CPU0 CPU1
==== ====
corsairpsu_probe()
hid_device_io_start()
... unlock driver_input_lock
hid_hw_stop()
kfree(hidraw) __hid_input_report()
... acquire driver_input_lock
hid_report_raw_event()
hidraw_report_event()
... access hidraw's list_lock // trigger uaf
Consequently, when corsairpsu_probe() fails and hid_hw_stop() needs to
be executed, the io_started flag is first cleared while holding the
driver_input_lock to prevent potential race conditions involving input
reports.
[1]
BUG: KASAN: slab-use-after-free in rt_spin_lock+0x83/0x400 kernel/locking/spinlock_rt.c:56
Call Trace:
hidraw_report_event+0x5d/0x3a0 drivers/hid/hidraw.c:577
hid_report_raw_event+0x311/0x1730 drivers/hid/hid-core.c:2076
__hid_input_report drivers/hid/hid-core.c:2152 [inline]
hid_input_report+0x44e/0x580 drivers/hid/hid-core.c:2174
hid_irq_in+0x47e/0x6d0 drivers/hid/usbhid/hid-core.c:286
__usb_hcd_giveback_urb+0x3b3/0x5e0 drivers/usb/core/hcd.c:1657
dummy_timer+0x8a9/0x47d0 drivers/usb/gadget/udc/dummy_hcd.c:2005
Allocated by task 10:
hidraw_connect+0x57/0x430 drivers/hid/hidraw.c:606
hid_connect+0x5bf/0x19d0 drivers/hid/hid-core.c:2277
hid_hw_start+0xa8/0x120 drivers/hid/hid-core.c:2387
corsairpsu_probe+0xd9/0x3c0 drivers/hwmon/corsair-psu.c:782
Freed by task 10:
hidraw_disconnect+0x4f/0x60 drivers/hid/hidraw.c:662
hid_disconnect drivers/hid/hid-core.c:2362 [inline]
hid_hw_stop+0x101/0x1e0 drivers/hid/hid-core.c:2407
corsairpsu_probe+0x327/0x3c0 drivers/hwmon/corsair-psu.c:826
Fix the problem by calling hid_device_io_stop() before calling
hid_hw_stop().
[groeck: Updated subject and description;
call hid_device_io_stop() only if IO has been started]
In the Linux kernel, the following vulnerability has been resolved:
hwmon: (corsair-cpro) Stop device IO before calling hid_hw_stop
Calling hid_hw_stop() does not stop the device IO.
This results in a race condition between hid_input_report() and the point
immediately following the execution of hid_device_io_start() within
the driver probe function. If the probe operation fails after "io start"
has been initiated, this race condition will result in a UAF vulnerability.
Fix the problem by calling hid_device_io_stop() before calling
hid_hw_stop().
In the Linux kernel, the following vulnerability has been resolved:
hwmon: (nzxt-smart2) Stop device IO before calling hid_hw_stop
Calling hid_hw_stop() does not stop the device IO.
This results in a race condition between hid_input_report() and the point
immediately following the execution of hid_device_io_start() within
the driver probe function. If the probe operation fails after "io start"
has been initiated, this race condition will result in a UAF vulnerability.
Fix the problem by calling hid_device_io_stop() before calling
hid_hw_stop().
In the Linux kernel, the following vulnerability has been resolved:
hwmon: (nzxt-kraken3) Stop device IO before calling hid_hw_stop
Calling hid_hw_stop() does not stop the device IO.
This results in a race condition between hid_input_report() and the point
immediately following the execution of hid_device_io_start() within
the driver probe function. If the probe operation fails after "io start"
has been initiated, this race condition will result in a UAF vulnerability.
Fix the problem by calling hid_device_io_stop() before calling
hid_hw_stop().
In the Linux kernel, the following vulnerability has been resolved:
watchdog: pretimeout: Fix UAF in watchdog_unregister_governor()
When a watchdog governor is unregistered, it updates existing watchdog
devices that were using this governor by falling back to `default_gov`.
If the governor being unregistered is currently set as `default_gov`,
the `default_gov` is never cleared. This leads to 2 use-after-free
issues:
1. New watchdog devices registered after this point will inherit the
dangling `default_gov`.
2. Existing watchdog devices using the unregistered governor will have
their `wdd->gov` reassigned to the dangling `default_gov`.
Fix the UAF by clearing `default_gov` if it matches the governor being
unregistered.
In the Linux kernel, the following vulnerability has been resolved:
watchdog: airoha: Prevent division by zero when clock frequency is zero
clk_get_rate() can return 0 when the clock provider is not properly
configured or the clock is unmanaged. The driver uses wdt_freq as a
divisor directly in airoha_wdt_probe() to compute max_timeout and in
airoha_wdt_get_timeleft() to compute the remaining time, which results
in a division by zero.
Add a check for wdt_freq == 0 in probe and return -EINVAL with
dev_err_probe() to prevent the division by zero and provide a
diagnostic message.
In the Linux kernel, the following vulnerability has been resolved:
wifi: ath11k: fix potential buffer underflow in ath11k_hal_rx_msdu_list_get()
When the first entry in msdu_details has a zero buffer address,
the code accesses msdu_details[i - 1] with i == 0, causing a
buffer underflow.
Fix similarly to ath12k_wifi7_hal_rx_msdu_list_get() by adding
a separate check for i == 0 before the main condition to prevent
the out-of-bounds access.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
In the Linux kernel, the following vulnerability has been resolved:
firewire: net: Fix fragmented datagram reassembly
fwnet_frag_new() keeps a sorted list of received fragments for a partial
datagram. When a new fragment is adjacent to an existing fragment, the
code checks whether the new fragment also closes the gap to the next or
previous list entry.
Those neighbor lookups currently assume that the current fragment always
has a real next or previous fragment. At a list edge, the next or
previous entry is the list head, not a struct fwnet_fragment_info.
The gap checks also compare against the old edge of the current fragment
instead of the edge after adding the new fragment. As a result, a
fragment that bridges two existing ranges may leave two adjacent ranges
unmerged, so fwnet_pd_is_complete() can miss a complete datagram.
Check for the list head before looking up the neighboring fragment, and
compare the neighbor against the new fragment's far edge when deciding
whether to merge all three ranges.
This issue was found by a static analysis checker and confirmed by
manual source review.
In the Linux kernel, the following vulnerability has been resolved:
wifi: ath6kl: fix OOB read from firmware num_msg in TX complete handler
The firmware-controlled num_msg field (u8, 0-255) drives the loop in
ath6kl_wmi_tx_complete_event_rx() without validation against the buffer
length. This allows out-of-bounds reads of up to 1020 bytes past the
WMI event buffer when the firmware sends an inflated num_msg.
Add a check that the buffer is large enough to hold the fixed struct
and the num_msg variable-length entries.
In the Linux kernel, the following vulnerability has been resolved:
wifi: ath6kl: fix OOB read from firmware IE lengths in connect event
The firmware-controlled beacon_ie_len, assoc_req_len, and assoc_resp_len
fields in ath6kl_wmi_connect_event_rx() are not validated against the
buffer length. Their sum (up to 765) can exceed the actual WMI event
data, causing out-of-bounds reads during IE parsing and state corruption
of wmi->is_wmm_enabled.
Add a check that the total IE length fits within the buffer.
In the Linux kernel, the following vulnerability has been resolved:
wifi: carl9170: bound memcpy length in cmd callback to prevent OOB read
When the firmware sends a command response with a length mismatch,
carl9170_cmd_callback() logs the mismatch and calls carl9170_restart()
but then falls through to memcpy(ar->readbuf, buffer + 4, len - 4).
Since len comes from the firmware and can exceed ar->readlen, this
copies more data than the readbuf was allocated for.
Bound the memcpy to min(len - 4, ar->readlen) so that the response
is still completed -- avoiding repeated restarts from queued garbage --
while preventing an overread past the response buffer.
In the Linux kernel, the following vulnerability has been resolved:
wifi: carl9170: fix OOB read from off-by-two in TX status handler
The bounds check in carl9170_tx_process_status() uses
`i > ((cmd->hdr.len / 2) + 1)` which is off by two, allowing
2 extra iterations past valid _tx_status entries when the firmware-
controlled hdr.ext exceeds hdr.len/2. Fix by using the correct
comparison `i >= (cmd->hdr.len / 2)`.
In the Linux kernel, the following vulnerability has been resolved:
wifi: carl9170: fix buffer overflow in rx_stream failover path
The failover continuation in carl9170_rx_stream() copies the full tlen
from the second USB transfer instead of capping at rx_failover_missing
bytes. When both transfers are near maximum size, the total exceeds the
65535-byte failover SKB, triggering skb_over_panic.
Limit the copy size to the missing byte count.
[Fix checkpatch CHECK:PARENTHESIS_ALIGNMENT]
In the Linux kernel, the following vulnerability has been resolved:
ASoC: tas2781: bound firmware description string parsing
The TAS2781 firmware parser reads several variable-length description
strings with strlen() before checking that the string terminator is
present inside the firmware blob. A malformed firmware image without a
NUL terminator can therefore make the parser walk past the end of the
firmware buffer before the later size checks run.
Add a small bounded string-length helper and use it for all description
fields that are parsed from the firmware buffer. Keep the existing size
checks for the fixed bytes that follow each string.
In the Linux kernel, the following vulnerability has been resolved:
ALSA: hda: cs35l41: validate and free ACPI mute object
cs35l41_get_acpi_mute_state() evaluates a _DSM method to get the ACPI
mute state and reads the first byte from the returned object.
However, the returned ACPI object is owned by the caller and is never
freed after use, so each successful query leaks the _DSM result object.
The code also assumes that the returned object is a buffer with at least
one byte. A malformed firmware response can return a different object
type or an empty buffer, and the direct ret->buffer.pointer dereference
can then access an invalid pointer.
Use the typed _DSM helper, validate that the returned buffer contains at
least one byte, and free the ACPI object after reading it.
In the Linux kernel, the following vulnerability has been resolved:
arm_mpam: guard MBWU state before adding it to garbage
__destroy_component_cfg() adds each RIS mbwu_state object to the MPAM
garbage list when destroying component configuration.
However, mbwu_state is allocated per RIS and only for RISes with MBWU
monitors. A component can therefore have comp->cfg allocated while some
RISes still have ris->mbwu_state set to NULL.
Passing a NULL mbwu_state to add_to_garbage() dereferences the NULL
pointer inside the macro.
Skip RISes that do not have an mbwu_state object before adding them to
the garbage list.
In the Linux kernel, the following vulnerability has been resolved:
usb: atm: ueagle-atm: reject descriptors that confuse probe and disconnect
uea_probe() distinguishes a pre-firmware device from a post-firmware one
using the USB id (UEA_IS_PREFIRM()), and stores a different object as the
interface data in each case: a 'struct completion' for a pre-firmware
device (to be waited on in .disconnect()), or a 'struct usbatm_data' for a
post-firmware one.
uea_disconnect() instead tells the two apart by the number of interfaces
of the active configuration (a pre-firmware device exposes a single
interface, ADI930 has 2 and eagle has 3), and casts the interface data
accordingly.
Because the two handlers use different criteria, a crafted device that
advertises a pre-firmware id together with a multi-interface descriptor
(or a post-firmware id with a single interface) makes them disagree: the
small 'struct completion' stored by uea_probe() is then passed to
usbatm_usb_disconnect(), which casts it to 'struct usbatm_data' and takes
instance->serialize, reading past the end of the allocation:
BUG: KASAN: slab-out-of-bounds in __mutex_lock+0x152a/0x1b80
Read of size 8 at addr ffff8880470e2c60 by task kworker/1:2/982
...
__mutex_lock+0x152a/0x1b80
usbatm_usb_disconnect+0x70/0x820
uea_disconnect+0x133/0x2c0
usb_unbind_interface+0x1dd/0x9e0
...
which belongs to the cache kmalloc-96 of size 96
The buggy address is located 0 bytes to the right of
allocated 96-byte region [ffff8880470e2c00, ffff8880470e2c60)
Reject such inconsistent descriptors in uea_probe() so that both handlers
always make the same pre/post-firmware decision.
In the Linux kernel, the following vulnerability has been resolved:
smb: client: validate DFS referral PathConsumed
parse_dfs_referrals() validates that the response contains the fixed
referral entry array and, on for-next, the per-referral string offsets.
However, the response also contains a PathConsumed value that is later
used for DFS path parsing.
If a malformed response provides a PathConsumed value larger than the
search name, later DFS parsing can advance beyond the end of the path.
Validate PathConsumed against the search name length before storing it in
the parsed referral.
In the Linux kernel, the following vulnerability has been resolved:
ovpn: avoid putting unrelated P2P peer on socket release
ovpn_peer_release_p2p() is called when an OVPN UDP socket is being
destroyed. It checks the currently published P2P peer and releases it only
if that peer still uses the socket being destroyed.
A peer replacement can publish a new peer before the old UDP socket is
destroyed. When the old socket destruction path runs afterwards,
ovpn_peer_release_p2p() observes the new peer through ovpn->peer. Since the
new peer uses a different socket, the function takes the socket mismatch
branch.
That branch still calls ovpn_peer_put(peer). At this point, however, peer
is the currently published replacement peer, not the peer associated with
the socket being destroyed. Dropping its reference can free it while
ovpn->peer still points to it, leading to later use-after-free accesses
from the peer and socket cleanup paths.
KASAN reports this as a slab-use-after-free on the kmalloc-1k ovpn_peer
object. In the reproducer, the object is allocated from ovpn_peer_new() via
ovpn_nl_peer_new_doit(), and freed through ovpn_peer_release_rcu() from RCU
callback processing. Observed access sites include ovpn_peer_remove(),
ovpn_socket_release(), ovpn_nl_peer_del_notify(), and unlock_ovpn().
Fix this by returning from the socket mismatch branch without putting the
peer.
In the Linux kernel, the following vulnerability has been resolved:
ovpn: fix use after free in unlock_ovpn()
unlock_ovpn() iterates over the release_list using llist_for_each_entry()
and drops the peer reference inside the loop body via ovpn_peer_put().
If this drops the last reference, the peer is eventually freed. However,
llist_for_each_entry() reads peer->release_entry.next in the loop advance
expression, which runs after the body. By that time the peer may have
already been freed, resulting in a use after free when advancing to the
next list entry.
Fix this by using llist_for_each_entry_safe(), which caches the next
pointer before executing the loop body.
In the Linux kernel, the following vulnerability has been resolved:
hwmon: occ: validate poll response sensor blocks
The OCC poll response parser walks a counted list of sensor data blocks.
It used the static backing-array capacity as the parse boundary, but a
transport response makes only data_length bytes current and valid. A
truncated response can therefore make the parser consume a block header or
block extent outside the current response.
Use data_length as the parent boundary, prove the fixed poll header and
each current block header before reading them, and prove the complete block
before advancing. Keep parsed sensor metadata local until the complete
response has passed validation, then publish it. Propagate
malformed-response errors before publishing the OCC as active.
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: btusb: validate Realtek vendor event length
btusb_recv_event_realtek() reads the event code at data[0] and the Realtek
subevent code at data[2] before deciding whether to consume a vendor event
as a coredump.
For example, the two-byte event ff 00 contains a complete vendor-event
header declaring zero parameters. The old classifier still reads a
nonexistent third byte and can misclassify the event as a coredump if the
adjacent byte is 0x34.
Require the HCI event header and first parameter to be present before
inspecting the Realtek subevent code. Short events continue through the
normal HCI receive path, which owns their protocol validation.
In the Linux kernel, the following vulnerability has been resolved:
net/packet: avoid fanout hook re-registration after unregister
packet_set_ring() temporarily detaches a socket from packet delivery while
reconfiguring its ring. It records the previous running state, clears
po->num, unregisters the protocol hook when needed, drops po->bind_lock,
and later restores po->num and re-registers the hook from the saved
was_running value.
That unlocked window can race with NETDEV_UNREGISTER. The notifier can
observe the socket as not running, skip __unregister_prot_hook(), and
invalidate the per-socket binding by setting po->ifindex to -1 and clearing
po->prot_hook.dev. A one-member fanout group can still retain its shared
fanout hook device pointer. When packet_set_ring() resumes, re-registering
solely from the stale was_running state can re-add the fanout hook after
the device has been unregistered.
Treat po->ifindex == -1 as an invalidated binding after reacquiring
po->bind_lock. This is distinct from ifindex 0, the normal
unbound/wildcard state: ifindex -1 marks an existing device binding that
was invalidated when the device was unregistered. Restore po->num as
before, but do not re-register the hook if device unregister already
detached the socket.
In the Linux kernel, the following vulnerability has been resolved:
bpf: Reject redirect helpers without a bpf_net_context
The bpf_redirect*() helpers and skb_do_redirect() obtain the per-task
bpf_redirect_info via bpf_net_ctx_get_ri(), which dereferences the
current->bpf_net_context unconditionally. That context is established
on the paths that run tc BPF such as sch_handle_{ingress,egress}(),
*except* for the case where {cls,act}_bpf was attached to a proper
qdisc. A program running from there reaches the NULL deref in two ways:
* It calls bpf_redirect() directly, which dereferences the context at
the top of the helper:
tc qdisc add dev eth0 root handle 1: red limit 1MB min 10KB max 20KB \
avpkt 1000 burst 100 qevent early_drop block 10
tc filter add block 10 pref 1 bpf obj redirect.o
* It simply returns TC_ACT_REDIRECT without helper call: tcf_qevent_handle()
then dispatches to skb_do_redirect(), which dereferences the context
Rather than extending bpf_net_context management into the qdisc path,
make the redirect helpers refuse to operate when no context exists, and
have tcf_qevent_handle() drop a TC_ACT_REDIRECT verdict instead of
calling skb_do_redirect(). Previous behaviour was a crash, so nothing
regresses by not supporting it.
In the Linux kernel, the following vulnerability has been resolved:
bonding: fix devconf_all NULL dereference when IPv6 is disabled
When booting with the 'ipv6.disable=1' parameter, the devconf_all is
never initialized because inet6_init() exits before addrconf_init() is
called which initializes it. bond_send_validate(), however, will still
call bond_ns_send_all() even ipv6 is indeed disabled. It will lead to
NULL derefence of net->ipv6.devconf_all in ip6_pol_route().
BUG: kernel NULL pointer dereference, address: 000000000000000c
[...]
Workqueue: bond0 bond_arp_monitor [bonding]
RIP: 0010:ip6_pol_route+0x69/0x480
[...]
Call Trace:
<TASK>
? srso_return_thunk+0x5/0x5f
? __pfx_ip6_pol_route_output+0x10/0x10
fib6_rule_lookup+0xfe/0x260
? wakeup_preempt+0x8a/0x90
? srso_return_thunk+0x5/0x5f
? srso_return_thunk+0x5/0x5f
? sched_balance_rq+0x369/0x810
ip6_route_output_flags+0xd7/0x170
bond_ns_send_all+0xde/0x280 [bonding]
bond_ab_arp_probe+0x296/0x320 [bonding]
? srso_return_thunk+0x5/0x5f
bond_activebackup_arp_mon+0xb4/0x2c0 [bonding]
process_one_work+0x196/0x370
worker_thread+0x1af/0x320
? srso_return_thunk+0x5/0x5f
? __pfx_worker_thread+0x10/0x10
kthread+0xe3/0x120
? __pfx_kthread+0x10/0x10
ret_from_fork+0x199/0x260
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Fix this by adding ipv6_mod_enabled() condition check in the caller.
In the Linux kernel, the following vulnerability has been resolved:
rds: drop incoming messages that cross network namespace boundaries
rds_find_bound() looks up the destination socket using a global
rhashtable keyed solely on (addr, port, scope_id). Network namespaces
are not part of the key, so a sender in netns A can deliver an incoming
message (inc) to a socket that lives in a different netns B.
When this happens, inc->i_conn points to an rds_connection whose c_net
is netns A, but the receiving rs lives in netns B. Once the child
process that created netns A exits, cleanup_net() calls
rds_loop_exit_net() -> rds_loop_kill_conns() -> rds_conn_destroy(),
freeing that connection. If the survivor socket in netns B still holds
the inc, any subsequent dereference of inc->i_conn is a use-after-free.
There are two dangerous sites in rds_clear_recv_queue():
1. inc->i_conn->c_lcong (offset 88 of freed rds_connection, size 200)
read via rds_recv_rcvbuf_delta() -- confirmed by KASAN.
2. inc->i_conn->c_trans->inc_free(inc) (function pointer at offset 80)
called via rds_inc_put() when the inc refcount reaches zero -- same
race window, potential call-through-freed-object primitive.
The bug is reachable from unprivileged user namespaces
(CLONE_NEWUSER + CLONE_NEWNET), available since Linux 3.8.
Fix this by rejecting the delivery in rds_recv_incoming() when the
socket returned by rds_find_bound() belongs to a different network
namespace than the connection that carried the message. Use the
existing rds_conn_net() / sock_net() helpers and net_eq() for the
comparison.
In the Linux kernel, the following vulnerability has been resolved:
rxrpc: fix io_thread race in rxrpc_wake_up_io_thread()
rxrpc_wake_up_io_thread() checks local->io_thread before waking it, but
then reloads the pointer for wake_up_process().
local->io_thread is cleared with WRITE_ONCE() when the I/O thread exits, so
the second load can see NULL even if the first load did not.
Take a READ_ONCE() snapshot and use it for both the NULL check and the
wake_up_process() call, as rxrpc_encap_rcv() already does.
In the Linux kernel, the following vulnerability has been resolved:
dpaa2-switch: put MAC endpoint device on disconnect
fsl_mc_get_endpoint() returns the MAC endpoint device with a reference
taken through device_find_child(). The switch port connect path stores
that device in mac->mc_dev and keeps it for the lifetime of the connected
MAC object.
However, the disconnect path only closes the MAC and frees the dpaa2_mac
object. It does not drop the endpoint device reference stored in
mac->mc_dev, so every successful connect leaks that device reference when
the MAC is later disconnected.
Drop the endpoint device reference before freeing the dpaa2_mac object.
In the Linux kernel, the following vulnerability has been resolved:
net: airoha: Fix potential use-after-free in airoha_ppe_deinit()
airoha_ppe_deinit() replaces the NPU pointer with NULL via
rcu_replace_pointer() but does not wait for existing RCU readers
to exit before calling ppe_deinit() and airoha_npu_put(). This can
cause a use-after-free if a reader in an RCU read-side critical
section still holds a reference to the NPU when it is freed.
The init path (airoha_ppe_init) already calls synchronize_rcu()
after rcu_assign_pointer(), but the deinit path introduced in
commit 6abcf751bc08 ("net: airoha: Fix schedule while atomic in
airoha_ppe_deinit()") omitted the matching barrier when switching
from rcu_read_lock()/rcu_dereference() to rcu_replace_pointer().
Add synchronize_rcu() before ppe_deinit() to ensure all existing
RCU readers have completed before the NPU resources are released.
In the Linux kernel, the following vulnerability has been resolved:
dpaa2-eth: put MAC endpoint device on disconnect
fsl_mc_get_endpoint() returns the MAC endpoint device with a reference
taken through device_find_child(). The Ethernet connect path stores that
device in mac->mc_dev and keeps it for the lifetime of the connected MAC
object.
However, the disconnect path only disconnects and closes the MAC before
freeing the dpaa2_mac object. It does not drop the endpoint device
reference stored in mac->mc_dev, so every successful connect leaks that
device reference when the MAC is later disconnected.
Drop the endpoint device reference after closing the MAC and before
freeing the dpaa2_mac object.
In the Linux kernel, the following vulnerability has been resolved:
net: airoha: Fix DMA direction for NPU mailbox buffer
airoha_npu_send_msg() always maps the mailbox buffer with DMA_TO_DEVICE,
but some callers expect the NPU to write response data back into the
same buffer:
- airoha_npu_wlan_msg_get() (NPU_OP_GET): NPU writes response into
the buffer, then the caller reads it via memcpy()
- airoha_npu_ppe_stats_setup() (NPU_OP_SET): NPU writes back
npu_stats_addr field in the response
On non-cache-coherent architectures like EN7581 (Cortex-A53 without
hardware cache coherency for NPU DMA), DMA_TO_DEVICE unmap is a no-op
— it does not invalidate the CPU cache. If the NPU-written cache line
is still present in the CPU cache when the caller reads the buffer,
the CPU observes stale data instead of the NPU response.
This is a timing-sensitive bug: small mailbox buffers (~24 bytes)
typically fit in a single cache line and may survive in the cache
until the caller reads them, producing silent data corruption rather
than a crash. The bug is more likely to trigger when the caller reads
the response immediately after dma_unmap_single() without intervening
cache-evicting operations.
Fix by using DMA_BIDIRECTIONAL for both map and unmap, which ensures
dma_unmap_single() invalidates the CPU cache on non-coherent systems.
The mailbox buffers are small so there is no performance concern.
In the Linux kernel, the following vulnerability has been resolved:
iommu/amd: Wait for completion instead of returning early in iommu_completion_wait()
need_sync is a per-IOMMU flag shared by all domains and devices behind
that IOMMU. It is set whenever a command is queued with sync == true and
cleared when a completion-wait (CWAIT) command is queued. However, a
cleared need_sync only means that a covering CWAIT has been queued, not
that all previously queued commands have actually completed in hardware.
iommu_completion_wait() read need_sync locklessly and returned early
when it was false. This breaks the "block until all previously queued
commands have completed" contract in a multi-CPU scenario:
CPU2: queue inv-B => need_sync = true
CPU1: queue CWAIT(N); need_sync = false; then wait_on_sem(N)
CPU2: read need_sync == false => return 0 (no wait!)
CPU2 returns without waiting for any sequence number even though its
inv-B may not have completed yet (CWAIT(N), queued after inv-B, has not
been signaled). CPU2 then proceeds to, for example, free page-table
pages while the IOMMU can still walk stale translations, opening a
use-after-free window. This is a logical race in the meaning of the
flag, not a memory-visibility issue, so barriers alone do not help.
Fix it without losing the optimization of avoiding redundant CWAIT
commands: take iommu->lock before testing need_sync, and when it is
false do not return early but wait for the last allocated sequence
number (cmd_sem_val). Since need_sync == false implies no sync command
was queued after the last CWAIT, that CWAIT is FIFO-ordered after every
not-yet-completed command, so waiting for its sequence number guarantees
all prior commands (possibly queued by another CPU) have completed. The
common path with pending work is unchanged and no extra hardware command
is issued.
In the Linux kernel, the following vulnerability has been resolved:
nfp: Check resource mutex allocation
nfp_cpp_resource_find() allocates a CPP mutex handle for the matching
resource-table entry and then reports success. nfp_resource_try_acquire()
immediately passes that handle to nfp_cpp_mutex_trylock().
However, nfp_cpp_mutex_alloc() returns NULL on failure. If that happens
for a matching table entry, the resource lookup still returns success and
the following trylock dereferences a NULL mutex pointer while opening the
resource.
nfp_resource_acquire() already treats failure to allocate the table mutex
as -ENOMEM. Do the same for the resource mutex and fail the lookup before
publishing the rest of the resource handle.
This issue was found by a static analysis checker and confirmed by
manual source review.
In the Linux kernel, the following vulnerability has been resolved:
wan: wanxl: Only reset hardware after BAR mapping
wanxl_pci_init_one() stores the freshly allocated card in driver data
before the PLX BAR is mapped. Several early probe failures then unwind
through wanxl_pci_remove_one(), including failure to allocate the coherent
status area or to restore the DMA mask.
wanxl_pci_remove_one() unconditionally calls wanxl_reset(), and
wanxl_reset() dereferences card->plx. On those early failures card->plx
is still NULL, so the error path can dereference a NULL MMIO pointer.
Only issue the hardware reset once the BAR mapping exists. The remaining
cleanup in wanxl_pci_remove_one() already checks whether later resources
were allocated.
This issue was found by a static analysis checker and confirmed by
manual source review.
In the Linux kernel, the following vulnerability has been resolved:
wifi: mwifiex: bound uAP association event IEs to the event buffer
mwifiex_process_uap_event() handles EVENT_UAP_STA_ASSOC by exposing the
(re)association request IEs that the firmware copies into the event:
sinfo->assoc_req_ies = &event->data[len];
len = (u8 *)sinfo->assoc_req_ies - (u8 *)&event->frame_control;
sinfo->assoc_req_ies_len = le16_to_cpu(event->len) - (u16)len;
event->len is supplied by the device firmware and is never validated,
and the subtraction is unchecked. assoc_req_ies points into
adapter->event_body[MAX_EVENT_SIZE], a fixed-size array embedded in the
kmalloc()'d struct mwifiex_adapter.
On the ap_11n_enabled path mwifiex_set_sta_ht_cap() walks these IEs with
cfg80211_find_ie(), whose for_each_element() loop dereferences each
element header. A firmware-reported event->len larger than the bytes
actually received makes assoc_req_ies_len describe IEs that extend past
event_body, so the walk reads out of the adapter slab object, a
slab-out-of-bounds read (KASAN: slab-out-of-bounds in cfg80211_find_ie).
An event->len smaller than the header instead makes the int subtraction
negative, which wraps to a huge size_t when stored in assoc_req_ies_len.
The same length is handed to cfg80211_new_sta(), so a more modest
over-claim can also copy stale event_body bytes into the
NL80211_CMD_NEW_STATION notification.
A malicious or malfunctioning mwifiex device (USB/SDIO/PCIe) can deliver
such an event while the interface is in AP/uAP mode.
Validate event->len before use: reject a length that underflows the
header or that would place the IEs outside the event_body[] buffer the
event was copied into. event->len here is struct mwifiex_assoc_event.len,
a payload field internal to this event, not the transport frame length,
so it is validated in this handler rather than at the generic
MWIFIEX_TYPE_EVENT receive path, which only sees the event cause and the
transport frame length. The bound is against event_body[MAX_EVENT_SIZE]
rather than the actually-received length because the transports store the
event differently (USB and SDIO leave the 4-byte event header in
event_skb, PCIe strips it via skb_pull), whereas event_body is the single
fixed buffer all of them copy the event into. This is the event-path
analogue of the receive-path bounds checks added in commit 119585281617
("wifi: mwifiex: Fix OOB and integer underflow when rx packets").
In the Linux kernel, the following vulnerability has been resolved:
iommu/amd: Bound the early ACPI HID map
The ivrs_acpihid command-line parser appends entries to a fixed
four-element early_acpihid_map array. Unlike the sibling IOAPIC and HPET
parsers, it does not reject a fifth entry before incrementing the map size.
Check the capacity at the common found label before parsing the HID and
UID or writing the entry.
In the Linux kernel, the following vulnerability has been resolved:
iommu/intel: Fix out-of-bounds memset in dmar_latency_disable()
dmar_latency_disable() intends to zero out only the single
latency_statistic entry for the given type, but the memset size was
computed as sizeof(*lstat) * DMAR_LATENCY_NUM, which clears the entire
array starting from &lstat[type].
When type > 0, this writes beyond the end of the allocated array,
corrupting adjacent memory.
Fix by using sizeof(*lstat) to clear only the target entry.
In the Linux kernel, the following vulnerability has been resolved:
tipc: serialize udp bearer replicast list updates
tipc_udp_rcast_add() and cleanup_bearer() both update ub->rcast.list with
list_add_rcu() / list_del_rcu(), but nothing serializes them. The add runs
from the encap receive softirq (via tipc_udp_rcast_disc()) without
rtnl_lock(), so it can race the cleanup delete and corrupt the list:
list_del corruption. prev->next should be ffff8880298d7ab8,
but was ffff88802449ad38. (prev=ffff888027e3ec98)
kernel BUG at lib/list_debug.c:62!
RIP: __list_del_entry_valid_or_report+0x17a/0x200
Workqueue: events cleanup_bearer
Call Trace:
cleanup_bearer (net/tipc/udp_media.c:811)
process_one_work (kernel/workqueue.c:3302)
worker_thread (kernel/workqueue.c:3466)
The bearer can be enabled from an unprivileged user namespace, as the
TIPCv2 generic-netlink ops carry no GENL_ADMIN_PERM.
Add a spinlock to struct udp_bearer and take it around the list_add_rcu()
in tipc_udp_rcast_add() and the list_del_rcu() loop in cleanup_bearer() so
the two writers can no longer corrupt the list.
Reject a duplicate peer under the same lock before allocating, and remove
tipc_udp_is_known_peer(). The old lockless pre-check in
tipc_udp_rcast_disc() was racy: two softirqs discovering the same peer
could both find it absent and add it twice.
cleanup_bearer() runs from a workqueue after tipc_udp_disable() clears the
bearer's up bit, so an encap softirq can still reach tipc_udp_rcast_add()
and add a peer after cleanup_bearer() has already emptied the list, leaking
that entry when the bearer is freed. Mark the bearer disabled under
rcast_lock once the list is emptied and refuse further additions.
In the Linux kernel, the following vulnerability has been resolved:
rds: Fix inet6_addr_lst NULL dereference when IPv6 is disabled
When booting with the 'ipv6.disable=1' parameter, inet6_addr_lst
is never initialized because inet6_init() exits before addrconf_init()
is called to initialize it. An attempt to bind an RDS socket to
an ipv6 address results in a crash in __ipv6_chk_addr_and_flags()
KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
RIP: 0010:__ipv6_chk_addr_and_flags+0x1df/0x7e0
Call Trace:
<TASK>
ipv6_chk_addr+0x3b/0x50
rds_tcp_laddr_check+0x155/0x3b0 [rds_tcp]
rds_trans_get_preferred+0x15d/0x2d0 [rds]
? trace_hardirqs_on+0x2d/0x110
rds_bind+0x1433/0x1d60 [rds]
? rds_remove_bound+0xd50/0xd50 [rds]
? aa_af_perm+0x250/0x250
? __might_fault+0xde/0x190
? __sys_bind+0x1dc/0x210
__sys_bind+0x1dc/0x210
? __ia32_sys_socketpair+0x100/0x100
? restore_fpregs_from_fpstate+0x53/0x100
__x64_sys_bind+0x73/0xb0
? syscall_enter_from_user_mode+0x1c/0x50
do_syscall_64+0x34/0x80
entry_SYSCALL_64_after_hwframe+0x6e/0xd8
RIP: 0033:0x7f47f8269ea9
</TASK>
The following code reproduces the issue:
struct sockaddr_in6 addr;
s = socket(PF_RDS, SOCK_SEQPACKET, 0);
memset(&addr, 0, sizeof(addr));
inet_pton(AF_INET6, ADDRESS, &addr.sin6_addr);
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(PORT);
bind(s, &addr, sizeof(addr));
Found by InfoTeCS on behalf of Linux Verification Center
(linuxtesting.org) with Syzkaller.
In the Linux kernel, the following vulnerability has been resolved:
net: txgbe: fix FDIR filter leak on remove
Perfect FDIR filters can be added while the interface is down and are
kept on the software list for later restore. unregister_netdev() only
calls ndo_stop when the device is up, so txgbe_fdir_filter_exit() in
txgbe_close() is skipped in that case and the filters are leaked on
driver remove. Free the filter list from txgbe_remove() as well.