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:
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) {
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);
} 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
* errors.
*/
nvgpu_vm_unmap(vm, mapped_buf->addr, batch);
nvgpu_vm_unmap(vm, buf_addr, batch);
}
free_vm_area:
if (fixed_gpu_va && !(subcase & SPECIAL_CASE_NO_FREE)) {