Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <olvaffe@gmail.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Chia-I Wu and committed by
Alex Deucher
629fcf0b 22f1482a

+10 -6
+10 -6
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
··· 1312 1312 args->n_success = i+1; 1313 1313 } 1314 1314 1315 - mutex_unlock(&p->mutex); 1316 - 1317 1315 err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev, (struct kgd_mem *) mem, true); 1318 1316 if (err) { 1319 1317 pr_debug("Sync memory failed, wait interrupted by user signal\n"); 1320 1318 goto sync_memory_failed; 1321 1319 } 1320 + 1321 + mutex_unlock(&p->mutex); 1322 1322 1323 1323 /* Flush TLBs after waiting for the page table updates to complete */ 1324 1324 for (i = 0; i < args->n_devices; i++) { ··· 1335 1335 bind_process_to_device_failed: 1336 1336 get_mem_obj_from_handle_failed: 1337 1337 map_memory_to_gpu_failed: 1338 + sync_memory_failed: 1338 1339 mutex_unlock(&p->mutex); 1339 1340 copy_from_user_failed: 1340 - sync_memory_failed: 1341 1341 kfree(devices_arr); 1342 1342 1343 1343 return err; ··· 1351 1351 void *mem; 1352 1352 long err = 0; 1353 1353 uint32_t *devices_arr = NULL, i; 1354 + bool flush_tlb; 1354 1355 1355 1356 if (!args->n_devices) { 1356 1357 pr_debug("Device IDs array empty\n"); ··· 1404 1403 } 1405 1404 args->n_success = i+1; 1406 1405 } 1407 - mutex_unlock(&p->mutex); 1408 1406 1409 - if (kfd_flush_tlb_after_unmap(pdd->dev)) { 1407 + flush_tlb = kfd_flush_tlb_after_unmap(pdd->dev); 1408 + if (flush_tlb) { 1410 1409 err = amdgpu_amdkfd_gpuvm_sync_memory(pdd->dev->adev, 1411 1410 (struct kgd_mem *) mem, true); 1412 1411 if (err) { 1413 1412 pr_debug("Sync memory failed, wait interrupted by user signal\n"); 1414 1413 goto sync_memory_failed; 1415 1414 } 1415 + } 1416 + mutex_unlock(&p->mutex); 1416 1417 1418 + if (flush_tlb) { 1417 1419 /* Flush TLBs after waiting for the page table updates to complete */ 1418 1420 for (i = 0; i < args->n_devices; i++) { 1419 1421 peer_pdd = kfd_process_device_data_by_id(p, devices_arr[i]); ··· 1432 1428 bind_process_to_device_failed: 1433 1429 get_mem_obj_from_handle_failed: 1434 1430 unmap_memory_from_gpu_failed: 1431 + sync_memory_failed: 1435 1432 mutex_unlock(&p->mutex); 1436 1433 copy_from_user_failed: 1437 - sync_memory_failed: 1438 1434 kfree(devices_arr); 1439 1435 return err; 1440 1436 }