Re: [PATCH 10/12] drm/panthor: Make the VM cleanup path more robust against UAF
[email protected] Tue, 04 Aug 2026 15:23:51 +0000
| Newsgroups | org.freedesktop.lists.dri-devel |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [High] Use-After-Free of `mmu` structure during device teardown due to incorrect drmm action registration order. - [Medium] Memory leak of stranded VMs in `cleanup_list` if the device suspends before a scheduled reset can execute. -- --- Patch [10]: [PATCH 10/12] drm/panthor: Make the VM cleanup path more robust against UAF --- commit 67363ef0cc8662df9cc3d191fcef3a128e79f9d4 Author: Boris Brezillon <[email protected]> Subject: drm/panthor: Make the VM cleanup path more robust against UAF The VM cleanup tries to gracefully evict the page table from its AS slot to make sure the HW doesn't have access to the memory anymore. But it might happen that the eviction fails because the HW hung, and in that case, we have no guarantee that the HW won't access the memory until we've properly reset the GPU. Defer the cleanup of VMs after the reset is effective when this situation happens. diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c [ ... ] @@ -2098,64 +2129,114 @@ void panthor_mmu_post_reset(struct panthor_device *ptdev) > + if (!drm_dev_enter(&ptdev->base, &cookie)) { > + guard(mutex)(&ptdev->mmu->as.slots_lock); > > - if (drm_dev_enter(&ptdev->base, &cookie)) { > - panthor_mmu_as_disable(ptdev, as->hw_slot.id, false); > - drm_dev_exit(cookie); > + /* We're in the unplug path and can't recover from > + * that, so we just forcibly evict the pgtable. The > + * no-unmap restriction will leak resources if > + * we can't guarantee the HW stopped. > + */ > + if (as->hw_slot.id >= 0) > + panthor_as_release_hw_slot_locked(as); > > - panthor_as_release_hw_slot_locked(as); > + return true; > + } > > - } > - mutex_unlock(&ptdev->mmu->as.slots_lock); > - mutex_unlock(&vm->as->op_lock); > > - if (vm->dummy) > - drm_gem_object_put(&vm->dummy->base); > + scoped_guard(mutex, &ptdev->mmu->as.slots_lock) { > + if (as->hw_slot.id >= 0) { > + ret = panthor_mmu_as_disable(ptdev, as->hw_slot.id, false); > + if (!ret) { > + panthor_as_release_hw_slot_locked(as); > + } else { > + list_add_tail(&vm->node, &ptdev->mmu->as.cleanup_list); > + panthor_device_schedule_reset(ptdev); [Severity: Medium] Could this leak stranded VMs if the device suspends before the scheduled reset executes? If a hardware hang prevents AS slot eviction here, the VM is added to the cleanup_list and a reset is scheduled. If the device suspends before the reset work executes, panthor_device_suspend() synchronously cancels the reset work. During resume, panthor_mmu_resume() is called but does not invoke mmu_post_reset_cleanup() to process this cleanup_list, leaving the VMs stranded. > + } > } > > - panthor_as_release_hw_slot_locked(as); > + /* Page table is no longer resident, we can relax the no-unmap > + * restriction. > + */ > + ready_for_cleanup = as->hw_slot.id < 0; > + if (ready_for_cleanup) > + atomic_and(~PANTHOR_AS_FORBID_UNMAP, &as->restrictions); > } [ ... ] @@ -3488,6 +3573,27 @@ static void panthor_mmu_info_init(struct panthor_device *ptdev) > ptdev->mmu_info.page_size_bitmap = SZ_4K | SZ_2M; > } > > +static void mmu_cleanup_vms_work(struct work_struct *work) > +{ > + struct panthor_mmu *mmu = > + container_of(work, struct panthor_mmu, vm.cleanup_work); > + struct panthor_vm *vm, *tmp; > + LIST_HEAD(cleanup_list); > + > + /* Collect the VMs to cleanup first. */ > + scoped_guard(mutex, &mmu->as.slots_lock) { > + list_for_each_entry_safe(vm, tmp, &mmu->as.cleanup_list, node) { [Severity: High] Can this result in a use-after-free during device teardown? In panthor_device_init(), the panthor_device_flush_cleanup_wq action is registered via drmm_add_action() before panthor_mmu_init() is called. Then, in panthor_mmu_init(), ptdev->mmu is allocated via drmm_kzalloc(). Because drmm actions execute in LIFO order, ptdev->mmu will be freed before the workqueue is flushed. If this delayed work is pending or running during teardown, it will access the already-freed mmu structure here when trying to acquire the as.slots_lock. > + if (vm->as->hw_slot.id < 0) > + list_move_tail(&vm->node, &cleanup_list); > + } > + } > + > + list_for_each_entry_safe(vm, tmp, &cleanup_list, node) { > + list_del(&vm->node); > + vm_cleanup(vm); > + } > +} > + -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=10