gpu: nvgpu: unit: avoid use-after-free in unmap test

The error path in map_buffer() attempts to unmap a buffer twice to check
that such action does not cause errors. The call site uses a field of a
freed structure in the second call; store that in a local variable to
avoid reading freed memory.

Change-Id: I20fe66cf255dce25b1c4012bda2a6f864daf419a
Signed-off-by: Konsta Hölttä <kholtta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2605495
Reviewed-by: Alex Waterman <alexw@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Konsta Hölttä
2021-10-05 11:20:23 +03:00
committed by mobile promotions
parent dedde87e48
commit 4c62b1aad4

View File

@@ -789,18 +789,25 @@ static int map_buffer(struct unit_module *m,
free_mapped_buf: free_mapped_buf:
if ((mapped_buf != NULL) && !(subcase & SPECIAL_CASE_NO_FREE)) { if ((mapped_buf != NULL) && !(subcase & SPECIAL_CASE_NO_FREE)) {
/*
* A second unmap will be attempted; the first one will free
* mapped_buf, so get the address before that happens.
*/
u64 buf_addr = mapped_buf->addr;
if (subcase & SPECIAL_CASE_TIMEOUT_INIT_FAIL) { if (subcase & SPECIAL_CASE_TIMEOUT_INIT_FAIL) {
nvgpu_posix_enable_fault_injection(timers_fi, true, 0); nvgpu_posix_enable_fault_injection(timers_fi, true, 0);
nvgpu_vm_unmap(vm, mapped_buf->addr, batch); nvgpu_vm_unmap(vm, buf_addr, batch);
nvgpu_posix_enable_fault_injection(timers_fi, false, 0); nvgpu_posix_enable_fault_injection(timers_fi, false, 0);
} else { } else {
nvgpu_vm_unmap(vm, mapped_buf->addr, batch); nvgpu_vm_unmap(vm, buf_addr, batch);
} }
mapped_buf = NULL;
/* /*
* Unmapping an already unmapped buffer should not cause any * Unmapping an already unmapped buffer should not cause any
* errors. * errors.
*/ */
nvgpu_vm_unmap(vm, mapped_buf->addr, batch); nvgpu_vm_unmap(vm, buf_addr, batch);
} }
free_vm_area: free_vm_area:
if (fixed_gpu_va && !(subcase & SPECIAL_CASE_NO_FREE)) { if (fixed_gpu_va && !(subcase & SPECIAL_CASE_NO_FREE)) {