| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
net/mlx5e: Fix HV VHCA stats agent registration race
mlx5e_hv_vhca_stats_create() registers the stats agent through
mlx5_hv_vhca_agent_create(). The helper publishes the agent in
hv_vhca->agents[type] under agents_lock and immediately schedules an
asynchronous control invalidation on the HV VHCA workqueue before
returning to mlx5e.
The asynchronous invalidation invokes the control agent's invalidate
callback, which reads the hypervisor control block and forwards the
command to mlx5e_hv_vhca_stats_control(). That callback may either:
- call cancel_delayed_work_sync(&priv->stats_agent.work), or
- call queue_delayed_work(priv->wq, &sagent->work, sagent->delay).
However, the delayed_work and priv->stats_agent.agent are only
initialized after mlx5_hv_vhca_agent_create() returns to mlx5e:
agent = mlx5_hv_vhca_agent_create(...); /* publish + invalidate */
...
priv->stats_agent.agent = agent; /* too late */
INIT_DELAYED_WORK(&priv->stats_agent.work, ...); /* too late */
If the asynchronous control path runs before the two assignments
above, it can:
- Operate on an uninitialized delayed_work whose timer.function is
NULL. queue_delayed_work() calls add_timer() unconditionally, so
when the timer expires the timer softirq invokes a NULL function
pointer.
- Re-initialize the timer later through INIT_DELAYED_WORK() while
the timer is already enqueued in the timer wheel, corrupting the
hlist (entry.pprev cleared while the previous bucket node still
points at this entry).
- When the worker eventually runs, mlx5e_hv_vhca_stats_work() reads
sagent->agent (NULL) and dereferences it inside
mlx5_hv_vhca_agent_write().
Fix this by:
- Initializing priv->stats_agent.work before invoking
mlx5_hv_vhca_agent_create(), so the work is always in a valid
state when the control callback observes it.
- Adding a struct mlx5_hv_vhca_agent **ctx_update out-parameter
to mlx5_hv_vhca_agent_create(). The helper writes the agent
pointer to *ctx_update before publishing into hv_vhca->agents[]
and triggering the agents_update flow, so any callback
subsequently invoked from that flow already sees a valid
priv->stats_agent.agent. This avoids having the control
callback participate in agent initialization.
While at it, access priv->stats_agent.agent with
READ_ONCE()/WRITE_ONCE() for the cross-CPU access with the worker, and
clear priv->stats_agent.buf on the agent_create() failure path. |
| In the Linux kernel, the following vulnerability has been resolved:
net: microchip: vcap: fix races on the shared Super VCAP block
The VCAP instances on a chip are not independent, yet they are locked
independently. On sparx5 and lan969x the IS0 and IS2 instances are
backed by the same Super VCAP hardware block and share its cache and
command registers: every access drives the shared VCAP_SUPER_CTRL
register and moves data through the shared cache registers.
Accessing one instance therefore races with accessing another. The
per-instance admin->lock cannot prevent this, as each instance takes a
different lock.
The locking issue is mostly disguised by the fact that the core usage of
the vcap api runs under rtnl. However, the full rule dump in debugfs
decodes rules straight from hardware (a READ command followed by a cache
read) and runs outside rtnl, so it races a concurrent tc-flower rule
write to another Super VCAP instance.
Besides corrupting the dump, the read repopulates the shared cache
between the writers cache fill and its write command, so the writer
commits the wrong data and corrupts the hardware entry.
Introduce vcap_lock() and vcap_unlock() helpers and route every rule
lock site in the VCAP API and its debugfs code through them. Replace the
per-instance admin->lock with a single mutex in struct vcap_control that
serializes access to all instances. The helpers reach it through a new
admin->vctrl back-pointer, and the clients initialise and destroy the
control lock instead of a per-instance one.
No path holds more than one instance lock, so collapsing them onto a
single mutex cannot self-deadlock. |
| In the Linux kernel, the following vulnerability has been resolved:
qede: fix off-by-one in BD ring consumption on build_skb failure
qede_rx_build_skb() and qede_tpa_rx_build_skb() do not check for a
NULL return from qede_build_skb(). When it returns NULL under memory
pressure, the functions still consume a BD from the ring before
returning NULL. The callers then recycle additional BDs, resulting in
one extra BD being consumed (off-by-one). This desynchronizes the BD
ring, which can corrupt DMA page reference counts and lead to SLUB
freelist corruption.
Commit 4e910dbe3650 ("qede: confirm skb is allocated before using")
added a NULL check inside qede_build_skb() to prevent a NULL pointer
dereference, but did not address the missing NULL checks in the
callers, making this off-by-one reachable.
Fix this by adding NULL checks for the return value of
qede_build_skb() in both qede_rx_build_skb() and
qede_tpa_rx_build_skb(), returning NULL immediately before any BD ring
manipulation. |
| In the Linux kernel, the following vulnerability has been resolved:
net/sched: act_pedit: fix TOCTOU heap OOB write in tc offload
There is a TOCTOU race condition in flower lockless approach between sizing
a flow_rule buffer and filling it.
[email protected] reports:
The cls_flower classifier operates with TCF_PROTO_OPS_DOIT_UNLOCKED
(fl_change runs without RTNL), while RTM_NEWACTION holds RTNL, so the
independent locking domains make the race reachable in practice. KASAN
confirms:
BUG: KASAN: slab-out-of-bounds in tcf_pedit_offload_act_setup+0x81b/0x930
Write of size 4 at addr ffff888001f27520 by task poc-toctou/312
The buggy address is located 0 bytes to the right of
allocated 288-byte region [ffff888001f27400, ffff888001f27520)
(cache kmalloc-512)
Note: The result is a heap OOB write attacker-controlled content into the
adjacent slab object (requires CAP_NET_ADMIN).
The fix introduces reading tcfp_nkeys under act->tcfa_lock in all places
using a new tcf_pedit_nkeys_locked() which replaces the old tcf_pedit_nkeys().
Additionally we close the remaining TOCTOU window between the sizing read and
the fill reads by more careful accounting.
Rather than silently truncating the key count, which leads to incorrect
action semantics offloaded to hardware and secondary OOB writes if
the remaining capacity is zero or consumed by prior actions, we enforce
remaining capacity checks and return -ENOSPC if the required space exceeds
the remaining capacity. |
| In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: MGMT: Fix adv monitor add failure cleanup
hci_add_adv_monitor() publishes a new adv_monitor in
hdev->adv_monitors_idr before the powered MSFT setup step. The MSFT
offload add path can then fail either locally before the controller add
command completes, or in the MSFT add callback. In the current queued
management add flow, hci_cmd_sync_work() still invokes
mgmt_add_adv_patterns_monitor_complete() with the original pending command
after msft_add_monitor_pattern() returns.
The buggy scenario involves two paths, with each column showing the order
within that path:
MSFT add handling MGMT completion
1. insert monitor and handle 1. receive sync error
2. send MSFT add command 2. call add-monitor completion
3. callback sees bad response 3. load cmd->user_data
4. callback frees monitor 4. read monitor->handle
Local MSFT setup failures have the other half of the same ownership bug:
they return an error after the IDR insertion, but no later code removes the
failed monitor from the IDR.
Keep ownership with the pending management command until its completion.
For normal management adds, the MSFT add callback now records successful
controller state and returns errors to its caller. The management
completion frees the monitor on non-success after copying the response
handle, while resume/reregister callback-error cleanup remains in the
MSFT callback. The success path keeps the existing bookkeeping.
Validation reproduced this kernel report:
BUG: KASAN: slab-use-after-free in mgmt_add_adv_patterns_monitor_complete+0xfb/0x260 [bluetooth]
Call Trace:
<TASK>
dump_stack_lvl+0x66/0xa0
print_report+0xce/0x5f0
? mgmt_add_adv_patterns_monitor_complete+0xfb/0x260 [bluetooth]
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x19f/0x330
? mgmt_add_adv_patterns_monitor_complete+0xfb/0x260 [bluetooth]
kasan_report+0xe0/0x110
? mgmt_add_adv_patterns_monitor_complete+0xfb/0x260 [bluetooth]
mgmt_add_adv_patterns_monitor_complete+0xfb/0x260 [bluetooth]
? srso_alias_return_thunk+0x5/0xfbef5
? 0xffffffffc00d00da
? __pfx_mgmt_add_adv_patterns_monitor_complete+0x10/0x10 [bluetooth]
? __pfx_mgmt_add_adv_patterns_monitor_complete+0x10/0x10 [bluetooth]
? hci_cmd_sync_work+0x1ab/0x210 [bluetooth]
hci_cmd_sync_work+0x1c0/0x210 [bluetooth]
? __pfx_mgmt_add_adv_patterns_monitor_complete+0x10/0x10 [bluetooth]
process_one_work+0x4fd/0xbc0
? __pfx_process_one_work+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? __list_add_valid_or_report+0x37/0xf0
? __pfx_hci_cmd_sync_work+0x10/0x10 [bluetooth]
? 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 471 on cpu 3 at 285.205389s:
kasan_save_stack+0x33/0x60
kasan_save_track+0x17/0x60
__kasan_kmalloc+0xaa/0xb0
add_adv_patterns_monitor_rssi+0xd5/0x230 [bluetooth]
hci_sock_sendmsg+0x96b/0xf80 [bluetooth]
__sys_sendto+0x2bc/0x2d0
__x64_sys_sendto+0x76/0x90
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 454 on cpu 2 at 285.217112s:
kasan_save_stack+0x33/0x60
kasan_save_track+0x17/0x60
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
kfree+0x313/0x590
msft_add_monitor_sync+0x54a/0x570 [bluetooth]
hci_add_adv_monitor+0x133/0x180 [bluetooth]
hci_cmd_sync_work+0x187/0x210 [bluetooth]
process_one_work+0x4fd/0xbc0
worker_thread+0x2d8/0x570
kthread+0x1ad/0x1f0
ret_from_fork+0x3c9/0x540
ret_from_fork_asm+0x1a/0x30 |
| In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: ISO: fix malformed ISO_END/CONT handling
Core specification (Part C vol 4 sec 5.4.5) does not exclude empty
ISO_CONT, ISO_END packets. We currently reject them if they are last.
If controller sends malformed sequence
ISO_START -> rx_len = 4, ISO_CONT skb->len 4, ISO_START
that ends payload in ISO_CONT, we leak conn->rx_skb. If controller sends
too long ISO_END, we panic on skb_put. If controller sends too short
ISO_END we accept it.
Fix by marking unfinished ISO_START via conn->rx_skb != NULL. Check
skb->len properly before skb_put. Combine the ISO_CONT/END code paths
as they require the same initial checks. Reject too short ISO_END
packets. |
| In the Linux kernel, the following vulnerability has been resolved:
accel/amdxdna: Fix VMA access race
aie2_populate_range() and amdxdna_umap_release() access a saved VMA
pointer that may have already been freed, leading to a potential
use-after-free.
Remove the VMA accesses from these functions to avoid the race. |
| In the Linux kernel, the following vulnerability has been resolved:
net/tls: Consume empty data records in tls_sw_read_sock()
A peer may send a zero-length TLS application_data record; TLS 1.3
explicitly permits these as a traffic-analysis countermeasure (RFC
8446, Section 5.1). After decryption such a record has full_len ==
0. tls_sw_read_sock() hands it to the read_actor, which has no
payload to consume and returns zero. The loop treats a zero return
as backpressure (used <= 0), requeues the skb at the head of
rx_list, and stops. rx_list is serviced head-first on the next
call, so the empty record is dequeued, fails the same way, and is
requeued again; every later record on the connection is blocked
behind it.
tls_sw_recvmsg() does not stall on this: a zero-length data record
copies nothing and falls through to consume_skb(). Mirror that in
the read_sock() path by recognizing an empty data record before
the actor runs, consuming it, and continuing. |
| In the Linux kernel, the following vulnerability has been resolved:
net/liquidio: drop cached VF pci_dev LUT
The PF SR-IOV enable path caches VF pci_dev pointers in
dpiring_to_vfpcidev_lut[] by iterating with pci_get_device(). Those
entries do not own a reference, because the iterator drops the previous
device reference on each step. The cached pointer is then dereferenced
later when handling OCTEON_VF_FLR_REQUEST.
Replace the cached VF mapping with runtime lookup on the mailbox DPI
ring: derive the VF index from q_no, resolve the VF via exported PCI
IOV helpers, validate it with the PF pointer and VF ID, then issue
pcie_flr() and drop the reference with pci_dev_put(). Remove the
unused VF lookup table initialization and cleanup. |
| In the Linux kernel, the following vulnerability has been resolved:
accel/amdxdna: Fix potential amdxdna_umap lifetime race
amdxdna_umap_release() calls the blocking mmu_interval_notifier_remove()
before removing the object from abo->mem.umap_list. If
aie2_populate_range() runs concurrently, it may obtain a reference to an
amdxdna_umap that is being released, leading to a potential use-after-free.
Use kref_get_unless_zero() in aie2_populate_range() when acquiring a
reference. If the reference count has already dropped to zero, release
is in progress and the entry is skipped. |
| In the Linux kernel, the following vulnerability has been resolved:
ipv4: igmp: Fix potential UAF in igmp_gq_start_timer()
A race condition exists between device teardown (inetdev_destroy) and
incoming IGMP query processing (igmp_rcv), leading to a Use-After-Free
in the IGMP timer callback.
During device destruction, inetdev_destroy() drops the primary reference
to in_device, which can drop its refcount to 0. The actual freeing of
in_device memory is deferred via RCU (using call_rcu()).
Concurrently, igmp_rcv() runs under RCU read lock and obtains the
in_device pointer. Because the memory is RCU-protected, CPU-0 can safely
dereference in_device even if its refcount has hit 0.
However, if CPU-0 calls igmp_gq_start_timer() and re-arms the timer, it
attempts to acquire a reference using in_dev_hold(). This increments the
refcount from 0 to 1, triggering a "refcount_t: addition on 0" warning.
Since the in_device memory is still scheduled to be freed after the RCU
grace period (as the free callback does not check the refcount again),
the device is freed while the timer is still armed. When the timer
expires, it accesses the freed memory, causing a kernel panic.
Fix this by using refcount_inc_not_zero() (via a new helper
in_dev_hold_safe()) to prevent acquiring a reference if the device is
already being destroyed. If the refcount is 0, we do not arm the timer.
A similar issue in IPv6 MLD is fixed in a subsequent patch. |
| In the Linux kernel, the following vulnerability has been resolved:
ipv6: mcast: Fix potential UAF in MLD delayed work
A race condition exists between device teardown and incoming MLD query
processing, leading to a Use-After-Free in the MLD delayed work.
During device destruction, the primary reference to inet6_dev is dropped,
which can drop its refcount to 0. The actual freeing of inet6_dev memory
is deferred via RCU.
Concurrently, the packet receive path runs under RCU read lock and obtains
the inet6_dev pointer. Because the memory is RCU-protected, CPU-0 can
safely dereference inet6_dev even if its refcount has hit 0.
However, if CPU-0 calls igmp6_event_query() and schedules delayed work, it
attempts to acquire a reference using in6_dev_hold(). This increments the
refcount from 0 to 1, triggering a "refcount_t: addition on 0" warning.
Since the inet6_dev memory is still scheduled to be freed after the RCU
grace period, the device is freed while the work is still scheduled.
When the work runs, it accesses the freed memory, causing a kernel panic.
Fix this by using refcount_inc_not_zero() (via a new helper
in6_dev_hold_safe()) to prevent acquiring a reference if the device is
already being destroyed. If the refcount is 0, we do not schedule the work. |
| In the Linux kernel, the following vulnerability has been resolved:
netfilter: nft_lookup: fix catchall element handling with inverted lookups
nft_lookup_eval() decides whether a lookup matched (`found`) from the
direct set lookup and priv->invert before falling back to the
catchall element used by interval sets (e.g. nft_set_rbtree) for the
open-ended default range. Since `found` is never recomputed after
`ext` is replaced by the catchall lookup, inverted lookups
(NFT_LOOKUP_F_INV, "!= @set") can wrongly match or wrongly skip the
catchall element, producing the wrong verdict. Fold the catchall
lookup into `ext` before computing `found`, matching the order
already used by nft_objref_map_eval(). |
| In the Linux kernel, the following vulnerability has been resolved:
ipvs: ensure inner headers in ICMP errors are in headroom
Sashiko points out that after stripping the outer headers
with pskb_pull() we should ensure the inner IP headers
in ICMP errors from tunnels are present in the skb headroom
for functions like ipv4_update_pmtu(), icmp_send() and
IP_VS_DBG().
Also, add more checks for the length of the inner headers. |
| In the Linux kernel, the following vulnerability has been resolved:
cifs: validate DFS referral string offsets
parse_dfs_referrals() validates that the response header and referral
array fit in the received buffer, but each referral also contains string
offsets supplied by the server.
Those offsets are used to compute the DfsPath and NetworkAddress string
pointers without checking whether they still point inside the response
buffer. A malformed referral can therefore make the computed pointer
exceed the end of the buffer. The resulting negative max_len is then
passed to cifs_strndup_from_utf16(), and the non-Unicode path forwards it
to kstrndup() as a size_t, allowing strnlen() to read out of bounds.
Validate each string offset before deriving the string pointer. |
| In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: pin upper rpc_clnt across the TLS connect_worker
The TLS connect path has a use-after-free: nothing pins the
upper rpc_clnt across the delayed connect_worker. xs_connect()
stores task->tk_client in sock_xprt::clnt as a raw pointer
and queues the worker; for TLS-secured transports that worker
is xs_tcp_tls_setup_socket(), which reads several fields out
of the saved pointer (cl_timeout, cl_program, cl_prog,
cl_vers, cl_cred, cl_stats) to construct the args for the
inner handshake rpc_clnt.
The xprt does not reference the rpc_clnt; the rpc_clnt
references the xprt. xs_destroy() does cancel the
connect_worker, but it runs only when the xprt's refcount
drops to zero, which cannot happen until the rpc_clnt
releases its cl_xprt reference in rpc_free_client_work().
When a TLS handshake fails fatally (for example, an mTLS
mount whose client cert does not match the server), the
connecting task is woken with -EACCES and exits, the mount
caller invokes rpc_shutdown_client(), and the upper rpc_clnt
is freed before the queued connect_worker fires.
xs_tcp_tls_setup_socket() then dereferences the freed clnt,
producing the refcount_t underflow Michael Nemanov reported.
Take a reference on the upper rpc_clnt in xs_connect() for
TLS transports via a new rpc_hold_client() helper, and drop
it in the connect_worker's exit path with rpc_release_client().
The xprt_lock_connect() / xprt_unlock_connect() pairing
already serialises xs_connect() with xs_tcp_tls_setup_socket(),
so the take and release are balanced one-for-one.
The non-TLS connect worker (xs_tcp_setup_socket) never reads
sock_xprt::clnt, so leave that path alone and avoid the
clnt-holds-xprt-holds-clnt cycle that would otherwise prevent
xprt destruction. |
| In the Linux kernel, the following vulnerability has been resolved:
smb: client: fix busy dentry warning on unmount after DIO
Commit c68337442f03 ("cifs: Fix busy dentry used after unmounting") fixed
the issue in cifs where deferred close of a file led to a dentry reference
count not being released in umount, by flushing deferredclose_wq in
cifs_kill_sb() to solve it.
However, the cifs DIO path suffers from the same busy-dentry problem caused
by a delayed dentry reference-count release:
[dio] [cifsd] [close + umount]
netfs_unbuffered_write_iter_locked
...
cifs_demultiplex_thread
netfs_unbuffered_write
cifs_issue_write
netfs_wait_for_in_progress_stream [1]
...
netfs_write_subrequest_terminated
netfs_subreq_clear_in_progress
netfs_wake_collector // wake [1]
netfs_put_subrequest
netfs_put_request
queue_work(system_dfl_wq, xxx) [2]
// dio write return cifs_close
_cifsFileInfo_put
// cfile->count 2->1
--cfile->count [3]
// umount
cifs_kill_sb
kill_anon_super
// warning triggered!
shrink_dcache_for_umount [4]
[system_dfl_wq] [5]
netfs_free_request
...
_cifsFileInfo_put
// cfile->count 1->0
--cfile->count
queue_work(fileinfo_put_wq, xxx)
[fileinfo_put_wq] [6]
cifsFileInfo_put_work
cifsFileInfo_put_final
dput
If the umount path is triggered before [5], it results warning:
BUG: Dentry 00000000eab1f070{i=9a917b66ae404fec,n=test} still in use (1)
[unmount of cifs cifs]
The existing per-inode ictx->io_count wait in cifs_evict_inode() does not
help: it lives in the inode eviction path, which runs after
shrink_dcache_for_umount() has already warned about the busy dentries.
Fix it by adding a per-superblock outstanding-rreq counter that is
incremented in cifs_init_request() and decremented in cifs_free_request().
In cifs_kill_sb(), before kill_anon_super(), wait for this counter to reach
0 - which guarantees that all cleanup_work for this sb have run and thus
all relevant cfile puts are queued on fileinfo_put_wq or serverclose_wq.
Then drain the workqueue so the dentry refs are dropped.
This is a targeted wait, not a flush of the system-wide system_dfl_wq. |
| In the Linux kernel, the following vulnerability has been resolved:
regulator: core: regulator_lock_two() should test for EDEADLK not EDEADLOCK
Compare against -EDEADLK, which is what ww_mutex_lock() actually
returns and what every other deadlock check in this file already uses.
Function regulator_lock_two() acquires two regulators via
regulator_lock_nested() -> ww_mutex_lock(). On contention,
ww_mutex_lock() returns -EDEADLK, which is the caller's signal to drop
the lock it holds and retry the acquisition in the canonical order.
However, regulator_lock_two() tests the return value against -EDEADLOCK
rather than -EDEADLK. On most architectures, EDEADLK and EDEADLOCK are
the same value, so the comparison happens to be correct and the bug is
invisible. But on MIPS, SPARC, and PowerPC, those two errors have
different values. The test is wrong: a genuine -EDEADLK backoff no
longer matches -EDEADLOCK, so instead of unlocking and retrying, the
code falls into WARN_ON(ret) and returns with only one of the two
regulators locked.
In practice, this is a bug only on MIPS, because the regulator core is
not built or used on the other two platforms.
In general, EDEADLK is preferred over EDEADLOCK for new code. |
| In the Linux kernel, the following vulnerability has been resolved:
octeontx2-af: fix VF bringup affecting PF promiscuous state
Mbox handling of nix_set_rx_mode for a VF with promiscuous and
all_multi flags set to false causes deletion of the PF's promiscuous
and allmulti MCAM rules. This occurs because the APIs that
enable/disable these rules operate only on the PF, even when the
mbox request is made via a VF interface.
Guard both rvu_npc_enable_allmulti_entry() and
rvu_npc_enable_promisc_entry() disable paths with an is_vf() check so
that a VF bringing up or tearing down its interface cannot inadvertently
clear the PF's MCAM rules. |
| In the Linux kernel, the following vulnerability has been resolved:
smb: client: fix overflow in passthrough ioctl bounds check
smb2_ioctl_query_info() validates the PASSTHRU_FSCTL response payload
before copying it to userspace.
The payload offset and length both come from 32-bit fields. The bounds
check currently adds OutputOffset and qi.input_buffer_length directly, so
the addition can wrap in 32-bit arithmetic before the result is compared
against the response buffer length.
A malicious server can use a large OutputOffset and a small OutputCount
to make the wrapped sum pass the bounds check. The later copy_to_user()
then reads from io_rsp + OutputOffset, outside the response buffer.
Use size_add() for the offset plus length check so overflow is treated as
out of bounds. |