| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
media: vicodec: fix out-of-bounds write in FWHT encoder
vidioc_s_fmt_vid_out() sizes the encoder CAPTURE buffer from the
compressed descriptor pixfmt_fwht, whose sizeimage_mult is 3:
coded_w * coded_h * 3 + sizeof(struct fwht_cframe_hdr). fwht_encode_frame()
encodes one plane per component, and an incompressible plane takes the
FWHT_FRAME_UNENCODED path in encode_plane(), copying the plane verbatim.
For a 4-component pixel format all four planes are full resolution
(width_div == height_div == 1), so a frame that forces every plane
through the unencoded fallback writes
sizeof(struct fwht_cframe_hdr) + 4 * coded_w * coded_h bytes, overrunning
the plane by coded_w * coded_h, which can result in corruption
of adjacent kernel heap memory.
Bump pixfmt_fwht.sizeimage_mult from 3 to 4, matching the largest
components_num among the supported raw formats, so the capture buffer is
always large enough for the unencoded fallback. |
| In the Linux kernel, the following vulnerability has been resolved:
nilfs2: fix slab-out-of-bounds in nilfs_direct_propagate after truncation
Shuangpeng Bai reported that KASAN detected a slab-out-of-bounds error
in nilfs_direct_propagate() during testing.
Analysis revealed that after truncating a file, a node block immediately
below the B-tree root was not deleted. Instead, it remained in the B-tree
node cache in a dirty state. The log writer subsequently detected this
block and incorrectly invoked nilfs_direct_propagate() on it, which is
designed to handle only data blocks in direct mapping.
B-tree nodes in the cache are managed by virtual block numbers, and their
logical keys typically exceed the range expected by direct mapping.
Consequently, processing such a node as a direct mapping entry triggers
a slab-out-of-bounds access.
The root cause is that when a B-tree mapping collapses into a direct
mapping during truncation, an intermediate node block pointed to by the
root node is left behind as garbage instead of being explicitly deleted.
This resolves the issue by adding a nilfs_btree_discard() operation
to delete the remaining intermediate node block during the conversion.
A 'deform' flag is added to the bop_delete interface to explicitly signal
that the deletion is part of a mapping transformation. This allows the
B-tree mapping implementation to perform the necessary cleanup and
discarding of the residual node structure that would be otherwise be left
orphaned after the transition. |
| In the Linux kernel, the following vulnerability has been resolved:
PCI/sysfs: Fix out-of-bounds read in pci_write_legacy_io()
pci_write_legacy_io() loads 4 bytes from the kernfs write buffer
regardless of how many bytes userspace wrote:
if (count != 1 && count != 2 && count != 4)
return -EINVAL;
return pci_legacy_write(bus, off, *(u32 *)buf, count);
kernfs_fop_write_iter() allocates the buffer with kmalloc(len + 1),
so a 1-byte write to the legacy_io sysfs file allocates 2 bytes and
the unconditional u32 load reads up to 2 bytes past the end of the
allocation, which KASAN reports as a slab-out-of-bounds read.
Similarly, a 2-byte write overreads by 1 byte.
Thus, read only the number of bytes requested using get_unaligned_le16()
and get_unaligned_le32() for the 2 and 4 byte cases, interpreting the
buffer as little-endian to match the byte ordering of PCI I/O port
space.
The PowerPC implementation previously compensated for the generic
code's native-endian 32-bit load by shifting the value into place
for the 1 and 2 byte cases. The shifts were only correct on
big-endian kernels.
On little-endian PowerPC (POWER8 and later), they extracted the wrong
bytes, so a 1-byte write wrote an out-of-bounds byte instead of the
requested value. On big-endian, the native load also caused out_le16()
and out_le32() to reverse the user's bytes on the wire for 2 and 4 byte
writes. The little-endian helpers resolve both issues, so the shifts
are removed.
No changes are needed for the Alpha platform.
The legacy_io file is root-only and exists only on Alpha and PowerPC,
the two architectures that define HAVE_PCI_LEGACY. |
| In the Linux kernel, the following vulnerability has been resolved:
phy: rockchip-samsung-dcphy: fix out-of-range max_register
The PHY register block is 64KB, so with a register stride of 4 the
last accessible register sits at offset 0xfffc. max_register names
0x10000, one register past the end of the mapping: dumping the
registers through the regmap debugfs interface reads beyond the
ioremapped region and oopses on the unmapped page. The oops fires
with the regmap lock held, so later PHY operations deadlock. |
| In the Linux kernel, the following vulnerability has been resolved:
ubifs: fix out-of-bounds read in signature length check
ubifs_sb_verify_signature() bounds the on-disk ubifs_sig_node->len field
before handing the signature payload to verify_pkcs7_signature(), but the
check has the wrong sign:
if (le32_to_cpu(signode->len) > snod->len + sizeof(struct ubifs_sig_node))
The signature bytes start sizeof(struct ubifs_sig_node) (UBIFS_SIG_NODE_SZ,
64 bytes) into the node, so the payload is at most
snod->len - sizeof(struct ubifs_sig_node)
bytes long. Adding the header size instead of subtracting it accepts a
declared length up to 2 * UBIFS_SIG_NODE_SZ larger than the node actually
holds -- past the end of c->sbuf, which is vmalloc(c->leb_size).
verify_pkcs7_signature() -> pkcs7_parse_message() -> asn1_ber_decoder()
is then handed that inflated length and reads beyond the allocation while
walking the DER headers. The node length comes straight from the mounted
image, so a crafted signed UBIFS image reaches this via
ubifs_read_superblock() before the signature is cryptographically checked.
snod->len is guaranteed to be >= UBIFS_SIG_NODE_SZ by the node scanner
(c->ranges[UBIFS_SIG_NODE].min_len == UBIFS_SIG_NODE_SZ), so the corrected
subtraction cannot underflow. Legitimately signed images are unaffected: a
correct superblock never declares a signature longer than the node it is
embedded in. |
| In the Linux kernel, the following vulnerability has been resolved:
zram: fix out-of-bounds access in read_block_state()
read_block_state() calculates nr_pages before taking dev_lock. If the
device is reset and reinitialized with a smaller disksize before lock
acquisition, nr_pages still describes the old table. The subsequent loop
can then call slot_lock() past the end of the newly allocated table.
Read disksize after acquiring dev_lock and checking that the device is
initialized. The read lock then keeps the table and its bound stable for
the duration of the scan. |
| In the Linux kernel, the following vulnerability has been resolved:
zram: fix out-of-bounds access in writeback_store()
Patch series "zram: fix stale scan bounds after reinitialization".
Both writeback_store() and read_block_state() derive their table scan
bounds from zram->disksize before acquiring dev_lock. If the device is
reset and reinitialized with a smaller disksize between that read and lock
acquisition, the bound can describe the old table while the scan operates
on the new one. This can lead to out-of-bounds slot accesses.
Move both bound calculations under dev_lock so each bound remains
consistent with the table throughout its scan. Keep the fixes separate
because the affected interfaces originate from different commits and can
be backported independently.
This patch (of 2):
writeback_store() calculates the table scan bounds before taking dev_lock.
A reset followed by reconfiguration with a smaller disksize can therefore
replace zram->table while writeback_store() is waiting for the lock. Once
it acquires the lock, it sees an initialized device but scans the new
table using the old upper bound, resulting in an out-of-bounds access.
Calculate the number of pages while holding dev_lock so the scan bound
matches the table protected by the lock. |
| In the Linux kernel, the following vulnerability has been resolved:
zram: set default primary compressor in zram_destroy_comps()
Patch series "zram: fix zram issues reported by sashiko".
Sashiko drove by and reported [1] a couple of zram issues:
a possible BUG_ON() in zlib code due to missing winbits range
validation and one possible NULL-ptr dereference in zcomp.
Both are low risk yet still worth fixing.
This patch (of 2):
zram_destroy_comps() resets all compressors and leaves them set to NULL,
including the primary one, which is invalid device state, as now
comp_algorithm_show()->strcmp() can be called on a NULL compressor. Set
default primary compressor in zram_destroy_comps(). |
| In the Linux kernel, the following vulnerability has been resolved:
zram: validate deflate params
We must validate user-supplied deflate winbits before we pass it to
zlib_deflate_workspacesize(), which triggers BUG_ON() if winbits value is
outside of valid ranges. |
| In the Linux kernel, the following vulnerability has been resolved:
NFS/localio: fix ref leak on nfs_uuid_add_file failure
When nfs_uuid_add_file() races with nfs_uuid_put() tearing down
uuid->net, it returns -ENXIO without publishing nfl->nfs_uuid via
rcu_assign_pointer(). nfs_open_local_fh() then enters its error
branch and only releases the slot's file ref and its paired net
ref plus its own entry-time net ref, while the close path is a
no-op:
nfs_close_local_fh()
nfs_uuid = rcu_dereference(nfl->nfs_uuid);
if (!nfs_uuid) { rcu_read_unlock(); return; } /* always */
nfsd_open_local_fh() returns localio holding a caller-owned +1
nfsd_file reference (from nfsd_file_get() after
nfsd_file_acquire_local()) and an entry-time nfsd_net reference
(from its first nfsd_net_try_get()) embedded as nf->nf_net. Both
are leaked on the failure path, pinning one nfsd_file (and the
underlying struct file, dentry, inode) and one nfsd_net_ref per
occurrence, which blocks nfsd_net and netns teardown.
Fix by releasing the caller-owned file ref and its net ref through
the existing helper, using a stack-local RCU pointer so the helper
can xchg it out, then returning -ENXIO so callers do not
dereference a localio whose slot has been cleared:
struct nfsd_file __rcu *tmp = RCU_INITIALIZER(localio);
nfs_to_nfsd_file_put_local(pnf);
nfs_to_nfsd_file_put_local(&tmp);
localio = ERR_PTR(-ENXIO);
The trailing nfs_to_nfsd_net_put(net) continues to release the
outer net ref, so all three nfsd_net_try_get() increments are
balanced on the error branch. |
| In the Linux kernel, the following vulnerability has been resolved:
NFS: fix delegation_hash_table leak when nfs4_server_common_setup() fails
nfs4_server_common_setup() allocates server->delegation_hash_table
first, but server->destroy - the only path that frees the table via
nfs4_destroy_server() - is not assigned until the very end of the
function. If any intermediate step fails (the is_ds_only_client()
check, nfs4_init_session(), nfs4_get_rootfh(), or nfs_probe_server()),
the function returns with server->destroy still NULL, so the caller's
nfs_free_server() skips the destroy callback and the hash table is
leaked (4 KiB per attempt with the default delegation watermark).
This is trivially reachable from userspace: every failed NFSv4 mount
leaks one allocation. A client that persistently retries a mount that
cannot succeed leaks kernel memory without bound. Observed in
production where a Longhorn backup poller retried mount.nfs4 against
an NFSv3-only server roughly 10 times per second, leaking ~3.4 GiB of
unreclaimable slab (kmalloc-rnd-13-4k) per day; the node accumulated
12 GiB of leaked slab before the source was identified via the
kmem:kmalloc tracepoint (call_site=nfs4_delegation_hash_alloc).
Reproducer:
# server exports NFSv3 only (or export path absent for v4)
while :; do mount -t nfs4 <server>:/missing /mnt; done
# watch SUnreclaim in /proc/meminfo grow 4 KiB per iteration
Free the table on the error paths between the allocation and the
assignment of server->destroy. |
| In the Linux kernel, the following vulnerability has been resolved:
NFSD: check truncate permission under inode lock
nfsd_setattr() checks whether a size update needs NFSD_MAY_TRUNC
before it takes inode_lock(). The comparison uses the file size sampled
by that unlocked read, but the actual ATTR_SIZE update is applied later
under inode_lock() by notify_change().
This leaves a TOCTOU window for append-only files. If a client sends a
SETATTR that does not shrink the file at the time of the unlocked
sample, a concurrent append can extend the file before nfsd_setattr()
takes inode_lock(). notify_change() then applies a real truncation
without the NFSD_MAY_TRUNC check that rejects IS_APPEND(inode). The VFS
truncate syscall paths perform their own append-only checks before
calling notify_change(), so NFSD must make this decision against the
locked size it is about to change.
Split the write-count acquisition from the truncation permission check.
Keep get_write_access() before the locked setattr work, then recheck
whether the requested size is below i_size_read(inode) after inode_lock()
has been acquired and before notify_change(ATTR_SIZE). This also avoids
the plain unlocked inode->i_size load. |
| In the Linux kernel, the following vulnerability has been resolved:
NFSD: restart ssc_expire_umount walk after dropping nfsd_ssc_lock
nfsd4_ssc_expire_umount() walks nn->nfsd_ssc_mount_list with
list_for_each_entry_safe(ni, tmp, ...). For each expired entry it
sets nsui_busy = true, drops nfsd_ssc_lock to run mntput() on the
source vfsmount, then reacquires the lock to list_del + kfree the
entry and continue iterating via the macro's saved tmp pointer.
The nsui_busy flag protects the current ni from concurrent
nfsd4_ssc_setup_dul() finders during the lock-drop window, but it
does not pin tmp. Another nfsd RPC thread that fails its source-
server mount and reaches nfsd4_ssc_cancel_dul() will, during that
same window, take nfsd_ssc_lock, list_del + kfree its own ssc_umount
item, and release the lock. If that item is the saved tmp of the
expire walk, the next iteration dereferences a freed
nfsd4_ssc_umount_item.
Restart the walk from the head after the mntput() unlock window so
no saved next pointer survives the lock-drop. The list is bounded
by the number of active inter-server source mounts (typically small)
and the expire delayed-work runs periodically rather than per-IO,
so the restart is cheap. |
| In the Linux kernel, the following vulnerability has been resolved:
NFSD: remove flawed WARN_ON_ONCE from nfsd_mode_check
The header for commit e75b23f9e323 ("nfsd: check d_can_lookup in
fh_verify of directories") details the assumption that justified
adding the WARN_ON_ONCE to nfsd_mode_check(), that assumption is
invalid (in the case of NFS reexport).
When NFSD exports an NFS filesystem it is very possible for
nfsd_mode_check() to encounter a @dentry that doesn't have
i_op->lookup (see nfs_fhget()'s NFS_ATTR_FATTR_MOUNTPOINT and
NFS_ATTR_FATTR_V4_REFERRAL handling, and d_flags_for_inode()).
So remove nfsd_mode_check()'s WARN_ON_ONCE(). The nfserr_notdir
return on that branch must stay. It guards the subsequent
lookup_one_unlocked() -> __lookup_slow() path, which calls
inode->i_op->lookup() with no NULL check, so returning nfserr_notdir
is what keeps a client LOOKUP into such a @dentry from dereferencing
a NULL method pointer. |
| In the Linux kernel, the following vulnerability has been resolved:
NFSv4.1: fix layout segment leak on the pnfs_layout_process() forget path
When the server returns a new layout stateid while a valid one is still
held, pnfs_layout_process() calls pnfs_mark_matching_lsegs_return() on
the on-stack free_me list and jumps to out_forget. Segments whose
reference count drops to zero are unlinked from lo->plh_segs and moved
to free_me by mark_lseg_invalid(); for an idle cached segment the layout
header holds the only reference, so this happens on the first decrement.
out_forget never drains free_me -- only the success path calls
pnfs_free_lseg_list().
Commit 814b84971388 ("pNFS/NFSv4: Fix a layout segment leak in
pnfs_layout_process()") added the drain; commit 08bd8dbe8882
("pNFS/NFSv4: Try to return invalid layout in pnfs_layout_process()")
removed it while switching the destination to lo->plh_return_segs, which
is drained elsewhere. Commit fb700ef02676 ("NFSv4.1: Simplify layout
return in pnfs_layout_process()") switched the destination back to
free_me without restoring the drain.
Restore the pnfs_free_lseg_list() call. |
| In the Linux kernel, the following vulnerability has been resolved:
lockd, nfsd: RCU-protect nlmsvc_ops dispatch
nlmsvc_ops is published by nfsd_lockd_init() and cleared by
nfsd_lockd_shutdown() with plain stores, while lockd dereferences
it unguarded from dispatch sites in fs/lockd/svcsubs.c. The pointer
targets nfsd's .rodata and the fopen/fclose callbacks live in nfsd's
.text, so a stale load after rmmod nfsd results in either a NULL
deref or a module-text use-after-free.
Declare nlmsvc_ops as __rcu, publish via rcu_assign_pointer(), clear
via RCU_INIT_POINTER() + synchronize_rcu(). Add a struct module
*owner field to nlmsvc_binding and pin the module across indirect
calls with try_module_get/module_put. When the binding is torn down,
fall back to fput() to avoid leaking struct file references. |
| In the Linux kernel, the following vulnerability has been resolved:
nfsd: RCU-protect cl_cb_session to fix use-after-free on session teardown
After a DESTROY_SESSION the per-session teardown path can free a
session while rpciod still holds an inflight callback rpc_task that
dereferences clp->cl_cb_session. nfsd4_probe_callback_sync() flushes
cl_callback_wq, but once nfsd4_run_cb_work() has called
rpc_call_async() the rpc_task lives on rpciod; flushing the workqueue
does not wait for it. rpc_shutdown_client() does drain rpciod tasks,
but uses a 1-second wait_event_timeout — tasks stuck in rpc_delay()
(e.g. 2-second NFS4ERR_DELAY retries) can outlive the drain.
destroy path rpciod
------------ ------
unhash_session(ses)
nfsd4_probe_callback_sync(clp)
flush_workqueue(cl_callback_wq)
/* returns; rpc_task still live */
nfsd4_put_session_locked(ses)
free_session(ses) -> kfree(ses)
nfsd4_cb_sequence_done()
reads cb_clp->cl_cb_session
/* freed slab */
A second window exists in nfsd4_process_cb_update(). When
__nfsd4_find_backchannel() returns NULL because unhash_session() has
already removed the destroyed session from cl_sessions,
setup_callback_client() takes the v4.1 early return so
clp->cl_cb_session = ses never fires and the field retains a pointer
to the about-to-be-freed session.
Fix both by converting cl_cb_session to an RCU-protected pointer:
- Move the cl_cb_session = ses assignment in setup_callback_client()
to after rpc_create() succeeds, so it is only published when a
working backchannel exists. Clear cl_cb_session on the error
return in nfsd4_process_cb_update(). Both stores use
rcu_assign_pointer().
- Annotate cl_cb_session with __rcu. All rpciod-side readers use
rcu_read_lock()/rcu_dereference() and check for NULL, bailing to
the appropriate error or requeue path:
encode_cb_sequence4args(), decode_cb_sequence4resok(),
nfsd41_cb_get_slot(), nfsd41_cb_release_slot(),
nfsd4_cb_prepare(), and nfsd4_cb_sequence_done().
- Switch __free_session() from kfree() to kfree_rcu() so the
session slab is not reclaimed until after an RCU grace period,
guaranteeing that rpciod readers inside rcu_read_lock() never
dereference freed memory.
- Pass the session pointer to the nfsd_cb_seq_status and
nfsd_cb_free_slot tracepoints instead of having them re-read
cl_cb_session.
- nfsd4_cb_prepare() calls rpc_exit() when the session is NULL,
routing through the done/release path to requeue the callback. |
| In the Linux kernel, the following vulnerability has been resolved:
nfsd: release path refs on follow_down() error
nfsd_cross_mnt() initializes a local struct path with mntget() and
dget() before calling follow_down(). On a negative return the error
arm jumps to out without releasing those references:
err = follow_down(&path, follow_flags);
if (err < 0)
goto out;
follow_down() never drops the caller's entry-time refs on any error
sub-case; for example a pre-cross d_manage() failure leaves path
untouched, so the mntget()/dget() taken on entry survive the call.
Every other early-exit arm in nfsd_cross_mnt() (other-namespace
return, IS_ERR(exp2), and the success tail after the swap) already
calls path_put(&path); the err < 0 arm is the lone omission. The
leak inflates mnt_count and d_count on each failed cross-mount,
blocking umount and pinning dentries against the shrinker, and is
reachable by any authenticated NFS client through nfsd_lookup_dentry
or the NFSv4 READDIR encode path.
Fix by calling path_put(&path) before the goto out in the err < 0
arm so the entry-time refs are released on all follow_down() error
returns. |
| In the Linux kernel, the following vulnerability has been resolved:
nfsd: Reset write verifier when async COPY writeback fails
Async COPY captures nn->writeverf at request time and reports it to
the client via CB_OFFLOAD after the worker kthread completes. When
the post-copy vfs_fsync_range() or filemap_check_wb_err() in
_nfsd_copy_file_range() reports an error, the worker correctly
leaves NFSD4_COPY_F_COMMITTED clear so that CB_OFFLOAD encodes
wr_stable_how as NFS_UNSTABLE, but the server's write verifier is
not rotated.
A client that receives NFS_UNSTABLE in CB_OFFLOAD follows up with
COMMIT to make the copied data durable. With the verifier
unchanged, COMMIT returns the same value the client just received
via CB_OFFLOAD, and the client concludes the copy is durable --
silently dropping the data whose writeback in fact failed. This
violates the UNSTABLE+COMMIT durability contract (RFC 7862 section
15.1, RFC 8881 section 18.32) and matches the bug just fixed in
nfsd_vfs_write() and nfsd_commit().
Rotate nn->writeverf at the writeback-failure site. The async COPY
worker has no svc_rqst, so commit_reset_write_verifier() is not
available here; calling nfsd_reset_write_verifier() directly
mirrors the trace-less reset already used by
nfsd_file_check_write_error() for the same purpose. Filter out
-EAGAIN and -ESTALE, matching commit_reset_write_verifier(), since
neither indicates a durable-storage failure. |
| In the Linux kernel, the following vulnerability has been resolved:
nfsd: restore rq_status_counter to even on all nfsd_dispatch() exit paths
nfsd_dispatch() sets rq_status_counter to an odd value once a request has
been decoded, and back to an even value once it has been fully processed,
forming a seq-lock like protocol with the lockless reader in
nfsd_nl_rpc_status_get_dumpit().
Only the fully successful path restored the counter to even. The cache-hit
(RC_REPLY), drop (RC_DROPIT / RQ_DROPME) and encode-error paths all return
after the odd-valued store without ever bringing the counter back to even.
Once one of those paths is taken, rq_status_counter is left odd: the next
request's decode ORs in 1 (still odd) and only a subsequent successful
encode restores even. While stuck odd, the dumpit reader treats the rqstp
fields as stable and its retry check compares against the same unchanging
odd value, so it never detects concurrent mutation. This exposes actively
mutating fields (e.g. args->ops / args->opcnt during compound decode and
release) to the lockless reader, which can read past the end of the
8-element inline ops array.
Add a helper that advances the counter to the next even value and call it
on every return path that follows the odd-valued store. The decode-error
path is left untouched as it is reached before the counter is set odd. |