From 4c62b1aad4a29f065ef0509f8d609bc4cef73586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konsta=20H=C3=B6ltt=C3=A4?= Date: Tue, 5 Oct 2021 11:20:23 +0300 Subject: [PATCH] gpu: nvgpu: unit: avoid use-after-free in unmap test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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ä Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2605495 Reviewed-by: Alex Waterman Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions --- userspace/units/mm/vm/vm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/userspace/units/mm/vm/vm.c b/userspace/units/mm/vm/vm.c index a9fdccdec..c49d6ac93 100644 --- a/userspace/units/mm/vm/vm.c +++ b/userspace/units/mm/vm/vm.c @@ -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)) {