Skip to content

Commit 9da050b

Browse files
olvaffealexdeucher
authored andcommitted
drm/amdkfd: fix potential kgd_mem UAFs
kgd_mem pointers returned by kfd_process_device_translate_handle are only guaranteed to be valid while p->mutex is held. As soon as the mutex is unlocked, another thread can free the BO. Signed-off-by: Chia-I Wu <[email protected]> Signed-off-by: Felix Kuehling <[email protected]> Reviewed-by: Felix Kuehling <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent d71e38d commit 9da050b

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

drivers/gpu/drm/amd/amdkfd/kfd_chardev.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,14 +1312,14 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
13121312
args->n_success = i+1;
13131313
}
13141314

1315-
mutex_unlock(&p->mutex);
1316-
13171315
err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev, (struct kgd_mem *) mem, true);
13181316
if (err) {
13191317
pr_debug("Sync memory failed, wait interrupted by user signal\n");
13201318
goto sync_memory_failed;
13211319
}
13221320

1321+
mutex_unlock(&p->mutex);
1322+
13231323
/* Flush TLBs after waiting for the page table updates to complete */
13241324
for (i = 0; i < args->n_devices; i++) {
13251325
peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
@@ -1335,9 +1335,9 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
13351335
bind_process_to_device_failed:
13361336
get_mem_obj_from_handle_failed:
13371337
map_memory_to_gpu_failed:
1338+
sync_memory_failed:
13381339
mutex_unlock(&p->mutex);
13391340
copy_from_user_failed:
1340-
sync_memory_failed:
13411341
kfree(devices_arr);
13421342

13431343
return err;
@@ -1351,6 +1351,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
13511351
void *mem;
13521352
long err = 0;
13531353
uint32_t *devices_arr = NULL, i;
1354+
bool flush_tlb;
13541355

13551356
if (!args->n_devices) {
13561357
pr_debug("Device IDs array empty\n");
@@ -1403,16 +1404,19 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
14031404
}
14041405
args->n_success = i+1;
14051406
}
1406-
mutex_unlock(&p->mutex);
14071407

1408-
if (kfd_flush_tlb_after_unmap(pdd->dev)) {
1408+
flush_tlb = kfd_flush_tlb_after_unmap(pdd->dev);
1409+
if (flush_tlb) {
14091410
err = amdgpu_amdkfd_gpuvm_sync_memory(pdd->dev->adev,
14101411
(struct kgd_mem *) mem, true);
14111412
if (err) {
14121413
pr_debug("Sync memory failed, wait interrupted by user signal\n");
14131414
goto sync_memory_failed;
14141415
}
1416+
}
1417+
mutex_unlock(&p->mutex);
14151418

1419+
if (flush_tlb) {
14161420
/* Flush TLBs after waiting for the page table updates to complete */
14171421
for (i = 0; i < args->n_devices; i++) {
14181422
peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]);
@@ -1428,9 +1432,9 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
14281432
bind_process_to_device_failed:
14291433
get_mem_obj_from_handle_failed:
14301434
unmap_memory_from_gpu_failed:
1435+
sync_memory_failed:
14311436
mutex_unlock(&p->mutex);
14321437
copy_from_user_failed:
1433-
sync_memory_failed:
14341438
kfree(devices_arr);
14351439
return err;
14361440
}

0 commit comments

Comments
 (0)