| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
tcp: fix use-after-free in do_tcp_getsockopt(TCP_CONGESTION)
do_tcp_getsockopt() reads icsk->icsk_ca_ops->name without holding
rcu_read_lock(). Since commit 0baf26b0fcd7 ("bpf: tcp: Support
tcp_congestion_ops in bpf"), icsk_ca_ops can point to dynamically
allocated BPF struct_ops memory that may be freed concurrently via
setsockopt(TCP_CONGESTION), leading to a use-after-free.
BUG: KASAN: slab-use-after-free in _copy_to_user+0x37/0x60
Read of size 16 at addr ffff888013505260 by task exploit/149
_copy_to_user+0x37/0x60
do_tcp_getsockopt+0x158a/0x2460 (net/ipv4/tcp.c:4585)
tcp_getsockopt+0x91/0xf0
__sys_getsockopt+0xf7/0x170
Fix this by holding rcu_read_lock() around the ca_ops->name access,
using READ_ONCE() to load icsk_ca_ops, and copying the name to a
stack buffer before releasing the lock. Also annotate the relevant
icsk_ca_ops stores with WRITE_ONCE() to fix the accompanying KCSAN
data-race issue. |
| In the Linux kernel, the following vulnerability has been resolved:
tcp: fix use-after-free in do_tcp_getsockopt(TCP_CC_INFO)
do_tcp_getsockopt() reads icsk->icsk_ca_ops and dereferences the
get_info function pointer without rcu_read_lock(). With BPF struct_ops
congestion control, ca_ops can point to dynamically allocated memory
that is freed concurrently, resulting in a use-after-free when the
kernel dereferences or calls through the stale pointer.
BUG: KASAN: slab-use-after-free in do_tcp_getsockopt+0x2037/0x23e0
Read of size 8 at addr ffff888013701258 by task exploit/149
do_tcp_getsockopt+0x2037/0x23e0 (net/ipv4/tcp.c:4564)
tcp_getsockopt+0x91/0xf0
__sys_getsockopt+0xf7/0x170
Fix this by wrapping the ca_ops load and get_info call within
rcu_read_lock()/rcu_read_unlock(), and using READ_ONCE() to load
the icsk_ca_ops pointer. |
| In the Linux kernel, the following vulnerability has been resolved:
dm-integrity: fix infinite loop on discard with large tag size
When integrity_metadata handles a discard, it fills a buffer with
DISCARD_FILLER and writes it over the tags, max_blocks blocks at a
time. If the kmalloc fails, the buffer is the on-stack array
checksums_onstack and max_size is set to HASH_MAX_DIGESTSIZE. So if the
tag size is larger than HASH_MAX_DIGESTSIZE, max_blocks is zero, bi_size
is never decremented and the loop never terminates.
Fix this by using sizeof(checksums_onstack) as max_size. The array has
MAX_TAG_SIZE bytes since commit b93b6643e9b5 ("dm integrity: fix a
crash with unusually large tag size"), so max_blocks is at least 1. |
| In the Linux kernel, the following vulnerability has been resolved:
mac802154: fix data race and NULL deref on local->assoc_dev
local->assoc_dev is shared between the association path and the
association-response worker without common synchronization.
mac802154_perform_association() stores the coordinator pointer and waits
for a response. Its timeout and error paths clear the pointer and return
to mac802154_associate(), which may then free the coordinator object.
Meanwhile, mac802154_rx_mac_cmd_worker() may observe the associating bit
and enter mac802154_process_association_resp(), which dereferences
assoc_dev.
The worker's bit test and the handler's pointer dereference are not
atomic with respect to cleanup. Cleanup can clear assoc_dev between them,
causing a NULL dereference, or free the coordinator while the response
handler still uses the pointer.
The recorded result is exposed to the same window. assoc_status and
assoc_addr are written by the handler but read by the association path
while the associating bit is still set, so a second response for the same
request - a malicious one, for instance - can replace them between those
reads and leave the caller with an incoherent status and address pair.
The response handler only needs the coordinator extended address.
Replace assoc_dev with a cached address, removing the pointer lifetime
dependency. Protect the cached address and the associating bit with a
dedicated spinlock. A READ_ONCE()/WRITE_ONCE() pair would not guarantee
an atomic __le64 access on all 32-bit architectures.
wpan_dev->association_lock cannot be reused here: nl802154_associate()
holds it across rdev_associate(), hence for the whole of
mac802154_perform_association() including the wait for the response.
A response handler taking that lock would only get it once the
association has already given up.
Reset the completion, publish the cached address, and set the associating
bit while holding the lock. The response handler takes the lock, rechecks
the bit and the cached address, records the response, clears the bit, and
only then completes the waiter. Thus cleanup cannot pass the handler
between its state check and completion, and the cached 64-bit value
cannot tear.
The handler clears the bit before completing, not the woken waiter:
otherwise complete() is issued under the lock and a second (e.g.
malicious) response can reacquire it before the waiter and replace the
result. So a wait that returns success implies the bit is already clear,
and the success and negative-response paths return directly. The
transmit-error and timeout paths still clear it under assoc_lock, which
serializes any racing response against the cleanup while the call returns
the error it already selected. Both paths snapshot assoc_status and
assoc_addr under the same lock.
Both users run in process context, so a plain spinlock is sufficient.
The lock is not held while waiting for the completion. |
| In the Linux kernel, the following vulnerability has been resolved:
net/iucv: fix the recvmsg window update
iucv_sock_recvmsg() sends the HiperSockets-only AF_IUCV_FLAG_WIN without
testing the transport, so on a classic z/VM socket iucv_send_ctrl() sizes
the skb through a NULL iucv->hs_dev. SO_MSGLIMIT accepts 1, so msglimit / 2
is zero and one recvmsg() on its own socket is enough for an unprivileged
process to take a spurious disconnect.
It also calls iucv_send_ctrl() under spin_lock_bh(&message_q.lock), which
allocates GFP_KERNEL inside a section the code treats as atomic. Sending
outside that lock lets two recvmsg() reach afiucv_hs_send() at once, where
msg_recv is sampled for the advertised window and subtracted after
dev_queue_xmit() -- and sendmsg reaches that counter under lock_sock()
while recvmsg holds no socket lock, so both can subtract the same value,
the counter goes negative and the credit reaches the peer twice.
Test the transport, claim the credit with atomic_xchg() after the last
error exit and hand it back if the transmit fails, and send once the lock
is dropped. |
| In the Linux kernel, the following vulnerability has been resolved:
xfs: don't hold buffer locks across sync transaction commit in xfs_sync_sb_buf
xfs_sync_sb_buf() holds sb/rtsb buffer locks across a synchronous
xfs_trans_commit(), which flushes the CIL push workqueue internally.
If shutdown occurs during the CIL push, xfs_buf_item_unpin() needs to
lock these buffers to fail them, causing a deadlock:
setlabel: holds buf lock -> flush_workqueue(xfs-cil)
CIL push worker: xfs_buf_item_unpin -> xfs_buf_lock(same buf)
Remove the xfs_trans_bhold() calls so that commit releases the buffer
locks normally. After the sync commit, re-acquire the buffers via
mp->m_sb_bp / mp->m_rtsb_bp for the on-disk writeback. |
| In the Linux kernel, the following vulnerability has been resolved:
io_uring/cancel: don't spin on local work the task can't run
io_uring_cancel_generic() refuses to sleep while any ring on the exiting
task's tctx has local work pending. It assumes the task is that ring's
submitter and that the next io_uring_try_cancel_requests() pass will run
the work. This does not hold for a ring that was still
IORING_SETUP_R_DISABLED when the task got its tctx node from
io_uring_create() or io_ringfd_register(). The submitter is set later by
IORING_REGISTER_ENABLE_RINGS, possibly from another task, and only the
submitter may run local work on an IORING_SETUP_DEFER_TASKRUN ring. To
the exiting task the work stays pending forever, the loop never reaches
schedule(), and the task trips the WARN_ON_ONCE() once and then spins in
do_exit().
An unprivileged user can set this up at will by creating a disabled
ring, having a child enable it and stop, posting to the ring with
IORING_OP_MSG_RING and exiting with a request in flight that only the
child can complete. The exiting thread burns a CPU until the child runs
or dies, and with panic_on_warn set the WARN panics the kernel.
Fix by skipping the sleep only when io_allowed_defer_tw_run() allows the
task to run the work. This is reasonable since work it cannot run cannot
complete any of its requests either, so nothing is lost by sleeping.
Drop the WARN_ON_ONCE() since handing a disabled ring to another thread
is a supported scenario, not a bug state. |
| In the Linux kernel, the following vulnerability has been resolved:
sctp: validate chunk length in the inqueue parser
SCTP chunks always include a four-byte generic header, but
sctp_inq_pop() currently accepts shorter declared lengths. A zero-length
chunk leaves chunk_end at the current header.
When ASCONF is covered by the association's SCTP-AUTH policy,
sctp_assoc_bh_rcv() can continue before the state machine performs its
normal chunk-length check. sctp_inq_pop() then returns the same malformed
chunk repeatedly and the receive softirq can lock up.
A remote SCTP peer can trigger this after establishing an association on
a kernel built with CONFIG_IP_SCTP and configured with
net.sctp.addip_enable=1 and net.sctp.auth_enable=1. The reproducer did
not require application credentials, a shared SCTP AUTH key, or
net.sctp.addip_noauth_enable=1.
On commit f967455fb2a5 ("seg6: reset IP6CB after IPv6 decapsulation"),
one zero-length ASCONF caused repeated
watchdog soft-lockup reports in a two-vCPU KVM guest. All 3 pre-trigger
health probes succeeded, while 36 of 37 post-trigger probes failed. With
this change, all 37 post-trigger probes succeeded and no equivalent
soft-lockup signature appeared.
Reject chunks shorter than the generic SCTP header at the shared inqueue
parser boundary. Mark the packet for discard before either caller can
continue processing it, while preserving the four-byte generic minimum.
Declared-length 1 through 4 controls and kernel-generated ASCONF traffic
remained healthy. The patched sctp_hello selftest passed for IPv4 and
IPv6.
The complete private reproducer and validation evidence are available
directly to maintainers on request. |
| In the Linux kernel, the following vulnerability has been resolved:
page_pool: keep frag_offset aligned for odd-sized requests
page_pool_alloc_frag_netmem() rounds the requested fragment size with
size = ALIGN(size, dma_get_cache_alignment());
dma_get_cache_alignment() returns 1 unless the architecture defines
ARCH_DMA_MINALIGN, which DMA-coherent architectures such as x86 do not.
There the ALIGN() is a no-op and pool->frag_offset advances by the raw,
unrounded size.
A single caller asking for an odd size then leaves frag_offset misaligned
for every fragment carved out of that page afterwards. The pool is shared,
so the damage is not confined to the caller that caused it.
The per-cpu system_page_pool used by generic XDP hits this.
skb_pp_cow_data() allocates its fragments with the raw packet length:
size = min_t(u32, len, PAGE_SIZE);
truesize = size;
page = page_pool_dev_alloc(pool, &page_off, &truesize);
leaving frag_offset odd for whatever is carved out of that page next. Its
own head allocation is already aligned -- SKB_HEAD_ALIGN(size) plus the
XDP_PACKET_HEADROOM its callers pass -- so it is a later user of the shared
pool that pays: page_pool_dev_alloc_va() returns a misaligned buffer,
napi_build_skb() installs it as skb->head, and skb_shinfo(skb) ==
skb->head + skb->end is misaligned with it.
skb_shinfo()->dataref is a 4-byte atomic_t at offset 0x20, so the
atomic_inc() in __skb_clone() straddles a cache line. On x86 with split
lock detection -- fatal for kernel split locks by default -- this panics
the machine:
Oops: Split lock detected
RIP: 0010:skb_clone+0x154/0x1e0
Call Trace:
<IRQ>
raw_local_deliver+0x1ed/0x2c0
ip_protocol_deliver_rcu+0x54/0x1c0
ip_local_deliver_finish+0x85/0x100
ip_local_deliver+0x67/0x100
__netif_receive_skb_one_core+0x85/0xa0
process_backlog+0x87/0x130
Reproduced by attaching any generic-mode XDP program to loopback and
opening a RAW IPPROTO_UDP socket, which makes raw_local_deliver() clone
every locally delivered UDP packet; ordinary DNS traffic then triggers it,
roughly once per 2500 clones. Observed on 6.12.101 and 7.1.8.
Tracing page_pool_alloc_frag_netmem() over one such run shows the
amplification -- two odd-sized requests, nine misaligned offsets:
requested size & 7: 0: 17035 5: 1 7: 1
frag_offset & 7: 0: 17028 3: 1 4: 1 5: 1 6: 1 7: 5
and skb_pp_cow_data() returning heads that were aligned on entry:
head 0xffff8f4c86aeac00 -> 0xffff8f4c53a9a9c4 (&7=4)
head 0xffff8f4d6a8a42c0 -> 0xffff8f4c4f7b7a45 (&7=5)
Round the fragment size up to at least the alignment struct skb_shared_info
requires, so fragments are always suitably aligned for the objects callers
build on them. Architectures needing a larger DMA alignment keep it.
This also makes the remainder computed in page_pool_alloc_netmem(),
*size = max_size - *offset;
aligned, since max_size is a power of two -- which fixes the matching
misalignment of skb->end.
Verified with a controlled A/B under QEMU/KVM: same tree, same config,
same compiler, same rootfs and identical traffic, differing only by this
patch. A SEC("xdp.frags") XDP_PASS program on lo plus UDP datagrams
larger than max_head_size drives skb_pp_cow_data()'s fragment loop, which
passes raw packet lengths to the pool. Measured at the return of
skb_pp_cow_data():
unpatched patched
skb_pp_cow_data calls 40800 40800
misaligned skb->head 1120 0
dataref at line offset >60 80 0
The last row counts the accesses that actually fault:
skb_shinfo()->dataref sits at head+end+0x20 and is a 4-byte atomic, so
`lock incl` splits a 64-byte cache line only when that address lands at
offset 61..63. All 80 occurrences were at offset 61; the panic reported
above was at offset 62. Eliminating the misalignment removes every one
of them.
Same class of bug as commit 3bed3cc4156e ("net: Do not allocate page
fragments t
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
s390/ctcm: Prevent XID null dereference
The mpc_validate_xid() function sets grp->saved_xid2->xid2_flag2 to 0x40
to signal XID validation error. If peer XID is NULL or r/w channel
pairing mismatch happens, grp->saved_xid2 is never initialized. An
attempt to set the flag in such case leads to NULL dereference.
Fix this by using the always available priv->xid->xid2_flag2 instead of
grp->saved_xid2->xid2_flag2 for validation errors. |
| In the Linux kernel, the following vulnerability has been resolved:
s390/pci: Fix leak of uninitialized kernel data in SCLP report
While report_error_write() checks that the provided buffer is at least
as large as the header struct, but not that it is large enough to
contain the report with the length claimed by report->length. If
user-space provides a short buffer, meaning a larger report->length than
the actually written payload, up to around 4K of kernel data from past
the kmalloc(len + 1) sized buffer allocated in kernfs_fop_write_iter()
will leak into the SCLP report.
However, as the entity processing the SCLP is privileged and able to
access at least the page including the report, this does not leak data
that entity could not access but it is still an out of bounds read and
a malformed error report that should be rejected. |
| In the Linux kernel, the following vulnerability has been resolved:
ipv4: avoid divide by zero in fib_rebalance
fib_rebalance() computes the total eligible nexthop weight in one pass
and programs upper bounds in a second pass. A concurrent change to
ignore_routes_with_linkdown can make the first pass return zero while
the second pass sees an eligible nexthop, resulting in division by zero.
If the first pass reports a zero total, set each nexthop upper bound to
-1 and skip the division. This matches the IPv6 fix in commit
d2c26c2911dd ("ipv6: avoid divide by zero in rt6_multipath_rebalance")
and preserves the lock-free rebalance path. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/i915/dmc: Harden DMC firmware payload parsing
Validate the conversion of the DMC firmware size from dwords to bytes
using check_mul_overflow() before calculating the firmware payload size.
Reject zero-length payloads and zero MMIO counts in the DMC firmware
header so malformed firmware is caught early. Also set dmc_fw_size only
after the payload allocation succeeds.
(cherry picked from commit efde6601a1f1daedfe3dcc2816c934ddb44e3eef) |
| In the Linux kernel, the following vulnerability has been resolved:
ksmbd: fill in FileSysIdentifier in FS_POSIX_INFORMATION
smb2_get_info_filesystem() reports 56 bytes for FS_POSIX_INFORMATION,
that is the whole of FILE_SYSTEM_POSIX_INFO, but never assigns
FileSysIdentifier. Those eight bytes go to the client as they are found
in the response buffer.
The buffer is zeroed on allocation, so a standalone request leaks
nothing. A compound request can leak: the offset of the next response
is advanced by the length pinned for the previous one, so a reply that
was written into the buffer and then dropped in favour of the short
error response of smb2_set_err_rsp() stays there, and the next reply is
laid over it with only the header cleared.
Report the file system id statfs() returned, which is what the field is
for. FileSysIdentifier is __le64 and f_fsid is a pair of ints, so
assemble the value first, val[0] as the low half, and convert it on the
way out. |
| In the Linux kernel, the following vulnerability has been resolved:
ksmbd: initialize FileSystemControlFlags in FS_CONTROL_INFORMATION
smb2_get_info_filesystem() reports 48 bytes for FS_CONTROL_INFORMATION,
that is the whole of struct smb2_fs_control_info, but never assigns
FileSystemControlFlags. Those four bytes go to the client as they are
found in the response buffer.
The buffer is zeroed on allocation, so a standalone request leaks
nothing. A compound request can leak: the offset of the next response
is advanced by the length pinned for the previous one, so a reply that
was written into the buffer and then dropped in favour of the short
error response of smb2_set_err_rsp() stays there, and the next reply is
laid over it with only the header cleared.
ksmbd does not implement quota tracking, so report no control flags. |
| In the Linux kernel, the following vulnerability has been resolved:
ksmbd: zero the FS_OBJECT_ID_INFORMATION buffer before filling it in
smb2_get_info_filesystem() reports 64 bytes for FS_OBJECT_ID_INFORMATION,
that is the whole of struct object_id_info, but writes only 46 of them:
- objid[] is 16 bytes, and when the volume UUID is not available only
sizeof(stfs.f_fsid) (8) bytes are copied into it;
- extended_info.version_string[] is STRING_LENGTH (28) bytes, and only
strlen("1.1.0") (5) bytes are copied into it.
The response buffer is zeroed on allocation (kvzalloc() in
smb2_allocate_rsp_buf()), so for a standalone request the remaining 31
bytes are zero. In a compound request they need not be. The offset of
the next response is advanced by the length pinned for the previous one,
so if a preceding command wrote its reply into the buffer and then
failed, smb2_set_err_rsp() pins only the short error response and the
next reply lands inside the area that has already been written. Only
the header is cleared there:
memset((char *)rsp_hdr, 0, sizeof(struct smb2_hdr) + 2);
The client then receives up to 31 bytes of a response it was not meant
to see, including one that failed with an access denied error.
Clear the structure before filling it in. As a side effect
version_string is now NUL terminated. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/amdgpu: free the userptr ranges when a CS fails after parser_bos
amdgpu_cs_parser_bos() allocates an HMM range for every userptr entry of
the BO list and looks up the user pages. Those ranges are only freed when
amdgpu_cs_parser_bos() itself fails or when amdgpu_cs_submit() checks
them under the notifier lock. If amdgpu_cs_patch_jobs(),
amdgpu_cs_vm_handling(), amdgpu_cs_sync_rings() or the early part of
amdgpu_cs_submit() fails, nothing frees them: neither
amdgpu_cs_parser_fini() nor amdgpu_bo_list_free() touch e->range.
Each such CS then leaks the range, its hmm_pfns array (8 bytes per page
of the userptr BO) and the BO reference the range holds. An IB on a ring
that patches the CS in place (e.g. VCN) with an unmapped va_start fails
in amdgpu_cs_patch_ibs() and takes this path.
Free the ranges on those error paths. Ranges amdgpu_cs_submit() already
dropped are NULL, so freeing them again is a no-op.
(cherry picked from commit c52a9542ed7cfd527feb938bd0accada2ac8d267) |
| In the Linux kernel, the following vulnerability has been resolved:
sched_ext: Fix stall when a task enqueued with SCX_ENQ_LAST lands back on its CPU's local DSQ
With SCX_OPS_ENQ_LAST, the last runnable task on a CPU is passed to
ops.enqueue() instead of being kept running. Exiting tasks without
SCX_OPS_ENQ_EXITING, migration disabled tasks without
SCX_OPS_ENQ_MIGRATION_DISABLED and tasks on an offline rq skip ops.enqueue()
and go straight to the local DSQ. This happens in put_prev_task_scx() after
the pick has settled on idle, so nothing reschedules the CPU, which idles
with the task queued until an unrelated wakeup lands on it or the watchdog
fires.
scx_mitosis, which sets SCX_OPS_ENQ_LAST without SCX_OPS_ENQ_EXITING, hit
this during mass cgroup teardown: exiting tasks stuck in exit_mmap() for
over 40 seconds.
A task put on the local DSQ runs, as anywhere else. If the SCX_ENQ_LAST
enqueue left the task on this CPU's local DSQ, set need_resched on the task
being switched in, as proxy_resched_idle() does. resched_curr() would flag
the task being put instead, and __schedule() clears that right after the
pick. |
| In the Linux kernel, the following vulnerability has been resolved:
workqueue: Fix unbound pool lifetime for pending pwqs
KASAN reports a use-after-free of an unbound worker_pool in
node_activate_pending_pwq():
BUG: KASAN: slab-use-after-free in _raw_spin_trylock+0x6d/0x120
Read of size 4 at addr ffff8880089ce000 by task kworker/u22:0/318
CPU: 1 UID: 0 PID: 318 Comm: kworker/u22:0 Not tainted 7.2.0 #1 PREEMPT(lazy)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
Workqueue: 0x0 (flush-8:0)
Call Trace:
<TASK>
dump_stack_lvl+0x53/0x70
print_report+0xce/0x610
kasan_report+0xce/0x100
_raw_spin_trylock+0x6d/0x120
pwq_dec_nr_in_flight+0x4b4/0xcb0
process_one_work+0x921/0x11a0
worker_thread+0x4d0/0xd20
kthread+0x2de/0x3c0
ret_from_fork+0x3aa/0x620
ret_from_fork_asm+0x1a/0x30
</TASK>
Allocated by task 311:
alloc_pwq+0x439/0xca0
apply_wqattrs_prepare+0x75e/0xd10
apply_workqueue_attrs_locked+0x44/0xa0
wq_nice_store+0x350/0x450
Freed by task 0:
kfree+0x127/0x3b0
rcu_core+0x523/0x1780
handle_softirqs+0x1b3/0x610
Last potentially related work creation:
put_unbound_pool+0x3f3/0x7d0
pwq_release_workfn+0x494/0x8e0
kthread_worker_fn+0x1ff/0x790
Canceling the last inactive work skips pwq_dec_nr_active(), so an empty
pwq can remain on pending_pwqs when its refcnt reaches zero.
pwq_release_workfn() currently puts the pool before removing that pwq.
If this drops the last pool reference, the pool can be RCU-freed while
the pwq remains reachable, and node_activate_pending_pwq() may trylock
the freed pool->lock.
Remove the pwq from pending_pwqs before putting the pool. |
| In the Linux kernel, the following vulnerability has been resolved:
wifi: p54: validate firmware record lengths
The p54 firmware parser accesses component ID and component version
records without checking that their lengths cover the fields being read.
A malformed record can therefore make the parser read past the record.
Validate the component ID and component version record lengths before
accessing their data. The descriptor record is also checked against the
shortest descriptor length found in the supported firmware images.
Reject descriptor values that underflow the RX offset or produce an empty
RX range before updating the driver state. |