In the Linux kernel, the following vulnerability has been resolved:
can: dev: init_can_skb(): restore skb header initialization
Commit 9f10374bb024 ("can: remove private CAN skb headroom infrastructure")
removed the skb_reset_mac_header()/skb_reset_network_header()/
skb_reset_transport_header() calls from init_can_skb(). As a result, RX
skbs from alloc_can_skb() and friends again carry mac_header = 0xFFFF.
When such an skb reaches packet_rcv_spkt() (SOCK_PACKET), the push length
calculation overflows and triggers skb_under_panic -> kernel BUG -> full
machine panic.
The same issue was originally reported in 2014 on linux-can and fixed by
commit 969439016d2c ("can: add missing initialisations in CAN related
skbuffs"). packet_rcv_spkt() itself has never been hardened: only
packet_rcv() and tpacket_rcv() gained dev_has_header() checks in
commit d549699048b4 ("net/packet: fix packet receive on L3 devices
without visible hard header").
In the Linux kernel, the following vulnerability has been resolved:
cgroup/cpuset: Handle cpu hotplug race in guarantee_active_cpus()
With commit 2125c0034c5d ("cgroup/cpuset: Make cpuset hotplug processing
synchronous"), the cpuset hotplug operation becomes synchronous. That
commit also removes the code that handles race between cpuset_hotplug_work
and cpu hotplug notifier with the assumption that race is now gone.
Later commit 7a0aabd9ce69 ("cgroup/cpuset: Always use cpu_active_mask")
updates the cpuset code to always use cpu_active_mask instead of
cpu_online_mask in some places including guarantee_online_cpus() which
is renamed to guarantee_active_cpus() in that commit.
In the case of CPU offline operation, cpu_active_mask is updated
first in sched_cpu_deactivate() to remove the offline CPU before
cpuset_handle_hotplug() is called to update the effective_cpus of the
affected cpusets. The cpu_online_mask is updated after that near the end
of the offline operation to remove the offline CPU. As a result, the race
comes back and the top cpuset may not have any active CPU leading to NULL
pointer dereference during the race window when guarantee_active_cpus()
is called after cpu_active_mask is updated to remove the CPU to be torn
down but before cpuset_handle_hotplug() is able to properly update the
effective_cpus of the top cpuset.
Fix this by adding back the NULL cs check to avoid this problem.
In the Linux kernel, the following vulnerability has been resolved:
cipso: adjust cached option offsets when removing CIPSO
cipso_v4_skbuff_delattr() removes the CIPSO bytes but does not adjust
cached offsets for options that follow them.
For example, with a valid 10-byte CIPSO option followed by a seven-byte
RR option, parsing records rr at offset 30. Removing CIPSO moves RR to
offset 20, while the cached offset remains 30. Consumers such as
ip_forward_options() and __ip_options_echo() then access the wrong bytes;
the latter may interpret packet data as the option length and copy it into
fixed-size option storage.
Mirror cipso_v4_delopt() and subtract cipso_len from the srr, rr, ts and
router_alert offsets when they follow CIPSO. cipso_len is the distance
the first memmove() shifts those options. The later header move and
network-header reset relocate the bytes and their offset base together.
In the Linux kernel, the following vulnerability has been resolved:
dm ioctl: don't let data_start run past the buffer
struct dm_ioctl has seven bytes of trailing padding, so the smallest
buffer userspace is allowed to ask for, offsetof(struct dm_ioctl, data),
is seven bytes shorter than sizeof(struct dm_ioctl).
get_result_buffer() sets data_start to sizeof(struct dm_ioctl) without
looking at how big the buffer actually is. Ask for the minimum and
data_start ends up seven bytes past the end. Callers add it to
data_size, and ctl_ioctl() copies that much back to userspace:
BUG: KASAN: slab-out-of-bounds in _copy_to_user+0xad/0xd0
Read of size 312 at addr ffff8880169e4c00 by task repro-dm/140
ctl_ioctl+0x5e3/0xcb0
dm_ctl_ioctl+0x25/0x40
allocated 305-byte region [ffff8880169e4c00, ffff8880169e4d31)
A DM_LIST_DEVICES with data_size set to 305 is enough to hit it, and the
seven bytes that leak are whatever sat next to the allocation.
Clamp data_start to the buffer size.
Note that this is not a security bug because the out-of-bounds read can
only be triggered by root.
In the Linux kernel, the following vulnerability has been resolved:
vsock/virtio: account only unread bytes in read_skb()
After a partial stream receive, rx_bytes tracks the unread suffix while
buf_used and peer credit still cover the whole packet.
virtio_transport_read_skb() dequeues that packet but passes pkt_len for
both counters, underflowing rx_bytes.
On a connected CID_LOCAL stream with an SK_SKB verdict, a 40-byte read
from a 100-byte packet made SIOCINQ report -40, an empty recv return
ELOOP, and poll report the empty socket readable. After verdict detach,
receiving 40 bytes wrapped the counter to zero and hid those queued bytes
until one more byte arrived. The fixed run kept the counter balanced
and exposed all queued data immediately.
This was found during an LLM-assisted manual source audit of VSOCK
receive accounting while re-evaluating virtio_transport_read_skb() after
CVE-2024-50169.
Subtract only skb->len minus the VSOCK offset from rx_bytes. Retain the
full packet length for buf_used and peer credit.
In the Linux kernel, the following vulnerability has been resolved:
wifi: brcmfmac: fix P2P device removal race in brcmf_detach()
When the driver is removed while the user space process that created
the P2P device (e.g. wpa_supplicant) is still exiting, the P2P device
interface is removed twice and the kernel crashes.
The two paths are:
- wpa_supplicant, on exit, sends NL80211_CMD_DEL_INTERFACE for the P2P
device. nl80211_del_interface() holds RTNL and the wiphy mutex and
calls brcmf_p2p_del_vif(), which disables discovery and waits up to
1.5 s for BRCMF_E_IF_DEL. Then it calls brcmf_remove_interface(),
which unregisters the wdev and frees the vif and the ifp.
- brcmf_detach() sets the bus down, so BRCMF_E_IF_DEL never arrives,
and calls brcmf_remove_interface(ifp, false) for the same ifp.
brcmf_p2p_ifp_removed() reads ifp->vif and then blocks on
rtnl_lock(). When brcmf_p2p_del_vif() releases RTNL, it calls
cfg80211_unregister_wdev() on the wdev that was already unregistered
and freed.
The second list_del_rcu() of wdev->list faults on LIST_POISON2:
brcmfmac: brcmf_p2p_del_vif delete P2P vif
brcmfmac: brcmf_p2p_deinit_discovery enter
brcmfmac: brcmf_p2p_del_vif P2P: GO_NEG_PHASE status cleared
brcmfmac: brcmf_detach Enter
brcmfmac: brcmf_bus_change_state 1 -> 0
brcmfmac: brcmf_remove_interface Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_del_if Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_p2p_ifp_removed P2P: device interface removed
[1.5 s later, brcmf_p2p_del_vif() timed out]
brcmfmac: brcmf_remove_interface Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_del_if Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_p2p_ifp_removed P2P: device interface removed
Unable to handle kernel paging request at virtual address dead000000000122
Internal error: Oops: 96000044 [#1] PREEMPT_RT SMP
pc : _cfg80211_unregister_wdev+0x6c/0x264 [cfg80211]
Call trace:
_cfg80211_unregister_wdev+0x6c/0x264 [cfg80211]
cfg80211_unregister_wdev+0x10/0x1c [cfg80211]
brcmf_p2p_ifp_removed+0x84/0xb0 [brcmfmac]
brcmf_remove_interface+0x1f4/0x254 [brcmfmac]
brcmf_detach+0x88/0x180 [brcmfmac]
brcmf_sdio_remove+0x90/0x7b0 [brcmfmac]
brcmf_sdiod_remove+0x20/0xa0 [brcmfmac]
brcmf_ops_sdio_remove+0xbc/0x12c [brcmfmac]
sdio_bus_remove+0x38/0x144
device_release_driver_internal+0x1e8/0x2c0
device_release_driver+0x14/0x20
brcmf_sdio_bus_remove+0x2c/0x40 [brcmfmac]
brcmf_fwvid_unregister_vendor+0xd8/0x170 [brcmfmac]
__exit_compat+0x18/0x418 [brcmfmac_cyw]
__arm64_sys_delete_module+0x1ac/0x244
The log was taken with debug=0x406 on an i.MX 8M Plus board with a
CYW55513 (Sona IF513) on SDIO. The driver is the Ezurio backport of
brcmfmac from v6.18.22 on a 5.4-rt kernel. The code involved is the same
in mainline.
To reproduce:
1. Start wpa_supplicant on wlan0 and let it associate. It creates the
P2P device (iw dev shows "type P2P-device").
2. Stop wpa_supplicant and remove the driver without waiting for
wpa_supplicant to exit:
kill $(pidof wpa_supplicant)
rmmod brcmfmac_cyw brcmfmac
The crash is reproducible on that board.
For the interface without a netdev (the P2P device), take RTNL and the
wiphy mutex in brcmf_detach() before reading iflist, and remove it with
locked=true. If brcmf_p2p_del_vif() runs first, brcmf_detach() finds the
slot empty. If brcmf_detach() runs first, nl80211 does not find the wdev
any more. The interfaces with a netdev are removed as before, because
brcmf_del_if() takes RTNL on its own for the primary interface.
In the Linux kernel, the following vulnerability has been resolved:
wifi: mt76: mt7603: initialize global station WCID
mt7603 uses a driver-private global station WCID for frames that have
neither a station nor a vif, including frames injected through a monitor
interface. Unlike the core global WCID initialized by
mt76_register_device(), this WCID is published without ever being passed
to mt76_wcid_init().
Since commit 0335c034e726 ("wifi: mt76: fix race condition related to
checking tx queue fill status"), mt76_tx() queues every such frame on the
WCID's tx_pending or tx_offchannel queue and links its tx_list. The first
injected frame therefore reaches __skb_queue_tail() with an uninitialized
sk_buff_head and dereferences a NULL prev pointer.
Initialize the WCID before publishing it.
The fix was tested on an MT7603 PCIe device. Three wildcard probe requests
were injected through a monitor interface. The hardware queue head and tail
advanced from 0 to 3 and a second radio captured the third request over the
air. No oops or reset occurred. After restoring AP mode, a 150 MB transfer
also completed without a reset.
In the Linux kernel, the following vulnerability has been resolved:
wireguard: noise: reject response consumption after intermediate initiation
Two threads begin processing the identical response message, received
twice. The first thread, A, runs. While it's running, the second one,
B, gets partway through, and during that slow calculation, or even while
blocking on down_write(), A completes and then also a handshake
initiation that's already been queued up runs in thread C, which itself
takes that same down_write(). The handshake initiation creation
succeeds, and sets the state back to waiting-for-response, and calls
up_write(), at which point thread B resumes, because either its finished
its calculations or was finally allowed to acquire down_write(). Thread
B then copies the state back to the peer, and begins a new session,
using that state, which is the same session as the one made in thread A.
Thread A Thread B Thread C
down_read()
sA = handshake->state
memcpy(cA, handshake->crypto)
up_read()
if (sA != 1)
goto fail
slow_crypto(cA)
down_read()
sB = handshake->state
memcpy(cB, handshake->crypto)
up_read()
if (sB != 1)
goto fail
slow_crypto(cB)
down_write()
if (sA != handshake->state)
goto fail
memcpy(handshake->crypto, cA)
handshake->state = 2
up_write()
down_write()
if (handshake->state != 2)
goto fail
derive_session(handshake->crypto)
up_write()
down_write()
slow_crypto(handshake->crypto)
handshake->state = 1
up_write()
down_write()
if (sB != handshake->state)
goto fail
memcpy(handshake->crypto, cB)
handshake->state = 2
up_write()
down_write()
if (handshake->state != 2)
goto fail
derive_session(handshake->crypto)
up_write()
This seems basically impossible to hit in a meaningful way in practice,
but ensure that it absolutely cannot happen by comparing the ephemeral
private key that's on the stack with the latest one that the peer's
handshake state has.
In the Linux kernel, the following vulnerability has been resolved:
workqueue: Fix NULL current_pwq deref in chained work check
current_wq_worker() only tells us that %current is a kworker. It does
not guarantee that the worker is currently executing a work item, as
worker->current_pwq is populated only while process_one_work() is running
the work function.
is_chained_work() can be reached while queueing on a draining or
destroying workqueue. If a kworker outside work-item execution reaches
that path, current_wq_worker() returns a worker but worker->current_pwq is
NULL, and the chained-work test can fault before it emits the intended
warning.
Guard the chained-work test with worker->current_pwq. A kworker without
current_pwq is not executing work on the target workqueue, so the helper
should return false and let the draining/destroying warning fire.
In the Linux kernel, the following vulnerability has been resolved:
xen/netfront: don't leak the skb when xennet_fill_frags() fails
When a response chain has more slots than fit in the skb's frags,
xennet_fill_frags() returns an error and xennet_poll() jumps to its
error path. That path moves what's left on tmpq to errq to be freed,
but the skb being filled was already dequeued from tmpq, so it's never
freed. Each chain that overflows leaks the skb and the pages attached
to it as frags, and the backend decides how many slots it sends.
Put the skb back on tmpq before taking the error path, like the
xennet_set_skb_gso() failure just above it does.
In the Linux kernel, the following vulnerability has been resolved:
strparser: make sure __strp_recv isn't running before tearing down the parser
The comment above strp_done() claims that if strp is stopped,
strp_recv will no longer be called. That's only true if the caller has
a mechanism (eg locking) to guarantee that strp_recv() calls that
started before strp_stop() have completed by the time we call
strp_done().
This adds a dummy lock_sock/release_sock pair to guarantee that any
in-flight strp_recv() (which runs under either bh_lock_sock or
lock_sock, depending if it's called from ->sk_data_ready or strp_work)
has completed.
Only espintcp can be affected by this race condition, but this patch
makes sure no future user of strp can have the bug.
This could crash on strp->sk ("general mode" of strp), but this mode
has been here for 9 years and has never been used. It'll be gone soon,
no point worrying about it.
Switch the stopped/paused/etc bits to u8's to avoid races between
strp_stop() and strp_pause/unpause().
A reproducer has been published and turns the possible UAF into an
exploit [1].
In the Linux kernel, the following vulnerability has been resolved:
tcp: reject net_iov in zerocopy receive mapping hints
After copying a readable prefix, receive_fallback_to_copy() asks
tcp_zerocopy_set_hint_for_skb() where page mapping can resume. If the
next skb is unreadable, find_next_mappable_frag() passes its net_iov
fragment to can_map_frag().
skb_frag_page() returns NULL for a net_iov, but can_map_frag()
dereferences it in PageCompound(). A v7.2 KASAN run on a connected TCP
socket with 64 readable bytes followed by a 4096-byte NET_IOV_DMABUF
fragment reported:
BUG: KASAN: null-ptr-deref in can_map_frag
tcp_zerocopy_receive -> can_map_frag
Kernel panic - not syncing: KASAN: panic_on_warn set
The diagnostic inserted the net_iov directly because the test host has
no devmem-capable NIC. Hardware end-to-end reachability remains untested
and requires CONFIG_NET_DEVMEM plus a supported DMA-buf-bound RX queue.
Reject all net_iov fragments before skb_frag_page(). This covers both
DMABUF and IOURING net_iov types while leaving page-backed checks
unchanged. With the guard, the same queue copied the readable prefix,
returned a 4096-byte skip hint, and completed without a fault.
In the Linux kernel, the following vulnerability has been resolved:
tipc: destroy topsrv workqueues before closing connections
tipc_topsrv_stop() closed subscriber connections while the topology
server's send and receive workqueues were still running. Socket
callbacks and subscription events could then queue more work, and
in-flight send/recv work could drop the last connection reference
during the conn_idr walk.
That race produced several teardown failures: refcount_t addition on
0 from conn_get() on a connection whose release was blocked on
idr_lock, a subsequent use-after-free in tipc_conn_close(),
queue_work() on an already destroyed workqueue from the listener
data-ready callback, and an RCU stall in tipc_topsrv_exit_net()
while the walk spun under idr_lock.
Clear srv->listener under idr_lock so it acts as a shutdown flag,
skip queue_work() once it is NULL, destroy the workqueues to flush
in-flight work, and only then close the remaining connections.
Refuse tipc_conn_lookup() after that flag is cleared, and drop
idr_lock when the teardown walk finds no connection, so an
in-flight subscription event cannot pin idr_in_use while the
walk holds the lock.
v3 supersedes the narrower in-thread diff Tung Quang Nguyen
posted on 2026-09-23. It keeps his teardown order and adds the
lookup refusal and the empty-idr unlock.
In the Linux kernel, the following vulnerability has been resolved:
tipc: hold a reference to nodes found by link name
tipc_node_find_by_name() returns a node after dropping its RCU read lock
without taking a reference. The LINK_SET, LINK_GET and LINK_RESET_STATS
handlers then lock and access the node, racing with timer-driven cleanup of
a down peer. Generic netlink serialization does not exclude the node
timer.
The following interleaving can leave a handler using a freed node:
CPU 0: find the node under RCU and release the node read lock
CPU 1: tipc_node_timeout() clears the links and unlinks the down node
CPU 1: drop the list and timer references, queuing tipc_node_free()
CPU 0: leave the RCU read-side critical section
CPU 1: complete the grace period and free the node
CPU 0: acquire the node lock through the stale pointer
LINK_SET also uses the node's media address after releasing the node lock,
when passing queued packets to tipc_bearer_xmit().
KASAN on v7.3-rc5 reported:
BUG: KASAN: slab-use-after-free in _raw_read_lock_bh
Write of size 4 at addr ffff88807e06f008 by task poc/92
Call Trace:
_raw_read_lock_bh kernel/locking/spinlock.c:287
tipc_nl_node_set_link net/tipc/node.c:2475
genl_family_rcv_msg_doit net/netlink/genetlink.c:1114
genl_rcv_msg net/netlink/genetlink.c:1209
netlink_rcv_skb net/netlink/af_netlink.c:2575
Allocated by task 0:
tipc_node_create net/tipc/node.c:539
tipc_node_check_dest net/tipc/node.c:1196
tipc_disc_rcv net/tipc/discover.c:252
Freed by task 92:
kfree mm/slub.c:6801
rcu_core kernel/rcu/tree.c:2919
Last potentially related work creation:
__call_rcu_common.constprop.0 kernel/rcu/tree.c:3181
tipc_node_timeout net/tipc/node.c:814
Acquire a reference to the selected node with kref_get_unless_zero() before
leaving RCU, returning NULL if the node has already been released. Release
that reference on every caller exit after the last node access, including
transmission in LINK_SET. Keep the existing link lookup order and locking
so concurrent link removal still takes the existing error paths.
In the Linux kernel, the following vulnerability has been resolved:
selinux: preserve NATIVE_LABELS on already-initialized sb in set_mnt_opts
When an NFSv4 filesystem exported with security_label is mounted a
second time, sget_fc() returns the existing superblock and
nfs_get_root() calls security_sb_set_mnt_opts() again on it. Since the
superblock is already SB_INITIALIZED, selinux_set_mnt_opts() takes an
early exit without setting SECURITY_LSM_NATIVE_LABELS in
*set_kern_flags. nfs_get_root() then sees kflags without
SECURITY_LSM_NATIVE_LABELS set and clears NFS_CAP_SECURITY_LABEL on
the shared nfs_server, silently disabling per-file labeling for both
the new and the original mount.
Commit 3815a245b501 ("security/selinux: fix SECURITY_LSM_NATIVE_LABELS
on reused superblock") fixed the same problem in
selinux_sb_clone_mnt_opts(). The reused-superblock path for a plain
second mount now goes through sb_set_mnt_opts rather than
sb_clone_mnt_opts, so it needs the same treatment: on both
SE_SBINITIALIZED early exits, set SECURITY_LSM_NATIVE_LABELS in
*set_kern_flags when the superblock was already using
SECURITY_FS_USE_NATVE.
In the Linux kernel, the following vulnerability has been resolved:
fsverity: RCU-delay the freeing of struct fsverity_info
__fsverity_get_info() calls rhashtable_lookup_fast(), which just uses
rcu_read_lock() and doesn't directly synchronize with
fsverity_remove_info().
For the same inode this isn't a problem: its fsverity_info is removed
only at inode eviction time or upon failure to enable verity, when the
inode no longer needs its fsverity_info and it will no longer be
accessed via that inode.
However, this is broken and can cause a use-after-free for concurrent
__fsverity_get_info() for *different* inodes. Those rely on following
fsverity_info::rhash_head in the rhashtable under rcu_read_lock() only.
They also use fsverity_info::inode to do the key comparison.
Fix this by RCU-delaying the freeing of 'struct fsverity_info' after
it's been removed from the rhashtable.
In the Linux kernel, the following vulnerability has been resolved:
gpio: mpsse: fix race when arming the IRQ poll worker
gpio_mpsse_irq_enable() arms the poll worker before publishing it:
schedule_work() runs before the worker is added to priv->workers. If
gpio_mpsse_disconnect() walks the list in that window it misses the
worker, and once disconnect returns, the USB core frees mpsse_priv
while the orphaned gpio_mpsse_poll() work keeps accessing it, causing
a use-after-free.
Fix this by publishing and arming the worker in one irq_spin
critical section. Teardown walks the same list under irq_spin, so a
worker found on the list is guaranteed to be armed, and
cancel_work_sync() handles it whether it is queued or running.
A worker armed after the disconnect walk would still be missed, so
also set a new priv->dying flag under irq_spin before the teardown
walk, and check it in the same critical section, freeing it via
kfree_rcu() instead when the device is going away, since kfree()
would be called with the IRQ core's raw spinlock held and may sleep
on PREEMPT_RT. schedule_work() is safe to call with irq_spin held,
and the next probe gets a fresh mpsse_priv, so the flag never needs
to be cleared.
This issue was found by an in-house static analysis tool.
In the Linux kernel, the following vulnerability has been resolved:
gpio: xilinx: fix runtime PM leak on request error path
pm_runtime_get_sync() leaves the usage counter incremented even when it
fails, and xgpio_request() returns the error without dropping it.
gpiolib does not call ->free() when ->request() fails, so xgpio_free(),
which holds the only matching pm_runtime_put(), never runs. The reference
is leaked and the controller can no longer runtime-suspend, so its clock
stays enabled.
Switch to pm_runtime_resume_and_get(), which only increments the usage
counter on success.
In the Linux kernel, the following vulnerability has been resolved:
gve: fix napi_disable deadlock when attempting to disable XSK pools
When disabling XSK pools, GVE calls the unlocked versions of
napi_disable and napi_enable. However, the netdev lock has already been
acquired before ndo_bpf is called because GVE supports queue management
ops. Calling the unlocked versions of napi_disable/enable results in a
deadlock when attempting to disable XSK pools, as the thread attempts to
re-acquire a lock it already holds.
Update the NAPI calls to use the locked versions.
This issue was found in production.
In the Linux kernel, the following vulnerability has been resolved:
gve: fix XSK buffer leak when rings are stopped
GVE does not free XSK buffers when resetting ring state as a part of
stopping queues. This causes all XSK buffers which are posted to the
NIC to be leaked.
Free XSK buffers attached to an allocated buf_state when stopping rings.
This issue was hit in production.
In the Linux kernel, the following vulnerability has been resolved:
gve: fix XSK buffer leak on error descriptor
When the error bit is set in the RX completion descriptor, the buf_state
and its attached buffer should be freed. In the case of AF_XDP ZC, the
XSK buffer was not freed, leading to a leak.
This issue was caught by LLM.
In the Linux kernel, the following vulnerability has been resolved:
ibmveth: h_free logical LAN on open-fail after register
ibmveth_open() registers the logical LAN, then allocates the RX
buffer pools. A pool failure jumps to out_free_buffer_pools without
h_free_logical_lan(), so PHYP still owns the buffer-list page when
it is unmapped. request_irq() failure already issued the hypercall
before taking the same label.
Move that h_free to the shared post-register unwind so both paths
deregister before the buffer list is unmapped.
In the Linux kernel, the following vulnerability has been resolved:
ice: fix use-after-free in dynamic port cleanup
ice_dealloc_dynamic_port() uses dyn_port->vsi->idx to erase the dynamic
port from pf->dyn_ports. However, it frees the VSI before reading the
index for the erase, resulting in a use-after-free.
Follow the reverse of the allocation order in ice_alloc_dynamic_port()
by erasing the xarray entry before freeing the VSI.
In the Linux kernel, the following vulnerability has been resolved:
ice: fix metadata_dst refcount handling on representor teardown
ice_eswitch_release_repr() uses metadata_dst_free() to release the
representor's metadata_dst. metadata_dst_free() directly frees the
underlying memory without checking the dst_entry refcount.
When ice_eswitch_port_start_xmit() processes a packet, it takes a
reference via dst_hold() and attaches the metadata_dst to the skb.
If the representor is torn down while packets are still queued on
the lower device (e.g. in a qdisc), the metadata_dst is freed while
references are still held.
Use dst_release() instead, which correctly decrements the refcount
and only frees the object when all references are dropped. The dst
subsystem already handles metadata_dst cleanup in dst_destroy() when
DST_METADATA is set.
Other drivers sharing this pattern (nfp, airoha, bnxt) already use
dst_release() for their metadata_dst lifecycle.
In the Linux kernel, the following vulnerability has been resolved:
io_uring/net: populate CONNECT filter fields for 24-byte sockaddr_in6
io_connect_bpf_populate() fills connect.port and connect.v6_addr for
AF_INET6 only when addr_len >= sizeof(struct sockaddr_in6), i.e. 28
bytes.
The IPv6 connect paths accept SIN6_LEN_RFC2133 (24 bytes), which
already holds sin6_port and sin6_addr. io_connect() passes addr_len to
the socket layer unchanged.
At addr_len 24 the filter sees family AF_INET6 with port and address
zero, while the kernel connects to the real destination. A filter that
denies an IPv6 port or address is bypassed. Denying connect.port == P
rejects [::1]:P with -EACCES at addr_len 28 but connects at addr_len 24.
Use SIN6_LEN_RFC2133 as the threshold. sin6_scope_id stays zero when
absent.
The threshold mismatch was found by an AI coding assistant (Claude Code)
comparing this hook against the net/ipv6 length checks on my
instructions; it also drafted the reproducer and this patch. I verified
the bypass and the fix in a VM on 7.3-rc6 and that 7.2 has the same
code.
In the Linux kernel, the following vulnerability has been resolved:
ip6_gre: remove obsolete ERSPAN PMTU update
A tc tunnel_key action can attach a METADATA_IP_TUNNEL dst to an skb,
and mirred can redirect it to a native ip6erspan device. The legacy PMTU
update in ip6erspan_tunnel_xmit() treats that metadata dst as a route.
Since it has no output device, dst_dev(dst)->mtu dereferences NULL.
On v7.2 with KASAN, an initial UID/GID 65534 process with CapEff 0 used
self-created user and network namespaces to trigger:
KASAN: null-ptr-deref
RIP: ip6erspan_tunnel_xmit+0x10fc/0x2cc0
Kernel panic - not syncing: Fatal exception in interrupt
The update is obsolete. Commit fe1a4ca0a2b7 ("ip6_gre: process toobig
in a better way") changed IPv6 GRE Too Big handling to update the
underlay route and removed the equivalent block from __gre6_xmit().
ip6_tnl_xmit() then propagates the underlay PMTU to the overlay route.
Remove the stale ERSPAN copy and its now-unused dst variable. This
eliminates the metadata-dst dereference and keeps ERSPAN aligned with
IPv6 GRE PMTU handling.
In the Linux kernel, the following vulnerability has been resolved:
KEYS: Fix add_key() race with keyring restriction
__key_create_or_update() snapshots keyring->restrict_link before taking
the destination keyring's semaphore. keyring_restrict() installs a
restriction while holding that semaphore.
This allows a writer to observe no restriction, wait for the keyring
owner to install a reject-all restriction and return successfully, and
then link a key using the stale NULL snapshot. The writer only needs
write permission on the destination keyring.
Move the restrict_link read after __key_link_lock() and
__key_link_begin(). The read and the subsequent restriction check are
then serialized with restriction installation by keyring->sem.
The race was reproduced on v7.2.8 in 19 executions where restriction
installation returned before the link completed. All 19 linked the key
despite the reject-all restriction. With this change, 312 executions
reached the same ordering and every add_key() call failed with -EPERM.
The issue was found by manual concurrency analysis assisted by AI-based
analysis and independently verified with a QEMU reproducer and kernel
instrumentation.
In the Linux kernel, the following vulnerability has been resolved:
memstick: core: wait for request completion before freeing card
In memstick_alloc_card() and memstick_set_rw_addr(),
wait_for_completion_timeout() is used to wait for device identification
and address configuration requests to complete.
The memstick subsystem does not provide an abort or cancellation
callback in struct memstick_host for in-flight requests. If
wait_for_completion_timeout() expires (for instance, when a USB transfer
or command retry is delayed), memstick_alloc_card() returns an error and
frees the memstick_dev structure via kfree(card).
However, the host controller driver (such as rtsx_usb_ms) is still
running the request asynchronously in worker context. When the transfer
eventually finishes, the driver writes into host->req->data, which
points to memory inside the already freed card structure. This leads to
a KASAN slab-use-after-free write:
BUG: KASAN: slab-use-after-free in ms_read_bytes+0x8fe/0x990
Write of size 1 at addr ffff88813c188079 by task kworker/1:5/5239
Workqueue: events rtsx_usb_ms_handle_req
Call Trace:
ms_read_bytes+0x8fe/0x990 drivers/memstick/host/rtsx_usb_ms.c:450
rtsx_usb_ms_issue_cmd drivers/memstick/host/rtsx_usb_ms.c:477 [inline]
rtsx_usb_ms_handle_req+0x557/0x1a00 drivers/memstick/host/rtsx_usb_ms.c:531
process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
worker_thread+0x5ef/0xe50 kernel/workqueue.c:3560
kthread+0x373/0x450 kernel/kthread.c:436
Allocated by task 1662:
memstick_alloc_card drivers/memstick/core/memstick.c:383 [inline]
memstick_check+0x2c1/0x10d0 drivers/memstick/core/memstick.c:452
process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
Freed by task 1662:
kfree+0x20c/0x650 mm/slub.c:6792
memstick_alloc_card drivers/memstick/core/memstick.c:420 [inline]
memstick_check+0x72b/0x10d0 drivers/memstick/core/memstick.c:452
process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
Host controller drivers (rtsx_usb_ms, jmb38x_ms, tifm_ms, r592) already
implement their own hardware and bus timeouts, and callers in
mspro_block and ms_block already rely on wait_for_completion()
unconditionally.
Replace wait_for_completion_timeout() with wait_for_completion() in
memstick_set_rw_addr() and memstick_alloc_card() so that the card
structure is never freed while an asynchronous request is in flight.
In the Linux kernel, the following vulnerability has been resolved:
memstick: rtsx_usb_ms: complete requests after eject instead of dropping them
memstick_check() can pass its host->removing check just before
rtsx_usb_ms_drv_remove() sets eject/removing. Its next request is then
silently dropped: rtsx_usb_ms_request() skips schedule_work() once eject
is set, and drv_remove's cancel_work_sync() can also cancel a queued
handle_req before it picks the request up. Nobody completes
card->mrq_complete.
Once memstick core waits for requests without a timeout ("memstick: core:
wait for request completion before freeing card"), this hangs removal:
memstick_check() never returns and memstick_remove_host() blocks in
flush_workqueue():
INFO: task kworker/u10:3:65 blocked for more than 20 seconds.
Workqueue: kmemstick memstick_check
__wait_for_common
memstick_check
INFO: task kworker/1:1:33 blocked for more than 20 seconds.
Workqueue: usb_hub_wq hub_event
__flush_workqueue
memstick_remove_host
rtsx_usb_ms_drv_remove
Never drop a request. rtsx_usb_ms_request() always schedules handle_req,
and handle_req fails requests with -ENOMEDIUM once eject is set, without
touching the device. drv_remove flushes handle_req instead of cancelling
it, and cancels it only after memstick_remove_host(), when no new
request can arrive, so it cannot run on a freed host.
The host_mutex drain in drv_remove is removed: handle_req always leaves
host->req NULL when it finishes, so the drain never had anything to do,
and it would now race with handle_req.
In the Linux kernel, the following vulnerability has been resolved:
dm-crypt: reject the lmk IV mode with AEAD ciphers
A "capi:" table line that pairs an AEAD cipher with the lmk IV mode,
for example "capi:gcm(aes)-lmk" with the integrity:28:aead option,
causes an oops when it is loaded. lmk sets tfms_count to 64, but
crypt_alloc_tfms_aead only allocates one transform, so crypt_setkey
reads past the end of the tfms_aead array and calls crypto_aead_setkey
on the values it finds there.
lmk exists for compatibility with Loop-AES, which uses CBC, so refuse
it with an AEAD cipher rather than allocate 64 AEAD transforms. The
check cannot go in crypt_iv_lmk_ctr with the other lmk checks, because
the IV constructor runs after crypt_set_key.
Note that this is not a security bug because the memory corruption can
only be triggered by root.
In the Linux kernel, the following vulnerability has been resolved:
dm: fix reading free memory in do_resume
When do_resume calls dm_table_get_mode(new_map), the call is done without
holding any locks (it only holds a reference to the md). It may be
possible that another concurrent ioctl on the same device will swap table
after dm_swap_table and before dm_table_get_mode. In this case,
dm_table_get_mode(new_map) reads freed memory.
This race condition was triggered by syzbot.
This commit fixes the race by reading mode of the new table before
dm_swap_table. Note that new_map is also passed to dm_ima_need_measure,
but this function doesn't attempt to dereference it, so this call should
be safe.
Note that this is not a security bug because only root can trigger it and
the commonly used tools such as lvm or cryptsetup do not call the ioctls
concurrently, so that they can't trigger it acceidentally.
In the Linux kernel, the following vulnerability has been resolved:
mmc: mtk-sd: Cancel request timeout work on remove
The driver queues req_timeout while a request is active.
msdc_request_done() uses cancel_delayed_work(), which does not wait for
a timeout callback that has already started.
The timeout callback calls mmc_request_done(), which wakes the request
waiter, and then continues to use host->dev_comp and check the SDIO IRQ.
During unbind, msdc_drv_remove() can return and the managed mmc_host can
be freed before the callback finishes.
KASAN reported use-after-free accesses in msdc_request_done() and
msdc_recheck_sdio_irq() in each of three unbind tests. The same tests
completed without a kernel diagnostic after this change.
Call cancel_delayed_work_sync() after mmc_remove_host() has stopped new
requests and before the driver releases the host resources.
In the Linux kernel, the following vulnerability has been resolved:
mmc: sdhci-sprd: disable runtime PM on remove
sdhci_sprd_probe() enables runtime PM, while sdhci_sprd_remove() does
not perform the corresponding runtime PM cleanup.
The probe failure path disables runtime PM before disabling the clocks,
but the normal remove path directly disables clocks that are also
managed by the runtime PM callbacks. If the device is runtime
suspended, those clocks may already be disabled.
Resume the device before removal, disable runtime PM and drop the
temporary runtime PM reference before disabling the clocks.
This issue was found by manual code inspection.
In the Linux kernel, the following vulnerability has been resolved:
net/packet: guard the ll header push in packet_rcv_spkt()
packet_rcv_spkt() restores the link layer header with
skb_push(skb, skb->data - skb_mac_header(skb));
That subtraction is only meaningful when the device actually has a link
layer header. packet_rcv() and tpacket_rcv() both wrap it in
dev_has_header(), which is also the predicate the block comment at the
top of the file states the restore in terms of; packet_rcv_spkt() does
not. commit d549699048b4 ("net/packet: fix packet receive on L3
devices without visible hard header") introduced the helper and changed
the two call sites, and this one stayed behind.
A device without a visible ll header can leave skb->mac_header at the
0xFFFF sentinel that __alloc_skb() initialises it to. A CAN skb does:
init_can_skb() sets pkt_type and ip_summed but does not reset the
headers, and commit 9f10374bb024 ("can: remove private CAN skb
headroom infrastructure") dropped the skb_reset_*_header() calls that
used to be there. skb_mac_header() is then 0xFFFF, the length becomes
a large negative number and skb_push() reports it through
skb_under_panic() -- from softirq context, so it is a full system panic
even with panic_on_oops=0:
skbuff: skb_under_panic: text:ffffffff8bd21bc1 len:-65455 put:-65471 head:... data:... tail:0x50 end:0x180 dev:can0
kernel BUG at net/core/skbuff.c:214!
RIP: 0010:skb_panic+0x50/0x60
Call Trace:
<IRQ>
skb_push+0x38/0x40
packet_rcv_spkt+0xe1/0x170
__netif_receive_skb_core.constprop.0+0x7e8/0xd30
...
Kernel panic - not syncing: Fatal exception in interrupt
The socket type is reachable: packet_create() accepts SOCK_PACKET
alongside SOCK_RAW and SOCK_DGRAM behind the same CAP_NET_RAW check,
and neither the socket length nor a capability check keeps it away
from a CAN interface.
The missing skb_reset_*_header() calls in init_can_skb() are a
regression in their own right and are being fixed separately, but a
packet socket should not turn a link layer that did not initialise its
mac header into a kernel panic. Guard the push the way the other two
receive paths do.
Tested on v7.3-rc5 under QEMU with a slcan device on a pty, which is
the driver RX path: vcan does not reproduce it, because can_send()
resets the headers on the way out. One SOCK_PACKET socket bound to
can0 and one frame written into the line discipline panics an
unpatched kernel with the trace above; the same image with this patch
prints no panic and powers off normally. Both kernels are this tree,
defconfig plus CONFIG_CAN_SLCAN=y, differing only in this hunk.
In the Linux kernel, the following vulnerability has been resolved:
net/smc: protect clcsock lifetime in smc_getname
smc_getname() dereferences smc->clcsock without holding
clcsock_release_lock. Link-group termination can release the CLC socket
through smc_close_active_abort() while the SMC socket is still open,
for example after shutdown(SHUT_WR).
A getsockname() caller can load smc->clcsock, then the termination worker
can clear the pointer and call sock_release() before the caller accesses
clcsock->ops or invokes getname(). This causes a use-after-free; if the
worker clears the pointer before the load, it causes a NULL dereference.
The syscall's file reference keeps the SMC socket alive but does not
prevent asynchronous release of its CLC socket.
KASAN reported the following with test-only timing instrumentation:
BUG: KASAN: slab-use-after-free in smc_getname+0x19e/0x1b0
Read of size 8 at addr ffff888109abb4e0 by task poc/103
Call Trace:
smc_getname+0x19e/0x1b0
do_getsockname+0xe5/0x170
__sys_getsockname+0x8c/0x100
Allocated by task 95:
sock_alloc_inode+0x1e/0x280
sock_alloc+0x3d/0x240
__sock_create+0x7e/0x430
smc_create+0x121/0x240
Freed by task 0:
kmem_cache_free+0xcc/0x340
rcu_core+0x50a/0x1850
Last potentially related work creation:
evict+0x446/0x6c0
smc_clcsock_release+0xa8/0xd0
smc_close_active_abort+0x26a/0x3a0
__smc_lgr_terminate.part.0+0x137/0x2e0
Hold clcsock_release_lock across the pointer check and the getname()
callback to serialize with smc_clcsock_release(). Return -EBADF if the
CLC socket has already been released, preserving the existing peer
state check and the callback's return value otherwise.
In the Linux kernel, the following vulnerability has been resolved:
net: bridge: avoid recursive multicast port cleanup
br_multicast_sg_del_exclude_ports() removes automatically added STAR_EXCL
port groups by calling br_multicast_del_pg(). For S,G entries, that
deletion calls back into br_multicast_sg_del_exclude_ports(), so a large
number of STAR_EXCL ports consumes one kernel stack frame per port and can
hit the stack guard page.
Keep the complete port-group deletion path for cleanup, but suppress the
S,G exclude-port cleanup while that helper is already walking the same
entry. Normal deletion callers retain the existing behavior.
In the Linux kernel, the following vulnerability has been resolved:
net: skbuff: don't leave stale bytes in skb_copy_and_csum_bits()
When skb_copy_and_csum_bits() reaches unreadable frags it returns 0
after copying only the linear part, and the rest of the caller's buffer
is left as it was. The callers copy into a buffer that is about to go
out on the wire: an ICMP error quoting the offending packet, or a
driver's TX bounce buffer in skb_copy_and_csum_dev(). Neither buffer
is zeroed beforehand, so whatever was in memory there gets sent.
Zero the part of the buffer we didn't fill. The checksum usually
won't match the data any more, so the receiver will usually drop the
packet, but either way it no longer carries anything it shouldn't.
Only zero for a positive @len, a negative one from a broken caller must
not turn into a huge memset().
In the Linux kernel, the following vulnerability has been resolved:
net: sparx5: free the matchall entry on destroy
sparx5_tc_matchall_replace() allocates a struct sparx5_mall_entry for
every offloaded matchall filter and adds it to sparx5->mall_entries.
sparx5_tc_matchall_destroy() removes the entry from the list, but never
frees it, so the entry of every deleted mirror and goto matchall filter
is leaked.
Free the entry after unlinking it.
The leak was discovered by an AI code review agent, and reproduced with
kmemleak on a lan969x EV board (EV23X71A) by repeatedly adding and
deleting matchall mirror and goto filters. With the fix, kmemleak no
longer reports the leak.
In the Linux kernel, the following vulnerability has been resolved:
net: xilinx: axienet: Free outstanding DMA buffers on dmaengine stop
In the dmaengine path the driver pre-submits RX buffers and holds
in-flight TX buffers whose SKBs are DMA-mapped by the driver and freed
only in the completion callbacks. On ndo_stop() dmaengine_terminate_sync()
aborts these descriptors without running their callbacks, and the driver
then frees only the ring shells, leaking every SKB still owned by the
engine and its DMA mapping on each ifdown. With 128 RX buffers pre-posted
per channel, the mapping leak can eventually exhaust a limited IOMMU
aperture.
Clear the slot's skb in the TX and RX callbacks so a non-NULL skb marks a
slot that still owns a live, DMA-mapped buffer, and on stop unmap and free
every such buffer.
axienet_dma_rx_cb() runs from the DMA tasklet and re-arms the RX ring on
each completion, so it can race axienet_stop(): a completion may submit a
fresh buffer after dmaengine_terminate_sync() has returned, leaving the
channel armed with a buffer the teardown then frees while the engine may
still write into it (dma_release_channel() does not stop it either). Add a
lock that axienet_dma_rx_cb() holds across the @stopping check and the
resubmit, and axienet_stop() holds to set @stopping before terminating.
Once @stopping is set no callback can arm a new buffer, and any armed just
before is aborted by the terminate, so teardown only frees buffers the
engine no longer owns.
In the Linux kernel, the following vulnerability has been resolved:
net: team: stop reusing skb after queue override
A nonzero dev_queue_xmit() result does not return ownership of the skb.
When an override port's qdisc drops it, the queue override helper used to
try another port or the mode transmit op with the freed skb.
Return the handoff decision separately from transmit success. Select only
the first override port under RCU and stop after handing it the skb,
regardless of the lower transmit result. Keep the existing success and
drop accounting.
BUG: KASAN: slab-use-after-free in sk_skb_reason_drop
Write of size 4 by task poc/5040
sk_skb_reason_drop (net/core/skbuff.c:1240)
dev_kfree_skb_any_reason (net/core/dev.c:3470)
ab_transmit (drivers/net/team/team_mode_activebackup.c:49)
team_xmit (drivers/net/team/team_core.c:1849)
__dev_direct_xmit (net/core/dev.c:4934)
Freed by task 5040:
__tcf_kfree_skb_list (net/sched/sch_generic.c:43)
__dev_queue_xmit (net/core/dev.c:4831)
team_xmit (drivers/net/team/team_core.c:1846)
Kernel panic - not syncing: KASAN: panic_on_warn set ...
In the Linux kernel, the following vulnerability has been resolved:
net: team: free skb when broadcast has no txable port
bc_transmit() sends the original skb through the last txable port.
When no port is txable, it returns false without consuming the skb, but
team_xmit() still returns NETDEV_TX_OK. AF_PACKET sends then retain the
skb and its socket write-memory charge.
A TX-enabled, link-down port keeps the broadcast transmit op installed.
Carrier can stay up through a second link-up, TX-disabled port or be
forced on by userspace. Free the original skb on the no-port path while
leaving the existing drop accounting intact.
Discovered by Sashiko during review of previous commit.
In the Linux kernel, the following vulnerability has been resolved:
openvswitch: fix soft lockup in the netlink flow dump
A production compute node carrying a few thousand datapath flows hit a
soft lockup inside a single netlink flow dump and panicked.
ovs_flow_cmd_dump() calls ovs_flow_stats_get() for every flow it
emits, and that releases stats->lock with spin_unlock_bh() once per
CPU that has touched the flow. Every release is a local_bh_enable(),
and each one runs the pending softirq backlog in the dumping thread's
own context.
The skb bounds the flows one callback emits, but not the softirq work
it absorbs. On a CPU that carries the box's packet load the backlog
refills as fast as it drains, so the dumping thread becomes that CPU's
softirq engine. It never sleeps and it has no reschedule point, so
under voluntary preemption nothing can take the CPU away from it:
neither the ksoftirqd the kernel woke to take the work over, nor the
stopper thread the softlockup detector dispatches to refresh its
timestamp.
Hold BH off across the whole callback instead, the way
ctnetlink_dump_table() does, so the nested spin_unlock_bh() stop
draining softirqs. The loop already runs under rcu_read_lock() and
cannot sleep. What it gives up is preemption under CONFIG_PREEMPT,
since a BH-off region is not preemptible outside PREEMPT_RT. The
region stays short: the skb caps the flows one callback emits, and
empty buckets cost no skb space but are each visited once per dump, as
the cursor only moves forward. The table grows on insert and shrinks
only on flush, so the walk is bounded by the largest flow count the
datapath has held. The softirq backlog the callback used to absorb has
no bound at all.
In the Linux kernel, the following vulnerability has been resolved:
optee: register TEE devices only once fully initialized
optee_probe() called tee_device_register() on both the client and the
supplicant device before the rest of struct optee had been initialized.
tee_device_register() calls cdev_device_add(), which does two things at
once: it creates /dev/tee0 and /dev/teepriv0, and it links the device
into the tee class so that class_find_device() can find it. From that
moment on the device is reachable both from user space via tee_open()
and from kernel space via tee_client_open_context(). The only gate in
teedev_open() is tee_device_get(), which merely checks that
teedev->desc is non-NULL, which was already set by tee_device_alloc().
Therefore, there is effectively no gate at all.
A context opened in that window can run against a struct optee where
- optee->call_queue.mutex is not initialized by optee_cq_init()
- optee->supp mutex and completions is not initialized by
optee_supp_init()
- optee->rpmb_dev_mutex is not initialized yet,
- the message argument cache is not initialized by
optee_shm_arg_cache_init()
- optee->ctx is still NULL
Any open session or invoke during this window takes uninitialized
mutexes and dereferences a NULL pointer.
Fix it by moving both tee_device_register() calls down to the point
where all of struct optee is set up.
[JW: adding fixes and cc]
In the Linux kernel, the following vulnerability has been resolved:
power: sequencing: pcie-m2: Fix leaking array from of_regulator_bulk_get_all()
of_regulator_bulk_get_all() allocates the consumers array and hands it to
the caller, who is expected to free it at an appropriate time.
pwrseq-pcie-m2.c never did, leading to a memory leak.
Add an explicit kfree() for the consumers array.
In the Linux kernel, the following vulnerability has been resolved:
regulator: ltc3676: don't read the write-only HRST and CLIRQ registers
HRST (0x1e) and CLIRQ (0x1f) are write-only command strobes. Writing HRST
triggers a hard reset of the chip and writing CLIRQ clears the interrupt;
reading them returns nothing useful, and the read itself fires the command.
The result is that a plain register dump resets the board:
cat /sys/kernel/debug/regmap/2-003c/registers
walks every readable register, hits HRST, and the board reboots.
Split the callback back in two so HRST and CLIRQ stay writable but are no
longer readable. The readable range is left unchanged
(LTC3676_BUCK1 ... LTC3676_IRQSTAT).
In the Linux kernel, the following vulnerability has been resolved:
regulator: of: fill in supply names in of_regulator_bulk_get_all()
of_regulator_bulk_get_all() returns an array it allocated itself, and
fills in only the consumer of each entry. Every other way of getting a
bulk array has the supply name set, because the caller provides it, and
the core expects it to be there: regulator_bulk_enable() prints it when
a supply fails to enable, so a caller that hands such an array to it
dereferences uninitialised memory on that path.
Copy each name into the array's own allocation, right behind the
entries, so that it shares the array's lifetime and callers still have
nothing extra to free. That also retires the fixed 64 byte stack buffer
the names were assembled in, which is_supply_name() never bounded the
copy against.
In the Linux kernel, the following vulnerability has been resolved:
regulator: tps6594-regulator: Fix n_linear_ranges for TPS65224 BUCK2-4
The TPS65224 BUCK2, BUCK3 and BUCK4 descriptors pass 4 as
n_linear_ranges, but tps65224_bucks_2_3_4_ranges[] only has two
entries, covering selectors 0x00-0x45.
The linear range helpers loop over n_linear_ranges entries, so any
lookup of a selector above 0x45 reads past the end of the array and
treats whatever follows it as two more ranges. This happens on the
normal registration path when the core checks the voltage constraints
against every selector. TPS652G1 uses the same descriptors and is
affected too.
Use ARRAY_SIZE() so the count always matches the table.
In the Linux kernel, the following vulnerability has been resolved:
scsi: ch: Do not keep references to data transfer element devices
ch_readconfig() looks up the scsi_device of every data transfer element
whose SCSI id the changer reports in READ ELEMENT STATUS, and stores it in
ch->dt[]. scsi_device_lookup() takes a reference, and nothing ever drops
it: ch_destroy() frees the array with kfree(). ch->dt[] is read nowhere
else - it only supplies the vendor, model and revision printed in the same
loop.
Once such a drive is removed, its scsi_device can never be released. It
stays on the host's device list at its address, so a new device there is
refused by anything that walks the list - target_core_pscsi reports
"scsi_device_get() failed for H:C:T:L" - and the low-level driver's module
can no longer be unloaded. Only a reboot recovers.
It shows with any changer that reports its drives' ids; with the mhvtl
virtual library (IBM 3573-TL personality), each create and remove of a
library with four drives leaves four references behind, counted by the
module's use count in lsmod. With ch not bound the count is unchanged, and
with this patch applied it is unchanged too.
Drop the reference as soon as the name has been printed, and remove the now
unused dt[] array. That also removes the array leaked when ch_probe() fails
after ch_readconfig().
The same leak was reported with an RFC patch in 2022, which was not merged.
In the Linux kernel, the following vulnerability has been resolved:
riscv: entry: gate shadow call stack reload on sstatus.SPP, not tp
Under CONFIG_SHADOW_CALL_STACK, handle_exception() reloads the kernel
shadow call stack pointer (gp) only when the trap came from userspace.
It made that decision with scs_load_current_if_task_changed, which
compares the trap-time tp (read back from sscratch into s5) against the
current tp:
beq \prev, tp, _skip_scs
scs_load_current
_skip_scs:
tp is a user-writable register. A user task that sets tp to the
linear-map address of its own task_struct (¤t) before trapping
makes the comparison succeed (can achieve by brute force with KASLR
enable under our test), so the kernel skips scs_load_current and
keeps running with the gp that userspace left in place. Under
CONFIG_SHADOW_CALL_STACK gp is the shadow call stack pointer and
load_global_pointer is a no-op, so the compiler-emitted
"sd ra, -8(gp)" / "ld ra, -8(gp)" in every non-leaf function then write
to, and return through, an attacker-controlled address -- an
unprivileged kernel arbitrary-write and control-flow-hijack primitive.
The poisoned gp is saved to task_struct.scs_sp on return, so the reload
is skipped on every subsequent entry as well.
Decide "came from userspace" from the hardware sstatus.SPP bit (already
in s1 at this point) instead of from tp, mirroring the check that
ret_from_exception already uses a few instructions later. SPP is
written by hardware on trap entry and cannot be forged from U-mode.
Legitimate behaviour is unchanged: user entries (SPP=0) reload the task
shadow call stack, nested kernel entries (SPP=1) skip it.
In the Linux kernel, the following vulnerability has been resolved:
riscv: errata: select RISCV_ALTERNATIVE_EARLY for THEAD GHOSTWRITE
errata_probe_ghostwrite() only marks the CPU as vulnerable when it is
called at the RISCV_ALTERNATIVES_EARLY_BOOT stage, and the mitigation
in ghostwrite_enable_mitigation() only takes effect if the vulnerable
state was recorded before the boot alternatives are patched.
The early boot stage is only executed when CONFIG_RISCV_ALTERNATIVE_EARLY
is enabled, which currently is only selected by ERRATA_THEAD_MAE. In a
kernel built with ERRATA_THEAD_GHOSTWRITE=y but ERRATA_THEAD_MAE=n, the
early alternatives never run, so ghostwrite_state is never set to
VULNERABLE: ghostwrite_enable_mitigation() returns false, xtheadvector
remains enabled, and sysfs reports "Not affected" on a vulnerable
T-Head C9xx CPU.
Select RISCV_ALTERNATIVE_EARLY from ERRATA_THEAD_GHOSTWRITE so that the
vulnerability is detected in the early boot stage and the default
mitigation is applied.