| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
jbd2: bound shrinker scans by examined checkpoint buffers
The jbd2 shrinker currently accounts only checkpoint buffers that it
successfully releases against nr_to_scan. Busy buffers therefore do not
consume the scan budget.
If a checkpoint transaction contains mostly busy buffers, the shrinker
can scan its entire checkpoint list while holding journal->j_list_lock.
Large checkpoint lists can result in excessive lock hold times and leave
other CPUs spinning on j_list_lock, causing soft lockups or RCU stalls.
Pass nr_to_scan into journal_shrink_one_cp_list() and decrement it for
every buffer examined, including busy buffers. Pass NULL from checkpoint
cleanup paths so their existing full-list behavior is preserved.
This restores the scan-budget semantics that existed before
journal_shrink_one_cp_list() was changed to always scan a complete
checkpoint list. |
| In the Linux kernel, the following vulnerability has been resolved:
jbd2: check need_resched() when skipping busy checkpoint buffers
journal_shrink_one_cp_list() skips busy checkpoint buffers when called
with JBD2_SHRINK_BUSY_SKIP. The continue statement on this path also
skips the need_resched() check at the end of the loop body.
Consequently, when a checkpoint list contains mostly busy buffers, the
shrinker can walk the entire list while holding journal->j_list_lock,
even when a reschedule has been requested. Large checkpoint lists under
memory pressure can therefore cause long lock hold times and leave other
CPUs spinning on j_list_lock, resulting in soft lockups or RCU stalls.
Route the busy-buffer path through the need_resched() check so that the
shrinker can release j_list_lock and reschedule promptly, restoring
parity with the clean-buffer path, which already checks need_resched().
This does not change which checkpoint buffers are eligible for removal. |
| In the Linux kernel, the following vulnerability has been resolved:
ip: orphan prefetched skbs before multicast forwarding
IPv4 and IPv6 input preserve an skb->sk association installed by
bpf_sk_assign() so that local delivery can use the selected socket under
RCU. Both address families can also prefetch a socket in UDP early demux.
In both paths (BPF and UDP early demux) a reference is not guaranteed to
be held on the socket.
When a multicast packet is not locally deliverable, IPv6 hands the
original skb to ip6_mr_input(). IPv4's ip_mr_input() similarly keeps the
original skb when local delivery is not needed. Either path can put the
skb on an unresolved multicast route queue or forward it after the
receive-side RCU section ends.
After the prefetched socket is destroyed, a later skb free invokes
sock_pfree() and dereferences the stale skb->sk. Orphan the skb before
each non-local multicast forwarding path. Local delivery retains the
original skb; the existing skb_clone() calls provide multicast forwarding
with a socket-free clone. |
| In the Linux kernel, the following vulnerability has been resolved:
ipv6: rpl: fix NULL dereference of idev in ipv6_rpl_srh_rcv()
ipv6_rpl_srh_rcv() dereferences idev from __in6_dev_get() without a NULL
check when reading idev->cnf.rpl_seg_enabled.
When the device's MTU drops below IPV6_MIN_MTU, addrconf_ifdown() clears
dev->ip6_ptr through RCU_INIT_POINTER(). A packet that passed the idev
check in ip6_rcv_core() can then reach ipv6_rpl_srh_rcv() with
dev->ip6_ptr already NULL.
Reproduced by flooding the receiving interface with ping6 traffic while
flapping its MTU between 1500 and 1200:
BUG: KASAN: null-ptr-deref in ipv6_rpl_srh_rcv+0xb3/0x1070
Read of size 4 at addr 00000000000006b4 by task ping6/394
CPU: 2 UID: 0 PID: 394 Comm: ping6 Not tainted 7.2.0-rc7-micro-vm-dev-00095-g24ef02f934ee #240 PREEMPT(full)
Call Trace:
<IRQ>
kasan_report+0xc6/0x100
ipv6_rpl_srh_rcv+0xb3/0x1070
ip6_protocol_deliver_rcu+0x759/0x9a0
ip6_input_finish+0xa8/0x1b0
ip6_input+0xe1/0x490
ipv6_rcv+0x33d/0x460
__netif_receive_skb_one_core+0xd6/0x130
process_backlog+0x2cc/0xa00
__napi_poll.constprop.0+0x56/0x270
net_rx_action+0x327/0x730
handle_softirqs+0x11e/0x630
do_softirq+0xb3/0xf0
</IRQ>
Both ipv6_rpl_srh_rcv() and ipv6_srh_rcv() are called only from
ipv6_rthdr_rcv(), which already has an idev lookup.
Fix the NULL dereference on the RPL path by checking idev in
ipv6_rthdr_rcv(), before it calls either function. The callees take idev as
an argument and no longer call __in6_dev_get(), so the packet is now
dropped in one place, with SKB_DROP_REASON_IPV6DISABLED on both paths. |
| In the Linux kernel, the following vulnerability has been resolved:
params: fix charp corruption on allocation failure
param_set_charp() stores charp parameters in allocated memory after slab is
available, and releases the previous value when the parameter is updated.
The previous value is released before the replacement allocation succeeds.
If kmalloc_parameter() fails, the setter returns -ENOMEM with the parameter
left as NULL.
Failing zswap's compressor update before zswap is initialized can later
trigger:
BUG: kernel NULL pointer dereference, address: 0000000000000000
RIP: 0010:strcmp+0x10/0x30
Call Trace:
zswap_setup+0x3b1/0x490
zswap_enabled_param_set+0x5b/0xa0
param_attr_store+0x93/0xe0
module_attr_store+0x1c/0x30
kernfs_fop_write_iter+0x116/0x1f0
Allocate and copy the replacement first, then replace the parameter value
only after allocation succeeds. |
| In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: fix gssx_dec_option_array error path bugs
Four coupled defects in the gssx XDR option-array decoder make the
error paths unsafe: a NULL deref in the caller, a refcount leak on
the decoded group_info, and a latent use-after-free that the leak
fix would otherwise expose.
gssx_dec_option_array() sets oa->count = 1 before allocating
oa->data. If that allocation fails, -ENOMEM is returned with
oa->count == 1 and oa->data == NULL. All other error paths jump
to free_oa: which frees oa->data and NULLs it but also leaves
oa->count == 1. The caller trusts the count:
gssp_accept_sec_context_upcall()
gssx_dec_accept_sec_context()
gssx_dec_option_array() /* fails, count=1 data=NULL */
data = res.options.data[0].value /* NULL deref */
Independently, free_creds: releases the partially decoded svc_cred
with a bare kfree(creds). gssx_dec_linux_creds() installs a
groups_alloc() result into creds->cr_group_info; that object is
kvmalloc-backed and refcounted, and only put_group_info() reaches
kvfree(). A plain kfree(creds) drops the wrapper and leaks the
group_info allocation.
The natural fix for the leak is to call free_svc_cred(creds) before
kfree(creds), but free_svc_cred() invokes put_group_info() on
creds->cr_group_info unconditionally when non-NULL. The existing
out_free_groups: path in gssx_dec_linux_creds() already called
groups_free() on that pointer without clearing it, so once
free_svc_cred() is wired in, the subsequent put_group_info() would
touch freed memory.
Fix all four together:
- Move the oa->count = 1 assignment below the oa->data allocation
so it is never set when oa->data is NULL.
- Reset oa->count to 0 at free_oa: so count and data stay
coherent and the caller sees an empty option array.
- Call free_svc_cred(creds) before kfree(creds) at free_creds:
so the refcounted cr_group_info is released. free_svc_cred()
either NULL-guards each field explicitly (cr_group_info has
an if() check) or delegates to a helper that is NULL-safe
itself (kfree for the string fields, gss_mech_put() which
guards with if(gm) at gss_mech_switch.c:342), so it is safe
to call on a partially decoded svc_cred where only
cr_uid/cr_gid/cr_group_info have been written and everything
else is zero from kzalloc.
- In gssx_dec_linux_creds()'s out_free_groups: path, release
cr_group_info with put_group_info() rather than groups_free()
so the teardown matches free_svc_cred()'s refcount-aware path,
and clear the pointer so a later free_svc_cred() on the same
creds does not release it a second time. |
| In the Linux kernel, the following vulnerability has been resolved:
sunrpc: fix use-after-free in __rpc_clnt_handle_event and __rpc_clnt_remove_pipedir
Normal client creation goes through rpc_setup_pipedir(), which records
clnt->pipefs_sb, but the mount-event path in __rpc_clnt_handle_event()
calls rpc_setup_pipedir_sb() directly and never refreshes that field.
The umount path also removes the directory without clearing
clnt->pipefs_sb.
After a late pipefs mount or any remount, rpc_clnt_remove_pipedir()
compares the current superblock against a stale pipefs_sb pointer and
skips cleanup, leaving pipefs dentries whose inode private data still
points at a freed rpc_clnt, leading to a potential use-after-free during
subsequent rpc_info_open() or rpc_show_info() calls.
Fix this by properly updating clnt->pipefs_sb upon mount events and
clearing it during unmount or failure paths. |
| In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: reject duplicate CREDS_VALUE options
gssx_dec_option_array() walks the wire-supplied option array and, for
every entry whose name matches CREDS_VALUE, calls
gssx_dec_linux_creds() on the same struct svc_cred. That helper
unconditionally installs a fresh groups_alloc() result into
creds->cr_group_info without releasing whatever pointer was already
there:
for (i = 0; i < count; i++) {
... decode name ...
if (length == sizeof(CREDS_VALUE) &&
memcmp(p, CREDS_VALUE, sizeof(CREDS_VALUE)) == 0) {
err = gssx_dec_linux_creds(xdr, creds);
...
}
}
A reply that carries two CREDS_VALUE entries therefore overwrites
cr_group_info on the second iteration and orphans the group_info
allocated by the first call. The earlier free_creds path only
releases the last cr_group_info via free_svc_cred(), so the first
allocation's refcount stays at one and its kvmalloc-backed storage
is leaked. No in-tree caller of gssp_accept_sec_context_upcall()
expects more than one CREDS_VALUE per reply.
Fix by tracking whether a CREDS_VALUE option has already been
decoded and returning -EINVAL on any subsequent match, so the
free_creds path releases the single group_info that was installed. |
| In the Linux kernel, the following vulnerability has been resolved:
SUNRPC: Reject short RFC 4121 MIC tokens in gss_krb5_verify_mic_v2
gss_krb5_verify_mic_v2() reads the token ID at ptr[0..1], the flags
byte at ptr[2], and padding at ptr[3..7], then passes
ptr + GSS_KRB5_TOK_HDR_LEN and cksum_len to gss_krb5_mic_build_sg().
None of these accesses check read_token->len first.
The minimum safe token size is GSS_KRB5_TOK_HDR_LEN (16) plus
ctx->krb5e->cksum_len (12-24, depending on the enctype). All callers
accept shorter tokens from the wire:
- gss_unwrap_resp_integ() enforces only an upper bound
(offset + len <= rcv_buf->len) before allocating
mic.data = kmalloc(len) and passing it to gss_verify_mic().
A malicious NFS server can therefore supply a short checksum
opaque, producing a small slab allocation that the Kerberos MIC
verifier reads past.
- gss_validate() enforces only len <= RPC_MAX_AUTH_SIZE (400)
before passing the wire-supplied length to
gss_validate_seqno_mic(), which constructs a mic xdr_netobj
and calls gss_verify_mic().
- svcauth_gss_verify_header() enforces only
checksum.len >= XDR_UNIT (4 bytes) before dispatching to
gss_verify_mic().
- svcauth_gss_unwrap_integ() checks only that the checksum fits
in gsd->gsd_scratch.
Add a length guard at the top of gss_krb5_verify_mic_v2(), before any
ptr[] access or scatterlist construction. Well-formed MIC tokens from
gss_krb5_get_mic_v2() already have exactly GSS_KRB5_TOK_HDR_LEN +
cksum_len bytes, so valid traffic is unaffected. |
| In the Linux kernel, the following vulnerability has been resolved:
svcrdma: Clear sc_cm_id when ADDR_CHANGE replacement fails
When svc_rdma_listen_handler() handles RDMA_CM_EVENT_ADDR_CHANGE,
it creates a replacement listener cm_id and returns 1, telling
the CM core to destroy the old one. If the replacement allocation
fails, sc_cm_id still points at the old cm_id that the CM core is
about to destroy. Any subsequent dereference of sc_cm_id --
such as svc_rdma_detach()'s rdma_disconnect() call -- is a
use-after-free.
NULL sc_cm_id on the failure path and guard svc_rdma_detach()'s
rdma_disconnect() call against NULL so that the listener can
be torn down safely when the server shuts down. |
| In the Linux kernel, the following vulnerability has been resolved:
svcrdma: Reject connection when transport allocation fails
handle_connect_req() returns without action when
svc_rdma_create_xprt() fails to allocate the new transport.
The CM core returns 0 for CONNECT_REQUEST events, so it does
not destroy the new rdma_cm_id. Each allocation failure under
memory pressure leaks one rdma_cm_id, and a remote peer driving
connection attempts can amplify this.
Reject the connection by returning a non-zero status from the
CM event handler, which tells the CM core to destroy the
orphaned cm_id. |
| In the Linux kernel, the following vulnerability has been resolved:
svcrdma: Reject inline replies that overflow the pull-up buffer
An RPC-over-RDMA client can request a reply, such as an NFS READ
payload, without providing a Write list or a Reply chunk to carry
it. When such a reply needs more scatter/gather entries than the
device's Send Queue supports, svc_rdma_pull_up_needed() selects
pull-up and svc_rdma_pull_up_reply_msg() linearizes the whole
reply into sctxt->sc_xprt_buf. That buffer is only sc_max_req_size
bytes, while the reply on this path is bounded only by the client's
request, so svc_rdma_xb_linearize() copies past the end of the
buffer and corrupts adjacent slab memory. The oversized length is
then stored in sc_sges[0].length and posted, so the device also
reads beyond the mapped region.
The SGE-exhaustion branch is the only pull-up path that can exceed
the buffer: the threshold branch pulls up only replies smaller
than RPCRDMA_PULLUP_THRESH, and replies that fit the device's SGE
budget are sent directly without linearization. Make
svc_rdma_pull_up_needed() report -E2BIG when the reply it would
pull up cannot fit sc_max_req_size, and fail the request with
ERR_CHUNK as RFC 8166 Section 4.5.3 directs rather than dropping
the connection.
The helper no longer answers a simple yes/no question: it now
reports pull-up, no pull-up, or -E2BIG for a reply too large to
linearize. Rename svc_rdma_pull_up_needed() to
svc_rdma_check_pull_up() so its name no longer implies a boolean
predicate. |
| In the Linux kernel, the following vulnerability has been resolved:
svcrdma: Reject Read lists that exceed the page budget
Individual Read segment lengths are validated at decode time, but
nothing prevents a requester from sending multiple segments whose
cumulative length exceeds the rq_pages array budget. When one
segment fills the page array exactly, the runtime guard in
svc_rdma_build_read_segment() is bypassed because len reaches zero.
A subsequent segment then accesses the NULL sentinel slot at
rq_pages[rq_maxpages], resulting in a NULL pointer dereference during
DMA mapping.
Accumulate pages across all Read segments and reject the message at
decode time when the total would overflow the page budget. |
| In the Linux kernel, the following vulnerability has been resolved:
svcrdma: Use svc_xprt_put to free listener on create failure
svc_rdma_create() calls kfree(cma_xprt) when
svc_rdma_create_listen_id() fails. svc_xprt_init() has already
acquired a net namespace reference via get_net_track(); kfree
bypasses svc_xprt_free() which releases it.
Replace the kfree() with svc_xprt_put() so the kref_init birth
reference drops to zero and svc_xprt_free() dispatches
svc_rdma_free() to clean up properly. sc_cm_id is still NULL
at that point; the preceding patch added the necessary NULL
guard in svc_rdma_free().
svc_xprt_free() also drops the module reference via
module_put(), but the caller _svc_xprt_create() does the same
on xpo_create failure, double-putting the single
try_module_get() it acquired. Take a compensating
__module_get() before the svc_xprt_put() to keep the count
balanced, matching the convention in svc_rdma_accept()'s error
path. |
| In the Linux kernel, the following vulnerability has been resolved:
svcrdma: Validate Read chunk positions before reconstruction
The RPC/RDMA Read chunk position field is supplied by the remote
client and stored verbatim in the parsed chunk list.
xdr_count_read_segments() checks only 4-byte alignment; it never
compares the position against the received inline body length.
In the single-chunk path, svc_rdma_read_complete_one() splits the
head and tail kvecs at ch_position. A position past the inline
body underflows the tail length, exposing adjacent slab memory to
the upper XDR decoder.
In the multi-chunk path, svc_rdma_read_multiple_chunks() computes
gap lengths between chunks as unsigned subtractions from
ch_position. Overlapping Read chunks cause these subtractions to
underflow. A final position past the inline body likewise
underflows the trailing gap length. svc_rdma_copy_inline_range()
then copies past the receive buffer into request pages that are
returned to the client through the Reply channel.
Bound inline-range copies in svc_rdma_copy_inline_range() against
the decoded inline RPC body saved in rc_saved_arg. Reject a
single Read chunk positioned beyond that body, and reject
multi-chunk lists where accumulated read bytes exceed the next
chunk's position. Apply the same position and overlap checks in
the call-chunk interleaving path. |
| In the Linux kernel, the following vulnerability has been resolved:
sched/core: Make core-sched flips wait for in-flight selections
Core scheduling's pick_next_task() operates on all sibling rqs under one
acquisition of the shared core-wide lock. A ->pick_task() that releases the
rq lock leaves every sibling __lock momentarily free, letting
__sched_core_flip(false) complete mid-selection and rebind rq_lockp() under
it. The selection resumes on the split locks, touching sibling state it no
longer protects, and __schedule() finally releases a lock that was never
taken while leaking the one that was.
Count in-flight core-wide selections in the leader's rq->core_pick_in_flight
and make __sched_core_flip() wait for the count to drain. The count only
changes under the shared lock, which the flip holds while sampling, so no
other ordering is needed. The wait can repeat while selections overlap, but
the flip backs off between samples and flips are rare cookie-lifetime
events.
sched_core_cpu_deactivate() moves the count to the new leader - a stale copy
left behind would bias it forever if that CPU later returns as its own
leader. |
| In the Linux kernel, the following vulnerability has been resolved:
ocfs2: validate directory-index entry counts when reading metadata
ocfs2_validate_dx_leaf() and ocfs2_validate_dx_root() check the ECC and
signature of an indexed-directory block before it reaches higher-level
callers, but neither validator bounds the ocfs2_dx_entry_list counts
against the capacity of the block that holds them.
ocfs2_dx_dir_search() then walks
for (i = 0; i < le16_to_cpu(entry_list->de_num_used); i++)
dx_entry = &entry_list->de_entries[i];
over de_num_used entries with no bounds check. entry_list is either
dx_leaf->dl_list (from ocfs2_read_dx_leaf) or, for an inline root,
dx_root->dr_entries. A crafted on-disk image can set de_num_used (and
de_count, which is the __counted_by_le() bound of de_entries) to 0xffff
and make the walk read far past the end of the 4KB metadata block, giving
a slab out-of-bounds read reachable from any path lookup, stat() or open()
on an indexed directory once the image is mounted.
Commit 775c17386a6f ("ocfs2: validate dx_root extent list fields during
block read") already bounds dr_list for the non-inline dx_root, but left
the inline dr_entries path and the dx_leaf dl_list unchecked. Add the
same read-time validation for both entry lists: de_count must equal the
capacity of the block (ocfs2_dx_entries_per_leaf()/per_root()) and
de_num_used must not exceed de_count, rejecting corrupted metadata with
-EFSCORRUPTED before ocfs2_dx_dir_search() can walk an out-of-range entry
array.
de_count is always written as exactly the block capacity when a leaf or
inline root is formatted, so the equality check does not reject any valid
image.
Found by 0sec automated security-research tooling (https://0sec.ai). |
| In the Linux kernel, the following vulnerability has been resolved:
lockd: fix NULL dereference on lockowner allocation failure
nlmclnt_locks_init_private() installs NLM file lock operations even when
nlmclnt_find_lockowner() fails to allocate a lockowner. nlmclnt_proc()
then returns -ENOMEM, but the VFS still tears down the partially
initialized file_lock and calls locks_release_private().
That invokes nlmclnt_locks_release_private(), which dereferences
fl->fl_u.nfs_fl.owner and crashes because the owner was never installed.
Clear fl_ops before attempting to initialize the NLM private state, and
install the NLM lock operations only after a lockowner has been allocated
successfully. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: charger-manager: register regulators before exposing sysfs
charger_manager_remove() and the err_reg_extcon probe error path free each
charger regulator with regulator_put() before tearing down the power_supply
sysfs entries (power_supply_unregister()). charger_manager_remove() also
calls try_charger_enable(cm, false) after the regulator_put() loop. A
concurrent write to a charger's externally_control sysfs attribute that
lands between regulator_put() and power_supply_unregister() can run
charger_externally_control_store() and call try_charger_enable(), which,
when charging is enabled, dereferences the already-freed consumer handle.
When charging is enabled, try_charger_enable(cm, false) in .remove() also
dereferences the freed handles directly. Both leave use-after-free windows.
Symmetrically, probe registers the sysfs entries (power_supply_register)
before acquiring the regulators (regulator_get, inside
charger_manager_register_extcon), so userspace can reach externally_control
before the regulators are available.
Split charger_manager_register_extcon() on the sync/async boundary:
charger_manager_get_regulators() (regulator_get only, no async producer)
now runs before power_supply_register() so sysfs is not live before
regulators are available, and charger_manager_register_extcon() keeps only
the extcon notifier/work setup, still after power_supply_register() so a
power_supply_register() failure cannot reach extcon setup. This keeps the
sysfs setup/teardown ordering symmetric without introducing an asynchronous
producer on the earlier probe-error path.
Move power_supply_unregister() and try_charger_enable(cm, false) ahead of
the regulator_put() loop on both teardown paths, and adjust err_reg_extcon
(power_supply_unregister() then fall through err_regulator for
regulator_put(); get_regulators self-rolls back on its own failure).
This does not address the separate extcon-notifier-driven deref of the same
handles, which needs its own synchronization design.
Found by an in-house static analysis tool. |
| In the Linux kernel, the following vulnerability has been resolved:
power: supply: lp8788-charger: fix use-after-free on remove
lp8788_charger_remove() flushes charger_work before unregistering the
IRQs. An IRQ thread can queue charger_work after flush_work() has
returned. The work can then run after devres frees pchg and dereference
it in lp8788_charger_event().
Unregister the IRQs first. free_irq() waits for any running threaded
handler, so no handler can queue more work afterwards. Then use
cancel_work_sync() to cancel pending work or wait for running work to
finish.
This issue was found by an in-house static analysis tool. |