On Fri, Jun 12, 2026 at 10:29 PM Mario Limonciello <[email protected]> wrote: > > The cleanup tail of kfd_criu_resume_svm() walks > svms->criu_svm_metadata_list and kfree()s each struct criu_svm_metadata > without removing it from the list. The list head is left pointing at > freed kmalloc-96 objects. > > A second AMDKFD_IOC_CRIU_OP from the same process re-enters: list_empty() > reads the dangling ->next (use-after-free), the loop walks freed entries, > and each is kfree()'d again (double-free). This is reachable by an > unprivileged render-group user via /dev/kfd with no capabilities required. > > Add list_del() before the kfree() so the list is properly emptied. The > list_for_each_entry_safe() iterator already caches the next pointer, so > unlinking during the walk is safe. > > Fixes: 2a909ae71871 ("drm/amdkfd: CRIU resume shared virtual memory ranges") > Signed-off-by: Mario Limonciello <[email protected]>
Reviewed-by: Alex Deucher <[email protected]> > --- > drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c > b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c > index 8d241ad760f19..df7fca65e9a21 100644 > --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c > @@ -4115,6 +4115,7 @@ int kfd_criu_resume_svm(struct kfd_process *p) > list_for_each_entry_safe(criu_svm_md, next, > &svms->criu_svm_metadata_list, list) { > pr_debug("freeing criu_svm_md[]\n\tstart: 0x%llx\n", > criu_svm_md->data.start_addr); > + list_del(&criu_svm_md->list); > kfree(criu_svm_md); > } > > -- > 2.43.0 >
