| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
mm: page_ext: add count limit to page_ext_iter_next to prevent invalid PFN access
The page_ext iteration API does not validate if the PFN still belongs to a
valid section while advancing the iterator. When dynamically adding
memory in the hotplug path, it can lead to a NULL pointer dereference
during page_ext_lookup at the boundary of the last valid section when
iterator count equals __pgcount.
The for_each_page_ext() macro calls page_ext_iter_next() as its loop
increment. for_each_page_ext() does a "__page_ext =
page_ext_iter_next(&__iter)" at the end. This causes page_ext_iter_next()
to increment iter->index past __pgcount and call page_ext_lookup(start_pfn
+ __pgcount). During memory hotplug (online), the PFN at start_pfn +
__pgcount may belong to a section that has not yet been initialized,
causing page_ext_lookup() to trigger a NULL pointer dereference.
[ 14.555124][ T846] Call trace:
[ 14.555125][ T846] lookup_page_ext+0x6c/0x108 (P)
[ 14.555127][ T846] page_ext_lookup+0x30/0x3c
[ 14.555129][ T846] __reset_page_owner+0x11c/0x260
[ 14.571201][ T846] __free_pages_ok+0x5e8/0x8e0
[ 14.571204][ T846] __free_pages_core+0x78/0xf0
[ 14.571206][ T846] generic_online_page+0x14/0x24
[ 14.597782][ T846] online_pages+0x178/0x30c
[ 14.597784][ T846] memory_block_change_state+0x284/0x32c
[ 14.597787][ T846] memory_subsys_online+0x4c/0x64
[ 14.597789][ T846] device_online+0x88/0xb0
[ 14.597791][ T846] online_memory_block+0x30/0x40
[ 14.597793][ T846] walk_memory_blocks+0xac/0xe8
[ 14.597794][ T846] add_memory_resource+0x280/0x298
[ 14.656161][ T846] add_memory+0x60/0x98
Move the iteration boundary enforcement inside the iterator functions, so
callers cannot inadvertently access beyond the requested range. |
| In the Linux kernel, the following vulnerability has been resolved:
iommufd: Use sizeof(*hdr) instead of sizeof(hdr) in veventq read
The bound-check in iommufd_veventq_fops_read() for the normal vEVENT
path uses sizeof(hdr) where the surrounding code uses sizeof(*hdr):
if (!vevent_for_lost_events_header(cur) &&
sizeof(hdr) + cur->data_len > count - done) {
hdr is declared as struct iommufd_vevent_header *, so sizeof(hdr)
evaluates to the size of the pointer. Surrounding code uses
sizeof(*hdr) consistently:
if (done >= count || sizeof(*hdr) > count - done) {
...
if (copy_to_user(buf + done, hdr, sizeof(*hdr))) {
...
done += sizeof(*hdr);
struct iommufd_vevent_header is currently 8 bytes (two __u32 fields,
flags and sequence), so on 64-bit (sizeof(void *) == 8) the two
expressions happen to be equal and the check works as intended.
On 32-bit (sizeof(void *) == 4) the check under-counts the header by
4 bytes: a vEVENT whose data_len causes 8 + cur->data_len to exceed
count - done while 4 + cur->data_len does not will pass the check,
then the loop will copy_to_user 8 bytes of header followed by data_len
bytes of payload, writing past the user-supplied buffer.
It is also a latent bug for any future expansion of struct
iommufd_vevent_header beyond sizeof(void *) on 64-bit; the check
should not depend on the type happening to match the host pointer
width.
Use sizeof(*hdr) to match the rest of the function and the actual
amount that will be copied. |
| In the Linux kernel, the following vulnerability has been resolved:
iommufd: Set veventq_depth upper bound
iommufd_veventq_alloc() accepts any !0 veventq_depth from userspace, with
an upper bound at U32_MAX.
This leaves a vulnerability where userspace can allocate excessively large
queues to exhaust kernel memory reserves.
Cap the veventq_depth (maximum number of entries) to 1 << 19, matching the
maximum number of entries in the SMMUv3 EVTQ (the largest use case today). |
| In the Linux kernel, the following vulnerability has been resolved:
KVM: arm64: nv: Avoid dereferencing NULL VNCR pseudo-TLB
VNCR TLB invalidation occurs from MMU notifiers or TLBI instructions,
and either can race against a vcpu not being onlined yet (no pseudo-TLB
allocated). Similarly, the TLB might be invalid, and the invalidation
should be skipped in this case.
Both kvm_invalidate_vncr_ipa() and kvm_invalidate_vncr_va() are
expected to perform the same checks, except that the latter doesn't
check for the allocation and blindly dereferences the pointer.
Solve this by introducing a new iterator built on top of the usual
kvm_for_each_vcpu() that checks for both of the above conditions,
and convert the two users to it. |
| In the Linux kernel, the following vulnerability has been resolved:
KVM: arm64: Bound used_lrs when flushing the pKVM hyp vCPU
flush_hyp_vcpu() copies the host vGIC state into the hyp's private vCPU
on every run. The vGIC list register save and restore use used_lrs as
their loop bound and expect it to stay within the number of implemented
list registers. While this is generally the case, flush_hyp_vcpu()
copies vgic_v3 verbatim and does not enforce this, so a value provided
by the host is used at EL2 to index vgic_lr[] and access ICH_LR<n>_EL2
(host -> EL2).
Fix by clamping used_lrs to the number of implemented list registers
after the copy, as the trusted path already does in
vgic_flush_lr_state(). The number of implemented list registers is
constant after init, so it is replicated once from
kvm_vgic_global_state.nr_lr into hyp_gicv3_nr_lr rather than read on
every entry. |
| In the Linux kernel, the following vulnerability has been resolved:
KVM: arm64: Clear __hyp_running_vcpu when flushing the pKVM hyp vCPU
flush_hyp_vcpu() copies the host vCPU context into the hyp's private
vCPU on every run. ctxt_to_vcpu() expects a guest context to have a
NULL __hyp_running_vcpu, which is only ever set on the host context, so
that it resolves the vCPU via container_of(). While this is generally
the case, flush_hyp_vcpu() copies the context verbatim and does not
enforce this, so a value provided by the host is dereferenced at EL2
(host -> EL2).
Fix by clearing __hyp_running_vcpu after the copy. |
| In the Linux kernel, the following vulnerability has been resolved:
KVM: x86: Ensure vendor's exit handler runs before fastpath userspace exits
Move the handling of fastpath userspace exits into vendor code to ensure
KVM runs vendor specific operations that need to run before userspace gains
control of the vCPU. E.g. for VMX (and soon to be for SVM as well), KVM
needs to flush the PML buffer prior to exiting to userspace, otherwise any
memory written by the final KVM_RUN might never be flagged as dirty.
Note, waiting to snapshot CR0 and CR3 until svm_handle_exit() is flawed in
general, as that risks consuming stale state in a fastpath handler. That
will be addressed in a future change. |
| In the Linux kernel, the following vulnerability has been resolved:
KVM: guest_memfd: Treat memslot binding offset+size as unsigned values
When binding a memslot to a guest_memfd file, treat the offset and size as
unsigned values to fix a bug where the sum of the two can result in a false
negative when checking for overflow against the size of the file. Passing
unsigned values also avoids relying on somewhat obscure checks in other
flows for safety, and tracks the offset and size as they are intended to be
tracked, as unsigned values.
On 64-bit kernels, the number of pages a memslot contains and thus the size
(and offset) of its guest_memfd binding are unsigned 64-bit values. Taking
the offset+size as an loff_t instead of a uoff_t inadvertently converts
the unsigned value to a signed value if the offset and/or size is massive.
Locally storing the offset and size as signed values is benign in and of
itself (though even that is *extremely* difficult to discern), but
operating on their sum is not.
For the offset, KVM explicitly checks against a negative value, which might
seem like a bug as KVM could incorrectly reject a legitimate binding, but
that's not actually the case as KVM_CREATE_GUEST_MEMFD takes a signed value
for its size, i.e. a would-be-negative offset is also greater than the
maximum possible size of any guest_memfd file.
Regarding the size, while KVM lacks an explicit check for a negative value,
i.e. seemingly has a flawed overflow check, KVM restricts the number of
pages in a single memslot to the largest positive signed 32-bit value:
if (id < KVM_USER_MEM_SLOTS &&
(mem->memory_size >> PAGE_SHIFT) > KVM_MEM_MAX_NR_PAGES)
return -EINVAL;
and so that maximum "size" will ever be is 0x7fffffff000.
The sum of the two is, however, problematic. While the size is restricted
by KVM's memslot logic, the offset is not, i.e. the offset is completely
unchecked until the "offset + size > i_size_read(inode)" check. If the
offset is the (nearly) largest possible _positive_ value, then adding size
to the offset can result in a signed, negative 64-bit value. When compared
against the size of the file (guaranteed to be positive), the negative sum
is always smaller, and KVM incorrectly allows the absurd offset.
Opportunistically add missing includes in kvm_mm.h (instead of relying on
its parents). |
| In the Linux kernel, the following vulnerability has been resolved:
svcrdma: wake sq waiters when the transport closes
Threads parked in svc_rdma_sq_wait() on sc_sq_ticket_wait or
sc_send_wait can hang indefinitely in TASK_UNINTERRUPTIBLE state
across transport teardown, pinning svc_xprt references and
blocking svc_rdma_free().
The close path sets XPT_CLOSE before invoking xpo_detach and both
wait_event predicates include an XPT_CLOSE term, but the
predicates are re-evaluated only on wakeup. sc_sq_ticket_wait has
no completion-driven wake path; it is advanced solely by the
chained ticket handoff inside svc_rdma_sq_wait() itself. Without
an explicit wake at close, parked threads never observe
XPT_CLOSE, hold their svc_xprt_get reference forever, and
svc_rdma_free() blocks on xpt_ref dropping to zero.
Two close entry points reach this transport. Local teardown runs
svc_rdma_detach() from svc_handle_xprt() -> svc_delete_xprt() ->
xpo_detach() on a worker thread. A remote disconnect arrives at
svc_rdma_cma_handler(), which calls svc_xprt_deferred_close():
that sets XPT_CLOSE and enqueues the transport but does not
access either RDMA waitqueue, so a worker already parked in
svc_rdma_sq_wait() never re-evaluates its predicate. With every
worker parked on this transport, no thread is available to run
the local teardown either, and the wake site there is
unreachable.
Introduce svc_rdma_xprt_deferred_close(), a thin svcrdma wrapper
that calls svc_xprt_deferred_close() and then wakes both
sc_sq_ticket_wait and sc_send_wait. Convert the svcrdma producers
that called svc_xprt_deferred_close() directly:
svc_rdma_cma_handler(), qp_event_handler(),
svc_rdma_post_send_err(), svc_rdma_wc_send(), the sendto drop
path, the rw completion error paths, and the recvfrom flush and
read-list error paths.
Wake both waitqueues from svc_rdma_detach() as well. The
synchronous svc_xprt_close() path (backchannel ENOTCONN, device
removal via svc_rdma_xprt_done) reaches detach without flowing
through svc_xprt_deferred_close() and therefore does not invoke
the new helper.
[ cel: add svc_rdma_xprt_deferred_close() to complete the fix ] |
| In the Linux kernel, the following vulnerability has been resolved:
i2c: core: fix adapter deregistration race
Adapters can be looked up by their id using i2c_get_adapter() which
takes a reference to the embedded struct device.
Remove the adapter from the IDR before tearing it down during
deregistration (and on registration failure) to make sure its resources
are not accessed after having been freed (e.g. the device name). |
| In the Linux kernel, the following vulnerability has been resolved:
Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count
rmi_f30_map_gpios() allocates gpioled_key_map with
min(gpioled_count, TRACKSTICK_RANGE_END) == at most 6 entries, but
rmi_f30_attention() iterates the full f30->gpioled_count (device query
register, range 0..31) and dereferences gpioled_key_map[i], and
input->keycodemax is set to the full gpioled_count while input->keycode
points at the 6-entry allocation.
A device that reports gpioled_count > 6 with GPIO support enabled
therefore causes an out-of-bounds read on the attention interrupt and
out-of-bounds read/write through the EVIOCGKEYCODE/EVIOCSKEYCODE ioctls,
which bound the index only against keycodemax. This is the same defect
as the F3A handler, which was copied from F30.
Size the keymap for the full gpioled_count; the mapping loop still
assigns only the first min(gpioled_count, TRACKSTICK_RANGE_END) entries. |
| In the Linux kernel, the following vulnerability has been resolved:
Input: elan_i2c - prevent division by zero and arithmetic underflow
The Elan I2C touchpad driver queries the device for its physical
dimensions and trace counts to calculate the device resolution and width.
However, if the device firmware or device tree provides invalid zero
values for x_traces or y_traces, it results in a fatal division-by-zero
exception leading to a kernel panic during device probe.
Add checks to ensure these parameters are non-zero before performing
the division. If invalid trace values are detected, fall back to a safe
default of 1.
Additionally, prevent an arithmetic underflow in the touch reporting
logic. Previously, if the calculated or fallback width was smaller than
ETP_FWIDTH_REDUCE (90), the subtraction would underflow, resulting in a
massive unsigned integer being reported to userspace. Clamp the adjusted
width to a minimum of 0 to safely handle small physical dimensions and
fallback scenarios.
Completing the probe with safe fallback values ensures the sysfs nodes
are created, keeping the firmware update path intact so a recovery
firmware can be flashed to the device. |
| In the Linux kernel, the following vulnerability has been resolved:
Input: goodix - clamp the device-reported contact count
goodix_ts_read_input_report() copies the number of touch points reported
by the device into an on-stack buffer
u8 point_data[2 + GOODIX_MAX_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
which is sized for at most GOODIX_MAX_CONTACTS (10) contacts. The only
runtime check bounds the per-interrupt count against ts->max_touch_num,
but that value is taken verbatim from a 4-bit field of the device
configuration block and is never clamped:
ts->max_touch_num = ts->config[MAX_CONTACTS_LOC] & 0x0f;
The nibble can be 0..15, so a malfunctioning, malicious or counterfeit
controller (or an attacker tampering with the I2C bus) can advertise up
to 15 contacts. goodix_ts_read_input_report() then accepts a touch_num
of up to 15 and the second goodix_i2c_read() writes
ts->contact_size * (touch_num - 1) bytes past the one-contact header into
point_data - up to 30 bytes (45 with the 9-byte report format) beyond the
92-byte buffer: a stack out-of-bounds write.
Clamp max_touch_num to GOODIX_MAX_CONTACTS, the number of contacts
point_data[] is sized for, when reading it from the configuration. |
| In the Linux kernel, the following vulnerability has been resolved:
Input: iforce - bound the device-reported force-feedback effect index
iforce_process_packet() handles a status report (packet id 0x02) by
taking a force-feedback effect index straight from the device wire and
using it to address the per-effect state array:
i = data[1] & 0x7f;
if (data[1] & 0x80) {
if (!test_and_set_bit(FF_CORE_IS_PLAYED,
iforce->core_effects[i].flags))
...
} else if (test_and_clear_bit(FF_CORE_IS_PLAYED,
iforce->core_effects[i].flags)) {
...
}
The index is masked only with 0x7f, so it ranges 0..127, but
core_effects[] holds only IFORCE_EFFECTS_MAX (32) entries. For an index
of 32..127 the test_and_set_bit()/test_and_clear_bit() is an
out-of-bounds single-bit read-modify-write past the array. core_effects[]
is the second-to-last member of struct iforce, so the write lands in the
trailing members and beyond the embedding kzalloc()'d iforce_serio /
iforce_usb object.
data[1] is unvalidated device payload on both transports (the USB
interrupt endpoint and serio), and the status path is not gated on force
feedback being present, so a malicious or counterfeit device can set or
clear a bit at an attacker-chosen offset past the object.
Reject an out-of-range index instead of indexing with it. Bound against
the array dimension IFORCE_EFFECTS_MAX rather than dev->ff->max_effects so
the check guarantees memory safety regardless of how many effects the
device registered. A legitimate "effect started/stopped" status always
carries an index below IFORCE_EFFECTS_MAX, so well-formed devices are
unaffected; the neighbouring mark_core_as_ready() loop is already bounded
and is left untouched. |
| In the Linux kernel, the following vulnerability has been resolved:
Input: mms114 - reject an oversized device packet size
mms114_interrupt() reads a packet of touch data from the device into a
fixed-size on-stack buffer
struct mms114_touch touch[MMS114_MAX_TOUCH];
which holds MMS114_MAX_TOUCH (10) events of MMS114_EVENT_SIZE (8) bytes,
i.e. 80 bytes. The length of the I2C read into it is taken verbatim from
the device:
packet_size = mms114_read_reg(data, MMS114_PACKET_SIZE);
if (packet_size <= 0)
goto out;
...
error = __mms114_read_reg(data, MMS114_INFORMATION, packet_size,
(u8 *)touch);
packet_size is a single device register byte (0x0F) and the only check
is the lower bound packet_size <= 0; it is never bounded against the
size of touch[]. A malfunctioning, malicious or counterfeit controller
(or an attacker tampering with the I2C bus) can report a packet_size of
up to 255, so __mms114_read_reg() writes up to 175 bytes past the end of
touch[] on the IRQ-thread stack: a stack out-of-bounds write that can
overwrite the stack canary, saved registers and the return address.
A well-formed device never reports more than the buffer holds, so reject
an oversized packet and drop the report, consistent with the handler's
other error paths, rather than reading past the buffer. |
| In the Linux kernel, the following vulnerability has been resolved:
fuse: avoid 32-bit prune notification count wrap
FUSE_NOTIFY_PRUNE validates the nodeid payload length with:
size - sizeof(outarg) != outarg.count * sizeof(u64)
On 32-bit kernels, size_t is also 32 bits, so the daemon-controlled
count multiplication can wrap. A prune notification with count
0x20000000 and no nodeid payload passes the check, enters the copy
loop, and asks the device copy path to read nodeids that are not
present in the userspace write buffer. In QEMU this reaches the
fuse_copy_fill() BUG_ON(!err) path.
Validate the payload length with array_size() instead. That accepts
exactly the same valid messages, but avoids wrapping arithmetic before
the copy loop consumes the count. |
| In the Linux kernel, the following vulnerability has been resolved:
fuse: re-lock request before returning from fuse_ref_folio()
fuse_ref_folio() unlocks the request but does not re-lock it before
returning. fuse_chan_abort() can end the request and the async end
callback (eg fuse_writepage_free()) can free the args while the
subsequent copy chain logic after fuse_ref_folio() accesses them,
leading to use-after-free issues.
Fix this by locking the request in fuse_ref_folio() before returning. |
| In the Linux kernel, the following vulnerability has been resolved:
fuse: clear intr_entry in fuse_resend and fuse_remove_pending_req
When fuse_resend() moves a request from fpq->processing back to
fiq->pending, it sets FR_PENDING and clears FR_SENT but does not
remove the requests intr_entry from fiq->interrupts. If the
request had FR_INTERRUPTED set from a prior signal, intr_entry
remains dangling on fiq->interrupts. When the requesting task
then receives a fatal signal, fuse_remove_pending_req() sees
FR_PENDING=1, removes the request from fiq->pending and frees it
via the refcount path, also without cleaning intr_entry. The
stale intr_entry causes use-after-free when fuse_read_interrupt()
iterates fiq->interrupts:
- list_del_init(&req->intr_entry) -> UAF write on freed slab
- req->in.h.unique -> UAF read, data leaked to userspace
Remove intr_entry from fiq->interrupts in fuse_resend() for
interrupted requests before they are placed back on fiq->pending.
Add a WARN_ON if the intr_entry is not empty on request destruction. |
| In the Linux kernel, the following vulnerability has been resolved:
fuse-uring: fix moving cancelled entry to ent_in_userspace list
fuse_uring_cancel() moves entries that are available (these have no reqs
attached) to the ent_in_userspace list. ent_list_request_expired()
checks the first entry on ent_in_userspace and dereferences
ent->fuse_req unconditionally, which will crash on a cancelled entry
that was moved to this list.
Fix this by freeing the entry and dropping queue_refs directly in
fuse_uring_cancel(). This is safe because cancel is the cancel handler
itself - after io_uring_cmd_done(), no more cancels will be dispatched
for this command, and teardown serializes with cancel via queue->lock.
Since cancel now decrements queue_refs, fuse_uring_abort() must no
longer gate fuse_uring_abort_end_requests() on queue_refs > 0, as
cancelled entries may have already dropped queue_refs while requests are
still queued. Remove the gate so abort always flushes requests and stops
queues. |
| In the Linux kernel, the following vulnerability has been resolved:
fuse-uring: Avoid queue->stopped races and set/read that value under lock
There are several readers of queue->stopped that check the value
under lock, but fuse_uring_commit_fetch() did not and actually
the value was not set under the lock in fuse_uring_abort_end_requests()
either. Especially in fuse_uring_commit_fetch it is important
to check under a lock, because due to races 'struct fuse_req'
might be freed with fuse_request_end, but another thread/cpu
might already do teardown work. |