In the Linux kernel, the following vulnerability has been resolved:
mptcp: fix slab-use-after-free in __inet_lookup_established
The ehash table lookups are lockless and rely on
SLAB_TYPESAFE_BY_RCU to guarantee socket...Show moreIn the Linux kernel, the following vulnerability has been resolved:
mptcp: fix slab-use-after-free in __inet_lookup_established
The ehash table lookups are lockless and rely on
SLAB_TYPESAFE_BY_RCU to guarantee socket memory stability
during RCU read-side critical sections. Both tcp_prot and
tcpv6_prot have their slab caches created with this flag
via proto_register().
However, MPTCP's mptcp_subflow_init() copies tcpv6_prot into
tcpv6_prot_override during inet_init() (fs_initcall, level 5),
before inet6_init() (module_init/device_initcall, level 6) has
called proto_register(&tcpv6_prot). At that point,
tcpv6_prot.slab is still NULL, so tcpv6_prot_override.slab
remains NULL permanently.
This causes MPTCP v6 subflow child sockets to be allocated via
kmalloc (falling into kmalloc-4k) instead of the TCPv6 slab
cache. The kmalloc-4k cache lacks SLAB_TYPESAFE_BY_RCU, so
when these sockets are freed without SOCK_RCU_FREE (which is
cleared for child sockets by design), the memory can be
immediately reused. Concurrent ehash lookups under
rcu_read_lock can then access freed memory, triggering a
slab-use-after-free in __inet_lookup_established.
Fix this by splitting the IPv6-specific initialization out of
mptcp_subflow_init() into a new mptcp_subflow_v6_init(), called
from mptcp_proto_v6_init() before protocol registration. This
ensures tcpv6_prot_override.slab correctly inherits the
SLAB_TYPESAFE_BY_RCU slab cache.Show less |
In the Linux kernel, the following vulnerability has been resolved:
netfilter: nft_ct: fix use-after-free in timeout object destroy
nft_ct_timeout_obj_destroy() frees the timeout object with kfree()
immediately after n...Show moreIn the Linux kernel, the following vulnerability has been resolved:
netfilter: nft_ct: fix use-after-free in timeout object destroy
nft_ct_timeout_obj_destroy() frees the timeout object with kfree()
immediately after nf_ct_untimeout(), without waiting for an RCU grace
period. Concurrent packet processing on other CPUs may still hold
RCU-protected references to the timeout object obtained via
rcu_dereference() in nf_ct_timeout_data().
Add an rcu_head to struct nf_ct_timeout and use kfree_rcu() to defer
freeing until after an RCU grace period, matching the approach already
used in nfnetlink_cttimeout.c.
KASAN report:
BUG: KASAN: slab-use-after-free in nf_conntrack_tcp_packet+0x1381/0x29d0
Read of size 4 at addr ffff8881035fe19c by task exploit/80
Call Trace:
nf_conntrack_tcp_packet+0x1381/0x29d0
nf_conntrack_in+0x612/0x8b0
nf_hook_slow+0x70/0x100
__ip_local_out+0x1b2/0x210
tcp_sendmsg_locked+0x722/0x1580
__sys_sendto+0x2d8/0x320
Allocated by task 75:
nft_ct_timeout_obj_init+0xf6/0x290
nft_obj_init+0x107/0x1b0
nf_tables_newobj+0x680/0x9c0
nfnetlink_rcv_batch+0xc29/0xe00
Freed by task 26:
nft_obj_destroy+0x3f/0xa0
nf_tables_trans_destroy_work+0x51c/0x5c0
process_one_work+0x2c4/0x5a0Show less |
In the Linux kernel, the following vulnerability has been resolved:
mm/damon/stat: deallocate damon_call() failure leaking damon_ctx
damon_stat_start() always allocates the module's damon_ctx object
(damon_stat_context...Show moreIn the Linux kernel, the following vulnerability has been resolved:
mm/damon/stat: deallocate damon_call() failure leaking damon_ctx
damon_stat_start() always allocates the module's damon_ctx object
(damon_stat_context). Meanwhile, if damon_call() in the function fails,
the damon_ctx object is not deallocated. Hence, if the damon_call() is
failed, and the user writes Y to “enabled” again, the previously
allocated damon_ctx object is leaked.
This cannot simply be fixed by deallocating the damon_ctx object when
damon_call() fails. That's because damon_call() failure doesn't guarantee
the kdamond main function, which accesses the damon_ctx object, is
completely finished. In other words, if damon_stat_start() deallocates
the damon_ctx object after damon_call() failure, the not-yet-terminated
kdamond could access the freed memory (use-after-free).
Fix the leak while avoiding the use-after-free by keeping returning
damon_stat_start() without deallocating the damon_ctx object after
damon_call() failure, but deallocating it when the function is invoked
again and the kdamond is completely terminated. If the kdamond is not yet
terminated, simply return -EAGAIN, as the kdamond will soon be terminated.
The issue was discovered [1] by sashiko.Show less |
In the Linux kernel, the following vulnerability has been resolved:
mmc: vub300: fix use-after-free on disconnect
The vub300 driver maintains an explicit reference count for the
controller and its driver data and the l...Show moreIn the Linux kernel, the following vulnerability has been resolved:
mmc: vub300: fix use-after-free on disconnect
The vub300 driver maintains an explicit reference count for the
controller and its driver data and the last reference can in theory be
dropped after the driver has been unbound.
This specifically means that the controller allocation must not be
device managed as that can lead to use-after-free.
Note that the lifetime is currently also incorrectly tied the parent USB
device rather than interface, which can lead to memory leaks if the
driver is unbound without its device being physically disconnected (e.g.
on probe deferral).
Fix both issues by reverting to non-managed allocation of the controller.Show less |
In the Linux kernel, the following vulnerability has been resolved:
net: lan966x: fix use-after-free and leak in lan966x_fdma_reload()
When lan966x_fdma_reload() fails to allocate new RX buffers, the restore
path resta...Show moreIn the Linux kernel, the following vulnerability has been resolved:
net: lan966x: fix use-after-free and leak in lan966x_fdma_reload()
When lan966x_fdma_reload() fails to allocate new RX buffers, the restore
path restarts DMA using old descriptors whose pages were already freed
via lan966x_fdma_rx_free_pages(). Since page_pool_put_full_page() can
release pages back to the buddy allocator, the hardware may DMA into
memory now owned by other kernel subsystems.
Additionally, on the restore path, the newly created page pool (if
allocation partially succeeded) is overwritten without being destroyed,
leaking it.
Fix both issues by deferring the release of old pages until after the
new allocation succeeds. Save the old page array before the allocation
so old pages can be freed on the success path. On the failure path, the
old descriptors, pages and page pool are all still valid, making the
restore safe. Also ensure the restore path re-enables NAPI and wakes
the netdev, matching the success path.Show less |
In the Linux kernel, the following vulnerability has been resolved:
ocfs2: fix use-after-free in ocfs2_fault() when VM_FAULT_RETRY
filemap_fault() may drop the mmap_lock before returning VM_FAULT_RETRY,
as documented i...Show moreIn the Linux kernel, the following vulnerability has been resolved:
ocfs2: fix use-after-free in ocfs2_fault() when VM_FAULT_RETRY
filemap_fault() may drop the mmap_lock before returning VM_FAULT_RETRY,
as documented in mm/filemap.c:
"If our return value has VM_FAULT_RETRY set, it's because the mmap_lock
may be dropped before doing I/O or by lock_folio_maybe_drop_mmap()."
When this happens, a concurrent munmap() can call remove_vma() and free
the vm_area_struct via RCU. The saved 'vma' pointer in ocfs2_fault() then
becomes a dangling pointer, and the subsequent trace_ocfs2_fault() call
dereferences it -- a use-after-free.
Fix this by saving ip_blkno as a plain integer before calling
filemap_fault(), and removing vma from the trace event. Since
ip_blkno is copied by value before the lock can be dropped, it
remains valid regardless of what happens to the vma or inode
afterward.Show less |
In the Linux kernel, the following vulnerability has been resolved:
mm: call ->free_folio() directly in folio_unmap_invalidate()
We can only call filemap_free_folio() if we have a reference to (or hold a
lock on) the m...Show moreIn the Linux kernel, the following vulnerability has been resolved:
mm: call ->free_folio() directly in folio_unmap_invalidate()
We can only call filemap_free_folio() if we have a reference to (or hold a
lock on) the mapping. Otherwise, we've already removed the folio from the
mapping so it no longer pins the mapping and the mapping can be removed,
causing a use-after-free when accessing mapping->a_ops.
Follow the same pattern as __remove_mapping() and load the free_folio
function pointer before dropping the lock on the mapping. That lets us
make filemap_free_folio() static as this was the only caller outside
filemap.c.Show less |
In the Linux kernel, the following vulnerability has been resolved:
KVM: x86: Use scratch field in MMIO fragment to hold small write values
When exiting to userspace to service an emulated MMIO write, copy the
to-be-wr...Show moreIn the Linux kernel, the following vulnerability has been resolved:
KVM: x86: Use scratch field in MMIO fragment to hold small write values
When exiting to userspace to service an emulated MMIO write, copy the
to-be-written value to a scratch field in the MMIO fragment if the size
of the data payload is 8 bytes or less, i.e. can fit in a single chunk,
instead of pointing the fragment directly at the source value.
This fixes a class of use-after-free bugs that occur when the emulator
initiates a write using an on-stack, local variable as the source, the
write splits a page boundary, *and* both pages are MMIO pages. Because
KVM's ABI only allows for physically contiguous MMIO requests, accesses
that split MMIO pages are separated into two fragments, and are sent to
userspace one at a time. When KVM attempts to complete userspace MMIO in
response to KVM_RUN after the first fragment, KVM will detect the second
fragment and generate a second userspace exit, and reference the on-stack
variable.
The issue is most visible if the second KVM_RUN is performed by a separate
task, in which case the stack of the initiating task can show up as truly
freed data.
==================================================================
BUG: KASAN: use-after-free in complete_emulated_mmio+0x305/0x420
Read of size 1 at addr ffff888009c378d1 by task syz-executor417/984
CPU: 1 PID: 984 Comm: syz-executor417 Not tainted 5.10.0-182.0.0.95.h2627.eulerosv2r13.x86_64 #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 Call Trace:
dump_stack+0xbe/0xfd
print_address_description.constprop.0+0x19/0x170
__kasan_report.cold+0x6c/0x84
kasan_report+0x3a/0x50
check_memory_region+0xfd/0x1f0
memcpy+0x20/0x60
complete_emulated_mmio+0x305/0x420
kvm_arch_vcpu_ioctl_run+0x63f/0x6d0
kvm_vcpu_ioctl+0x413/0xb20
__se_sys_ioctl+0x111/0x160
do_syscall_64+0x30/0x40
entry_SYSCALL_64_after_hwframe+0x67/0xd1
RIP: 0033:0x42477d
Code: <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007faa8e6890e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00000000004d7338 RCX: 000000000042477d
RDX: 0000000000000000 RSI: 000000000000ae80 RDI: 0000000000000005
RBP: 00000000004d7330 R08: 00007fff28d546df R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00000000004d733c
R13: 0000000000000000 R14: 000000000040a200 R15: 00007fff28d54720
The buggy address belongs to the page:
page:0000000029f6a428 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x9c37
flags: 0xfffffc0000000(node=0|zone=1|lastcpupid=0x1fffff)
raw: 000fffffc0000000 0000000000000000 ffffea0000270dc8 0000000000000000
raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff888009c37780: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ffff888009c37800: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>ffff888009c37880: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
^
ffff888009c37900: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ffff888009c37980: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
==================================================================
The bug can also be reproduced with a targeted KVM-Unit-Test by hacking
KVM to fill a large on-stack variable in complete_emulated_mmio(), i.e. by
overwrite the data value with garbage.
Limit the use of the scratch fields to 8-byte or smaller accesses, and to
just writes, as larger accesses and reads are not affected thanks to
implementation details in the emulator, but add a sanity check to ensure
those details don't change in the future. Specifically, KVM never uses
on-stack variables for accesses larger that 8 bytes, e.g. uses an operand
in the emulator context, and *al
---truncated---Show less |
In the Linux kernel, the following vulnerability has been resolved:
ASoC: qcom: q6apm: move component registration to unmanaged version
q6apm component registers dais dynamically from ASoC toplology, which
are allocate...Show moreIn the Linux kernel, the following vulnerability has been resolved:
ASoC: qcom: q6apm: move component registration to unmanaged version
q6apm component registers dais dynamically from ASoC toplology, which
are allocated using device managed version apis. Allocating both
component and dynamic dais using managed version could lead to incorrect
free ordering, dai will be freed while component still holding references
to it.
Fix this issue by moving component to unmanged version so
that the dai pointers are only freeded after the component is removed.
==================================================================
BUG: KASAN: slab-use-after-free in snd_soc_del_component_unlocked+0x3d4/0x400 [snd_soc_core]
Read of size 8 at addr ffff00084493a6e8 by task kworker/u48:0/3426
Tainted: [W]=WARN
Hardware name: LENOVO 21N2ZC5PUS/21N2ZC5PUS, BIOS N42ET57W (1.31 ) 08/08/2024
Workqueue: pdr_notifier_wq pdr_notifier_work [pdr_interface]
Call trace:
show_stack+0x28/0x7c (C)
dump_stack_lvl+0x60/0x80
print_report+0x160/0x4b4
kasan_report+0xac/0xfc
__asan_report_load8_noabort+0x20/0x34
snd_soc_del_component_unlocked+0x3d4/0x400 [snd_soc_core]
snd_soc_unregister_component_by_driver+0x50/0x88 [snd_soc_core]
devm_component_release+0x30/0x5c [snd_soc_core]
devres_release_all+0x13c/0x210
device_unbind_cleanup+0x20/0x190
device_release_driver_internal+0x350/0x468
device_release_driver+0x18/0x30
bus_remove_device+0x1a0/0x35c
device_del+0x314/0x7f0
device_unregister+0x20/0xbc
apr_remove_device+0x5c/0x7c [apr]
device_for_each_child+0xd8/0x160
apr_pd_status+0x7c/0xa8 [apr]
pdr_notifier_work+0x114/0x240 [pdr_interface]
process_one_work+0x500/0xb70
worker_thread+0x630/0xfb0
kthread+0x370/0x6c0
ret_from_fork+0x10/0x20
Allocated by task 77:
kasan_save_stack+0x40/0x68
kasan_save_track+0x20/0x40
kasan_save_alloc_info+0x44/0x58
__kasan_kmalloc+0xbc/0xdc
__kmalloc_node_track_caller_noprof+0x1f4/0x620
devm_kmalloc+0x7c/0x1c8
snd_soc_register_dai+0x50/0x4f0 [snd_soc_core]
soc_tplg_pcm_elems_load+0x55c/0x1eb8 [snd_soc_core]
snd_soc_tplg_component_load+0x4f8/0xb60 [snd_soc_core]
audioreach_tplg_init+0x124/0x1fc [snd_q6apm]
q6apm_audio_probe+0x10/0x1c [snd_q6apm]
snd_soc_component_probe+0x5c/0x118 [snd_soc_core]
soc_probe_component+0x44c/0xaf0 [snd_soc_core]
snd_soc_bind_card+0xad0/0x2370 [snd_soc_core]
snd_soc_register_card+0x3b0/0x4c0 [snd_soc_core]
devm_snd_soc_register_card+0x50/0xc8 [snd_soc_core]
x1e80100_platform_probe+0x208/0x368 [snd_soc_x1e80100]
platform_probe+0xc0/0x188
really_probe+0x188/0x804
__driver_probe_device+0x158/0x358
driver_probe_device+0x60/0x190
__device_attach_driver+0x16c/0x2a8
bus_for_each_drv+0x100/0x194
__device_attach+0x174/0x380
device_initial_probe+0x14/0x20
bus_probe_device+0x124/0x154
deferred_probe_work_func+0x140/0x220
process_one_work+0x500/0xb70
worker_thread+0x630/0xfb0
kthread+0x370/0x6c0
ret_from_fork+0x10/0x20
Freed by task 3426:
kasan_save_stack+0x40/0x68
kasan_save_track+0x20/0x40
__kasan_save_free_info+0x4c/0x80
__kasan_slab_free+0x78/0xa0
kfree+0x100/0x4a4
devres_release_all+0x144/0x210
device_unbind_cleanup+0x20/0x190
device_release_driver_internal+0x350/0x468
device_release_driver+0x18/0x30
bus_remove_device+0x1a0/0x35c
device_del+0x314/0x7f0
device_unregister+0x20/0xbc
apr_remove_device+0x5c/0x7c [apr]
device_for_each_child+0xd8/0x160
apr_pd_status+0x7c/0xa8 [apr]
pdr_notifier_work+0x114/0x240 [pdr_interface]
process_one_work+0x500/0xb70
worker_thread+0x630/0xfb0
kthread+0x370/0x6c0
ret_from_fork+0x10/0x20Show less |
In the Linux kernel, the following vulnerability has been resolved:
mm: blk-cgroup: fix use-after-free in cgwb_release_workfn()
cgwb_release_workfn() calls css_put(wb->blkcg_css) and then later accesses
wb->blkcg_css a...Show moreIn the Linux kernel, the following vulnerability has been resolved:
mm: blk-cgroup: fix use-after-free in cgwb_release_workfn()
cgwb_release_workfn() calls css_put(wb->blkcg_css) and then later accesses
wb->blkcg_css again via blkcg_unpin_online(). If css_put() drops the last
reference, the blkcg can be freed asynchronously (css_free_rwork_fn ->
blkcg_css_free -> kfree) before blkcg_unpin_online() dereferences the
pointer to access blkcg->online_pin, resulting in a use-after-free:
BUG: KASAN: slab-use-after-free in blkcg_unpin_online (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 block/blk-cgroup.c:1367)
Write of size 4 at addr ff11000117aa6160 by task kworker/71:1/531
Workqueue: cgwb_release cgwb_release_workfn
Call Trace:
<TASK>
blkcg_unpin_online (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 block/blk-cgroup.c:1367)
cgwb_release_workfn (mm/backing-dev.c:629)
process_scheduled_works (kernel/workqueue.c:3278 kernel/workqueue.c:3385)
Freed by task 1016:
kfree (./include/linux/kasan.h:235 mm/slub.c:2689 mm/slub.c:6246 mm/slub.c:6561)
css_free_rwork_fn (kernel/cgroup/cgroup.c:5542)
process_scheduled_works (kernel/workqueue.c:3302 kernel/workqueue.c:3385)
** Stack based on commit 66672af7a095 ("Add linux-next specific files
for 20260410")
I am seeing this crash sporadically in Meta fleet across multiple kernel
versions. A full reproducer is available at:
https://github.com/leitao/debug/blob/main/reproducers/repro_blkcg_uaf.sh
(The race window is narrow. To make it easily reproducible, inject a
msleep(100) between css_put() and blkcg_unpin_online() in
cgwb_release_workfn(). With that delay and a KASAN-enabled kernel, the
reproducer triggers the splat reliably in less than a second.)
Fix this by moving blkcg_unpin_online() before css_put(), so the
cgwb's CSS reference keeps the blkcg alive while blkcg_unpin_online()
accesses it.Show less |
In the Linux kernel, the following vulnerability has been resolved:
media: mediatek: vcodec: fix use-after-free in encoder release path
The fops_vcodec_release() function frees the context structure (ctx)
without first...Show moreIn the Linux kernel, the following vulnerability has been resolved:
media: mediatek: vcodec: fix use-after-free in encoder release path
The fops_vcodec_release() function frees the context structure (ctx)
without first cancelling any pending or running work in ctx->encode_work.
This creates a race window where the workqueue handler (mtk_venc_worker)
may still be accessing the context memory after it has been freed.
Race condition:
CPU 0 (release path) CPU 1 (workqueue)
--------------------- ------------------
fops_vcodec_release()
v4l2_m2m_ctx_release()
v4l2_m2m_cancel_job()
// waits for m2m job "done"
mtk_venc_worker()
v4l2_m2m_job_finish()
// m2m job "done"
// BUT worker still running!
// post-job_finish access:
other ctx dereferences
// UAF if ctx already freed
// returns (job "done")
kfree(ctx) // ctx freed
Root cause: The v4l2_m2m_ctx_release() only waits for the m2m job
lifecycle (via TRANS_RUNNING flag), not the workqueue lifecycle.
After v4l2_m2m_job_finish() is called, the m2m framework considers
the job complete and v4l2_m2m_ctx_release() returns, but the worker
function continues executing and may still access ctx.
The work is queued during encode operations via:
queue_work(ctx->dev->encode_workqueue, &ctx->encode_work)
The worker function accesses ctx->m2m_ctx, ctx->dev, and other ctx
fields even after calling v4l2_m2m_job_finish().
This vulnerability was confirmed with KASAN by running an instrumented
test module that widens the post-job_finish race window. KASAN detected:
BUG: KASAN: slab-use-after-free in mtk_venc_worker+0x159/0x180
Read of size 4 at addr ffff88800326e000 by task kworker/u8:0/12
Workqueue: mtk_vcodec_enc_wq mtk_venc_worker
Allocated by task 47:
__kasan_kmalloc+0x7f/0x90
fops_vcodec_open+0x85/0x1a0
Freed by task 47:
__kasan_slab_free+0x43/0x70
kfree+0xee/0x3a0
fops_vcodec_release+0xb7/0x190
Fix this by calling cancel_work_sync(&ctx->encode_work) before kfree(ctx).
This ensures the workqueue handler is both cancelled (if pending) and
synchronized (waits for any running handler to complete) before the
context is freed.
Placement rationale: The fix is placed after v4l2_ctrl_handler_free()
and before list_del_init(&ctx->list). At this point, all m2m operations
are done (v4l2_m2m_ctx_release() has returned), and we need to ensure
the workqueue is synchronized before removing ctx from the list and
freeing it.
Note: The open error path does NOT need cancel_work_sync() because
INIT_WORK() only initializes the work structure - it does not schedule
it. Work is only scheduled later during device_run() operations.Show less |
In the Linux kernel, the following vulnerability has been resolved:
media: em28xx: fix use-after-free in em28xx_v4l2_open()
em28xx_v4l2_open() reads dev->v4l2 without holding dev->lock,
creating a race with em28xx_v4l2...Show moreIn the Linux kernel, the following vulnerability has been resolved:
media: em28xx: fix use-after-free in em28xx_v4l2_open()
em28xx_v4l2_open() reads dev->v4l2 without holding dev->lock,
creating a race with em28xx_v4l2_init()'s error path and
em28xx_v4l2_fini(), both of which free the em28xx_v4l2 struct
and set dev->v4l2 to NULL under dev->lock.
This race leads to two issues:
- use-after-free in v4l2_fh_init() when accessing vdev->ctrl_handler,
since the video_device is embedded in the freed em28xx_v4l2 struct.
- NULL pointer dereference in em28xx_resolution_set() when accessing
v4l2->norm, since dev->v4l2 has been set to NULL.
Fix this by moving the mutex_lock() before the dev->v4l2 read and
adding a NULL check for dev->v4l2 under the lock.Show less |
In the Linux kernel, the following vulnerability has been resolved:
hwmon: (powerz) Fix use-after-free on USB disconnect
After powerz_disconnect() frees the URB and releases the mutex, a
subsequent powerz_read() call c...Show moreIn the Linux kernel, the following vulnerability has been resolved:
hwmon: (powerz) Fix use-after-free on USB disconnect
After powerz_disconnect() frees the URB and releases the mutex, a
subsequent powerz_read() call can acquire the mutex and call
powerz_read_data(), which dereferences the freed URB pointer.
Fix by:
- Setting priv->urb to NULL in powerz_disconnect() so that
powerz_read_data() can detect the disconnected state.
- Adding a !priv->urb check at the start of powerz_read_data()
to return -ENODEV on a disconnected device.
- Moving usb_set_intfdata() before hwmon registration so the
disconnect handler can always find the priv pointer.Show less |
In the Linux kernel, the following vulnerability has been resolved:
ALSA: 6fire: fix use-after-free on disconnect
In usb6fire_chip_abort(), the chip struct is allocated as the card's
private data (via snd_card_new with...Show moreIn the Linux kernel, the following vulnerability has been resolved:
ALSA: 6fire: fix use-after-free on disconnect
In usb6fire_chip_abort(), the chip struct is allocated as the card's
private data (via snd_card_new with sizeof(struct sfire_chip)). When
snd_card_free_when_closed() is called and no file handles are open, the
card and embedded chip are freed synchronously. The subsequent
chip->card = NULL write then hits freed slab memory.
Call trace:
usb6fire_chip_abort sound/usb/6fire/chip.c:59 [inline]
usb6fire_chip_disconnect+0x348/0x358 sound/usb/6fire/chip.c:182
usb_unbind_interface+0x1a8/0x88c drivers/usb/core/driver.c:458
...
hub_event+0x1a04/0x4518 drivers/usb/core/hub.c:5953
Fix by moving the card lifecycle out of usb6fire_chip_abort() and into
usb6fire_chip_disconnect(). The card pointer is saved in a local
before any teardown, snd_card_disconnect() is called first to prevent
new opens, URBs are aborted while chip is still valid, and
snd_card_free_when_closed() is called last so chip is never accessed
after the card may be freed.Show less |
In the Linux kernel, the following vulnerability has been resolved:
bcache: fix cached_dev.sb_bio use-after-free and crash
In our production environment, we have received multiple crash reports
regarding libceph, which...Show moreIn the Linux kernel, the following vulnerability has been resolved:
bcache: fix cached_dev.sb_bio use-after-free and crash
In our production environment, we have received multiple crash reports
regarding libceph, which have caught our attention:
```
[6888366.280350] Call Trace:
[6888366.280452] blk_update_request+0x14e/0x370
[6888366.280561] blk_mq_end_request+0x1a/0x130
[6888366.280671] rbd_img_handle_request+0x1a0/0x1b0 [rbd]
[6888366.280792] rbd_obj_handle_request+0x32/0x40 [rbd]
[6888366.280903] __complete_request+0x22/0x70 [libceph]
[6888366.281032] osd_dispatch+0x15e/0xb40 [libceph]
[6888366.281164] ? inet_recvmsg+0x5b/0xd0
[6888366.281272] ? ceph_tcp_recvmsg+0x6f/0xa0 [libceph]
[6888366.281405] ceph_con_process_message+0x79/0x140 [libceph]
[6888366.281534] ceph_con_v1_try_read+0x5d7/0xf30 [libceph]
[6888366.281661] ceph_con_workfn+0x329/0x680 [libceph]
```
After analyzing the coredump file, we found that the address of
dc->sb_bio has been freed. We know that cached_dev is only freed when it
is stopped.
Since sb_bio is a part of struct cached_dev, rather than an alloc every
time. If the device is stopped while writing to the superblock, the
released address will be accessed at endio.
This patch hopes to wait for sb_write to complete in cached_dev_free.
It should be noted that we analyzed the cause of the problem, then tell
all details to the QWEN and adopted the modifications it made.Show less |
In the Linux kernel, the following vulnerability has been resolved:
media: as102: fix to not free memory after the device is registered in as102_usb_probe()
In as102_usb driver, the following race condition occurs:
```...Show moreIn the Linux kernel, the following vulnerability has been resolved:
media: as102: fix to not free memory after the device is registered in as102_usb_probe()
In as102_usb driver, the following race condition occurs:
```
CPU0 CPU1
as102_usb_probe()
kzalloc(); // alloc as102_dev_t
....
usb_register_dev();
fd = sys_open("/path/to/dev"); // open as102 fd
....
usb_deregister_dev();
....
kfree(); // free as102_dev_t
....
sys_close(fd);
as102_release() // UAF!!
as102_usb_release()
kfree(); // DFB!!
```
When a USB character device registered with usb_register_dev() is later
unregistered (via usb_deregister_dev() or disconnect), the device node is
removed so new open() calls fail. However, file descriptors that are
already open do not go away immediately: they remain valid until the last
reference is dropped and the driver's .release() is invoked.
In as102, as102_usb_probe() calls usb_register_dev() and then, on an
error path, does usb_deregister_dev() and frees as102_dev_t right away.
If userspace raced a successful open() before the deregistration, that
open FD will later hit as102_release() --> as102_usb_release() and access
or free as102_dev_t again, occur a race to use-after-free and
double-free vuln.
The fix is to never kfree(as102_dev_t) directly once usb_register_dev()
has succeeded. After deregistration, defer freeing memory to .release().
In other words, let release() perform the last kfree when the final open
FD is closed.Show less |
In the Linux kernel, the following vulnerability has been resolved:
media: hackrf: fix to not free memory after the device is registered in hackrf_probe()
In hackrf driver, the following race condition occurs:
```
CP...Show moreIn the Linux kernel, the following vulnerability has been resolved:
media: hackrf: fix to not free memory after the device is registered in hackrf_probe()
In hackrf driver, the following race condition occurs:
```
CPU0 CPU1
hackrf_probe()
kzalloc(); // alloc hackrf_dev
....
v4l2_device_register();
....
fd = sys_open("/path/to/dev"); // open hackrf fd
....
v4l2_device_unregister();
....
kfree(); // free hackrf_dev
....
sys_ioctl(fd, ...);
v4l2_ioctl();
video_is_registered() // UAF!!
....
sys_close(fd);
v4l2_release() // UAF!!
hackrf_video_release()
kfree(); // DFB!!
```
When a V4L2 or video device is unregistered, the device node is removed so
new open() calls are blocked.
However, file descriptors that are already open-and any in-flight I/O-do
not terminate immediately; they remain valid until the last reference is
dropped and the driver's release() is invoked.
Therefore, freeing device memory on the error path after hackrf_probe()
has registered dev it will lead to a race to use-after-free vuln, since
those already-open handles haven't been released yet.
And since release() free memory too, race to use-after-free and
double-free vuln occur.
To prevent this, if device is registered from probe(), it should be
modified to free memory only through release() rather than calling
kfree() directly.Show less |
In the Linux kernel, the following vulnerability has been resolved:
drm/amdgpu: Fix fence put before wait in amdgpu_amdkfd_submit_ib
amdgpu_amdkfd_submit_ib() submits a GPU job and gets a fence
from amdgpu_ib_schedule(...Show moreIn the Linux kernel, the following vulnerability has been resolved:
drm/amdgpu: Fix fence put before wait in amdgpu_amdkfd_submit_ib
amdgpu_amdkfd_submit_ib() submits a GPU job and gets a fence
from amdgpu_ib_schedule(). This fence is used to wait for job
completion.
Currently, the code drops the fence reference using dma_fence_put()
before calling dma_fence_wait().
If dma_fence_put() releases the last reference, the fence may be
freed before dma_fence_wait() is called. This can lead to a
use-after-free.
Fix this by waiting on the fence first and releasing the reference
only after dma_fence_wait() completes.
Fixes the below:
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c:697 amdgpu_amdkfd_submit_ib() warn: passing freed memory 'f' (line 696)
(cherry picked from commit 8b9e5259adc385b61a6590a13b82ae0ac2bd3482)Show less |
In the Linux kernel, the following vulnerability has been resolved:
futex: Require sys_futex_requeue() to have identical flags
Nicholas reported that his LLM found it was possible to create a UaF
when sys_futex_requeue...Show moreIn the Linux kernel, the following vulnerability has been resolved:
futex: Require sys_futex_requeue() to have identical flags
Nicholas reported that his LLM found it was possible to create a UaF
when sys_futex_requeue() is used with different flags. The initial
motivation for allowing different flags was the variable sized futex,
but since that hasn't been merged (yet), simply mandate the flags are
identical, as is the case for the old style sys_futex() requeue
operations.Show less |
In the Linux kernel, the following vulnerability has been resolved:
tracing: Fix trace_marker copy link list updates
When the "copy_trace_marker" option is enabled for an instance, anything
written into /sys/kernel/tra...Show moreIn the Linux kernel, the following vulnerability has been resolved:
tracing: Fix trace_marker copy link list updates
When the "copy_trace_marker" option is enabled for an instance, anything
written into /sys/kernel/tracing/trace_marker is also copied into that
instances buffer. When the option is set, that instance's trace_array
descriptor is added to the marker_copies link list. This list is protected
by RCU, as all iterations uses an RCU protected list traversal.
When the instance is deleted, all the flags that were enabled are cleared.
This also clears the copy_trace_marker flag and removes the trace_array
descriptor from the list.
The issue is after the flags are called, a direct call to
update_marker_trace() is performed to clear the flag. This function
returns true if the state of the flag changed and false otherwise. If it
returns true here, synchronize_rcu() is called to make sure all readers
see that its removed from the list.
But since the flag was already cleared, the state does not change and the
synchronization is never called, leaving a possible UAF bug.
Move the clearing of all flags below the updating of the copy_trace_marker
option which then makes sure the synchronization is performed.
Also use the flag for checking the state in update_marker_trace() instead
of looking at if the list is empty.Show less |