In the Linux kernel, the following vulnerability has been resolved:
crypto: qat - fix VF2PF work teardown race in adf_disable_sriov()
The VF2PF interrupt handler queues PF-side response work that stores a
raw pointer to per-VF state (struct adf_accel_vf_info). Currently,
adf_disable_sriov() destroys per-VF mutexes and frees vf_info without
stopping new VF2PF work or waiting for in-flight workers to complete. A
concurrently scheduled or already queued worker can then dereference
freed memory.
This manifests as a use-after-free when KASAN is enabled:
BUG: KASAN: null-ptr-deref in mutex_lock+0x76/0xe0
Write of size 8 at addr 0000000000000260 by task kworker/24:2/...
Workqueue: qat_pf2vf_resp_wq adf_iov_send_resp [intel_qat]
Call Trace:
kasan_report+0x119/0x140
mutex_lock+0x76/0xe0
adf_gen4_pfvf_send+0xd4/0x1f0 [intel_qat]
adf_recv_and_handle_vf2pf_msg+0x290/0x360 [intel_qat]
adf_iov_send_resp+0x8c/0xe0 [intel_qat]
process_one_work+0x6ac/0xfd0
worker_thread+0x4dd/0xd30
kthread+0x326/0x410
ret_from_fork+0x33b/0x670
Add a PF-local flag, vf2pf_disabled, that gates work queueing, worker
processing, and interrupt re-enabling during teardown. Set this flag
atomically with the hardware interrupt mask inside
adf_disable_all_vf2pf_interrupts(). After masking, synchronize the AE
cluster MSI-X interrupt and flush the PF response workqueue before
tearing down per-VF locks and state so all in-flight work completes
before vf_info is destroyed.
Introduce adf_enable_all_vf2pf_interrupts() to clear the flag and
unmask all VF2PF interrupts under the same lock when SR-IOV is
re-enabled. This ensures the software flag and hardware state transition
atomically on both the enable and disable paths.
In the Linux kernel, the following vulnerability has been resolved:
staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie(), rtw_get_wapi_ie(), and rtw_get_wps_attr()
Three IE/attribute parsing functions have missing bounds checks.
rtw_get_sec_ie() and rtw_get_wapi_ie() iterate over a raw IE buffer
without verifying that the header bytes (tag + length) are within the
remaining buffer before reading them. Additionally, rtw_get_sec_ie()
compares the 4-byte WPA OUI at cnt+2 without checking that at least
6 bytes remain, and rtw_get_wapi_ie() compares a 4-byte WAPI OUI at
cnt+6 without checking that at least 10 bytes remain.
rtw_get_wps_attr() reads wps_ie[0] and wps_ie+2 unconditionally at
entry, before verifying that wps_ielen is large enough to contain
the 6-byte WPS IE header (element_id + length + 4-byte OUI). Inside
the attribute loop, get_unaligned_be16() is called on attr_ptr and
attr_ptr+2 without checking that 4 bytes remain in the buffer.
Add a cnt+2 bounds check before each loop body in rtw_get_sec_ie()
and rtw_get_wapi_ie(), guard each multi-byte comparison with a minimum
IE length requirement, add a wps_ielen < 6 early return in
rtw_get_wps_attr(), and add a 4-byte bounds check in its inner loop.
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn ref
l2cap_chan_timeout() runs asynchronously and accesses chan->conn. If
the connection is torn down while the timer is running or pending,
chan->conn can be freed, leading to a use-after-free when the timer
worker attempts to lock conn->lock:
| BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112 [inline]
| BUG: KASAN: slab-use-after-free in atomic_long_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:4456 [inline]
| BUG: KASAN: slab-use-after-free in __mutex_trylock_fast kernel/locking/mutex.c:161 [inline]
| BUG: KASAN: slab-use-after-free in mutex_lock+0x4f/0xa0 kernel/locking/mutex.c:318
| Write of size 8 at addr ffff8881298d9550 by task kworker/2:1/83
|
| CPU: 2 UID: 0 PID: 83 Comm: kworker/2:1 Not tainted 7.1.0-rc6-next-20260601-dirty #6 PREEMPT(full)
| Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
| Workqueue: events l2cap_chan_timeout
| Call Trace:
| <TASK>
| instrument_atomic_read_write include/linux/instrumented.h:112 [inline]
| atomic_long_try_cmpxchg_acquire include/linux/atomic/atomic-instrumented.h:4456 [inline]
| __mutex_trylock_fast kernel/locking/mutex.c:161 [inline]
| mutex_lock+0x4f/0xa0 kernel/locking/mutex.c:318
| l2cap_chan_timeout+0x5d/0x1b0 net/bluetooth/l2cap_core.c:422
| process_one_work kernel/workqueue.c:3326 [inline]
| process_scheduled_works+0x7c8/0xfb0 kernel/workqueue.c:3409
| worker_thread+0x8a9/0xcf0 kernel/workqueue.c:3490
| kthread+0x346/0x430 kernel/kthread.c:436
| ret_from_fork+0x1a3/0x470 arch/x86/kernel/process.c:158
| ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
| </TASK>
|
| Allocated by task 320:
| l2cap_conn_add+0xa7/0x820 net/bluetooth/l2cap_core.c:7075
| l2cap_connect_cfm+0xdb/0xd70 net/bluetooth/l2cap_core.c:7452
| hci_connect_cfm include/net/bluetooth/hci_core.h:2139 [inline]
| hci_remote_features_evt+0x52f/0x9f0 net/bluetooth/hci_event.c:3760
| hci_event_func net/bluetooth/hci_event.c:7796 [inline]
| hci_event_packet+0x561/0xa70 net/bluetooth/hci_event.c:7847
| hci_rx_work+0x370/0x890 net/bluetooth/hci_core.c:4040
| process_one_work kernel/workqueue.c:3326 [inline]
| process_scheduled_works+0x7c8/0xfb0 kernel/workqueue.c:3409
| worker_thread+0x8a9/0xcf0 kernel/workqueue.c:3490
| kthread+0x346/0x430 kernel/kthread.c:436
| ret_from_fork+0x1a3/0x470 arch/x86/kernel/process.c:158
| ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
|
| Freed by task 322:
| hci_disconn_cfm include/net/bluetooth/hci_core.h:2154 [inline]
| hci_conn_hash_flush+0x101/0x1f0 net/bluetooth/hci_conn.c:2736
| hci_dev_close_sync+0x889/0xde0 net/bluetooth/hci_sync.c:5405
| hci_dev_do_close net/bluetooth/hci_core.c:502 [inline]
| hci_unregister_dev+0x1f7/0x370 net/bluetooth/hci_core.c:2679
| vhci_release+0x12a/0x180 drivers/bluetooth/hci_vhci.c:690
| __fput+0x369/0x890 fs/file_table.c:510
| task_work_run+0x160/0x1d0 kernel/task_work.c:233
| get_signal+0xf5b/0x1120 kernel/signal.c:2810
| arch_do_signal_or_restart+0x4d/0x600 arch/x86/kernel/signal.c:337
| __exit_to_user_mode_loop kernel/entry/common.c:64 [inline]
| exit_to_user_mode_loop+0x85/0x510 kernel/entry/common.c:98
| do_syscall_64+0x263/0x3d0 arch/x86/entry/syscall_64.c:100
| entry_SYSCALL_64_after_hwframe+0x77/0x7f
|
| The buggy address belongs to the object at ffff8881298d9400
| which belongs to the cache kmalloc-512 of size 512
| The buggy address is located 336 bytes inside of
| freed 512-byte region [ffff8881298d9400, ffff8881298d9600)
Fix it by having chan->conn hold a reference to l2cap_conn (via
l2cap_conn_get) when the channel is added to the connection, and
releasing it in the channel destructor. This ensures the l2cap_conn
remains alive as long as the channel exists.
A new FLAG_DEL channel flag is introduced to indicate that the ch
---truncated---
In the Linux kernel, the following vulnerability has been resolved:
media: nxp: imx8-isi: Fix use-after-free on remove
KASAN reports a slab-use-after-free in __media_entity_remove_link()
during rmmod of imx8_isi:
BUG: KASAN: slab-use-after-free in __media_entity_remove_link+0x608/0x650
Read of size 2 at addr ffff0000d47cb02a by task rmmod/724
Call trace:
__media_entity_remove_link+0x608/0x650
__media_entity_remove_links+0x78/0x144
__media_device_unregister_entity+0x150/0x280
media_device_unregister_entity+0x48/0x68
v4l2_device_unregister_subdev+0x158/0x300
v4l2_async_unbind_subdev_one+0x22c/0x358
v4l2_async_nf_unbind_all_subdevs+0xfc/0x1c0
v4l2_async_nf_unregister+0x5c/0x14c
mxc_isi_remove+0x124/0x2a0 [imx8_isi]
Allocated by task 249:
__kmalloc_noprof+0x27c/0x690
mxc_isi_crossbar_init+0x22c/0x560 [imx8_isi]
Freed by task 724:
kfree+0x1e4/0x5b0
mxc_isi_crossbar_cleanup+0x34/0x80 [imx8_isi]
mxc_isi_remove+0x11c/0x2a0 [imx8_isi]
The problem is that mxc_isi_remove() calls mxc_isi_crossbar_cleanup()
before mxc_isi_v4l2_cleanup(). The crossbar cleanup frees the media
entity pads, but the subsequent v4l2 cleanup still tries to remove
media links that reference those pads.
Fix this by calling mxc_isi_v4l2_cleanup() before
mxc_isi_crossbar_cleanup() to ensure all media entities are properly
unregistered while the pads are still valid.
In the Linux kernel, the following vulnerability has been resolved:
gpio: sch: use raw_spinlock_t in the irq startup path
sch_irq_unmask() enables the GPIO IRQ and then updates the controller
state through sch_irq_mask_unmask(), which takes sch->lock with
spin_lock_irqsave(). The callback can be reached from irq_startup()
while setting up a requested IRQ. That path is not sleepable, but on
PREEMPT_RT a regular spinlock_t becomes a sleeping lock.
This issue was found by our static analysis tool and then manually
reviewed against the current tree.
The grounded PoC kept the request_threaded_irq() -> __setup_irq() ->
irq_startup() -> sch_irq_unmask() -> sch_irq_mask_unmask() carrier and
used the original spin_lock_irqsave(&sch->lock) edge. Lockdep reported:
BUG: sleeping function called from invalid context
hardirqs last disabled at ... __setup_irq.constprop.0 ... [vuln_msv]
sch_rt_spin_lock_irqsave+0x1c/0x30 [vuln_msv]
sch_irq_mask_unmask.constprop.0+0x31/0x70 [vuln_msv]
__setup_irq.constprop.0+0xd/0x30 [vuln_msv]
Convert the SCH controller lock to raw_spinlock_t. The same lock is
also used by the GPIO direction and value callbacks, but those critical
sections only update MMIO-backed GPIO registers and do not contain
sleepable operations. Keeping this register lock non-sleeping is
therefore appropriate for the irqchip callbacks and does not change the
GPIO-side locking contract.
In the Linux kernel, the following vulnerability has been resolved:
netfilter: ebtables: zero chainstack array
sashiko reports:
looking at ebtables table
translation, could a sparse cpu_possible_mask lead to an uninitialized pointer
free?
If cpu_possible_mask is sparse (for example, CPU 0 and CPU 2 are possible,
but CPU 1 is not), the allocation loop skips CPU 1. If vmalloc_node() fails at
CPU 2, the cleanup loop will blindly decrement and call vfree() on
newinfo->chainstack[1].
Not a real-world bug, such allocation isn't expected to fail
in the first place.
In the Linux kernel, the following vulnerability has been resolved:
mm: swap_cgroup: fix NULL deref in lookup_swap_cgroup_id on swapless host
lookup_swap_cgroup_id() passes swap_cgroup_ctrl[type].map to
__swap_cgroup_id_lookup() without checking that the type was ever
registered via swap_cgroup_swapon(). On a swapless host every ctrl->map
is NULL, so __swap_cgroup_id_lookup() dereferences NULL + a scaled
swp_offset().
Since commit bea67dcc5eea ("mm: attempt to batch free swap entries for
zap_pte_range()"), zap_pte_range() -> swap_pte_batch() calls
lookup_swap_cgroup_id() on any non-present, non-none PTE that decodes as a
real swap entry, without first validating it against swap_info[]. A
single PTE corrupted into a type-0 swap entry takes the host down at
process exit.
We hit this in production on a swapless 6.12.58 host: ~1s of
"get_swap_device: Bad swap file entry 3f800204222bb" (do_swap_page() being
correctly defensive about the same entry) followed by
BUG: unable to handle page fault for address: 000003f800204220
RIP: 0010:lookup_swap_cgroup_id+0x2b/0x60
Call Trace:
swap_pte_batch+0xbf/0x230
zap_pte_range+0x4c8/0x780
unmap_page_range+0x190/0x3e0
exit_mmap+0xd9/0x3c0
do_exit+0x20c/0x4b0
syzbot has reported the identical stack.
The source of the PTE corruption is a separate bug; this change makes the
teardown path as robust as the fault path already is. Every other caller
of lookup_swap_cgroup_id() is downstream of a get_swap_device() that has
already validated the entry, so the new branch is cold.
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()
hci_abort_conn() read hci_skb_event(hdev->sent_cmd) when a connection
was pending, but hdev->sent_cmd can be NULL while req_status is still
HCI_REQ_PEND, leading to a NULL pointer dereference and a general
protection fault from the hci_rx_work() receive path.
Instead of inspecting hdev->sent_cmd, track the in-flight create
connection command with a new per-connection HCI_CONN_CREATE flag and
route all cancellation through hci_cancel_connect_sync(), which
dispatches to a dedicated per-type cancel function. The create command
is in exactly one of two states: still queued, or in flight. The cancel
function holds cmd_sync_work_lock across the whole decision: the worker
takes this lock to dequeue every entry, so while it is held a queued
command cannot start running and an in-flight command cannot complete
and let the next command become pending. This keeps the flag test and
hci_cmd_sync_cancel() atomic with respect to the worker, so a queued
command is simply dequeued, and an in-flight command owned by this
connection is cancelled without the risk of cancelling an unrelated
command that became pending in the meantime. CIS uses the same flag
mechanism via HCI_CONN_CREATE_CIS but cannot be dequeued per-connection.
hci_acl_create_conn_sync() and hci_le_create_conn_sync() clear
HCI_CONN_CREATE after the create command completes, but the command
status handler can free conn via hci_conn_del() (for example when the
controller rejects the connection) while the worker is still blocked on
the connection complete event. Hold a reference on conn across the
create command so the flag can be cleared without a use-after-free.
In the Linux kernel, the following vulnerability has been resolved:
ksmbd: prevent path traversal bypass by restricting caseless retry
ksmbd_vfs_path_lookup() enforces LOOKUP_BENEATH to restrict path
resolution within the share root. When a crafted path attempts to
escape the share boundary using parent-directory components ('..'),
vfs_path_parent_lookup() detects this and immediately fails,
returning -EXDEV.
However, a bug exists in __ksmbd_vfs_kern_path() under caseless mode.
The function fails to intercept the -EXDEV error and erroneously
falls through to the caseless retry logic, which is intended only
for genuinely missing files. During this retry process, the path
is reconstructed, leading to an unintended LOOKUP_BENEATH bypass
that allows write-capable users to create zero-length files or
directories outside the exported share.
Fix this by ensuring that the execution only proceeds to the caseless
lookup retry when the error is specifically -ENOENT. Any other errors,
such as -EXDEV from a path traversal attempt, must be returned immediately.
In the Linux kernel, the following vulnerability has been resolved:
smb: client: resolve SWN tcon from live registrations
cifs_swn_notify() looks up a witness registration by id under
cifs_swnreg_idr_mutex, drops the mutex, and then uses the registration's
cached tcon pointer. That pointer is not a lifetime reference, and it is
not a stable representative once cifs_get_swn_reg() lets multiple tcons
for the same net/share name share one registration id.
A same-share second mount can keep the cifs_swn_reg alive after the first
tcon unregisters and is freed. The registration then still points at the
freed first tcon, so taking tc_lock or incrementing tc_count through
swnreg->tcon only moves the use-after-free earlier. Taking tc_lock while
holding cifs_swnreg_idr_mutex also violates the documented CIFS lock
order.
Fix this by making the registration store only the stable witness
identity: id, net name, share name, and notify flags. When a notify
arrives, copy that identity under cifs_swnreg_idr_mutex, drop the mutex,
then find and pin a live witness tcon that currently matches the net/share
pair under the normal cifs_tcp_ses_lock -> tc_lock order. The notification
path uses that pinned tcon directly and drops the reference when done.
Registration and unregister messages now use the live tcon passed by the
caller instead of a cached tcon in the registration. The final unregister
send is folded into cifs_swn_unregister() while the registration is still
protected by cifs_swnreg_idr_mutex. This removes the previous
find/drop/reacquire raw-pointer window. The release path only removes the
idr entry and frees the stable identity strings.
This preserves the intended one-registration/many-tcon behavior: a
registration id represents a net/share pair, and notify handling acts on a
live representative selected at use time. It also preserves CLIENT_MOVE
ordering for the representative tcon because the old-IP unregister is sent
before cifs_swn_register() sends the new-IP register.