A struct kref is embedded in user queue, which manages the lifecycle of a user queue. However, several code paths access user queues without hoding the kref of a user queue, especially from the doorbell XArray.
These accesses can race with the queue destruction process and result in use-after-free bugs. To fix this issue, this commit: 1) Introduces a new helper amdgpu_lookup_queue_by_doorbell, which looks up a user queue with locking and hold its kref during access. 2) Implement asynchronous userq destruction routine, because the last put of a queue kref may be placed in a code path where can not sleep or conflict locking with the destruction process. 3) Hold kref during access the user queues 4) Keep the userq manager alive as long as its queues, to avoid UAF issues. This seires passed amd_basic tests in igt tests Zhu Lingshan (10): drm/amdgpu: introduce amdgpu_lookup_queue_by_doorbell drm/amdgpu: keep the userq manager alive as long as its queues drm/amdgpu/gfx11: hold userq refs in private fault worker drm/amdgpu/gfx12: hold userq refs in private fault worker drm/amdgpu: implement asynchronous userq destruction routine drm/amdgpu: hold userq kref in MES reset drm/amdgpu: hold userq kref during isolation scheduling drm/amdgpu: hold userq kref during suspend and resume drm/amdgpu: free userq by kref_put when fails to create drm/amdgpu: take queue kref in userq_create to avoid UAF drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 214 +++++++++++++++++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 18 ++ drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 46 ++--- 5 files changed, 246 insertions(+), 46 deletions(-) -- 2.53.0
