In the Linux kernel, the following vulnerability has been resolved:
wifi: mac80211: capture fast-RX rate before mesh reuses skb->cb
ieee80211_invoke_fast_rx() reads RX status through
IEEE80211_SKB_RXCB(skb), which aliases the same skb->cb storage
that ieee80211_rx_mesh_data() reuses as IEEE80211_TX_INFO. In the
unicast forward path, mesh_data does:
info = IEEE80211_SKB_CB(fwd_skb);
memset(info, 0, sizeof(*info));
on the same skb the caller still names via rx->skb, then either
queues the skb for TX (success) or kfree_skb()'s it (no-route)
before returning RX_QUEUED. The caller's RX_QUEUED arm then
calls sta_stats_encode_rate(status) on memory that is either
zeroed (success path) or freed (no-route path). The latter is
KASAN slab-use-after-free in ieee80211_prepare_and_rx_handle.
Fix by encoding the rate from status before invoking
ieee80211_rx_mesh_data(), so the RX_QUEUED arm consumes a value
captured while status was still backed by valid memory.
In the Linux kernel, the following vulnerability has been resolved:
net: hsr: defer node table free until after RCU readers
HSR node-list and node-status generic-netlink operations run under
rcu_read_lock(). They walk hsr->node_db through hsr_get_next_node() and
hsr_get_node_data(), but RTM_DELLINK teardown removes the same node table
with plain list_del() and frees each node immediately.
That lets a generic-netlink reader hold a struct hsr_node pointer across
hsr_dellink(). In a KASAN build, widening the reader window after
hsr_get_next_node() obtains the node reproduces a slab-use-after-free
when the reader copies node->macaddress_A; the freeing stack is
hsr_del_nodes() from hsr_dellink().
Use list_del_rcu() and defer the free through the existing
hsr_free_node_rcu() callback. This matches the lifetime rule used by the
HSR prune paths, which already delete nodes with list_del_rcu() and
call_rcu().
In the Linux kernel, the following vulnerability has been resolved:
netfilter: x_tables: allocate hook ops while under mutex
arp/ip(6)t_register_table() add the table to the per-netns list via
xt_register_table() before allocating the per-netns hook ops copy
via kmemdup_array(). This leaves a window where the table is
visible in the list with ops=NULL.
If the pernet exit happens runs concurrently the pre_exit callback finds
the table via xt_find_table() and passes the NULL ops pointer to
nf_unregister_net_hooks(), causing a NULL dereference:
general protection fault in nf_unregister_net_hooks+0xbc/0x150
RIP: nf_unregister_net_hooks (net/netfilter/core.c:613)
Call Trace:
ipt_unregister_table_pre_exit
iptable_mangle_net_pre_exit
ops_pre_exit_list
cleanup_net
Fix by moving the ops allocation into the xtables core so the table is
never in the list without valid ops. Also ensure the table is no longer
processing packets before its torn down on error unwind.
nf_register_net_hooks might have published at least one hook; call
synchronize_rcu() if there was an error.
audit log register message gets deferred until all operations have
passed, this avoids need to emit another ureg message in case of
error unwinding.
Based on earlier patch by Tristan Madani.
In the Linux kernel, the following vulnerability has been resolved:
riscv: Fix register corruption from uninitialized cregs on error
compat_riscv_gpr_set() calls cregs_to_regs() unconditionally, even when
user_regset_copyin() fails. Since cregs is an uninitialized stack
variable, a copyin failure causes uninitialized stack data to be written
into the target task's pt_regs, corrupting its register state and
potentially leaking kernel stack contents.
compat_restore_sigcontext() has the same issue: it calls cregs_to_regs()
even when __copy_from_user() fails, leading to the same corruption of
the signal-returning task's register state on error.
Only call cregs_to_regs() when the user copy succeeds.
In the Linux kernel, the following vulnerability has been resolved:
netfs: Fix missing barriers when accessing stream->subrequests locklessly
The list of subrequests attached to stream->subrequests is accessed without
locks by netfs_collect_read_results() and netfs_collect_write_results(),
and then they access subreq->flags without taking a barrier after getting
the subreq pointer from the list. Relatedly, the functions that build the
list don't use any sort of write barrier when constructing the list to make
sure that the NETFS_SREQ_IN_PROGRESS flag is perceived to be set first if
no lock is taken.
Fix this by:
(1) Add a new list_add_tail_release() function that uses a release barrier
to set the pointer to the new member of the list.
(2) Add a new list_first_entry_or_null_acquire() function that uses an
acquire barrier to read the pointer to the first member in a list (or
return NULL).
(3) Use list_add_tail_release() when adding a subreq to ->subrequests.
(4) Use list_first_entry_or_null_acquire() when initially accessing the
front of the list (when an item is removed, the pointer to the new
front iterm is obtained under the same lock).
In the Linux kernel, the following vulnerability has been resolved:
netfs: Fix missing locking around retry adding new subreqs
Fix netfs_retry_read_subrequests() and netfs_retry_write_stream() to take
the appropriate lock when adding extra subrequests into
stream->subrequests.
In the Linux kernel, the following vulnerability has been resolved:
powerpc/hv-gpci: fix preempt count leak in sysfs show paths
Four sysfs show() callbacks in hv-gpci take get_cpu_var(hv_gpci_reqb)
(which calls preempt_disable()) but only call the matching put_cpu_var()
on the error path under the 'out:' label. Every successful read leaks
one preempt_disable():
processor_bus_topology_show()
processor_config_show()
affinity_domain_via_virtual_processor_show()
affinity_domain_via_domain_show()
(affinity_domain_via_partition_show() was already correct.)
On a CONFIG_PREEMPT=y kernel, repeated reads raise preempt_count and
eventually return to userspace with preemption still disabled. The
next user-mode page fault then hits faulthandler_disabled() == 1,
gets forced to SIGSEGV, and the resulting coredump trips
'BUG: scheduling while atomic' in call_usermodehelper_exec ->
wait_for_completion_state -> schedule:
BUG: scheduling while atomic: <task>/<pid>/0x00000004
...
__schedule_bug+0x6c/0x90
__schedule+0x58c/0x13a0
schedule+0x48/0x1a0
schedule_timeout+0x104/0x170
wait_for_completion_state+0x16c/0x330
call_usermodehelper_exec+0x254/0x2d0
vfs_coredump+0x1050/0x2590
get_signal+0xb9c/0xc80
do_notify_resume+0xf8/0x470
Add an out_success label that calls put_cpu_var() before returning
the byte count, mirroring affinity_domain_via_partition_show().
In the Linux kernel, the following vulnerability has been resolved:
afs: Fix the locking used by afs_get_link()
The afs filesystem in the kernel doesn't do locking correctly for symbolic
links. There are a number of problems:
(1) It doesn't do any locking around afs_read_single() to prevent races
between multiple ->get_link() calls, thereby allowing the possibility
of leaks.
(2) It doesn't use RCU barriering when accessing the buffer pointers
during RCU pathwalk.
(3) It can race with another thread updating the contents of the symlink
if a third party updated it on the server.
Fix this by the following means:
(0) Move symlink handling into its own file as this makes it more
complicated.
(1) Take the validate_lock around afs_read_single() to prevent races
between multiple ->get_link() calls.
(2) Keep a separate copy of the symlink contents with an rcu_head. This
is always going to be a lot smaller than a page, so it can be
kmalloc'd and save quite a bit of memory. It also needs a refcount
for non-RCU pathwalk.
(3) Split the symlink read and write-to-cache routines in afs from those
for directories.
(4) Discard the I/O buffer as soon as the write-to-cache completes as this
is a full page (plus a folio_queue).
(5) If there's no cache, discard the I/O buffer immediately after reading
and copying if there is no cache.
In the Linux kernel, the following vulnerability has been resolved:
fbdev: omap2: fix use-after-free in omapfb_mmap
omapfb_mmap() has a race condition with OMAPFB_SETUP_PLANE ioctl that
can lead to use-after-free:
The fb_mmap() entry point holds mm_lock but not lock (fb_info->lock),
while ioctl handlers like OMAPFB_SETUP_PLANE hold lock but not mm_lock.
This allows concurrent execution.
In omapfb_mmap():
1. rg = omapfb_get_mem_region(ofbi->region); // Get old region ref
2. start = omapfb_get_region_paddr(ofbi); // Read from NEW region
3. len = fix->smem_len; // Read from NEW region
4. vm_iomap_memory(vma, start, len); // Map NEW region memory
5. atomic_inc(&rg->map_count); // Increment OLD region!
Concurrently, OMAPFB_SETUP_PLANE can:
- Reassign ofbi->region = new_rg
- Update fix->smem_len
- OMAPFB_SETUP_MEM then checks NEW region's map_count (0!) and frees it
This leaves userspace with a mapping to freed physical memory.
The fix is to read all required values (start, len) from the same
region reference (rg) that will have its map_count incremented,
preventing the region from being freed while still mapped.
In the Linux kernel, the following vulnerability has been resolved:
power: supply: max77705: Free allocated workqueue and fix removal order
Use devm interface for allocating workqueue to fix two bugs at the same
time:
1. Driver leaks the memory on remove(), because the workqueue is not
destroyed.
2. Driver allocates workqueue and then registers interrupt handlers
with devm interface. This means that probe error paths will not use a
reversed order, but first destroy the workqueue and then, via devm
release handlers, free the interrupt.
The interrupt handler schedules work on this exact workqueue, thus if
interrupt is hit in this short time window - after destroying
workqueue, but before devm() frees the interrupt - the schedulled
work will lead to use of freed memory.
Change is not equivalent in the workqueue itself: use non-legacy API
which does not set (__WQ_LEGACY | WQ_MEM_RECLAIM). The workqueue is
used to update power supply (power_supply_changed()) status, thus there
is no point to run it for memory reclaim. Note that dev_name() is not
directly used in second argument to prevent possible unlikely parsing
any "%" character in device name as format.