| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
perf/core: Allow list_del during perf_event_overflow()
A PMU might use perf_sched_cb_inc() and perf_sched_cb_dec()
interface to get the PMU call back function pmu::sched_task
invoked at schedule in and schedule out. This is achieved
by walking along the list anchored by sched_cb_list.
The following scenario might lead to a list corruption.
perf_pmu_sched_task()
for_each_list_entry(..., &sched_cb_list)
+--> __perf_pmu_sched_task()
+--> event->pmu->sched_task())
+--> PMU_push_sample()
+--> perf_event_overflow()
+--> __perf_event_overflow()
+--> pmu->stop()
+--> perf_sched_cb_dec()
remove entry from sched_cb_list
while list node in use.
This happens when ioctl(fd, PERF_EVENT_IOC_REFRESH, xxx) has been
invoked and perf_event::event_limit hits zero.
Prevent the list corruption and convert for_each_list_entry()
to for_each_list_entry_safe(). |
| In the Linux kernel, the following vulnerability has been resolved:
configfs: pin the symlink target's dirent instead of chasing ->ci_dentry
create_link() reads the target's configfs_dirent from
item->ci_dentry->d_fsdata, relying on the item reference taken by
get_target(). That reference pins the item, not its dentry: the dentry is
pinned by DCACHE_PERSISTENT, which configfs_remove_dir() releases via
simple_rmdir() while the item is still alive. A symlink racing with rmdir
of its target can therefore find ->ci_dentry freed and its dirent
released, triggering WARN_ON(!atomic_read(&sd->s_count)) in configfs_get().
Take the dirent in get_target() as well, under ->d_lock and atomically
with the item reference, and pass it down to create_link(). A hashed
dentry has not been killed yet, so its ->d_fsdata reference keeps the
dirent alive there. |
| In the Linux kernel, the following vulnerability has been resolved:
configfs: unhash the dentry before dropping the item in rmdir
configfs_get_config_item() treats a hashed dentry as proof that
sd->s_element is a live config_item. configfs_rmdir() breaks that:
simple_rmdir() leaves the dentry hashed, the last reference to the item is
dropped right after, and the dentry is only unhashed by d_delete() once
->rmdir() has returned. configfs_symlink() resolves its target holding no
lock on it, so get_target() can land in that window:
BUG: KASAN: slab-use-after-free in config_item_get+0x26/0x90
get_target fs/configfs/symlink.c:128 [inline]
configfs_symlink+0x4ab/0x1030 fs/configfs/symlink.c:185
Unhash in configfs_remove_dir(), while the item is still guaranteed to be
there. A reference obtained just before that stays harmless, as
create_link() rechecks CONFIGFS_USET_DROPPING, already set by
configfs_detach_prep(). Both configfs_unregister_subsystem() paths
d_drop() after detaching, so this only makes rmdir match them. |
| In the Linux kernel, the following vulnerability has been resolved:
reboot: fix cad_pid use-after-free race
cad_pid is a single kernel-wide struct pid pointer. proc_do_cad_pid()
reads it and passes it to pid_vnr() without protecting the lifetime of
the referenced struct pid. A concurrent writer can replace cad_pid and
drop the final reference to the old struct pid after the reader has
loaded the pointer but before pid_vnr() has finished dereferencing it,
causing a use-after-free.
kill_cad_pid() has the same lifetime race when it passes cad_pid to
kill_pid().
At the time this issue was reported, an unprivileged user could reach the
sysctl through user and PID namespaces because cad_pid was registered in
pid_table[]. Moving cad_pid back to the global reboot sysctl table
corrected that namespace and permission mismatch, but did not fix the
underlying lifetime race.
Fix this by treating cad_pid as an RCU-protected pointer at both read
sites and by waiting for a grace period before dropping the old reference
on the write side.
call_rcu(&old_pid->rcu, ...) cannot be used here because free_pid()
also queues pid->rcu; queueing the same rcu_head twice can corrupt the
RCU callback list.
Original KASAN crash stack:
kernel/pid.c:545 pid_nr_ns() # reads freed pid->level
kernel/pid.c:556 pid_vnr() # calls pid_nr_ns()
kernel/pid.c:775 proc_do_cad_pid() # calls pid_vnr(cad_pid) |
| In the Linux kernel, the following vulnerability has been resolved:
tracing: Take trace_array reference when opening a tracer options file
When a tracer option file is opened, it is passed a descriptor that points
to an element on the trace_array's topts array. This element has
information to find the trace array and other information. It uses this
element to take a reference of the trace_array so that the trace_array
does not get removed while this file is opened.
Unfortunately, there's a race condition where the element itself could be
freed by the removal of the instance the trace_array represents causing a
use-after-free as this element that is used to find the trace_array to
increment its reference counter is also freed when the instance is
removed.
To solve this, add a trace_array_tracer_options_get() helper function that
will take the address of the element that is passed to the open function
by the inode->i_private pointer and search all the trace_arrays under a
lock to find the one that the element's address is in the range of the
trace_arrays topts array elements. When a match happens, that trace_array's
reference would be increased.
Note, there's a race where if an admin was deleting and creating trace
instances at the same time and the memory of the old trace_array's array
matched the memory of the new trace_array that it could in theory open the
option from the wrong trace array. But we do not care because it would be
stupid to perform that kind of action. As long as the only thing that can
happen is that the option from the wrong trace array is used and doesn't
crash the kernel it will only make the user confused. But if they are
doing something stupid like this, they are already confused, so no harm
done. |
| In the Linux kernel, the following vulnerability has been resolved:
tracing: Take the reference before publishing the named histogram trigger
event_hist_trigger_named_init() puts the trigger on the global
named_triggers list and only then takes the reference on the trigger it
shares its histogram with:
data->ref++;
save_named_trigger(data->named_data->name, data);
ret = event_hist_trigger_init(data->named_data);
if (ret < 0) {
kfree(data->cmd_ops);
data->cmd_ops = &trigger_hist_cmd;
}
return ret;
event_hist_trigger_init() fails when alloc_hist_pad() cannot allocate, and
nothing takes the trigger back off the list on the way out.
event_hist_trigger_parse() frees it, and the next lookup by name reads the
freed object:
BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
Read of size 8 at addr ffff888009346860 by task init/1
find_named_trigger+0xac/0xc0
hist_register_trigger+0xc1/0xa00
event_hist_trigger_parse+0x3146/0x6af0
event_trigger_write+0xce/0x160
Freed by task 67:
kfree+0x154/0x420
trigger_kthread_fn+0xfd/0x160
Do the reference first and publish once it has succeeded, so that nothing
which can fail runs after the trigger becomes findable. |
| In the Linux kernel, the following vulnerability has been resolved:
tracing: Undo the registration when enabling the histogram trigger fails
Commit 6f86bdeab633 ("tracing: Fix bad hist from corrupting named_triggers
list") described how a trigger that is registered but not on file->triggers
ends up freed while still on the global named_triggers list, and moved the
registration down so that hist_trigger_enable() follows it immediately. One
path still gets there. hist_trigger_enable() adds the trigger and takes it
straight back out when the event cannot be enabled:
list_add_tail_rcu(&data->list, &file->triggers);
update_cond_flag(file);
if (trace_event_trigger_enable_disable(file, 1) < 0) {
list_del_rcu(&data->list);
update_cond_flag(file);
ret--;
}
so the list walk in hist_unregister_trigger() matches nothing, test stays
NULL, and the ->free() that would call del_named_trigger() is skipped.
out_unreg falls through to out_free, which frees the trigger anyway:
BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
Read of size 8 at addr ffff8880091d3160 by task init/1
find_named_trigger+0xac/0xc0
hist_register_trigger+0xc1/0xa00
event_hist_trigger_parse+0x3146/0x6af0
event_trigger_write+0xce/0x160
Freed by task 69:
kfree+0x154/0x420
trigger_kthread_fn+0xfd/0x160
Leave the trigger where hist_unregister_trigger() can find it and let that
undo the registration, which is the only code that knows all of what
cmd_ops->init() took: the named list entry, the hist_pad reference, the
reference on the trigger a named histogram is shared with, and the copied
cmd_ops. It also pairs the failed trace_event_trigger_enable_disable(),
whose sm_ref and buffered event reference are otherwise left behind.
Since ->free() releases trigger_data and, for a trigger that does not share
its histogram, hist_data with it, out_unreg can no longer fall through to
out_free. For a trigger that does share, hist_register_trigger() has
already destroyed the caller's hist_data, so the fall-through was reading
freed memory there as well.
Move the enable_timestamps check in hist_unregister_trigger() above the
->free() call for the same reason: hist_data does not outlive it once the
trigger being removed is the one that owns it. |
| In the Linux kernel, the following vulnerability has been resolved:
ieee802154: cc2520: fix FIFOP work use-after-free
The FIFOP interrupt handler queues cc2520_fifop_irqwork. On removal,
cc2520_remove() only flushes the work. The devm-managed FIFOP IRQ
remains active until after ->remove() returns and can queue the work
again after that flush, allowing it to run after the private data is
released.
Disable the work with disable_work_sync() instead of flushing it, so
the handler can no longer queue it once removal begins. Destroy the
buffer mutex last, since the worker and the stop callback invoked
through ieee802154_unregister_hw() both take it.
Found by an in-house static analysis tool. |
| In the Linux kernel, the following vulnerability has been resolved:
scsi: qla2xxx: Unlink NVMe unsol ctx before freeing on LS reject error
qla_nvme_xmt_ls_rsp() obtains uctx, which was linked into
fcport->unsol_ctx_head by qla2xxx_process_purls_iocb() and is still linked
when the NVMe transport calls back to transmit the LS response. On the
error (out:) path the function frees uctx with kfree() but never removes
it from the list. This leaves a freed node in fcport->unsol_ctx_head: the
next list_add_tail() for that fcport writes through the freed node, and a
subsequent list_del() can corrupt the list or panic.
Unlink uctx with list_del() before kfree() on the error path, matching the
other free sites in qla_nvme_release_lsrsp_cmd_kref() and
qla2xxx_process_purls_pkt(). qla2x00_rel_sp() in the failure path only
returns the SRB to its pool and does not invoke sp->put_fn, so the out:
path is the sole free and uctx is always still linked there. |
| In the Linux kernel, the following vulnerability has been resolved:
wifi: mac80211: don't call ieee80211_handle_reconfig_failure when not needed
In case reconfiguration of NAN fails, we call
ieee80211_handle_reconfig_failure, that marks all interfaces as not in
the driver.
Then, at the error path of the reconfig, cfg80211_shutdown_all_interfaces
is called to destroy all the interfaces.
If we have any other interface but the NAN one, for example a BSS
station, then when its state (links, stations) will be removed, we
won't tell the driver about this, because we will think that the
interfaces are not in the driver, and then drivers might remain with
dangling pointers to objects like stations and links (at least for
iwlwifi this is the case).
ieee80211_handle_reconfig_failure is meant to be called after we cleaned
up the state in the driver, there is no reason to call it for NAN
reconfiguration failure.
Fix the code to just warn in such a case, as we do in other error paths
in reconfig where it is too complicated to rewind. |
| In the Linux kernel, the following vulnerability has been resolved:
wifi: iwlwifi: mvm: fix P2P-Device binding handling
Our binding handling for P2P-Device can run into the following
scenario, as observed by our testing:
- a station interface is connected on some channel
- the P2P-Device does a remain-on-channel (ROC) on that channel
- the ROC ends, and the P2P-Device is removed from the binding,
but the phy_ctxt pointer is left around as a PHY cache so we
don't need to recalibrate to the channel again and again in
case it's not shared
- a binding update by the station interface, even a removal,
will re-add the P2P-Device to the binding
- the P2P-Device is removed, which removes the PHY context, but
it's still in the binding so the firmware crashes
Since the P2P device is removed from the binding and only re-
added by unrelated code, but we want to keep the phy_ctxt around
as a cache for future ROC usage, fix it by adding a boolean that
indicates whether or not the P2P-Device should be added to the
binding, and handle that in the binding iterator. That way, the
station interface cannot re-add the P2P-Device to the binding
when that isn't active. |
| In the Linux kernel, the following vulnerability has been resolved:
pds_core: quiesce DMA before freeing resources
pdsc_teardown() frees DMA buffers but does not disable bus mastering,
leaving the device able to perform DMA after the buffers are freed.
This can lead to use-after-free if the device writes to freed memory.
Add pci_clear_master() to pdsc_teardown() to disable bus mastering
before freeing resources, ensuring all DMA is quiesced.
Add pci_set_master() to pdsc_setup() to re-enable bus mastering,
which is needed for the firmware recovery path since pdsc_teardown()
now disables it. |
| In the Linux kernel, the following vulnerability has been resolved:
mm/migrate_device: clear stale mapping after freeing swapcache
__migrate_device_pages() reads the folio mapping before calling
folio_free_swap(). When folio_free_swap() succeeds, the folio is removed
from the swap cache, but the saved mapping still points to swap_space.
Passing the stale mapping to folio_migrate_mapping() makes it use the
mapped-folio path for a folio that is no longer in swapcache. It can then
operate on swap_space.i_pages with invalid reference accounting,
eventually triggering a folio reference count BUG.
After a successful split, nr still contains the number of pages in the
original large folio, although each resulting page is now a separate
order-0 folio. Reset nr to 1 so each split folio is processed separately,
including its own swapcache removal and mapping lookup.
Refresh the saved mapping after folio_free_swap() so the current folio
state is used during migration. |
| In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: ISO: fix race of kfree vs kref_get_unless_zero
hci_conn::iso_data is accessed and modified without lock or RCU.
This leads to a race
[Task hdev->workqueue] [Task 2]
iso_recv iso_conn_put(conn)
conn = LOAD hcon->iso_data iso_conn_free(conn)
iso_conn_hold_unless_zero(conn) hcon->iso_data = NULL
kfree(conn)
kref_get_unless_zero(&conn->ref) /* UAF */
and also to races in iso_conn_add() vs. iso_conn_free().
Fix by adding spinlock hci_conn::proto_lock and using it to guard
hci_conn::iso_data. |
| In the Linux kernel, the following vulnerability has been resolved:
dibs: fix use-after-free of dmb_node in loopback attach/detach/unregister
dibs_lo_attach_dmb(), dibs_lo_detach_dmb() and dibs_lo_unregister_dmb()
look up the dmb_node under dmb_ht_lock, drop the lock and only then
operate on the node's refcount. Nothing keeps the node alive across
that window: __dibs_lo_unregister_dmb() removes the node from the hash
table under the write lock and immediately frees it.
A concurrent final put can therefore free the node between the lookup
and the refcount operation:
CPU0 (attach) CPU1 (owner unregisters)
read_lock_bh(&dmb_ht_lock)
find dmb_node (refcnt == 1)
read_unlock_bh(&dmb_ht_lock)
refcount_dec_and_test() 1 -> 0
write_lock_bh(&dmb_ht_lock)
hash_del(&dmb_node->list)
write_unlock_bh(&dmb_ht_lock)
kfree(dmb_node)
refcount_inc_not_zero(&dmb_node->refcnt) <-- use-after-free
The same window exists for the refcount_dec_and_test() calls in the
detach and unregister paths.
Close the race structurally by making hash table membership and the
refcount transitions atomic with respect to each other:
- Perform the final refcount_dec_and_test() and hash_del() in a single
dmb_ht_lock write-side critical section, in both the unregister and
the detach path. Freeing the node still happens after the lock is
dropped, which is safe because a node whose refcount reached zero has
left the hash table and can no longer be found.
- This establishes the invariant that any node found in the hash table
holds at least one reference, and that the final reference can only
be dropped under the write lock. dibs_lo_attach_dmb() can thus take
its reference with a plain refcount_inc() while still holding the
read lock; refcount_inc_not_zero() is no longer needed.
__dibs_lo_unregister_dmb() no longer touches the hash table and is
renamed to dibs_lo_free_dmb() accordingly.
Note: commit cc21191b584c ("dibs: Move data path to dibs layer") moved
the code to its current location; the race was introduced earlier by
commit c3a910f2380f ("net/smc: implement DMB-merged operations of
loopback-ism").
Tested SMC-D via ISM and dibs loopback. |
| In the Linux kernel, the following vulnerability has been resolved:
bpf: Clear rb node linkage when freeing bpf_rb_root
bpf_rb_root_free() detaches the root by copying the current rb_root_cached
and then replacing the live root with RB_ROOT_CACHED. It then walks the
copied root and drops each object contained in the tree.
This leaves the rb node state intact while dropping the object. If the
object is refcounted and survives the drop, its bpf_rb_node_kern still
contains an owner pointer to the freed root and stale rb tree linkage. If
a later bpf_rb_root allocation reuses the same address, bpf_rbtree_remove()
can incorrectly pass the owner check and call rb_erase_cached() on a node
whose rb pointers belong to the old tree.
Mirror the list draining behavior by marking nodes as busy while the root
is being detached, then clear the rb node and release the owner before
dropping the containing object. This makes surviving nodes unowned and
safe to reject from remove or accept for a later add. |
| In the Linux kernel, the following vulnerability has been resolved:
RDMA/bnxt_re: Free CQ toggle page after firmware teardown
Free the toggle page only after firmware teardown completes so that
an NQ interrupt arriving during bnxt_qplib_destroy_cq() won't write
the toggle value to an already-freed page. Move free_page() after
bnxt_qplib_destroy_cq. |
| In the Linux kernel, the following vulnerability has been resolved:
mmc: vub300: fix use-after-free on probe failure
The vub300 driver lifetime-manages its controller state using
vub300->kref, with vub300_delete() freeing the mmc host when the last
reference is dropped. The probe error path after the inactivity timer has
been armed still bypasses that lifetime rule, however, and falls through
to mmc_free_host() directly if mmc_add_host() fails.
The race window is between arming the inactivity timer and reaching the
probe error unwind after mmc_add_host() fails:
probe thread timer/workqueue
------------ ---------------
kref_init(&vub300->kref) ref = 1
kref_get(&vub300->kref) ref = 2, timer ref
add_timer(inactivity_timer) fires after one second
|
| race window
|<---------------------------------------------------->
|
mmc_add_host(mmc)
inactivity timer fires
vub300_queue_dead_work()
kref_get() ref = 3
queue_work(deadwork)
mmc_add_host() fails
timer_delete_sync()
mmc_free_host(mmc)
frees vub300
deadwork runs
use-after-free
The inactivity timeout is one second, so this would require
mmc_add_host() to both fail and take more than one second to do so. This
is unlikely to happen in practice, but the error path is still wrong.
timer_delete_sync() only waits for the timer callback itself. It does
not flush deadwork that the callback may already have queued. As a
result, queued deadwork can still hold a kref while the probe error path
directly frees the backing mmc host, including the vub300 storage.
Fix this by using the same lifetime mechanism as disconnect. Clear
vub300->interface so that the timer callback and any queued deadwork
return early and drop their references, then drop the initial probe
reference and return without falling through to err_free_host. |
| In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: hci_sync: extend conn_hash lookup critical sections
Using RCU-protected pointers outside the critical sections without
refcount is incorrect and may result to UAF.
Extend critical section to cover both hci_conn_hash lookup and use of
the returned conn.
Add surrounding rcu_read_lock() also when return value is not used, in
preparation for RCU lockdep requirement to hci_lookup_le_connect().
This avoids concurrent deletion of the conn before we are done
dereferencing it.
Also, make sure to hold hdev->lock when accessing hdev->accept_list. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/xe/guc: Keep scheduler timeline name alive
The scheduler keeps a pointer to the timeline name, but q->name
is freed with the exec queue while scheduler fences can still
reference it.
Store the name in struct xe_guc_exec_queue so it shares
the scheduler's RCU-deferred lifetime.
(cherry picked from commit 41075f0eb5dcbd3b065d15f15ef7bbe9315188e8) |