| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| In the Linux kernel, the following vulnerability has been resolved:
rds: ib: Clear the sg list when mapping an MR fails
rds_ib_map_frmr() stores the caller's scatterlist in the MR before DMA
mapping and registration can fail. On failure, __rds_rdma_map() unpins
the pages and frees the scatterlist, but rds_ib_free_frmr() can still
return the MR to the pool with the stale pointer set.
This leaves the pool with a dangling scatterlist and can lead to local
privilege escalation. KASAN detects the resulting use-after-free when the
MR is later torn down:
BUG: KASAN: slab-use-after-free in __rds_ib_teardown_mr
Read of size 8
Call Trace:
__rds_ib_teardown_mr
rds_ib_unreg_frmr
rds_ib_flush_mr_pool
rds_ib_flush_mrs
rds_free_mr
rds_setsockopt
Store the scatterlist in the MR only after DMA mapping succeeds. If DMA
mapping fails, return directly while the MR fields remain clear; the caller
keeps ownership of the scatterlist and its pinned pages. If a later
registration step fails, unmap the scatterlist and clear the MR fields
before returning. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/client: fix restore of partially initialized client
I got a null-ptr-deref report when closing a DRM file descriptor:
WARNING: drivers/gpu/drm/drm_atomic.c:2031 at
__drm_atomic_helper_set_config+0x18e/0x1b0 [drm]
Call Trace:
drm_client_modeset_commit_atomic+0x16b/0x220 [drm]
drm_client_modeset_commit_locked+0x56/0x160 [drm]
drm_client_modeset_commit+0x21/0x40 [drm]
__drm_fb_helper_restore_fbdev_mode_unlocked.part.0+0x7b/0x80
drm_fbdev_client_restore+0xe/0x20 [drm_client_lib]
drm_client_dev_restore+0x9f/0xc0 [drm]
drm_release+0xc5/0xe0 [drm]
The warning is followed by a NULL pointer dereference:
BUG: kernel NULL pointer dereference, address: 0000000000000008
RIP:
__drm_fb_helper_restore_fbdev_mode_unlocked.part.0+0x41/0x80
[drm_kms_helper]
Call Trace:
drm_fbdev_client_restore+0xe/0x20 [drm_client_lib]
drm_client_dev_restore+0x9f/0xc0 [drm]
drm_release+0xc5/0xe0 [drm]
__fput+0xdc/0x2b0
__x64_sys_close+0x39/0x80
do_syscall_64+0x8d/0x460
entry_SYSCALL_64_after_hwframe+0x76/0x7e
drm_client_register() adds the DRM client to the device client list
before invoking the initial hotplug callback. If the hotplug callback
fails, the client remains registered.
For the fbdev client, a failure during drm_fb_helper_initial_config()
causes the partially initialized fbdev helper to be cleaned up.
drm_fb_helper_fini() releases fb_helper->info and leaves it NULL.
The fbdev client therefore remains registered even though there is no
fully initialized framebuffer device.
Later, when userspace closes the DRM file descriptor, drm_release()
can invoke the restore callbacks of registered DRM clients:
drm_release()
drm_client_dev_restore()
drm_fbdev_client_restore()
drm_fb_helper_restore_fbdev_mode_unlocked()
drm_fbdev_client_restore() currently restores the fbdev state
unconditionally. For a partially initialized fbdev client this can
submit an incomplete modeset state and subsequently access fbdev
state which has not been initialized, resulting in the warning and
NULL pointer dereference above.
drm_fbdev_client_unregister() already uses fb_helper->info to
distinguish a fully probed framebuffer device from a partially
initialized client.
Use the same condition in drm_fbdev_client_restore() and skip restore
if no framebuffer device has been successfully initialized. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/imagination: Propagate map failures correctly from pvr_mmu_map_sgl()
Map failure from pvr_mmu_map_sgl() interface was not returned correctly
to pvr_mmu_map() interface. This resulted in pvr_mmu_map() interface to
continue instead of returning an error to caller.
Fix it by returning a proper error code from pvr_mmu_map_sgl() interface.
Call stack for crash:
[ 1179.286237] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
[ 1179.295067] Mem abort info:
[ 1179.297877] ESR = 0x0000000096000004
[ 1179.301656] EC = 0x25: DABT (current EL), IL = 32 bits
[ 1179.306987] SET = 0, FnV = 0
[ 1179.310048] EA = 0, S1PTW = 0
[ 1179.313198] FSC = 0x04: level 0 translation fault
[ 1179.318096] Data abort info:
[ 1179.320993] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[ 1179.326483] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[ 1179.331546] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[ 1179.336895] user pgtable: 4k pages, 48-bit VAs, pgdp=000000009822a000
[ 1179.343402] [0000000000000008] pgd=0000000000000000, p4d=0000000000000000
[ 1179.350243] Internal error: Oops: 0000000096000004 [#2] SMP
[ 1179.355908] Modules linked in: powervr gpu_sched drm_shmem_helper drm_gpuvm drm_exec xhci_plat_hcd xhci_hcd dwc3 usbcore usb_common snd_soc_simple_card snd_soc_simple_card_utils dwc3_am62 at24 sa2ul sha512 libsha512 sha256 authenc sch_fq_codel fuse dm_mod ipv6
[ 1179.378992] CPU: 1 UID: 1000 PID: 680 Comm: deqp-vk Tainted: G D 6.17.0 #1 PREEMPT
[ 1179.388120] Tainted: [D]=DIE
[ 1179.390994] Hardware name: Texas Instruments AM625 SK (DT)
[ 1179.396467] pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 1179.403415] pc : pvr_mmu_op_context_unmap_curr_page+0x6c/0x134 [powervr]
[ 1179.410140] lr : pvr_mmu_op_context_unmap_curr_page+0x58/0x134 [powervr]
[ 1179.416848] sp : ffff8000839ab8c0
[ 1179.420153] x29: ffff8000839ab8c0 x28: 0000000000000001 x27: 000000008f386000
[ 1179.427283] x26: ffff000016d1df98 x25: 0000000000247000 x24: 00000000000001e6
[ 1179.434413] x23: 0000000000000002 x22: 000000000000ffff x21: 0000000000000247
[ 1179.441540] x20: 0000000000000245 x19: ffff000016d1df60 x18: 0000000000000002
[ 1179.448668] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000001
[ 1179.455793] x14: 0000000000060810 x13: ffff80007fffffff x12: ffff000004190480
[ 1179.462921] x11: ffff8000853f7000 x10: ffff8000811ae000 x9 : ffff0000041900b8
[ 1179.470051] x8 : 0000000000000000 x7 : 00000000990c4001 x6 : 0000000000000007
[ 1179.477177] x5 : ffff000016d1df60 x4 : 0000000000000000 x3 : ffff00000a7d8000
[ 1179.484306] x2 : 00000000000001ff x1 : 0000000000000000 x0 : 0000000000000000
[ 1179.491433] Call trace:
[ 1179.493872] pvr_mmu_op_context_unmap_curr_page+0x6c/0x134 [powervr] (P)
[ 1179.500582] pvr_mmu_map+0x31c/0x388 [powervr]
[ 1179.505027] pvr_vm_gpuva_map+0x40/0x88 [powervr]
[ 1179.509732] __drm_gpuvm_sm_map+0x250/0x44c [drm_gpuvm]
[ 1179.514952] drm_gpuvm_sm_map+0x48/0x5c [drm_gpuvm]
[ 1179.519822] pvr_vm_bind_op_exec+0x64/0x70 [powervr]
[ 1179.524785] pvr_vm_map+0x1f8/0x2a8 [powervr]
[ 1179.529142] pvr_ioctl_vm_map+0x12c/0x188 [powervr]
[ 1179.534018] drm_ioctl_kernel+0xb8/0x128
[ 1179.537941] drm_ioctl+0x21c/0x4ec
[ 1179.541337] __arm64_sys_ioctl+0xac/0x108
[ 1179.545344] invoke_syscall+0x44/0x100
[ 1179.549091] el0_svc_common.constprop.0+0x40/0xe0
[ 1179.553790] do_el0_svc+0x1c/0x28
[ 1179.557106] el0_svc+0x34/0xf0
[ 1179.560159] el0t_64_sync_handler+0xd0/0xe4
[ 1179.564334] el0t_64_sync+0x198/0x19c
[ 1179.567996] Code: 54000300 35000360 f9402261 79409a62 (f9400421)
[ 1179.574081] ---[ end trace 0000000000000000 ]--- |
| In the Linux kernel, the following vulnerability has been resolved:
drm/i915: fix incorrect RCU teardown order
i915_gem_busy_ioctl uses dma_resv_for_each_fence_unlocked() to iterate
over the fences in an GEM object without holding a reference but only
the RCU read side lock.
What can happen here is that the GEM object is destroyed concurrently
while i915_gem_busy_ioctl is still running. This won't free the GEM
objects memory, but still drops all the dma_fence references.
Now when dma_resv_for_each_fence_unlocked() sees a destroyed dma_fence it
assumes that a new fence list was installed and re-starts the loop.
But in the case of a destroyed GEM object a new fence list is never
installed, only the old one freed and therefore the iteration never
finishes resulting in an endless loop.
The solution is to drop the fence references only after the RCU grace
period.
The fixes tag is not necessary the patch introducing the problem, but the
one making it so worse that we need to address it.
This problem was pointed out by Sashiko-bot.
(cherry picked from commit 5113479556025093bf8133bb2dcaa33be2d50921) |
| In the Linux kernel, the following vulnerability has been resolved:
drm/amdkfd: fix use-after-free and multi-container gap in kfd_dev_mapping
kfd_dev_mapping caches the address_space of the first /dev/kfd opener
so that the GPU reset path can call unmap_mapping_range() to zap all
userspace mappings of doorbell and MMIO ranges. This design has two
bugs that both manifest under SRIOV with multiple containers:
1. Use-after-free / rwsem deadlock. The cached pointer refers to an
inode owned by the first opener's container. When that container
exits and its inode is released, kfd_dev_mapping becomes a dangling
pointer. A subsequent GPU reset dereferences it inside
unmap_mapping_range(), which takes i_mmap_rwsem on the freed inode,
causing a hard hang observable as an uninterruptible rwsem wait.
2. Multi-container gap. Only the first opener's address_space is cached;
VMAs created by later openers live in a different address_space and
are never reached by unmap_mapping_range(). After a GPU reset those
stale mappings keep doorbell and MMIO pages accessible to guest
userspace with no GPU behind them, risking PCIe transaction timeouts
and NMI panics.
Fix both bugs with the same approach used by DRM core (drm_drv.c):
create a private pseudo-filesystem at module init time and allocate one
anonymous inode from it. In kfd_open() redirect every opener's
file->f_mapping to that inode's address_space. The inode is
module-owned, lives exactly as long as the amdgpu module, and collects
VMAs from all openers in one address_space. A single
unmap_mapping_range() call in the reset path then correctly reaches
every container's mappings with no dangling pointer risk.
The hang manifests as an NMI backtrace on the GPU reset workqueue stuck
spinning in rwsem_down_read_slowpath() with a corrupted i_mmap_rwsem:
Workqueue: amdgpu-reset-dev xgpu_ai_mailbox_flr_work [amdgpu]
Call Trace:
<TASK>
kvm_wait+0x1f/0x40
__pv_queued_spin_lock_slowpath+0x31d/0x3a0
_raw_spin_lock_irq+0x51/0x80
rwsem_down_read_slowpath+0xb3/0x550
down_read+0x48/0xd0
unmap_mapping_range+0x71/0x140
kfd_dev_unmap_mapping_range+0x5b/0x140 [amdgpu]
amdgpu_amdkfd_clear_kfd_mapping+0xd8/0x190 [amdgpu]
amdgpu_device_gpu_recover+0x232/0x450 [amdgpu]
xgpu_ai_mailbox_flr_work+0xb5/0xc0 [amdgpu]
process_one_work+0x18e/0x3e0
worker_thread+0x2e3/0x420
kthread+0x10a/0x230
(cherry picked from commit 1128b4a52de1572e87431de837fd9850cb99542c) |
| In the Linux kernel, the following vulnerability has been resolved:
drm/amdgpu: Fix runtime PM leak in amdgpu_debugfs_test_ib_show()
amdgpu_debugfs_test_ib_show() resumes the device with
pm_runtime_get_sync() before taking the reset domain semaphore with
down_write_killable(). If the write lock acquisition is interrupted,
the function returns without calling pm_runtime_put_autosuspend(),
leaking the runtime PM reference acquired for the device and keeping
the GPU awake.
Drop the runtime PM reference on the interrupted down_write_killable()
error path before returning.
(cherry picked from commit ec30a576c2d4c0364549e6c04218f50704ef56c8) |
| In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau/dmem: pin VRAM for the whole registered range
Commit c32287471077 ("gpu/drm/nouveau: enable THP support for GPU memory
migration") grew the device-private region that
nouveau_dmem_chunk_alloc() registers from DMEM_CHUNK_SIZE to
DMEM_CHUNK_SIZE * NR_CHUNKS, but left the VRAM buffer object backing that
region at DMEM_CHUNK_SIZE.
nouveau_dmem_page_addr() returns chunk->bo->offset plus the page's offset
within the registered region, so every page past the first chunk resolves
to VRAM outside the buffer object.
Size the buffer object to the region it backs. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau/uvmm: fix UAF in nouveau_uvmm_sm when BO is in TTM_PL_SYSTEM
nouveau_uvmm_sm() calls op_map(), which passes bo->resource through
nouveau_mem() to nouveau_uvma_map(). nouveau_uvmm_vmm_map() then reads
mem->mem.type.
But this is only valid when bo->resource is backed by struct nouveau_mem,
as is the case for VRAM and TT resources. If the BO is left in
TTM_PL_SYSTEM, bo->resource is only a struct ttm_resource. Treating it
as struct nouveau_mem makes the mem->mem.type read past the end of the
resource, causing a KASAN: slab-use-after-free Read in nouveau_uvmm_sm
report:
BUG: KASAN: slab-use-after-free in nouveau_uvmm_vmm_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:152 [inline]
BUG: KASAN: slab-use-after-free in nouveau_uvma_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:199 [inline]
BUG: KASAN: slab-use-after-free in op_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:849 [inline]
BUG: KASAN: slab-use-after-free in nouveau_uvmm_sm.constprop.0+0x6ab/0x900 drivers/gpu/drm/nouveau/nouveau_uvmm.c:903
Read of size 1 at addr ffff888127d3e3a0 by task kworker/0:1/11
CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 7.2.0 #5 PREEMPT(lazy)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: nouveau_sched_wq_2224 drm_sched_run_job_work
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x95/0xe0 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xcb/0x5a0 mm/kasan/report.c:482
kasan_report+0xca/0x100 mm/kasan/report.c:595
nouveau_uvmm_vmm_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:152 [inline]
nouveau_uvma_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:199 [inline]
op_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:849 [inline]
nouveau_uvmm_sm.constprop.0+0x6ab/0x900 drivers/gpu/drm/nouveau/nouveau_uvmm.c:903
nouveau_uvmm_sm_unmap drivers/gpu/drm/nouveau/nouveau_uvmm.c:932 [inline]
nouveau_uvmm_bind_job_run+0xd6/0x250 drivers/gpu/drm/nouveau/nouveau_uvmm.c:1532
nouveau_job_run drivers/gpu/drm/nouveau/nouveau_sched.c:350 [inline]
nouveau_sched_run_job+0x62/0xd0 drivers/gpu/drm/nouveau/nouveau_sched.c:364
drm_sched_run_job_work+0x356/0xa10 drivers/gpu/drm/scheduler/sched_main.c:1061
process_one_work+0x8a5/0x1900 kernel/workqueue.c:3322
process_scheduled_works kernel/workqueue.c:3405 [inline]
worker_thread+0x5dd/0xd80 kernel/workqueue.c:3486
kthread+0x31d/0x420 kernel/kthread.c:436
ret_from_fork+0x662/0x940 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Allocated by task 2224 on cpu 0 at 66.550027s:
kasan_save_stack+0x24/0x50 mm/kasan/common.c:57
kasan_save_track+0x17/0x60 mm/kasan/common.c:78
poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
__kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:415
kasan_kmalloc include/linux/kasan.h:263 [inline]
__do_kmalloc_node mm/slub.c:5334 [inline]
__kmalloc_noprof+0x304/0x7c0 mm/slub.c:5359
_kmalloc_noprof include/linux/slab.h:992 [inline]
dma_resv_list_alloc+0x27/0x90 drivers/dma-buf/dma-resv.c:106
dma_resv_reserve_fences+0x60e/0xa30 drivers/dma-buf/dma-resv.c:205
ttm_bo_alloc_resource+0x12c/0xbd0 drivers/gpu/drm/ttm/ttm_bo.c:721
ttm_bo_validate+0x1bc/0x4a0 drivers/gpu/drm/ttm/ttm_bo.c:856
ttm_bo_init_reserved+0x2c3/0x570 drivers/gpu/drm/ttm/ttm_bo.c:970
nouveau_bo_init+0x159/0x2c0 drivers/gpu/drm/nouveau/nouveau_bo.c:359
nouveau_gem_new+0x234/0x5f0 drivers/gpu/drm/nouveau/nouveau_gem.c:272
nouveau_gem_ioctl_new+0x1eb/0x420 drivers/gpu/drm/nouveau/nouveau_gem.c:352
drm_ioctl_kernel+0x192/0x350 drivers/gpu/drm/drm_ioctl.c:817
drm_ioctl+0x4f8/0xb40 drivers/gpu/drm/drm_ioctl.c:914
nouveau_drm_ioctl+0xea/0x2c0 drivers/gpu/drm/nouveau/nouveau_drm.c:1338
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl fs/ioctl.c:583 [inline]
__x64_sys_ioctl+0x180/0x1d0 fs/ioctl.c:583
do_syscall_x64 ar
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau: Fix bridge reference leak in nv1a_ram_new()
pci_get_domain_bus_and_slot() takes a reference to the PCI device,
which is never released once the memory size has been read from its
config space. Drop the reference before returning. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau: fix double-free in nvif_vmm_dtor
On failure, nouveau_cli_init() calls nouveau_cli_fini() to tear
the client down. Then, nouveau_drm_open() also enters into its
cleanup path and calls nouveau_cli_fini() AGAIN. nouveau_cli_fini()
calls nouveau_vmm_fini():
void
nouveau_vmm_fini(struct nouveau_vmm *vmm)
{
nouveau_svmm_fini(&vmm->svmm);
nvif_vmm_dtor(&vmm->vmm);
vmm->cli = NULL;
}
Inside nvif_vmm_dtor(), vmm->page is freed unconditionally:
void
nvif_vmm_dtor(struct nvif_vmm *vmm)
{
kfree(vmm->page);
nvif_object_dtor(&vmm->object);
}
vmm->page is never cleared after being freed, so the second call of
nvif_vmm_dtor() will cause a double-free.
Found by fuzzing the nouveau driver with a modified Syzkaller:
BUG: KASAN: double-free in nvif_vmm_dtor+0x31/0x50 drivers/gpu/drm/nouveau/nvif/vmm.c:194
Free of addr ffff888010fcdc30 by task syz.0.173/2567
CPU: 1 UID: 0 PID: 2567 Comm: syz.0.173 Not tainted 7.2.0 #24 PREEMPT(lazy)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x95/0xe0 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xcb/0x5a0 mm/kasan/report.c:482
kasan_report_invalid_free+0xaa/0xd0 mm/kasan/report.c:557
check_slab_allocation+0xe4/0x110 mm/kasan/common.c:235
kasan_slab_pre_free include/linux/kasan.h:199 [inline]
slab_free_hook mm/slub.c:2622 [inline]
slab_free mm/slub.c:6377 [inline]
kfree+0x192/0x590 mm/slub.c:6692
nvif_vmm_dtor+0x31/0x50 drivers/gpu/drm/nouveau/nvif/vmm.c:194
nouveau_vmm_fini+0x16/0x50 drivers/gpu/drm/nouveau/nouveau_vmm.c:127
nouveau_cli_fini+0x10e/0x210 drivers/gpu/drm/nouveau/nouveau_drm.c:225
nouveau_drm_open+0x24e/0x740 drivers/gpu/drm/nouveau/nouveau_drm.c:1255
drm_file_alloc+0x5f2/0xad0 drivers/gpu/drm/drm_file.c:176
drm_open_helper+0x1d7/0x4a0 drivers/gpu/drm/drm_file.c:335
drm_open+0x190/0x3d0 drivers/gpu/drm/drm_file.c:388
drm_stub_open+0x1f2/0x460 drivers/gpu/drm/drm_drv.c:1211
chrdev_open+0x21c/0x660 fs/char_dev.c:411
do_dentry_open+0x59d/0x12b0 fs/open.c:947
vfs_open+0x82/0x390 fs/open.c:1052
do_open fs/namei.c:4700 [inline]
path_openat+0x2345/0x3420 fs/namei.c:4863
do_file_open+0x207/0x460 fs/namei.c:4892
do_sys_openat2+0xd1/0x1d0 fs/open.c:1368
do_sys_open fs/open.c:1374 [inline]
__do_sys_openat fs/open.c:1390 [inline]
__se_sys_openat fs/open.c:1385 [inline]
__x64_sys_openat+0x144/0x200 fs/open.c:1385
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x115/0x690 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fc6d687594d
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fc6d5295008 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 00007fc6d6b06180 RCX: 00007fc6d687594d
RDX: 0000000000022501 RSI: 0000200000000000 RDI: ffffffffffffff9c
RBP: 00007fc6d691c303 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fc6d6b06218 R14: 00007fc6d6b06180 R15: 00007ffd9451d760
</TASK>
Allocated by task 2567 on cpu 1 at 163.593900s:
kasan_save_stack+0x24/0x50 mm/kasan/common.c:57
kasan_save_track+0x17/0x60 mm/kasan/common.c:78
poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
__kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:415
kasan_kmalloc include/linux/kasan.h:263 [inline]
__do_kmalloc_node mm/slub.c:5334 [inline]
__kmalloc_noprof+0x304/0x7c0 mm/slub.c:5359
_kmalloc_noprof include/linux/slab.h:992 [inline]
nvif_vmm_ctor+0x3c0/0x7e0 drivers/gpu/drm/nouveau/nvif/vmm.c:237
nouveau_vmm_init+0x40/0x90 drivers/gpu/drm/nouveau/nouveau_vmm.c:134
nouveau_cli_init+0x7b9/0
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau: Fix gem reference leak in validate_init()
On the ttm_bo_reserve() failure and "vma not found" error paths, the
loop breaks without adding the looked-up object to any validate list,
so the reference taken by drm_gem_object_lookup() is never released;
validate_fini() only walks the spliced lists. Drop the reference
before breaking out on both paths. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau: Fix runtime PM leak in nouveau_connector_detect()
If nvif_outp_edid_get() fails, nouveau_connector_detect() returns
early without dropping the runtime PM reference taken at the start
of the function, keeping the device powered on until the next
successful detect.
Balance the reference on the error path like the other exit paths
do. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau: RCU-free the scheduler-containing nouveau_sched
struct nouveau_sched embeds a struct drm_gpu_scheduler (base).
nouveau_sched_destroy() calls nouveau_sched_fini() (which does
drm_sched_fini(&sched->base)) and then frees the object with plain
kfree(sched).
drm_sched_fence_get_timeline_name() returns fence->sched->name, and the
scheduler fence keeps a .release callback so it is not ops-detached on
signalling. A finished fence exported to userspace via drm_syncobj /
sync_file therefore keeps pointing at &sched->base after nouveau_sched_destroy(),
and a later get_timeline_name() -- reachable unprivileged through
SYNC_IOC_FILE_INFO -- dereferences freed memory (KASAN slab-use-after-free
read).
Per the dma-fence lifetime contract the exporter must keep the data backing a
signalled fence alive for an RCU grace period. Free the scheduler-containing
object with kfree_rcu() instead of kfree(). |
| In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau: don't bump pin count on failed re-pin in nouveau_bo_pin_locked()
nouveau_bo_pin_locked() checks whether an already pinned BO is in a
memory domain compatible with a new pin request. When the domains are
incompatible, it sets -EBUSY but still calls ttm_bo_pin() before
returning.
Callers treat a failed nouveau_bo_pin() as not having acquired a new pin,
so the extra pin count is never decreased by a matching unpin.
This triggers the warning in ttm_bo_release():
WARN_ON_ONCE(bo->pin_count);
Found when fuzzing the nouveau driver with a modified Syzkaller:
WARNING: drivers/gpu/drm/ttm/ttm_bo.c:256 at ttm_bo_release+0x827/0x9e0 drivers/gpu/drm/ttm/ttm_bo.c:256, CPU#1: syz.3.24/2212
Modules linked in:
CPU: 1 UID: 0 PID: 2212 Comm: syz.3.24 Not tainted 7.2.0 #24 PREEMPT(lazy)
nouveau 0000:01:00.0: gsp:msg fn:103 len:0x40/0x20 res:0x19 resp:0x19
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
RIP: 0010:ttm_bo_release+0x827/0x9e0 drivers/gpu/drm/ttm/ttm_bo.c:256
Code: 02 00 0f 85 51 01 00 00 48 8b 7b 08 e8 d2 20 01 00 e9 80 fd ff ff e8 d8 15 c0 fe 90 0f 0b 90 e9 e1 f8 ff ff e8 ca 15 c0 fe 90 <0f> 0b 90 e9 a4 f8 ff ff e8 bc 15 c0 fe be 03 00 00 00 4c 89 e7 e8
msg: 00000000: 05 00 d0 c1 04 00 f0 f1 01 30 00 00 2d 90 00 00 .........0..-...
RSP: 0018:ffffc9000f5cf710 EFLAGS: 00010293
RAX: 0000000000000000 RBX: ffff888018e5d2a8 RCX: ffffffff82bb1b36
RDX: ffff888017b68000 RSI: 0000000000000004 RDI: ffff888018e5d2a8
msg: 00000010: 19 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
RBP: ffff88801261c720 R08: 0000000000000001 R09: ffffed10031cba55
R10: ffff888018e5d2ab R11: 00000000000000f3 R12: ffff888018e5d290
R13: ffff888018e5d2d4 R14: ffff88801b219c18 R15: dffffc0000000000
FS: 0000000000000000(0000) GS:ffff8880e0f6f000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b31223ffc CR3: 0000000028e00005 CR4: 0000000000770ef0
PKRU: 80000000
Call Trace:
<TASK>
kref_put include/linux/kref.h:65 [inline]
ttm_bo_put drivers/gpu/drm/ttm/ttm_bo.c:325 [inline]
ttm_bo_fini+0x55/0x80 drivers/gpu/drm/ttm/ttm_bo.c:330
nouveau_gem_object_del+0xb2/0x1b0 drivers/gpu/drm/nouveau/nouveau_gem.c:90
drm_gem_object_free+0x5f/0x90 drivers/gpu/drm/drm_gem.c:1165
kref_put include/linux/kref.h:65 [inline]
__drm_gem_object_put include/drm/drm_gem.h:562 [inline]
drm_gem_object_put include/drm/drm_gem.h:575 [inline]
nouveau_abi16_chan_fini.constprop.0+0x44f/0x5a0 drivers/gpu/drm/nouveau/nouveau_abi16.c:195
nouveau 0000:01:00.0: syz.2.23[2209]: Unknown handle 0x00000000
nouveau_abi16_fini+0x1d0/0x340 drivers/gpu/drm/nouveau/nouveau_abi16.c:225
nouveau_drm_postclose+0x18b/0x3e0 drivers/gpu/drm/nouveau/nouveau_drm.c:1284
nouveau 0000:01:00.0: syz.2.23[2209]: validate_init
drm_file_free.part.0+0x6d6/0xb60 drivers/gpu/drm/drm_file.c:267
drm_file_free drivers/gpu/drm/drm_file.c:237 [inline]
drm_close_helper.isra.0+0x11a/0x160 drivers/gpu/drm/drm_file.c:290
drm_release+0x1ab/0x330 drivers/gpu/drm/drm_file.c:438
__fput+0x39c/0xa60 fs/file_table.c:512
nouveau 0000:01:00.0: syz.2.23[2209]: validate: -2
task_work_run+0x15a/0x230 kernel/task_work.c:233
exit_task_work include/linux/task_work.h:40 [inline]
do_exit+0x82b/0x25a0 kernel/exit.c:1009
do_group_exit+0xc2/0x280 kernel/exit.c:1152
get_signal+0x1d6e/0x1f30 kernel/signal.c:3046
arch_do_signal_or_restart+0x7d/0x6e0 arch/x86/kernel/signal.c:337
__exit_to_user_mode_loop kernel/entry/common.c:66 [inline]
exit_to_user_mode_loop+0xdf/0x440 kernel/entry/common.c:101
__exit_to_user_mode_prepare include/linux/irq-entry-common.h:207 [inline]
syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:230 [inline]
syscall_exit_to_user_mode include/linux/entry-common.h:318 [inline]
do_syscall_64+0x4f8/0x690 arch/x86/entry/syscall_64.c:100
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RI
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
drm/xe/vm: nuke PTs only after unlinking contested VMAs
In xe_vm_close_and_put(), external-BO VMAs are queued on the contested
list for deferred destruction via xe_vma_destroy_unlocked(). However,
xe_vm_pt_destroy() was previously invoked before processing contested
VMAs, destroying vm->pt_root while those VMAs were still linked to their
respective buffer objects (vm_bo->list.gpuva).
If a concurrent thread evicts one of those shared buffer objects,
xe_bo_trigger_rebind() holding only bo->resv walks the BO's VMAs and, in
fault mode, calls xe_vm_invalidate_vma() -> xe_pt_zap_ptes(). Because
vm->pt_root[tile->id] is already NULL, dereferencing pt->level causes a
NULL ptr deref.
Fix this by deferring xe_vm_free_scratch() and xe_vm_pt_destroy() until
after all contested VMAs have been unlinked and destroyed.
User is reporting hitting a NULL ptr deref in xe_pt_zap_ptes(), which
could be explained by this race.
(cherry picked from commit c2863648959489767f08892fd6e90577d2ea0b6a) |
| In the Linux kernel, the following vulnerability has been resolved:
drm/virtio: fix memory leak of fence event on execbuffer failure
virtio_gpu_execbuffer_ioctl() reserves a DRM event with
drm_event_reserve_init() when VIRTGPU_EXECBUF_RING_IDX selects a ring that
userspace has enabled polling for. virtio_gpu_init_submit() does this
before the BO handles, the command buffer, the syncobj arrays and the
in-fence are processed, so every later error path runs with the event
already pending, including plain argument validation failures such as an
invalid bo_handle or an in-syncobj that carries no fence.
On those paths, virtio_gpu_cleanup_submit() drops the out-fence without
cancelling the event. The fence is freed without ever having been emitted,
taking the only driver-side pointer to the event with it. Closing the DRM
file does not help. drm_events_release() unlinks pending events but
deliberately leaves the freeing to the driver's later drm_send_event(),
which never runs for an orphaned event, so the allocation is leaked
permanently.
Found when fuzzing the virtio driver with Syzkaller:
BUG: memory leak
unreferenced object 0xffff88802c176e80 (size 96):
comm "syz.1.367", pid 10561, jiffies 4294960122
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
c8 6e 17 2c 80 88 ff ff 00 00 00 00 00 00 00 00 .n.,............
backtrace (crc e1973c6b):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4597 [inline]
slab_alloc_node mm/slub.c:4917 [inline]
__kmalloc_cache_noprof+0x49d/0x6f0 mm/slub.c:5485
_kmalloc_noprof include/linux/slab.h:988 [inline]
_kzalloc_noprof include/linux/slab.h:1309 [inline]
virtio_gpu_fence_event_create drivers/gpu/drm/virtio/virtgpu_submit.c:282 [inline]
virtio_gpu_init_submit drivers/gpu/drm/virtio/virtgpu_submit.c:398 [inline]
virtio_gpu_execbuffer_ioctl+0xbbf/0x1aa0 drivers/gpu/drm/virtio/virtgpu_submit.c:505
drm_ioctl_kernel+0x1f4/0x3e0 drivers/gpu/drm/drm_ioctl.c:817
drm_ioctl+0x5f4/0xc70 drivers/gpu/drm/drm_ioctl.c:914
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl fs/ioctl.c:583 [inline]
__x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x116/0x800 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Fix by cancelling and freeing the DRM event on the execbuffer error path
before dropping the fence. Clear the fence's event pointer after
cancellation so it does not retain a dangling pointer. |
| In the Linux kernel, the following vulnerability has been resolved:
drm/virtio: fix NULL pointer dereference on fence allocation failure
virtio_gpu_fence_alloc() can fail due to memory pressure and return NULL,
but its caller like virtio_gpu_init_submit() never checks it. Later,
virtio_gpu_init_submit() passes the NULL fence to
virtio_gpu_fence_event_create(), which unconditionally dereferences it.
Found when fuzzing the virtio driver with Syzkaller:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000012: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000090-0x0000000000000097]
CPU: 1 UID: 0 PID: 9991 Comm: syz.0.121 Not tainted 7.2.0 #4 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
RIP: 0010:virtio_gpu_fence_event_create drivers/gpu/drm/virtio/virtgpu_submit.c:295 [inline]
RIP: 0010:virtio_gpu_init_submit drivers/gpu/drm/virtio/virtgpu_submit.c:398 [inline]
RIP: 0010:virtio_gpu_execbuffer_ioctl+0xc78/0x1aa0 drivers/gpu/drm/virtio/virtgpu_submit.c:505
Code: 85 ed 0f 85 21 09 00 00 e8 05 5a c9 fb 48 8b 44 24 10 48 8d b8 90 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 9a 0d 00 00 48 8b 44 24 10 4c 89 b0 90 00 00 00
RSP: 0018:ffffc900039dfad0 EFLAGS: 00010216
RAX: dffffc0000000000 RBX: ffffc900039dfdd8 RCX: ffffffff85f6fd3d
RDX: 0000000000000012 RSI: ffffffff85f6fd4b RDI: 0000000000000090
RBP: 0000000000000000 R0virtio_gpu_virgl_process_cmd: ctrl 0x102, error 0x1203
R10: 0000000000000000 R11: 0000000000000000 R12: ffff8880132c4000
R13: 0000000000000000 R14: ffff888073b6c700 R15: 000000000000003b
FS: 00007fab480b96c0(0000) GS:ffff8880eb6e9000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007effbf5e55a8 CR3: 0000000048d19000 CR4: 0000000000350ef0
Call Trace:
<TASK>
drm_ioctl_kernel+0x1f4/0x3e0 drivers/gpu/drm/drm_ioctl.c:817
drm_ioctl+0x5f4/0xc70 drivers/gpu/drm/drm_ioctl.c:914
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl fs/ioctl.c:583 [inline]
__x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x116/0x800 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fab471a82bd
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fab480b9018 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007fab47435fa0 RCX: 00007fab471a82bd
RDX: 00002000000000c0 RSI: 00000000c0406442 RDI: 0000000000000003
RBP: 00007fab480b9080 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
R13: 00007fab47436038 R14: 00007fab47435fa0 R15: 00007ffe85ab0740
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:virtio_gpu_fence_event_create drivers/gpu/drm/virtio/virtgpu_submit.c:295 [inline]
RIP: 0010:virtio_gpu_init_submit drivers/gpu/drm/virtio/virtgpu_submit.c:398 [inline]
RIP: 0010:virtio_gpu_execbuffer_ioctl+0xc78/0x1aa0 drivers/gpu/drm/virtio/virtgpu_submit.c:505
Code: 85 ed 0f 85 21 09 00 00 e8 05 5a c9 fb 48 8b 44 24 10 48 8d b8 90 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 9a 0d 00 00 48 8b 44 24 10 4c 89 b0 90 00 00 00
RSP: 0018:ffffc900039dfad0 EFLAGS: 00010216
RAX: dffffc0000000000 RBX: ffffc900039dfdd8 RCX: ffffffff85f6fd3d
RDX: 0000000000000012 RSI: ffffffff85f6fd4b RDI: 0000000000000090
RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: ffff8880132c4000
R13: 0000000000000000 R14: ffff888073b6c700 R15: 000000000000003b
FS: 00007fab480b96c0(0000) GS:ffff888098ae9000(0000) knlGS:00000000
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish
On arm64 server, we find that a task trying to grab the anon_vma lock
triggers hungtask.
INFO: task main:2354726 blocked for more than 120 seconds.
Tainted: G E 5.10.0-0021.aarch64 #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:main state:D stack: 0 pid:2354726 ppid:2350673 flags:0x00000a01
Call trace:
__switch_to+0x7c/0xbc
__schedule+0x3b4/0x8a0
schedule+0x50/0xe0
rwsem_down_write_slowpath+0x3cc/0x6cc
down_write+0x60/0x260
__anon_vma_prepare+0x6c/0x210
do_anonymous_page+0x258/0x660
handle_pte_fault+0x188/0x214
__handle_mm_fault+0x1b0/0x380
handle_mm_fault+0xf4/0x284
do_page_fault+0x19c/0x494
do_translation_fault+0xcc/0xf8
do_mem_abort+0x48/0xac
el0_da+0x44/0x80
el0_sync_handler+0x88/0xb4
el0_sync+0x160/0x180
After analyzing the vmcore, we found the anon_vma->root->rwsem.count is
-1. There is another anon_vma whose anon_vma->root->rwsem.count is 1, the
anon_vma->root->rwsem.owner shows the lock is held, but the stack of the
task shows the task doesn't hold the anon_vma lock.
After adding more debugging info, we found __anon_vma_prepare() reuses
anon_vma and triggers the UAF of anon_vma->root due to missing memory
barrier, leading to locking and unlocking two different anon_vma->root,
thus leading to an anon_vma will never be unlocked, and another anon_vma
couldn't be locked anymore.
This race requires two adjacent VMAs that are not merged but are
anon_vma-compatible (e.g., they differ in VMA_ACCESS_FLAGS that can be
changed by mprotect()). Two threads fault on each VMA concurrently, both
calling __anon_vma_prepare() with only mmap_lock held for reading.
THREAD A THREAD B
__anon_vma_prepare __anon_vma_prepare
find_mergeable_anon_vma() -> NULL
anon_vma = anon_vma_alloc();
anon_vma->root = anon_vma;
// the two stores may be reordered
vma->anon_vma = anon_vma;
// finds A's anon_vma
anon_vma = find_mergeable_anon_vma(vma);
anon_vma_lock_write(anon_vma);
// may still see the old root
down_write(&anon_vma->root->rwsem);
anon_vma_unlock_write(anon_vma);
// see the new root, never unlock old
up_write(&anon_vma->root->rwsem);
thread A triggers page fault and calls __anon_vma_prepare() to prepare
anon_vma for the faulting vma. __anon_vma_prepare() allocates and
initializes a new anon_vma, and then publishes it to the vma with a plain
store. anon_vma_prepare() only requires the mmap_lock to be held for
reading, so two threads can fault on adjacent VMAs at the same time.
While thread A publishes a new anon_vma, thread B could find the anon_vma
via find_mergeable_anon_vma() and then locks anon_vma->root->rwsem.
The store to anon_vma->root in anon_vma_alloc() and the store to
vma->anon_vma can be reordered. The anon_vma_lock_write() and spin_lock()
only provide acquire semantics, which do not prevent prior stores from
being reordered after them. The release semantics of the corresponding
spin_unlock() and anon_vma_unlock_write() come too late, the store to
vma->anon_vma is already published before they take effect. As a result,
thread B can observe the following order:
vma->anon_vma = anon_vma;
anon_vma->root = anon_vma;
The anon_vma slab is SLAB_TYPESAFE_BY_RCU, so a newly allocated anon_vma
may reuse memory from a previously freed one. The constructor
(anon_vma_ctor) does not reset anon_vma->root, and __put_anon_vma()
doesn't clear it either, so the old root value persists until
anon_vma_alloc() overwrites it. If that store isn't v
---truncated--- |
| In the Linux kernel, the following vulnerability has been resolved:
mm/hugetlb: do not dissolve gigantic pages without runtime support
dissolve_free_hugetlb_folio() doesn't check
hstate_is_gigantic_no_runtime(h) though remove_hugetlb_folio()/
update_and_free_hugetlb_folio() silently bail for such folios, so it frees
a still-listed folio and, on vmemmap restore failure, the
add_hugetlb_folio() rollback corrupts the free list. |
| In the Linux kernel, the following vulnerability has been resolved:
mm/damon/vaddr: avoid hw-driven pte updates during damon_hugetlb_mkold()
damon_hugetlb_mkold() reads the page table entry into a local variable,
unsets the accessed bit in the variable, and updates the page table entry
with the updated variable value. If hardware updates the same page table
entry in parallel, the hw updates could be lost. For example,
hardware-updated dirty bits might be lost.
Avoid the parallel updates by clearing the page table entry when reading
it together, using huge_ptep_get_and_clear(). If a parallel write to the
memory is made after the clearing, the hw will see the page table entry is
cleared, trigger page fault and wait until it is handled. The page fault
handling will wait for damon_hugetlb_mkold() due to the page table lock.
Because hugetlbfs is an in-memory file system and hugetlb pages cannot be
reclaimed, no critical issue is expected to my best knowledge. But
definitely this is a nasty bug that should be fixed sooner rather than
later.
The issue was discovered [1] by Sashiko. |