| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
arm64: make huge_ptep_get handled unaligned addresses
huge_ptep_get() can be handed a virtual address pointing to the middle
of a contpmd/contpte mapped hugetlb folio (examples of callers are
pagemap_hugetlb_range, page_mapped_in_vma).
The arm64 helper rewalks the pgtables in find_num_contig to answer
whether the huge pte we have maps a contpmd or a contpte hugetlb folio,
and returns CONT_PMDS or CONT_PTES, so that it can collect a/d bits over
the contiguous ptes. We can falsely return CONT_PTES instead of
CONT_PMDS if the addr is not aligned. On systems where CONT_PTES !=
CONT_PMDS (meaning page size is 16K), we could collect excess A/D bit
state, meaning extra work for the kernel. Even worse, we may iterate
beyond the PTE table and dereference a garbage ptep pointer to access
physical memory we don't own. Since the ptep pointer is a linear map
address, we may run off the end of the linear map or into a hole,
dereference a VA not mapped into the kernel pgtables and cause kernel
panic.
Fix this by aligning the pmdp pointer down to a contpmd base before
checking equality with the passed huge pte pointer, to correctly answer
whether the huge pte is the base of a contpmd block. |
| In the Linux kernel, the following vulnerability has been resolved:
mptcp: fix stale skb->sk reference on subflow close
The backlog list is updated by mptcp_data_ready() under
mptcp_data_lock(). The cleanup of backlog references to a closing
subflow, however, was performed in mptcp_close_ssk(), before
__mptcp_close_ssk() acquires the ssk lock, and while holding neither
the ssk lock nor mptcp_data_lock().
Because that traversal ran without mptcp_data_lock(), concurrent softirq
RX processing on another CPU (subflow_data_ready() -> mptcp_data_ready()
-> __mptcp_add_backlog(), under mptcp_data_lock()) could add a backlog
entry referencing the ssk while the cleanup loop was in progress. Such
an entry could be missed by the cleanup, or the concurrent list update
could corrupt the traversal, leaving skb->sk pointing at the ssk after
it is freed.
A later mptcp_backlog_purge() then dereferences the stale pointer,
triggering a warning in inet_sock_destruct() (ssk->sk_rmem_alloc != 0)
followed by a use-after-free in mptcp_backlog_purge().
Fix this by moving the backlog cleanup into __mptcp_close_ssk(), after
subflow->closing is set to 1 and while the ssk lock is still held,
serialized under mptcp_data_lock(). The cleanup runs only on the push
path (MPTCP_CF_PUSH), where backlog references accumulate; on other
teardown paths the caller already handles cleanup.
With subflow->closing set and mptcp_data_lock() held across the purge,
any concurrent mptcp_data_ready() either completes its enqueue before
the purge runs and is caught, or observes closing=1 and bails out. Once
mptcp_data_unlock() is reached, no new skb referencing the ssk can be
enqueued, so the cleanup is exhaustive.
Remove the unprotected traversal from mptcp_close_ssk() entirely. |
| In the Linux kernel, the following vulnerability has been resolved:
mm/page_vma_mapped: fix device-private PMD handling
Commit 65edfda6f3f2 ("mm/rmap: extend rmap and migration support
device-private entries") introduced the concept of device-private PMD
entries, but did not correctly update the rmap walk code to account for
them.
As a result, when page_vma_mapped_walk() encounters device-private PMD
entries, it takes no action other than to acquire the PMD lock and exit.
However this is highly problematic for two reasons - firstly, device
private entries possess a PFN so check_pmd() needs to be called to ensure
an overlapping PFN range.
Secondly, and more importantly, if PVMW_MIGRATION is set the caller
assumes the returned entry is a migration entry, resulting in memory
corruption when the caller tries to interpret the device private entry as
such.
In addition, commit 146287290023 ("mm/huge_memory: implement
device-private THP splitting") allowed device private PMDs to be split
like THP mappings, but again did not update this code path.
As a result, we might race a PMD split prior to acquiring the PMD lock.
This patch addresses all of these issues by invoking check_pmd(), ensuring
PMVW_MIGRATION is not set and checks whether a split raced us we do for
PMD THP and migration entries.
Instead of checking for a subset of the cases after taking the pmd_lock(),
put device-private along with pmd_trans_huge() and
pmd_is_migration_entry(). Also remove thp_migration_supported() as it is
already guarded by pmd_is_migration_entry().
[akpm@linux-foundation.org: fix Raspberry Pi 1 build, per David] |
| In the Linux kernel, the following vulnerability has been resolved:
sctp: avoid auth_enable sysctl UAF during netns teardown
proc_sctp_do_auth() updates the SCTP control socket after changing
net.sctp.auth_enable. The handler gets the per-net SCTP state from
ctl->data, so an already opened sysctl file can still target a network
namespace while that namespace is being torn down.
SCTP previously registered its per-net sysctls from sctp_defaults_init(),
while the control socket is created later from sctp_ctrlsock_init(). This
exposed a window during initialization where auth_enable was writable
before net->sctp.ctl_sock existed, and a teardown window where auth_enable
stayed writable after inet_ctl_sock_destroy() had released the control
socket.
Move the per-net SCTP sysctl registration into sctp_ctrlsock_init() after
sctp_ctl_sock_init() succeeds, and unregister the sysctl table before
destroying the control socket in sctp_ctrlsock_exit(). If sysctl
registration fails after the control socket was created, destroy the
control socket in the same init path.
Make sctp_sysctl_net_unregister() tolerate a missing header and clear the
saved pointer so init-error and exit paths can safely share the unregister
helper. |
| In the Linux kernel, the following vulnerability has been resolved:
ceph: fix pre-auth out-of-bounds read on snaptrace in ceph_handle_caps()
ceph_handle_caps() reads snap_trace_len from the wire-format
ceph_mds_caps header and uses it unconditionally to build a fake
end pointer (snaptrace + snaptrace_len) that is later handed to
ceph_update_snap_trace() in the CEPH_CAP_OP_IMPORT case:
snaptrace = h + 1;
snaptrace_len = le32_to_cpu(h->snap_trace_len);
p = snaptrace + snaptrace_len;
...
case CEPH_CAP_OP_IMPORT:
if (snaptrace_len) {
...
if (ceph_update_snap_trace(mdsc, snaptrace,
snaptrace + snaptrace_len,
false, &realm)) { ... }
ceph_update_snap_trace() then decodes a struct ceph_mds_snap_realm
from snaptrace using ceph_decode_need(&p, e, sizeof(*ri), bad)
with the attacker-supplied fake end e == snaptrace + snaptrace_len.
With snaptrace_len == 0xFFFFFFFF the bound check is trivially
satisfied, ri = p reads sizeof(struct ceph_mds_snap_realm) past
the legitimate msg->front buffer, and ri->num_snaps /
ri->num_prior_parent_snaps then drive further out-of-bounds
reads of the encoded snap arrays.
The eleven msg_version >= 2 .. msg_version >= 12 decoder blocks
above the op switch each catch this OOB through their
ceph_decode_*_safe() / ceph_decode_need() helpers, but they sit
behind a hdr.version-gated if, so a malicious or compromised
MDS that sets msg->hdr.version = 1 reaches the IMPORT path with
no version-gated decoder having validated snap_trace_len. The
shape has been present since ceph_handle_caps() was introduced.
Validate snap_trace_len against the message front buffer before
consuming it, using the canonical ceph_decode_need() / ceph_has_room()
helper. The helper bounds the length with subtraction (n <= end - p,
guarded by end >= p) rather than pointer addition, so it is wrap-safe
for the attacker-controlled u32 length on 32-bit builds where
p + snap_trace_len could overflow the address space. This matches the
rest of the ceph decode path (e.g. the pool_ns_len check a few lines
below), and the existing goto bad cleanup already covers this exit
path. |
| In the Linux kernel, the following vulnerability has been resolved:
libceph: bound pg_{temp,upmap,upmap_items} length to CEPH_PG_MAX_SIZE
__decode_pg_temp() decodes an user-controlled length but only rejects
values large enough to overflow the allocation; it does not bound it to
CEPH_PG_MAX_SIZE. The helper backs both pg_temp and pg_upmap decoding, and
apply_upmap()/get_temp_osds() later copy the decoded list into the fixed-size
on-stack array struct ceph_osds.osds[CEPH_PG_MAX_SIZE]. A monitor that sends
an OSDMap with a pg_temp/pg_upmap entry longer than 32 thus causes a stack
out-of-bounds write.
An OSD set for a single PG can never exceed CEPH_PG_MAX_SIZE, so reject longer
entries at decode time. The bound is well below the old overflow threshold, so
it also covers the allocation-size overflow the previous check guarded against.
BUG: KASAN: stack-out-of-bounds in ceph_pg_to_up_acting_osds
Write of size 4 ... by task exploit
kasan_report (mm/kasan/report.c:595)
ceph_pg_to_up_acting_osds (net/ceph/osdmap.c:2617 net/ceph/osdmap.c:2833)
calc_target (net/ceph/osd_client.c:1638)
__submit_request (net/ceph/osd_client.c:2394)
ceph_osdc_start_request (net/ceph/osd_client.c:2490)
ceph_osdc_call (net/ceph/osd_client.c:5164)
rbd_dev_image_probe (drivers/block/rbd.c:6899)
do_rbd_add (drivers/block/rbd.c:7138)
...
kernel BUG at net/ceph/osdmap.c:2670!
[ idryomov: do the same in __decode_pg_upmap_items() ] |
| In the Linux kernel, the following vulnerability has been resolved:
libceph: Fix multiplication overflow in decode_new_up_state_weight()
If a message of type CEPH_MSG_OSD_MAP contains a (maliciously) corrupted
osdmap, out-of-bounds memory accesses may occur in
decode_new_up_state_weight(). This happens because the bounds check for
the new_state part is based on calculating its length depending on a len
value read from the incoming message. This calculation may overflow
leading to an incorrect bounds check. Subsequently, out-of-bounds reads
may occur when decoding this part.
This patch switches the multiplication to use check_mul_overflow() to
abort processing the osdmap if an overflow occurred. Therefore,
osdmaps/messages containing large values for len that result in a
multiplication overflow are treated as invalid.
[ idryomov: rename new_state_len -> new_state_item_size, formatting ] |
| In the Linux kernel, the following vulnerability has been resolved:
libceph: guard missing CRUSH type name lookup
Localized read selection can walk a parent bucket whose name exists in
the CRUSH map while its type has no matching entry in type_names.
get_immediate_parent() then dereferences a NULL type_cn and passes an
invalid pointer into strcmp(), causing a null-ptr-deref.
Skip such malformed parent buckets unless both the bucket name and type
name metadata are present. This keeps malformed hierarchy data from
crashing locality lookup and safely falls back to "not local".
[ idryomov: add WARN_ON_ONCE ] |
| In the Linux kernel, the following vulnerability has been resolved:
libceph: Reject monmaps advertising zero monitors
A message of type CEPH_MSG_MON_MAP contains a monmap that is sent from a
monitor to the client. This monmap contains information about the
existing monitors in the cluster. Currently, a monmap indicating that
there are zero monitors in the cluster is treated as valid. However, it
is impossible to have zero monitors in the cluster and still receive a
valid monmap from a monitor. Therefore, such a monmap must be corrupted
and should be treated as invalid. Furthermore, a monmap with a monitor
count of zero can subsequently crash the client when attempting to open
a session with a monitor in __open_session(). This happens because the
"BUG_ON(monc->monmap->num_mon < 1)" assertion in pick_new_mon() is
triggered.
This patch extends a check in ceph_monmap_decode() to also reject
arriving mon_maps with num_mon == 0 rather than only with
num_mon > CEPH_MAX_MON.
[ idryomov: drop "log output for unusual values of num_mon" part ] |
| In the Linux kernel, the following vulnerability has been resolved:
libceph: reject zero bucket types in crush_decode
CRUSH bucket type 0 is reserved for devices. The mapper relies on
that invariant and uses type 0 to identify leaf devices.
If crush_decode() accepts a bucket with type 0, a malformed CRUSH map
can make the mapper treat a negative bucket ID as a device and pass it
to is_out(), which then indexes the OSD weight array with a negative
value.
Reject zero bucket types while decoding the CRUSH map so the invalid
state never reaches the mapper. |
| In the Linux kernel, the following vulnerability has been resolved:
libceph: remove debugfs files before client teardown
ceph_destroy_client() tears down the monitor client before removing
the per-client debugfs files. A concurrent read of the monmap debugfs
file can enter monmap_show() after ceph_monc_stop() has freed
monc->monmap, triggering a use-after-free.
Remove the debugfs files before stopping the OSD and monitor clients.
debugfs_remove() drains active handlers and prevents new accesses, so
the debugfs callbacks can no longer race the rest of client teardown. |
| In the Linux kernel, the following vulnerability has been resolved:
amt: fix use-after-free in AMT delayed works
When an AMT device is removed, pending delayed works can still access
the freed amt_dev structure, which may result in kernel crashes or
memory corruption.
amt_dev_stop() cancels req_wq and discovery_wq with
cancel_delayed_work_sync(), but these works can be scheduled again
from event_wq after the cancellation. This allows delayed works to
access the freed amt_dev structure after the netdev has been released.
The following is a simple race scenario:
CPU0 CPU1
amt_dev_stop()
cancel_delayed_work_sync()
amt_event_work()
mod_delayed_work(req_wq)
free netdev
req_wq accesses freed amt_dev
Use disable_delayed_work_sync() in amt_dev_stop() to prevent req_wq and
discovery_wq from being queued again and wait for running work items
to complete.
The delayed works are disabled after initialization in
amt_newlink() and enabled only when the device is successfully opened.
This keeps the delayed work lifecycle synchronized with the lifetime
of the AMT device. |
| In the Linux kernel, the following vulnerability has been resolved:
fs: preserve ACL_DONT_CACHE state in forget_cached_acl()
The ACL_DONT_CACHE state is meant to be a constant state for the inode
for filesystems that want to opt out of posix acl caching.
Commit facd61053cff1 ("fuse: fixes after adapting to new posix acl api")
used this facility to opt out of posix acl caching for fuse inodes with
fuse server that does not negotiate FUSE_POSIX_ACL (fc->posix_acl).
The commit also takes care to gate the forget_all_cached_acls() call in
fuse_set_acl() on fc->posix_acl because there is no need for it, but
there are other placed in fuse code which call forget_all_cached_acls()
unconditional to fc->posix_acl and those cause the loss of the
ACL_DONT_CACHE state.
This is not only a functional bug. Properly timed, a get_acl() from this
fuse filesystem can return a stale cached value, as was observed in tests,
because set_acl() does not invalidate the unintentional acl cache.
We could fix this in fuse, but it actually makes no sense for the vfs
helper forget_cached_acl() to invalidate the ACL_DONT_CACHE state, so
let it not do that to fix fuse and future users of ACL_DONT_CACHE. |
| In the Linux kernel, the following vulnerability has been resolved:
fscrypt: Add missing superblock check in find_or_insert_direct_key()
The legacy 'fscrypt_direct_keys' table caches master keys that are used
by v1 encryption policies that have FSCRYPT_POLICY_FLAG_DIRECT_KEY.
It's just a global table for all filesystems (since the keys can be
provided by the legacy process-subscribed keyrings mechanism, which
makes it difficult to reuse super_block::s_master_keys).
The entries in it ('struct fscrypt_direct_key') do contain a super_block
pointer, though, for passing to fscrypt_destroy_inline_crypt_key() when
the last inode that references the key is evicted.
However, when finding the fscrypt_direct_key for an inode, we weren't
actually comparing the super_block pointer. As a result, inodes with
different super_blocks could point to the same fscrypt_direct_key. That
could extend the lifetime of a fscrypt_direct_key beyond the
super_block it points to, causing a use-after-free later.
Fix this by creating distinct fscrypt_direct_key structs for distinct
super_block structs.
Note that this problem doesn't exist in the v2 policy equivalent
("per-mode keys"), since the data structures there are per super_block. |
| In the Linux kernel, the following vulnerability has been resolved:
iomap: fix out-of-bounds bitmap_set() with zero-length range
ifs_set_range_dirty() and ifs_set_range_uptodate() compute last_blk
as (off + len - 1) >> i_blkbits. When off is 0 and len is 0, the
unsigned subtraction underflows to SIZE_MAX, producing a huge
last_blk and nr_blks value that causes bitmap_set() to write far
beyond the ifs->state allocation.
Regarding ifs_set_range_uptodate(), it is temporarily safe because len
cannot be passed in as 0. However, for ifs_set_range_dirty() this is
reachable from __iomap_write_end(): when copy_folio_from_iter_atomic()
returns 0 (e.g. user buffer fault) and the folio is already uptodate,
the guard at the top of __iomap_write_end() does not trigger because
!folio_test_uptodate() is false, and iomap_set_range_dirty() is called
with copied == 0.
Add a !len guard to both functions before the computation, so that a
zero-length range is a no-op. |
| In the Linux kernel, the following vulnerability has been resolved:
phonet: pep: fix use-after-free in pep_get_sb()
pep_get_sb() doesn't consider that pskb_may_pull() might have relocated
the skb data, and continue to access the older pointer, causing UAF.
Reproduced under KASAN:
BUG: KASAN: slab-use-after-free in pep_get_sb+0x234/0x3b0
Read of size 1 at addr ff11000105510f50 by task repro/157
pep_get_sb+0x234/0x3b0
pipe_handler_do_rcv+0x5f7/0xa10
pep_do_rcv+0x203/0x410
__sk_receive_skb+0x471/0x4a0
phonet_rcv+0x5b3/0x6c0
__netif_receive_skb+0xcc/0x1d0
Refetch the header with skb_header_pointer() after pskb_may_pull(), so
the possibly stale pointer is no longer dereferenced. There are better
ways to solve this, but, this is the less instrusive one. |
| In the Linux kernel, the following vulnerability has been resolved:
net: slip: serialize receive against buffer reallocation
sl_realloc_bufs() replaces rbuff and updates buffsize while holding
sl->lock. slip_receive_buf() reads those fields and writes through rbuff
without holding the lock.
An MTU change can therefore race with receive processing. An MTU shrink
can expose the new smaller rbuff with the old larger bound, causing an
out-of-bounds write. A receive callback which already loaded the old
rbuff can instead continue writing after that buffer has been freed.
Serialize receive processing with sl_realloc_bufs() by holding sl->lock
while consuming each receive batch. |
| In the Linux kernel, the following vulnerability has been resolved:
geneve: require CAP_NET_ADMIN in the device netns for changelink
A tunnel changelink() operates on at most two netns, dev_net(dev) and
the sticky underlay netns geneve->net. They differ once the device is
created in or moved to a netns other than the one the request runs in.
The rtnl changelink path checks CAP_NET_ADMIN only against dev_net(dev),
so a caller privileged there but not in geneve->net can rewrite a geneve
device whose underlay lives in geneve->net.
geneve_changelink() applies the new configuration against geneve->net:
geneve_link_config() and the geneve_quiesce()/geneve_unquiesce() pair
reopen the underlay sockets in that netns (geneve_sock_add() uses
geneve->net), so the same reasoning as the tunnel changelink series
applies here.
Gate geneve_changelink() with rtnl_dev_link_net_capable(), at the top of
the op before any attribute is parsed, matching ipgre_changelink() and
the rest of the "require CAP_NET_ADMIN in the device netns for
changelink" series.
Found by 0sec automated security-research tooling (https://0sec.ai). |
| In the Linux kernel, the following vulnerability has been resolved:
net/af_iucv: fix NULL deref in afiucv_hs_callback_syn()
afiucv_hs_callback_syn() allocates the child socket with GFP_ATOMIC.
If the allocation fails, nsk is NULL.
The connection-refused path is entered when the listen state check
fails, the accept backlog is full, or nsk is NULL. The code
unconditionally calls iucv_sock_kill(nsk) in that path.
iucv_sock_kill() does not accept a NULL socket pointer and immediately
dereferences sk via sock_flag(sk, SOCK_ZAPPED). When nsk is NULL,
calling iucv_sock_kill(nsk) results in a NULL pointer dereference.
Only call iucv_sock_kill() when a child socket was successfully
allocated. |
| In the Linux kernel, the following vulnerability has been resolved:
net/iucv: fix use-after-free of a severed iucv_path
af_iucv queues not-yet-received message notifications on iucv->message_q,
each holding a raw pointer to the connection's iucv_path. When the peer
severs the connection, iucv_sever_path() frees that path with
iucv_path_free() but leaves the notifications queued. A later recvmsg()
drains message_q via iucv_process_message_q() and hands the stale path to
message_receive() -- a use-after-free of the freed iucv_path.
Drop the queued notifications when the path is severed; once the path is
gone they can no longer be received. This also frees the notifications
leaked when a socket is closed with messages still queued. |