mirror of
https://github.com/torvalds/linux.git
synced 2026-05-03 22:12:32 -04:00
drm/amdgpu/userq: refcount userqueues to avoid any race conditions
To avoid race condition and avoid UAF cases, implement kref
based queues and protect the below operations using xa lock
a. Getting a queue from xarray
b. Increment/Decrement it's refcount
Every time some one want to access a queue, always get via
amdgpu_userq_get to make sure we have locks in place and get
the object if active.
A userqueue is destroyed on the last refcount is dropped which
typically would be via IOCTL or during fini.
v2: Add the missing drop in one the condition in the signal ioclt [Alex]
v3: remove the queue from the xarray first in the free queue ioctl path
[Christian]
- Pass queue to the amdgpu_userq_put directly.
- make amdgpu_userq_put xa_lock free since we are doing put for each get
only and final put is done via destroy and we remove the queue from xa
with lock.
- use userq_put in fini too so cleanup is done fully.
v4: Use xa_erase directly rather than doing load and erase in free
ioctl. Also remove some of the error logs which could be exploited
by the user to flood the logs [Christian]
Signed-off-by: Sunil Khatri <sunil.khatri@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 4952189b28)
Cc: <stable@vger.kernel.org> # 048c1c4e51: drm/amdgpu/userq: Consolidate wait ioctl exit path
Cc: <stable@vger.kernel.org>
This commit is contained in:
committed by
Alex Deucher
parent
048c1c4e51
commit
65b5c326ce
@@ -74,6 +74,7 @@ struct amdgpu_usermode_queue {
|
||||
struct dentry *debugfs_queue;
|
||||
struct delayed_work hang_detect_work;
|
||||
struct dma_fence *hang_detect_fence;
|
||||
struct kref refcount;
|
||||
|
||||
struct list_head userq_va_list;
|
||||
};
|
||||
@@ -112,6 +113,9 @@ struct amdgpu_db_info {
|
||||
struct amdgpu_userq_obj *db_obj;
|
||||
};
|
||||
|
||||
struct amdgpu_usermode_queue *amdgpu_userq_get(struct amdgpu_userq_mgr *uq_mgr, u32 qid);
|
||||
void amdgpu_userq_put(struct amdgpu_usermode_queue *queue);
|
||||
|
||||
int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
|
||||
|
||||
int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *file_priv,
|
||||
|
||||
Reference in New Issue
Block a user