| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
asymmetric_keys: reject trust keys without IDs
The PKCS#8 parser deliberately leaves the asym_key_ids payload slot
empty. key_or_keyring_common() unconditionally dereferences that slot
when a PKCS#8 key is supplied to a key_or_keyring restriction. Both the
plain and :chain forms reach this branch, allowing an unprivileged caller
to trigger a NULL pointer dereference through KEYCTL_RESTRICT_KEYRING
followed by add_key().
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
RIP: 0010:key_or_keyring_common (crypto/asymmetric_keys/restrict.c:205 crypto/asymmetric_keys/restrict.c:279)
Call Trace:
<TASK>
__key_create_or_update (security/keys/key.c:884)
key_create_or_update (security/keys/key.c:1021)
__do_sys_add_key (security/keys/keyctl.c:134)
do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
</TASK>
Kernel panic - not syncing: Fatal exception
Reject an asymmetric restriction key without key IDs. A PKCS#8 private
key cannot identify the signer of a candidate certificate and is not a
valid trust anchor. |
| In the Linux kernel, the following vulnerability has been resolved:
keys: Protect the read method check against type removal
keyctl_read_key() checks key->type->read without holding key->sem.
A reference keeps the key alive, but does not pin the module containing
its type. A surviving RxRPC key can therefore be read while AF_RXRPC
is being unloaded:
KEYCTL_READ task Module unload and key GC
---------------- ------------------------
lookup_user_key()
permission / possession checks
load key->type
af_rxrpc_exit()
unregister_key_type()
GC: down_write(key->sem)
GC: retype to key_type_dead
GC: up_write(key->sem)
unregister_key_type() returns
free_module()
read saved type's read member
The final access can read freed module storage. The read invocation in
__keyctl_read_key() is already protected by key->sem, but the earlier
method check is outside that critical section.
Move the method check into __keyctl_read_key(), after key_validate() and
under its existing read hold on key->sem. The check and invocation then
use the same protected type for length queries and every read retry.
The GC cannot retype the key until the semaphore is released, and type
unregistration waits for that GC pass before the module can be freed.
Return -EOPNOTSUPP when validation succeeds and the type has no read
method. A temporary buffer may now be allocated before this result;
allocation and copying to userspace remain outside the semaphore. |
| In the Linux kernel, the following vulnerability has been resolved:
keys: make keyring indexes independent of kernel addresses
KEYCTL_READ returns the serial numbers in a keyring in associative-array
traversal order. The first word of the index is a public, deterministic
hash of the type pointer, domain pointer and description. An unprivileged
user can therefore insert keys with known descriptions, predict their
order for each possible KASLR slide, and recover the kernel image address.
On an x86-64 build with 16 MiB alignment, 45 user keys suffice to
distinguish the candidate slides.
Remove the addresses from the whole index, not just its first hash word.
Assign each key type and domain a nonzero 64-bit ID and hash those IDs and
the description with a once-initialized SipHash key. Use the full IDs in
the later index chunks as well. Truncating or hashing the IDs there would
lose the guarantee that distinct type/domain/description tuples have a
differing index bit.
Allocate IDs lazily since private key types need not be registered. Cache
them in the index key so tree walks and copies of an existing index do not
need to dereference a type descriptor that may have been unregistered.
Keep the 32-bit chunk layout and diff_objects() bit offsets consistent,
and retain the separate root slot for keyrings used by recursive search.
The key comparison, permissions and userspace data format are unchanged;
only the address-dependent in-memory ordering is replaced. |
| In the Linux kernel, the following vulnerability has been resolved:
keys: Avoid the owner account dereference in named keyring lookup
Named keyring lookup must keep the storage containing the owner UID
alive through the namespace mapping check. find_keyring_by_name()
reads keyring->user->uid under keyring_name_lock, but that lock protects
the keyring's name entry and allocation, not its separate key_user.
A named session-keyring join can overlap a privileged KEYCTL_CHOWN on
another CPU. If the keyring holds the last reference to its old dynamic
key_user and the ownership transfer succeeds, the following ordering is
possible:
Named join Chown
find_keyring_by_name() keyctl_chown_key()
read_lock(keyring_name_lock) down_write(key->sem)
load old keyring->user
replace key->user and key->uid
up_write(key->sem)
key_put(key)
key_user_put(old user): free
read old user->uid
read_unlock(keyring_name_lock)
Chown neither takes keyring_name_lock nor key_session_mutex, so it can
free the old account between the pointer load and the UID read. The
lookup then reads freed memory even though the keyring itself is alive.
Use keyring->uid for the mapping check. key_alloc() initializes this
inline owner UID and keyctl_chown_key() updates it on chown.
The existing name lock keeps its containing keyring allocated throughout
the check, so lookup no longer depends on the account's lifetime. This
also matches the owner UID used by the permission check.
KASAN report as below:
BUG: KASAN: slab-use-after-free in find_keyring_by_name+0x577/0x5d0
Read of size 4 at addr ffff8881128ae2ec by task keycase/500 |
| In the Linux kernel, the following vulnerability has been resolved:
io_uring/cmd: don't leave list poison in ->hash_node
io_uring_cmd_del_cancelable() uses hlist_del() to take a command off
->cancelable_uring_cmd, which leaves LIST_POISON1/2 behind in
->hash_node. Requests are recycled through the request cache without
being reinitialised, and not every user of ->hash_node sets it up before
it is used:
If a vectored futex wait is woken while futex_wait_multiple_setup() is
still queueing the futexes, io_futexv_wait() doesn't add the request to
->futex_list, and leaves the completion to the task_work queued by the
wake up. io_futexv_complete() ends in __io_futex_complete(), whose
hlist_del_init() is fine for a request that is unhashed, which is how all
other users of the node leave it. If the request was a cancelable
uring_cmd in its previous life, e.g. a ublk FETCH_REQ, it writes through
LIST_POISON2:
Oops: general protection fault, probably for non-canonical address
KASAN: maybe wild-memory-access in range [0xdead000000000120-...]
RIP: 0010:io_futexv_complete+0x219/0x420
Call Trace:
tctx_task_work_run+0x804/0x950
tctx_task_work+0x71/0xa0
task_work_run+0x118/0x200
Leave the node unhashed. |
| In the Linux kernel, the following vulnerability has been resolved:
io_uring/waitid: own the request before clearing ->head
io_waitid_remove_wq() only takes the wait queue lock if ->head is set.
io_waitid_wait() clears ->head first thing, before it tries to become the
owner of the request by bumping ->refs. If somebody else owns the request
at that point, nothing keeps it from completing the request while the
wake up handler is still going to touch it:
CPU0 (io_waitid_wait) CPU1 (io_waitid, holds a ref)
list_del_init(&wait->entry)
smp_store_release(&iw->head, NULL)
__do_wait() finds another child
io_waitid_remove_wq()
// ->head == NULL, no locking
io_waitid_finish(), IOU_COMPLETE
// request freed and reused
atomic_fetch_inc(&iw->refs)
The same goes for __io_waitid_cancel() if it claims the request in that
window. ->refs is part of the per opcode data of the request, so this
increments whatever the next user of the request keeps there. If that
happens to be zero, the handler concludes that it owns the request, and
queues io_waitid_cb() for it. With the window held open by a delay, and
the request reused for a receive that is waiting for data:
BUG: KASAN: slab-use-after-free in __wake_up_common+0x1ca/0x1f0
__wake_up_sync_key+0x36/0x50
sock_def_readable+0xf1/0x420
unix_stream_sendmsg+0x60b/0x1110
Allocated by task 87:
io_arm_apoll+0x1ed/0x940
Freed by task 87:
__io_submit_flush_completions+0x118d/0x1a10
tctx_task_work_run+0x327/0x950
Only clear ->head once the handler owns the request. If it doesn't, the
owner finds ->head set and has to wait for the lock, which is held by the
caller of the handler. Deleting the already deleted entry again is
harmless. |
| In the Linux kernel, the following vulnerability has been resolved:
tracing: Unregister field variable histograms when the command fails
An action that names a field on another event needs that field as a
variable, so create_field_var_hist() registers a second hist trigger on
that event to provide it, and records it in
target_hist_data->field_var_hists[].
If a later part of the same command fails, create_actions() returns an
error and event_hist_trigger_parse() jumps to out_free. The write fails
with -EINVAL and sched_switch gets no trigger, but:
# echo 'hist:keys=pid:ts0=common_timestamp.usecs' >> \
events/sched/sched_waking/trigger
# echo 'my_synth u64 lat; int a; int b' >> synthetic_events
# echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:\
onmatch(sched.sched_waking).my_synth($wakeup_lat,prio,nosuchfld)'\
>> events/sched/sched_switch/trigger
# cat events/sched/sched_waking/trigger
hist:keys=pid:vals=hitcount:ts0=common_timestamp.usecs:sort=hitcount:size=2048:clock=global [active]
hist:keys=pid:vals=hitcount:synthetic_prio=prio:sort=hitcount:size=2048 [active]
The second histogram is the one created for 'prio'. It is still active and
still counting.
out_free reaches destroy_field_var_hists(), which frees the
field_var_hists[] entries, but never unregister_field_var_hists(), which is
what removes the triggers and runs only from event_hist_trigger_free(). The
entry is freed and the trigger is left with nothing tracking it.
Unregister the field variable histograms in out_free as well, and record
each one as soon as its trigger is registered rather than after the lookup
that follows it, so no exit can leave a registered trigger untracked. The
entry then belongs to field_var_hists[] and is released by
destroy_field_var_hists(), so freeing it on that exit would be a double
free. |
| In the Linux kernel, the following vulnerability has been resolved:
io_uring/waitid: prevent cancel reference wrap
io_waitid packs the cancellation state into bit 31 of ->refs and uses
bits 30:0 as a 31-bit reference counter:
#define IO_WAITID_CANCEL_FLAG BIT(31)
#define IO_WAITID_REF_MASK GENMASK(30, 0)
__io_waitid_cancel() marks a request canceled, then increments the low
bits of ->refs to claim completion ownership. When another path owns the
request, the increment remains even though cancellation returns false.
The request remains discoverable by cancellation, so repeated failed
attempts can wrap the 31-bit reference field to zero. A later
cancellation can claim ownership and complete the request a second time.
Use atomic_fetch_or() when setting the cancel flag and inspect the old
flag value. The first cancel attempt continues to the existing ownership
increment, preserving its wake and issuer handoff semantics. Later
attempts see the cancel flag and return without incrementing the
reference field.
This makes repeated failed cancellation attempts idempotent while
leaving the first-cancel state transitions unchanged. |
| In the Linux kernel, the following vulnerability has been resolved:
io_uring/io-wq: don't lose the signal that ends work
When a thread exits, only its tracked requests are cancelled. Then its
io-wq is torn down. io_wq_exit_workers() signals every worker, to get it
out of an interruptible sleep, and waits for all of them to exit. Before
they do, they go through the work that is left. Unbounded work is
cancelled. Bounded work is run, as it is expected to end by itself.
Not all of it does. An open has no file yet, so it counts as bounded, and
the open of a FIFO waits for the other end. That is what the signal is for.
But the workers are signalled once, and a worker that hasn't started the
work by then loses the signal:
io_wq_exit_workers() io_worker_handle_work()
io_wq_worker_wake()
set TIF_NOTIFY_SIGNAL
io_assign_current_work()
io_run_task_work()
clear TIF_NOTIFY_SIGNAL
io_wq_submit_work()
fifo_open()
wait_for_partner()
wait_for_completion_timeout()
The thread never gets out of do_exit():
IORING_OP_OPENAT of a FIFO without a writer, IOSQE_ASYNC
exit of the thread that has submitted it
hangs in more than 9 of 10 attempts (4 CPUs, KVM), until the process is
killed.
Set TIF_NOTIFY_SIGNAL for bounded work that is started with IO_WQ_BIT_EXIT
set. The bit is set before the workers are signalled, and it is tested
after the flag has been cleared, with clear_notify_signal() providing the
barrier. So either the flag stays, or the bit is seen.
Work that is started while the io-wq exits is treated like work that is
being run at that time: it isn't interrupted unless it waits
interruptibly. |
| In the Linux kernel, the following vulnerability has been resolved:
fork: release the files of a failed fork after sched_cancel_fork()
Reorder copy_process() cleanup so sched_fork() taking scx_fork_rwsem
scx_pre_fork() is safe and isn't held around exiting files. Right now, a
fork that fails while another thread closed the bpf link fd will
deadlock against its own read side. It also blocks every fork on the
system:
copy_process() holds scx_fork_rwsem for read
exit_files()
close_files()
filp_close_sync()
bpf_scx_unreg()
kthread_flush_work() waits for the disable work
scx_root_disable()
percpu_down_write(&scx_fork_rwsem)
Simply release the child's files after sched_cancel_fork() dropped the
lock. The task starts out as a copy of its parent so p->files points to
the parent's table until copy_files() replaces it. exit_files() must not
run for a fork that failed before that. Clear p->files up front so
exit_files() is a no-op for those and make copy_files() set it
explicitly for CLONE_FILES. |
| In the Linux kernel, the following vulnerability has been resolved:
coredump: hold RCU while releasing parked threads
coredump_finish() releases the parked threads by clearing ->task in
their core_thread entry and calling wake_up_process() on each of them.
It does that without holding a reference on the task and without being
inside rcu.
But calling wake_up_process(task) without rcu here isn't safe. A parked
thread doesn't need that wakeup to leave. A spurious wakeup or a
preemption after the store is enough for the task to go away.
So if the coredump client is preempted between the store and
wake_up_process() the thread can exit and be freed in the meantime and
try_to_wake_up() takes pi_lock in freed memory.
Hold rcu across the loop. |
| In the Linux kernel, the following vulnerability has been resolved:
perf: Fix perf_pmu_migrate_context() leaving events behind
__perf_pmu_remove() walks the group leaders of a CPU and PMU with
perf_event_groups_for_cpu_pmu(), removing each one as it goes.
perf_remove_from_context() takes the leader out of the groups rbtree,
after which rb_next() on that node returns NULL, prematurely ending the
walk. Other groups stay behind in the source context.
On CPU hotplug, they are then torn down with the dying CPU. They keep
running until teardown, while the PMU's interrupt and migrated events
are on a new CPU, which drivers rely on never happening.
Walk ctx->event_list instead and pick out the PMU's events by their
pmu_ctx. |
| In the Linux kernel, the following vulnerability has been resolved:
gpio: mxc: fix race between chained IRQ handler install and probe completion
mxc_update_irq_chained_handler() is called before the IRQ domain, the
generic IRQ chip, and the port list entry are set up. If an interrupt
arrives in that window:
- mx3_gpio_irq_handler() calls generic_handle_domain_irq() with
port->domain still NULL.
- mx2_gpio_irq_handler() walks mxc_gpio_ports, but the port has not
been added to the list yet.
Additionally, if any of the subsequent probe steps
(gpio_generic_chip_init(), devm_gpiochip_add_data(),
irq_domain_create_legacy(), or mxc_gpio_init_gc()) fail, the error
paths never unregister the chained handler, leaving a dangling handler
that points at freed memory.
Move the handler installation after all its dependencies are ready and
after list_add_tail(), so the handler is never live while the data
structures it touches are incomplete, and is never installed if probe
fails. |
| In the Linux kernel, the following vulnerability has been resolved:
autofs: ignore notification errors from a replaced pipe
autofs_notify_daemon() takes a reference to the current notification
pipe under wq_mutex, then drops the mutex before writing the request. The
write can block while the daemon enters catatonic mode and installs a
replacement pipe.
If the old pipe's reader is then closed, the delayed write returns -EPIPE
and the generic error path enters catatonic mode again. That transition
acts on the current superblock state, closes the replacement pipe, and
releases the new daemon generation's wait queues.
Only enter catatonic mode when the pipe which failed is still the current
pipe. Factor the already-locked transition so the identity check and state
change are atomic with respect to another replacement.
This was reproduced on v7.3-rc5-337-gff47652a4b66c in a local QEMU guest.
An unprivileged UID 65534 lookup filled the old packet pipe before a
normal CATATONIC/SETPIPEFD restart. On the unmodified kernel, the new pipe
received HUP and both a pending victim lookup and a later lookup failed
with ENOENT in two out of two fresh-mount runs.
With this change, the new pipe remained active, received an intact
304-byte request, and both victim lookups completed in two out of two
runs. Normal lookup and restart-without-a-blocked-writer controls passed.
No KASAN, oops, refcount, or lock diagnostic was observed. A source
reproducer and complete local logs are available privately on request.
The demonstrated impact is limited to denial of a shared autofs service
during a legitimate daemon restart. No memory corruption, information leak,
privilege escalation, or code execution primitive was observed. |
| In the Linux kernel, the following vulnerability has been resolved:
net: bcmgenet: unshare the skb before writing the control block
bcmgenet stores first_cb, last_cb and bytes_sent in the skb control
block and reads them back on completion to free the skb and credit BQL.
ether_setup() leaves IFF_TX_SKB_SHARING set, so the stack can resubmit
a shared skb that is still in the ring. The next transmit overwrites
last_cb, so the earlier slots complete without crediting their bytes
and BQL stalls the queue until the watchdog resets it.
Unshare the skb before writing the control block.
Reproduce with pktgen in clone_skb mode, which hands the driver the same
skb while earlier copies are still in the ring:
modprobe pktgen
pg=/proc/net/pktgen
echo "add_device eth0" > $pg/kpktgend_0
echo "dst_mac AA:BB:CC:DD:EE:FF" > $pg/eth0
echo "dst 192.0.2.1" > $pg/eth0
echo "clone_skb 8" > $pg/eth0
echo "count 0" > $pg/eth0
echo start > $pg/pgctrl &
sleep 5
echo stop > $pg/pgctrl
wait
cat /sys/class/net/eth0/queues/tx-0/byte_queue_limits/inflight
inflight stays nonzero on the now idle queue. clone_skb 0 leaves it at
zero. |
| In the Linux kernel, the following vulnerability has been resolved:
scsi: libsas: Fix SMP IO deadlock during HA resume
smp_execute_task_sg() calls pm_runtime_get_sync() on the host before
issuing an SMP command. When that command is itself issued from the HA
resume path, the get_sync() deadlocks: it waits for the ongoing resume
(the device is RPM_RESUMING), while the resume is blocked in
sas_drain_work() waiting for that same SMP IO to complete.
The deadlock needs an expander-attached SATA disk. During
sas_resume_ha() -> sas_drain_work(), DISCE_RESUME -> sas_resume_sata()
-> ata_sas_port_resume() requests ATA_EH_RESET, and the hard reset for
such a disk is done via SMP PHY CONTROL (sas_ata_hard_reset() ->
sas_phy_reset() -> sas_smp_phy_control() ->
smp_execute_task_sg()). Direct-attached SATA resets through
lldd_control_phy() and SSP devices use TMFs, so neither hits this.
Replace the get_sync()/put_sync() pair with
pm_runtime_get_noresume()/pm_runtime_put(). smp_execute_task_sg() only
needs to hold off autosuspend while the SMP is in flight, and it must
not try to resume the host: a sync resume issued from the HA resume path
itself is what deadlocks, and by the time sas_resume_ha() runs, hw_init
has already reinitialized the hardware, so the device is accessible
without one.
The usage reference is still required. Discovery work normally runs
inside an event worker's PM reference, taken at sas_notify_port_event()
notify time and held until the handler has flushed the disco
queue. sas_rediscover_ex_phy() however requeues DISCE_REVALIDATE_DOMAIN
from within the revalidation worker itself, and flush_workqueue() does
not wait for work items queued during execution, so that chained
revalidation runs with no outer PM reference - without the
get_noresume(), its SMP could race autosuspend.
For the BSG path, sas_smp_handler() is the only caller which may find
the host autosuspended: expander SMP requests do not go through any SCSI
device request queue, so nothing else in that path holds the host
awake. Resume it there with pm_runtime_resume_and_get() and check the
result. |
| In the Linux kernel, the following vulnerability has been resolved:
ring-buffer: Fix the sub-buffer array base in rb_meta_subbuf_idx()
On a persistent ring buffer, rb_meta_subbuf_idx() can return an index one
sub-buffer too high. rb_setup_ids_meta_page() then fills subbuf_ids[]
shifted by one and leaves subbuf_ids[0] NULL, which __rb_map_vma()
dereferences when userspace maps trace_pipe_raw. rb_update_meta_reader()
writes two such indices into meta->buffers[], which rb_cpu_meta_valid()
would reject on the next boot, discarding the previous boot's trace.
A CPU's sub-buffer array starts after its meta header and the nr_subbufs
integers that follow, aligned up to a sub-buffer. rb_meta_subbuf_idx()
inverts that calculation but skips only the integers, not the header, so
its base is one sub-buffer low whenever the omitted header size crosses
the alignment boundary.
Invert the calculation with rb_subbufs_from_meta() rather than repeating
it. rb_range_buffer() maps an index back to an address through the same
helper, so the two directions can no longer disagree. |
| In the Linux kernel, the following vulnerability has been resolved:
scsi: libiscsi: Reject a negative task index from parse_pdu_itt
A transport that implements parse_pdu_itt hands libiscsi an index taken
from the PDU, and both lookups bound it from above only:
if (i >= session->cmds_max)
i and cmds_max are both int, so a negative index passes and
session->cmds[i] is read from before the array.
be2iscsi produces one. beiscsi_parse_pdu() assigns the raw tag,
*index = (int)itt;
and beiscsi_complete_pdu() forwards an unsolicited NOP-In from the
hardware async ring without replacing its ITT, so the value is the
target's. It also reports the session's own age rather than the one in
the tag, which leaves the age comparison in iscsi_verify_itt() with
nothing to reject.
Bound the index from below in both lookups. |
| In the Linux kernel, the following vulnerability has been resolved:
scsi: st: Fix use-after-free race between st_remove() and st_open()
st_remove() drops the probe reference on the scsi_tape with kref_put()
and only afterwards removes its index from st_index_idr. If that was the
last reference, scsi_tape_release() frees the structure while it is
still published in the idr.
scsi_tape_get(), called from st_open(), looks up the tape in
st_index_idr and takes a reference under st_ref_mutex and
st_index_lock. remove_cdevs() does not wait for opens that are already
past chrdev_open(), so an open that is blocked on st_ref_mutex while
st_remove() holds it can take the mutex as soon as st_remove() drops it,
find the freed tpnt in the idr and call kref_get() on it:
BUG: KASAN: slab-use-after-free in st_open
Write of size 4 ...
st_open (drivers/scsi/st.c:254 drivers/scsi/st.c:1291)
chrdev_open
...
Freed by task ...:
kfree
st_remove (drivers/scsi/st.c:4512)
Remove the index from the idr before dropping the reference, all under
st_ref_mutex. A concurrent scsi_tape_get() now either runs first and
holds a valid reference that keeps the tape alive, or runs afterwards
and finds nothing, so st_open() fails with -ENXIO.
This restores the ordering st_remove() had before the conversion to
st_index_idr, where the tape was unpublished from scsi_tapes[] before
the final kref_put(). |
| In the Linux kernel, the following vulnerability has been resolved:
ring-buffer: Fix false warning in ring_buffer_map_get_reader()
The mmap reader can warn when it catches up with a writer that is still
committing events. rb_get_reader_page() returns NULL in this case, but
ring_buffer_map_get_reader() treats that result as an error.
The initial rb_per_cpu_empty() check filters out an empty buffer, but it
does not guarantee that the next reader page has committed data. Writers
do not take reader_lock and can advance commit_page before publishing the
committed length on the new page. rb_get_reader_page() can swap to that
page, catch up with the writer and return NULL.
Handle NULL through the existing no-data exit without warning. Remove the
caller's reader_page == commit_page check as well, since the reader-page
helper already handles that case. The existing metadata update and return
path remain in place. |