| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
usb: dwc3: clear forceRM when issuing EndTransfer
The forceRM bit of the DEPCMD register controls the behavior of the
EndTransfer command used to stop an active transfer. Older DWC3
programming guide revisions recommended setting forceRM=1 when
issuing EndTransfer. Newer programming guide revisions recommend
issuing EndTransfer with forceRM cleared.
With forceRM=1 on DWC_usb31 v2.00a and v2.10a controllers, a transfer
aborted through the ep_dequeue path was observed to remain active
after EndTransfer completion. A subsequent StartTransfer issued on the
same endpoint triggered writes associated with the aborted transfer.
This resulted in an SMMU fault because the transfer buffer had already
been unmapped during EndTransfer command-completion cleanup.
Using forceRM=0 eliminates the issue. Although older DWC3 programming
guide revisions recommended setting forceRM=1, no issues are known
from using forceRM=0. Clear forceRM when issuing EndTransfer to provide
consistent EndTransfer behavior and align with newer programming guide
recommendations. |
| In the Linux kernel, the following vulnerability has been resolved:
usb: storage: realtek_cr: fix use-after-free on disconnect
realtek_cr_destructor() calls timer_delete() before the chip containing
the timer is freed. The timer callback may still be running and can
rearm itself, resulting in a use-after-free.
Use timer_shutdown_sync() to wait for the callback and prevent further
rearming. Do this unconditionally because ss_en may be changed after
the timer is armed.
Move timer_setup() into init_realtek_cr() so the timer is initialized
before any failure path can invoke the destructor.
Found by static analysis. |
| In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: f_mass_storage: fix null pointer dereference in fsg_common_set_num_buffers()
Previously fsg_num_buffers_validate() was removed as it was not
necessary due to Kconfig setting the limits for n from 2 to 256 with
default as 2. However, setting the page content in such a way that
kstrtou8() reflects n value as either 0 or 1 bypasses these
restrictions leading to a null pointer dereference if n is 0. Fix
this by adding a check for n < 2 and returning -EINVAL if n is
either 0 or 1 consistent with Kconfig logic. |
| In the Linux kernel, the following vulnerability has been resolved:
staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie()
rtw_restruct_wmm_ie() scans in_ie for a WMM IE with:
while (i < in_len) {
...
if (i + 5 < in_len && in_ie[i] == 0xDD && ...) {
...
break;
}
i += (in_ie[i + 1] + 2); /* to the next IE element */
}
When the "i + 5 < in_len" match check fails simply because i is
within 5 bytes of the end of the buffer (i.e. no WMM IE was found
near the tail of in_ie), execution falls through to
"i += (in_ie[i + 1] + 2)", which reads in_ie[i + 1]. If i == in_len
- 1 at that point, this is a 1-byte out-of-bounds read of an
attacker-influenced IE buffer built from association/scan data.
Commit a75281626fc8f ("staging: rtl8723bs: fix potential
out-of-bounds read in rtw_restruct_wmm_ie") added the "i + 5 <
in_len" guard to the match condition itself, but did not add an
equivalent guard before the fallthrough advance, so the same class
of OOB read remained reachable through the non-matching path.
Add an explicit bounds check before advancing to the next IE. |
| In the Linux kernel, the following vulnerability has been resolved:
tracing: Take trace_array reference when opening options file
The options files do not take the trace_array reference for the options
they represent. This could cause a use-after-free kernel crash if one of
these files is opened by one task and another task removes the instance
that the option is for. Because it doesn't take a reference upon opening,
it will not stop the removal which will free the options descriptor that
is being used.
As the options are somewhat dynamic in their creation at boot up, each
file represents a flag in the trace_array. The trace_array has an array of
indexes to represent each of these flags that is stored in the
trace_flags_index array. The address of the index array element is used to
pass to the inode->i_private pointer. Then that element is read which
holds the index (which represents the flag) and then the index is used to
calculate the trace_array descriptor from its trace_flags_index array.
One issue is that the index element can not be referenced until the
trace_array's reference is taken. To handle this, create a new helper
function called: trace_array_options_get() that will iterate all the
existing trace_arrays in the ftrace_trace_arrays list (under the
trace_types_lock), and compare the passed in address of the index element
with the entire array of the trace_array's trace_flags_index array.
If it matches, then up the corresponding trace_array's reference and
return. |
| In the Linux kernel, the following vulnerability has been resolved:
ftrace: Take trace_array reference before accessing its ftrace_ops
The trace instance files set_ftrace_filter and set_ftrace_notrace was
updated to work with specific trace instances (trace_arrays). The issue is
that when these files are opened, there is a small race window where it
will use the ftrace_ops from the inode->private pointer to get a reference
to the trace_array and then take its reference. The problem is that the
ftrace_ops itself could be freed. If the rmdir on the instance happens at
the same time the set_ftrace_filter file is opened, the rmdir could have
also freed the ftrace_ops and referencing it will cause a use-after-free
bug and crash the kernel.
Instead, pass in the trace_array as the file private data (NULL for the
top level instance), and then pass both the trace_array and the ftrace_ops
to the ftrace_regex_open() function. If the trace_array is NULL, then it
just uses the ftrace_ops without the need to take its reference (like
normal). If the ftrace_ops is NULL, that is only the case for the top
level instance and the global_ops can be used.
This allows the trace_array to have its reference incremented before
touching the ftrace_ops that could also be freed when the instance is. |
| In the Linux kernel, the following vulnerability has been resolved:
dma-buf: dma-heap: don't publish fd before copy_to_user() succeeds
DMA_HEAP_IOCTL_ALLOC allocates a dma-buf and installs an fd into the
caller's fd table via dma_buf_fd() -> fd_install() before
dma_heap_ioctl() copies the result back to userspace. If the trailing
copy_to_user() fails, userspace never learns the fd number, but the
fd (and the underlying dma-buf reference) are already visible to
other threads in the same process and are leaked for the lifetime of
the process.
The obvious "close it on the failure path" fix is unsafe: once
fd_install() has run, another thread can already dup() the fd, send
it via SCM_RIGHTS, or close() it and let its number be reused, so a
subsequent close_fd() from the ioctl path can operate on an unrelated
file. This was pointed out by Christian König on v1 [1].
Restructure the allocation path so that fd_install() is the last,
unfailable step of a successful ioctl:
1. heap->ops->allocate() creates the dma_buf.
2. get_unused_fd_flags() reserves an fd number in the caller's
fd table without publishing it, so
no other thread can observe it.
3. copy_to_user() delivers the fd number to userspace;
on failure the fd is returned with
put_unused_fd() and the dma_buf
reference is dropped with
dma_buf_put(), leaving no user-
visible state behind.
4. dma_buf_fd_install() publishes the fd and emits the
trace_dma_buf_fd tracepoint -- from
here on the ioctl cannot fail.
A new dma_buf_fd_install() helper is introduced in dma-buf.c to wrap
fd_install() together with the DMA_BUF_TRACE() call, preserving the
export tracing that dma_buf_fd() provides. dma_heap_ioctl_allocate()
is refactored to return the struct dma_buf * directly (returning
ERR_PTR on failure) so the caller holds the dmabuf reference across
steps 3 and 4.
The failure at step 3 is easily reachable from userspace: pass a
struct dma_heap_allocation_data that lives in a page whose protection
is flipped to PROT_READ between copy_from_user() and copy_to_user()
(e.g. via mprotect()). Before this change each such ioctl leaks one
dmabuf fd; after it, the fd table is unchanged on failure and only
/dev/dma_heap/<name> remains open.
No UAPI or heap-driver interface change.
[1] https://lore.kernel.org/dri-devel/[email protected]/ |
| In the Linux kernel, the following vulnerability has been resolved:
nvme: add missing SRCU grace period in error path
nvme_alloc_ns() error path at out_unlink_ns removes ns from the
namespace head siblings list with list_del_rcu(&ns->siblings) but
does not wait for SRCU readers before freeing the namespace struct.
Multipath code iterates the head->list under srcu_read_lock() in
nvme_find_path() and nvme_mpath_revalidate_paths(), so a concurrent
reader can still hold a reference to ns when kfree(ns) runs.
The normal removal path in nvme_ns_remove() correctly calls
synchronize_srcu(&ns->head->srcu) after list_del_rcu() to wait for
in-progress readers. Add the same grace period in the error path. |
| In the Linux kernel, the following vulnerability has been resolved:
nvme: skip the zoned limits update if the zone info query failed
nvme_query_zone_info() returns either a negative errno or a positive
NVMe status code, but nvme_update_ns_info_block() only tests for the
negative case:
ret = nvme_query_zone_info(ns, lbaf, &zi);
if (ret < 0)
goto out;
If the device fails the Identify Namespace (I/O Command Set specific)
command, or the Identify Controller command issued by
nvme_set_max_append(), the positive status falls through and setup
continues with the zero-initialized zone info. nvme_update_zone_info()
then marks the queue zoned with chunk_sectors and ns->head->zsze set to
zero.
blk_validate_zoned_limits() does not check chunk_sectors, so the limits
commit succeeds. blk_revalidate_disk_zones() does reject the zero zone
size, but by then the limits are live and nothing rolls them back, so
I/O keeps being submitted to a zoned queue with a zero zone size and
disk_zone_no() shifts by ilog2(0):
nvme0n1: Invalid non power of two zone size (0)
UBSAN: shift-out-of-bounds in include/linux/blkdev.h:747:16
shift exponent -1 is negative
disk_zone_no include/linux/blkdev.h:747 [inline]
bio_straddles_zones include/linux/blkdev.h:1058 [inline]
blk_zone_wplug_handle_write block/blk-zoned.c:1423 [inline]
blk_zone_plug_bio.cold+0x25/0x1c8 block/blk-zoned.c:1605
blk_mq_submit_bio+0x18fb/0x2870 block/blk-mq.c:3196
submit_bh_wbc+0x575/0x740 fs/buffer.c:2824
__block_write_full_folio+0x728/0xdd0 fs/buffer.c:1933
Any device, firmware or NVMe-oF target that fails this one command
reaches this.
Skip the zoned limits update in that case, and log which of the two
things happened: during a revalidation the queue keeps the zone
geometry it was last validated with, and on a first scan the namespace
is registered without zoned limits, so that it is still available as a
handle for admin commands. Neither of the paths in
nvme_query_zone_info() that return a positive status logs anything, so
the failure would otherwise be silent.
zi.zone_size is an exact indicator: every path that returns a positive
status returns before it is assigned, and after that the only failure
left is -ENODEV, which the caller already handles.
Found by FuzzNvme. |
| In the Linux kernel, the following vulnerability has been resolved:
s390/vfio-ap: Fix missing lock required to access list of ap_matrix_mdev objects
In order to traverse or add/remove ap_matrix_mdev objects in the
matrix_dev->mdev_list, the matrix_dev->guests_lock mutex must be held.
There are two functions that access the list without holding the mutex:
vfio_ap_mdev_probe function
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The vfio_ap_mdev_probe function uses the matrix_dev->mdevs_lock
mutex to guard the add of a newly created ap_matrix_mdev object to the
matrix_dev->mdev_list. This mutex does not protect list access; its purpose
is to guard against concurrent access to fields contained in an
ap_matrix_mdev object. This could lead to kernel memory corruption or
use-after-free if another mdev is created or removed concurrently.
The adding of an ap_matrix_mdev object to matrix_dev->mdev_list
is now guarded by the matrix_dev->guests_lock which is the correct
way to protect against concurrent mdev_list access.
Also removed the following two lines of code because the matrix_mdev is
allocated via vfio_alloc_device macro which uses kzalloc, so req_trigger
and cfg_chg_trigger are already zero-initialised when the struct is
allocated before the call to vfio_register_emulated_iommu_dev. This
prevents a window whereby these triggers are set to NULL after
the device is exposed to userspace.
matrix_mdev->req_trigger = NULL;
matrix_mdev->cfg_chg_trigger = NULL;
vfio_ap_mdev_for_queue function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The status_show function that supports display of the status attribute of
the devices in /sys/bus/ap/devices calls the vfio_ap_mdev_for_queue
function which iterates the matrix_dev->mdev_list to find the object
representing the queue device whose status is to be displayed. In order to
traverse this list, the matrix_dev->guests_lock mutex must be held.
To fix this, the guests_lock mutex is taken prior to taking the
matrix_dev->mdevs_lock mutex in the status_show function. It is taken
there rather than the vfio_ap_mdev_for_queue function - where it is
needed - because it must be taken prior to the mdevs_lock mutex in order to
adhere to the proper locking order and prevent a lockdep splat; also
because the mdevs_lock is needed there to access fields within
the matrix_mdev object in that function.
See the vfio-ap-locking.rst in the linux kernel tree. |
| In the Linux kernel, the following vulnerability has been resolved:
KVM: s390: Zero initialize data structures for inject_pfault_token
__kvm_inject_pfault_token() only sets .type and .u.ext.ext_params2 of
the on-stack struct kvm_s390_irq but the full ext substructure is copied
into the cpu local variable on inject. ext_params and pad contain stale
stack values.
Interrupt delivery only uses ext_params2, so nothing leaks to the guest,
but a host user can use the migration ioctls to get to the data.
Fix by zero-initializing the irq struct.
Do the same for the inti data structure. |
| In the Linux kernel, the following vulnerability has been resolved:
media: chips-media: wave5: Add timeout while stop_streaming
When stop_streaming is called, an infinite loop may occur in some cases.
Add a bounded poll of the queue status: loop until the queues drain,
sleeping briefly between polls, and bail out once VPU_DEC_STOP_TIMEOUT
elapses. |
| In the Linux kernel, the following vulnerability has been resolved:
scsi: qla2xxx: Zero dport diagnostics buffer to avoid info leak
qla2x00_do_dport_diagnostics() allocates the qla_dport_diag response
buffer with kmalloc_obj() (non-zeroing) and, on success, copies the full
sizeof(*dd) back to user space via sg_copy_from_buffer(). The inbound
sg_copy_to_buffer() only fills as many bytes as the user request payload
provides, and qla26xx_dport_diagnostics() zeroes only dd->buf. The
options and unused[] fields are therefore copied out uninitialized,
leaking kernel heap contents to user space.
Allocate with kzalloc_obj(), matching qla2x00_do_dport_diagnostics_v2(). |
| In the Linux kernel, the following vulnerability has been resolved:
f2fs: validate MOVE_RANGE destination size
F2FS_IOC_MOVE_RANGE checks the source range, but not the destination end
before updating i_size. A source hole can expose this: __clone_blkaddrs()
skips NULL_ADDR entries and returns success, so the caller can still extend
the destination inode with unchecked pos_out + len.
Reject destination overflow and use inode_newsize_ok() before extending
the destination inode. |
| In the Linux kernel, the following vulnerability has been resolved:
f2fs: limit recovery filename logging to stored length
F2FS stores recovery filenames as a length plus a fixed-size i_name
buffer. The buffer is not NUL-terminated, but recover_inode() and
recover_dentry() print it with %s.
For a 255-byte filename, recovery logging can read past i_name into the
following raw inode fields.
Print the name with a precision bounded by i_namelen and F2FS_NAME_LEN. |
| In the Linux kernel, the following vulnerability has been resolved:
f2fs: fix dentry folio leak in find_in_level
find_in_level() gets a dentry folio with f2fs_find_data_folio() before
calling find_in_block(). If find_in_block() returns an error, the
function stores the error in res_folio and breaks out of the loop without
dropping the dentry folio.
This leaks the folio reference on the find_in_block() error path. Drop
the dentry folio before returning the error to the caller. |
| In the Linux kernel, the following vulnerability has been resolved:
f2fs: fix to clear dirty flag on folio in error path
If node block is corrupted due to chksum mismatch or inconsistent
footer info, it needs to drop clear flag of node folio, in order
to persist inconsistent node data to storage. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/amdgpu: avoid force-completing uninitialized UVD rings
uvd_v7_0_sw_init() does not initialize the UVD decode ring for an
SR-IOV VF. However, amdgpu_uvd_resume() unconditionally force-completes
the decode ring when restoring its fence sequence.
Skip fence completion when the fence driver is not initialized. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/sysfb: ofdrm: Fix integer overflow in fb_size calculation
The framebuffer size calculation `fb_size = linebytes * height` can
overflow when both values are large (e.g., 46341 * 46341 > INT_MAX).
Since linebytes and height are both int types, the multiplication is
performed as int * int, which results in undefined behavior on overflow.
Use check_mul_overflow() to detect and prevent this overflow, consistent
with the approach used in simpledrm.c and corebootdrm.c. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: ab8500_fg: fix use-after-free on remove
ab8500_fg_remove() destroys the driver workqueue while the threaded
interrupt handlers are still armed; they are devm-managed and freed
only after ->remove() returns, so a handler that fires in that
window queues work on the freed workqueue.
Tear the workqueue down through devm instead, registering its cleanup
after the power supply and before the interrupt requests. devm then
frees the interrupts first, so the handlers can no longer queue work,
before disabling the delayed and plain work items and destroying the
workqueue. Disabling the items, rather than cancelling them, keeps
them disabled so no producer (including the power-supply
external_power_changed callback) can requeue them.
Found by an in-house static analysis tool. |