Linux Linux vulnerabilities
🔔 Create alert RSS Version checker
Published CVEs affecting Linux Linux: 10814 record(s), with affected versions and fixes.
CVE-2026-89814
High · 7.8
Sep 16, 2026
drm/amdgpu: clamp the isolation index for rings outside a partition
In the Linux kernel, the following vulnerability has been resolved:
drm/amdgpu: clamp the isolation index for rings outside a partition
adev->isolation[] has one slot per partition, but a ring that is not
assigned to one keeps AMDGPU_XCP_NO_PARTITION, which is ~0, so indexing
the array with it is out of bounds. SDMA submissions hit this on both
the isolation enforcement and the VM flush path and trip UBSAN.
Fall back to the first slot the way the cleaner shader path already
does, and stop taking the address before the ring type check that makes
it relevant.
CVE-2026-89811
High · 8.8
Sep 16, 2026
drm/amdkfd: Add TLB flush after MES queue eviction/suspension
In the Linux kernel, the following vulnerability has been resolved:
drm/amdkfd: Add TLB flush after MES queue eviction/suspension
MES (Micro Engine Scheduler) does not perform heavy-weight TLB
invalidation after unmapping queues, unlike HWS which does this
automatically. This causes a race condition where in-flight DMA
descriptors can access memory that has been unmapped, leading to page
faults and GPU queue hangs during SVM page migration.
The issue manifests as KFDSVMRangeTest.MultiThreadMigrationTest
failures on gfx1151 (Strix Point) with XNACK mode 1 enabled - the GPU
compute queue hangs with packets submitted but never consumed.
Add kfd_flush_tlb() calls after MES queue removal in two locations:
- evict_process_queues_cpsch(): after all queues removed during eviction
- suspend_queues(): after debug/criu queue suspension (with mem_fence barrier)
This ensures all in-flight memory accesses from unmapped queues are
flushed before memory is freed or migrated.
(cherry picked from commit f5c4f88e0f9c45a8fb9dfac0c1df726c95e41b77)
CVE-2026-89810
High · 7.8
Sep 16, 2026
drm/amdkfd: Fix error path at svm_migrate_copy_to_ram
In the Linux kernel, the following vulnerability has been resolved:
drm/amdkfd: Fix error path at svm_migrate_copy_to_ram
If page migration from device to sys ram fails for some reasons driver needs
release and unlock allocated system pages. To do that driver should use page
physical address, or pfn, then get struct page*. Current driver uses dma
address(for adev) that is not correct with IOMMU enabled, or even in general.
The patch releases and unlocks allocated system pages based on where migration
failed by struct page* of sys ram pages. Also dma_unmap correspodent system
ram pages at error path.
CVE-2026-89809
Unknown
Sep 16, 2026
drm/amdkfd: fix scope of mqd_mgr dereference in pqm_debugfs_mqds
In the Linux kernel, the following vulnerability has been resolved:
drm/amdkfd: fix scope of mqd_mgr dereference in pqm_debugfs_mqds
Reading /sys/kernel/debug/kfd/mqds while a process holds an active KFD
queue triggers a NULL pointer dereference because the for loop that
calls mqd_mgr->debugfs_show_mqd() is incorrectly placed outside the
if (pqn->q) block that initializes mqd_mgr.
The queue list can contain entries where pqn->q is NULL (kernel queues
where only pqn->kq is valid). In the original code:
if (pqn->q) {
...
mqd_mgr = q->device->dqm->mqd_mgrs[mqd_type];
size = mqd_mgr->mqd_stride(...);
}
for (xcc = 0; xcc < num_xccs; xcc++) { // WRONG: outside if block
mqd = q->mqd + size * xcc;
r = mqd_mgr->debugfs_show_mqd(m, mqd);
}
When iterating over a queue node where pqn->q is NULL:
1. The if (pqn->q) block is skipped
2. mqd_mgr remains uninitialized (NULL from declaration)
3. The for loop executes anyway
4. mqd_mgr->debugfs_show_mqd(m, mqd) dereferences NULL
The crash manifests as:
BUG: kernel NULL pointer dereference, address: 0000000000000000
#PF: supervisor instruction fetch in kernel mode
RIP: 0010:0x0
Call Trace:
pqm_debugfs_mqds+0x10c/0x1d0 [amdgpu]
kfd_debugfs_mqds_by_process+0x9b/0x110 [amdgpu]
seq_read_iter+0x132/0x4b0
...
Fix by moving the for loop inside the if (pqn->q) block, so mqd_mgr
and related variables are only used when properly initialized.
(cherry picked from commit 8bfe29d5c798940f797aa24135d2734c3ffce9de)
CVE-2026-89813
Unknown
Sep 16, 2026
drm/amdgpu: force complete the KIQ ring fences on reset
In the Linux kernel, the following vulnerability has been resolved:
drm/amdgpu: force complete the KIQ ring fences on reset
Like the MES scheduler ring, the KIQ ring sets no_scheduler = true and uses a
polling fence, so it is skipped by the force-completion loop in
amdgpu_device_pre_asic_reset(). Its hw fence value lives in wb (GTT) memory and
survives a MODE1 reset while fence_drv.sync_seq keeps advancing, so after a
reset the first KIQ submission can poll forever on a seq that is never written
back.
Force complete the KIQ ring fences too so their hw fence is realigned to
sync_seq.
CVE-2026-89812
Unknown
Sep 16, 2026
drm/amdgpu: force complete the MES ring fences on reset
In the Linux kernel, the following vulnerability has been resolved:
drm/amdgpu: force complete the MES ring fences on reset
The MES scheduler ring has no drm scheduler (no_scheduler = true), so it is
skipped by the force-completion loop in amdgpu_device_pre_asic_reset(). It uses
a polling fence whose hw value lives in wb (GTT) memory and survives a MODE1
reset, while fence_drv.sync_seq keeps advancing for every packet.
When the reset is triggered because MES itself stopped responding, the
timed-out packets advance sync_seq past the last hw fence value MES wrote.
After resume the first MES submission polls forever on a seq that is never
written back, failing the resume and wedging the box on a second reset:
amdgpu: MES ring buffer is full.
amdgpu: *ERROR* ring gfx_0.0.0 test failed (-110)
amdgpu: resume of IP block <gfx_v11_0> failed -110
amdgpu: GPU reset end with ret = -110
Force complete the MES scheduler ring fences together with the scheduler rings
so their hw fence is realigned to sync_seq.
v2: cover all XCCs (one scheduler ring each), not just mes.ring[0].
CVE-2026-89808
High · 7.8
Sep 16, 2026
drm/amdkfd: Fix the case that vm range is hole at svm_migrate_copy_to_vram
In the Linux kernel, the following vulnerability has been resolved:
drm/amdkfd: Fix the case that vm range is hole at svm_migrate_copy_to_vram
When migration vm range is hole at cpu side(MIGRATE_PFN_MIGRATE set +
MIGRATE_PFN_VALID unset) driver still allocates device pages. There is no
dma map of src pages and migration. j is 0 and svm_migrate_copy_memory_gart()
will return an uninitialized r. That can trigger out_free_vram_pages to drop
all VRAM just set up.
Initialize r and only call the last svm_migrate_copy_memory_gart if j > 0.
Current code postponed the last page to the final copy. This patch flushes on
the last page when reach to the end of current drm_buddy_block; avoids another
svm_migrate_copy_memory_gart.
CVE-2026-89807
Unknown
Sep 16, 2026
drm/amdkfd: guard against NULL restore_mqd in CRIU queue restore
In the Linux kernel, the following vulnerability has been resolved:
drm/amdkfd: guard against NULL restore_mqd in CRIU queue restore
Both create_queue_cpsch() and create_queue_nocpsch() unconditionally
call mqd_mgr->restore_mqd() when a CRIU restore is in progress
(qd != NULL), with no NULL guard. On any system where restore_mqd is
not implemented for the given queue type, a user holding
CAP_CHECKPOINT_RESTORE can trigger a kernel NULL pointer dereference
and panic the machine by issuing KFD_IOC_CRIU_OP_RESTORE with a
crafted queue restore object. Note that checkpoint_mqd is likewise
unimplemented on GFX12, so no legitimate CRIU image can reach this
path — only a hand-crafted restore payload.
Add a NULL guard for restore_mqd immediately after mqd_mgr is
resolved, unwinding via the existing error labels and returning
-EOPNOTSUPP if the callback is not implemented. This mirrors the
existing checkpoint_mqd guard in checkpoint_mqd().
CVE-2026-89806
High · 8.4
Sep 16, 2026
drm/sysfb: ofdrm: Fix integer overflow in fb_size calculation
In the Linux kernel, the following vulnerability has been resolved:
drm/sysfb: ofdrm: Fix integer overflow in fb_size calculation
The framebuffer size calculation `fb_size = linebytes * height` can
overflow when both values are large (e.g., 46341 * 46341 > INT_MAX).
Since linebytes and height are both int types, the multiplication is
performed as int * int, which results in undefined behavior on overflow.
Use check_mul_overflow() to detect and prevent this overflow, consistent
with the approach used in simpledrm.c and corebootdrm.c.
CVE-2026-89805
High · 7.8
Sep 16, 2026
drm/pagemap: Fix folio allocation fallback and use-after-put
In the Linux kernel, the following vulnerability has been resolved:
drm/pagemap: Fix folio allocation fallback and use-after-put
drm_pagemap_migrate_populate_ram_pfn() had two issues when populating
RAM PFNs with higher-order folios:
1. The higher-order vma_alloc_folio()/folio_alloc() calls did not pass
__GFP_NOWARN, so a THP allocation failure under memory pressure
would spam the kernel log, and there was no fallback path despite a
TODO comment stating one was needed. Add __GFP_NOWARN to the
higher-order allocation and, on failure, fall back to order-0
allocations for the entire range originally covered by the failed
higher-order allocation, leaving MIGRATE_PFN_COMPOUND unset for
those PFNs.
2. In the free_pages error path, order was computed via
folio_order(page_folio(page)) *after* put_page(page) had already
dropped the reference, resulting in a use-after-free/put when that
was the last reference on the page. Compute order before releasing
the page.
Introducing the fallback in 1. also requires the source page array
handed to ->copy_to_ram() to be built differently. Both callers only
populated the entry at the head of each source folio, relying on the
copy callback to derive the rest of the folio from the order recorded
in the matching drm_pagemap_addr. Once the destination has been demoted
to order-0 folios the drm_pagemap_addr entries are per-page, so a source
page is needed for every one of them; leaving them NULL makes the copy
callback stop after the first page and the remainder of the range is
never copied.
The source folio is only split later, by migrate_vma_pages() /
migrate_device_pages(), so its order cannot be used to detect the
demotion - test the destination for MIGRATE_PFN_COMPOUND instead. Factor
the array population out into drm_pagemap_migrate_populate_src_pages()
and use it from both drm_pagemap_evict_to_ram() and
__drm_pagemap_migrate_to_ram().
CVE-2026-89804
High · 8.8
Sep 16, 2026
drm/nouveau/dmem: fix mismatched DMA unmap size for large folios
In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau/dmem: fix mismatched DMA unmap size for large folios
Device-private THP migration maps migration buffers with page_size()
and records that length in dma_info->size. For a compound folio
page_size() is PAGE_SIZE << order, but two teardown sites still pass a
literal PAGE_SIZE to dma_unmap_page():
- nouveau_dmem_migrate_to_ram() on the success path, and
- nouveau_dmem_migrate_copy_one() on the copy-error path.
For an order > 0 folio this unmaps less than was mapped, leaking the
remainder of the IOMMU/IOVA mapping. The other unmap sites, in
nouveau_dmem_migrate_chunk() and nouveau_dmem_evict_chunk(), already
use the saved size; use it here too.
CVE-2026-89803
High · 7.8
Sep 16, 2026
drm/nouveau: unsubscribe the channel-kill event before the fence context
In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau: unsubscribe the channel-kill event before the fence context
nouveau_channel_del() tears the fence context down first and only drops
the channel-kill subscription later, in the middle of the nvif object
teardown:
if (chan->fence)
nouveau_fence(chan->cli->drm)->context_del(chan);
...
nvif_object_dtor(&chan->vram);
nvif_event_dtor(&chan->kill);
The subscribed handler is nouveau_channel_killed(), which calls
nouveau_channel_kill() and from there nouveau_fence_context_kill() on
chan->fence. A kill event delivered in that window takes fctx->lock and
walks fctx->pending on a fence context that context_del() has already
freed.
Nothing reaches this below Fermi today, because the subscription is
gated on FERMI_CHANNEL_GPFIFO and nothing kills a channel there. On
Fermi and newer the window is real but narrow, since a kill has to land
exactly while the channel is being destroyed. That is reason enough on
its own, which is why this carries a Fixes: tag. The last patch in this
series subscribes Tesla channels as well; nothing kills those today, so
it does not widen the exposure now, but it is the groundwork for a
recovery path that would, and the ordering is better fixed before that
lands than alongside it.
Drop the subscription before anything it depends on is torn down.
CVE-2026-89802
Unknown
Sep 16, 2026
drm/nouveau/uvmm: fix NULL deref unwinding an OP_MAP_SPARSE op
In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau/uvmm: fix NULL deref unwinding an OP_MAP_SPARSE op
Each bind_job_op is zeroed by kzalloc_obj() in bind_job_op_from_uop(),
and the OP_MAP_SPARSE case in nouveau_uvmm_bind_job_submit() only creates
a region, so op->ops stays NULL for a successfully processed sparse map.
If a later op in the same job fails, the reverse unwind loop revisits that
op and calls drm_gpuva_ops_free(&uvmm->base, op->ops) unconditionally.
drm_gpuva_ops_free() dereferences its argument right away
(list_for_each_entry_safe on &ops->list), so a NULL op->ops oopses. The
path is reachable by any render-node fd holder, since NOUVEAU_VM_BIND is
DRM_RENDER_ALLOW.
Guard the free with IS_ERR_OR_NULL(), as nouveau_uvmm_bind_job_cleanup()
already does for the identical free.
CVE-2026-89801
High · 7.8
Sep 16, 2026
drm/nouveau/uvmm: fix premature region free on failed OP_UNMAP_SPARSE
In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau/uvmm: fix premature region free on failed OP_UNMAP_SPARSE
In nouveau_uvmm_bind_job_submit()'s OP_UNMAP_SPARSE arm, op->reg is set
from nouveau_uvma_region_find(), which only looks the region up and takes
no reference; a region's sole reference is its membership in
uvmm->region_mt. Two failure paths leave op->reg set: the -ENOENT check
when the region is busy, and the drm_gpuvm_sm_unmap_ops_create() failure.
The sibling nouveau_uvmm_sm_unmap_prepare() failure just below clears
op->reg; these two do not.
unwind_continue steps back one op, so the failing op is skipped by the
unwind loop and its op->reg stays set. nouveau_uvmm_bind_job_cleanup()
then enters its if (op->reg) branch and calls nouveau_uvma_region_remove()
and nouveau_uvma_region_put() on it, dropping the tree's sole reference
and freeing a region this job never created. The comment above the
cleanup loop documents the broken invariant: op->reg must be NULL on
submit failure.
This frees a live region on an unrelated failure, reachable single-job
when drm_gpuvm_sm_unmap_ops_create() returns -ENOMEM; if another job owns
the same region, its cleanup then removes and puts the freed region, a
use-after-free. Clear op->reg on both failure paths.
CVE-2026-89800
Unknown
Sep 16, 2026
drm/nouveau/uvmm: clear the dirty flag when unwinding an OP_UNMAP_SPARSE
In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau/uvmm: clear the dirty flag when unwinding an OP_UNMAP_SPARSE
A successful OP_UNMAP_SPARSE marks its region dirty with
nouveau_uvma_region_dirty() and defers the teardown to
nouveau_uvmm_bind_job_cleanup(); it does not remove the region from
uvmm->region_mt.
If a later op in the job fails, the unwind path never clears reg->dirty
(set in one place, cleared nowhere) and sets op->reg = NULL, so cleanup
skips the teardown. The region is left in the tree with dirty set and its
completion never signalled. Later binds over that range then fail
permanently -- -ENOENT or -EINVAL from the dirty checks, or an unkillable
wait_for_completion() in bind_validate_region() -- for the lifetime of
the uvmm.
Clear reg->dirty when the unwind reverts the sparse unmap, restoring the
region to the state it was found in.
CVE-2026-89799
High · 7.8
Sep 16, 2026
bpf: Disable preemption in bpf_get_stackid
In the Linux kernel, the following vulnerability has been resolved:
bpf: Disable preemption in bpf_get_stackid
The get_perf_callchain call needs disabled preemption plus we need
it disabled as long as we access its returned trace entries buffer.
Note the bpf_get_stackid_pe function is executed already with
preemption disabled.
CVE-2026-89798
Unknown
Sep 16, 2026
rpcrdma: arm rn_done before publishing the notification
In the Linux kernel, the following vulnerability has been resolved:
rpcrdma: arm rn_done before publishing the notification
rpcrdma_rn_register() inserts @rn into rd_xa with xa_alloc() before
storing the caller's callback in rn->rn_done. The xarray makes @rn
reachable to rpcrdma_remove_one(), which walks rd_xa and invokes
rn->rn_done(rn) for every registered notification. A device removal
that races a fresh registration can therefore observe @rn with
rn_done still NULL, because the notification objects are zero
allocated by their owners, and call through a NULL function pointer.
Store rn->rn_done before xa_alloc() publishes @rn. The xarray's
store-side and load-side ordering then guarantees that any CPU which
finds @rn in rd_xa also observes the armed callback.
rpcrdma_rn_unregister() treats a non-NULL rn_done as the sentinel
for a completed registration, so the early store must not survive a
failed registration. Clear rn_done again when xa_alloc() fails.
Were it left set, the failed-accept cleanup path would call
rpcrdma_rn_unregister() on an @rn that was never inserted, erasing
an unrelated rd_xa slot and underflowing rd_kref.
CVE-2026-89797
Unknown
Sep 16, 2026
power: supply: ab8500_fg: fix use-after-free on remove
In the Linux kernel, the following vulnerability has been resolved:
power: supply: ab8500_fg: fix use-after-free on remove
ab8500_fg_remove() destroys the driver workqueue while the threaded
interrupt handlers are still armed; they are devm-managed and freed
only after ->remove() returns, so a handler that fires in that
window queues work on the freed workqueue.
Tear the workqueue down through devm instead, registering its cleanup
after the power supply and before the interrupt requests. devm then
frees the interrupts first, so the handlers can no longer queue work,
before disabling the delayed and plain work items and destroying the
workqueue. Disabling the items, rather than cancelling them, keeps
them disabled so no producer (including the power-supply
external_power_changed callback) can requeue them.
Found by an in-house static analysis tool.
CVE-2026-89796
Unknown
Sep 16, 2026
mm/damon/core: avoid infinite kdamond_merge_regions() internal loop
In the Linux kernel, the following vulnerability has been resolved:
mm/damon/core: avoid infinite kdamond_merge_regions() internal loop
Patch series "mm/damon: unurgent fixes for infinite loop, NULL de-ref and
races", v1.1.
Sashiko found a few issues in DAMON that could cause infinite loop, NULL
dereference and monitoring results degradation. The first two sounds
scary but the infinite loop happens only under unreasonable user setup.
The NULL dereference is only in a unit test. Monitoring results
degradation is trivial since it is only best-effort, and those happens
from only unlikely races. Still those are bugs that better to fix if
possible. Fix those.
This patch (of 6):
Due to online parameter update like events, the number of DAMON regions
could be higher than the user-set upper limit. kdamond_merge_regions()
repeats merge regions until the number meets the limit, while doubling the
merge threshold up to the theoretical maximum threshold. It is tried only
up to the theoretical maximum threshold because even the aggressive
merging can fail from reducing the number of regions under the
user-defined upper limit. For example, there could be many user-defined
non-contiguous regions that cannot be merged.
The threshold based loop break condition is evaluated by comparing the
threshold for the next merging try against the theoretical maximum
threshold. If max_thres is larger than UINT_MAX / 2, doubling the
threshold could make it overflow, and bypass the loop break condition. In
the case, if the number of regions cannot be reduced under the upper limit
like explained above, the loop will run infinitely.
Prevent the case by doing the break condition check before doubling the
threshold. Also, prevent the threshold exceeding the maximum threshold,
as it could overflow and apply the wrong merge threshold.
This issue is unlikely to occur in real world, since having the max_thres
higher than UINT_MAX / 2 require unrealistically large aggregation
intervals compared to the sampling interval. Also, it requires an
unrealistically large number of uncontiguous regions setup. Nonetheless,
the consequence is bad and the fix is simple.
The issue was discovered [1] by Sashiko.
CVE-2026-89795
High · 8.4
Sep 16, 2026
PCI: Allow per function PCI slots to fix slot reset on s390
In the Linux kernel, the following vulnerability has been resolved:
PCI: Allow per function PCI slots to fix slot reset on s390
On s390 systems, which use a machine level hypervisor, PCI devices are
always accessed through a form of PCI pass-through which fundamentally
operates on a per PCI function granularity. This is also reflected in the
s390 PCI hotplug driver which creates hotplug slots for individual PCI
functions. Its reset_slot() function, which is a wrapper for
zpci_hot_reset_device(), thus also resets individual functions.
Currently, the pci_create_slot() assigns the same pci_slot object to
multifunction devices. This approach worked fine on s390 systems that only
exposed virtual functions as individual PCI domains to the operating
system. Since commit 44510d6fa0c0 ("s390/pci: Handling multifunctions")
s390 supports exposing the topology of multifunction PCI devices by
grouping them in a shared PCI domain. This creates a problem when resetting
a function through the hotplug driver's slot_reset() interface.
When attempting to reset a function through the hotplug driver, the shared
slot assignment causes the wrong function to be reset instead of the
intended one. It also leaks memory as we do create a pci_slot object for
the function, but don't correctly free it in pci_slot_release().
Add a flag for struct pci_slot to allow per function PCI slots for
functions managed through a hypervisor, which exposes individual PCI
functions while retaining the topology. Since we can use all 8 bits for
slot 'number' (for ARI devices), change slot 'number' u16 to account for
special values PCI_SLOT_PLACEHOLDER and PCI_SLOT_ALL_DEVICES.
CVE-2026-89794
Unknown
Sep 16, 2026
ksmbd: zero pipe read compound padding
In the Linux kernel, the following vulnerability has been resolved:
ksmbd: zero pipe read compound padding
Compound response handling extends the last response iov to an eight-byte
boundary.
smb2_read_pipe() allocates only the payload size, so the alignment padding
can expose up to seven bytes of uninitialized kernel heap memory.
Allocate the aligned size and clear the unused tail before pinning the
response buffer.
CVE-2026-89793
High · 7.8
Sep 16, 2026
ublk: clear VM_MAYWRITE on read-only ublk char device mmap
In the Linux kernel, the following vulnerability has been resolved:
ublk: clear VM_MAYWRITE on read-only ublk char device mmap
ublk_ch_mmap() rejects mmap requests with VM_WRITE set, but never
clears VM_MAYWRITE on the resulting read-only mapping. This allows
a userspace daemon to mmap the per-queue command buffer PROT_READ,
then upgrade it to PROT_WRITE via mprotect(), since VM_MAYWRITE was
never cleared.
The command buffer holds struct ublksrv_io_desc entries that are
kernel-written ABI; a writable mapping lets an unprivileged daemon
process corrupt fields such as addr, op_flags, nr_sectors, and
start_sector.
Same bug class as the drm/panthor and drm/vc4 VM_MAYWRITE fixes, and
the 2026-08-13 ptp/vmclock fix (a5edadbae57e).
Verified via mprotect() PoC: before the fix, a PROT_READ mapping can
be upgraded to PROT_READ|PROT_WRITE and a write into the command
buffer corrupts io_desc fields (confirmed under KASAN). After the
fix, mprotect() returns -EACCES.
CVE-2026-89792
High · 7.1
Sep 16, 2026
ksmbd: prevent out-of-bounds reads in share config responses
In the Linux kernel, the following vulnerability has been resolved:
ksmbd: prevent out-of-bounds reads in share config responses
Validate IPC share configuration payload sizes before consuming
variable-length fields. Bound veto list parsing and account for
the separator byte when deriving the path length.
CVE-2026-89791
High · 7.8
Sep 16, 2026
perf: Fix use-after-free when perf mmap() revival races with the last munmap()
In the Linux kernel, the following vulnerability has been resolved:
perf: Fix use-after-free when perf mmap() revival races with the last munmap()
perf_mmap_close() drops rb->mmap_count *without* holding
event->mmap_mutex (the refcount_dec_and_test() right before the
refcount_dec_and_mutex_lock() of event->mmap_count). A concurrent
perf_mmap_rb() can slot its entire "revival" path into that window
(perf_mmap holds event->mmap_mutex for its whole duration, including
rb_alloc):
munmap side (perf_mmap_close) mmap side (perf_mmap_rb)
----------------------------------- --------------------------------
rb->mmap_count 1 -> 0 (no lock) (holds event->mmap_mutex)
inc_not_zero(rb->mmap_count) fails
ring_buffer_attach(event, NULL)
rb_alloc() + attach new rb
refcount_set(&event->mmap_count, 1)
lock; event->mmap_count 1 -> 0
ring_buffer_attach(event, NULL)
ring_buffer_put() -> frees the *new* rb
The revival's refcount_set(&event->mmap_count, 1) is an invisible
1 -> 1 write: the close frees the just-revived buffer although the
other process still has it mapped -- a page-level use-after-free
allowing local privilege escalation to root by any unprivileged user
(default kernel.perf_event_paranoid=2).
Swap the order of the two counter updates: event->mmap_count is
dropped first via refcount_dec_and_mutex_lock(), so its 1 -> 0
transition and the ring_buffer_attach() stay serialized with
perf_mmap(). rb->mmap_count == 0 then implies every event using the
buffer is detached already, so the result of the rb->mmap_count drop
can gate the remaining teardown directly and detach_rest is no longer
needed.
An earlier fix for this race from Kyle Zeng and David Lee takes
event->mmap_mutex around both counter updates [0]; here the not-last
close stays lockless.
CVE-2026-89790
Unknown
Sep 16, 2026
ipv6: avoid divide by zero in rt6_multipath_rebalance
In the Linux kernel, the following vulnerability has been resolved:
ipv6: avoid divide by zero in rt6_multipath_rebalance
rt6_multipath_rebalance() calculates the total eligible nexthop weight
in one pass and programs upper bounds in a second pass. Since
RTM_NEWROUTE is RTNL-free, a concurrent
ignore_routes_with_linkdown update can make the first pass return zero
while the second sees an eligible nexthop, causing
rt6_upper_bound_set() to divide by zero.
UBSAN: division-overflow in net/ipv6/route.c:4845:17
Oops: divide error: 0000 [#1] SMP KASAN NOPTI
rt6_upper_bound_set() net/ipv6/route.c:4845
rt6_multipath_rebalance()
fib6_add_rt2node()
ip6_route_multipath_add()
inet6_rtm_newroute()
Skip upper-bound calculation when the first pass reports a zero total.
This respects the lock-free performance considerations here and solves
insecure scenarios.