Commit de15e623 authored by Mansur Alisha Shaik's avatar Mansur Alisha Shaik Committed by Mauro Carvalho Chehab

media: venus: handle use after free for iommu_map/iommu_unmap

In concurrency usecase and reboot scenario we are seeing muliple
crashes related to iommu_map/iommu_unamp of core->fw.iommu_domain.

In one case we are seeing "Unable to handle kernel NULL pointer
dereference at virtual address 0000000000000008" crash, this is
because of core->fw.iommu_domain in venus_firmware_deinit() and
trying to map in venus_boot() during venus_sys_error_handler()

Call trace:
 __iommu_map+0x4c/0x348
 iommu_map+0x5c/0x70
 venus_boot+0x184/0x230 [venus_core]
 venus_sys_error_handler+0xa0/0x14c [venus_core]
 process_one_work+0x210/0x3d0
 worker_thread+0x248/0x3f4
 kthread+0x11c/0x12c
 ret_from_fork+0x10/0x18

In second case we are seeing "Unable to handle kernel paging request
at virtual address 006b6b6b6b6b6b9b" crash, this is because of
unmapping iommu domain which is already unmapped.

Call trace:
 venus_remove+0xf8/0x108 [venus_core]
 venus_core_shutdown+0x1c/0x34 [venus_core]
 platform_drv_shutdown+0x28/0x34
 device_shutdown+0x154/0x1fc
 kernel_restart_prepare+0x40/0x4c
 kernel_restart+0x1c/0x64
 __arm64_sys_reboot+0x190/0x238
 el0_svc_common+0xa4/0x154
 el0_svc_compat_handler+0x2c/0x38
 el0_svc_compat+0x8/0x10
Signed-off-by: default avatarMansur Alisha Shaik <mansur@codeaurora.org>
Signed-off-by: default avatarStanimir Varbanov <stanimir.varbanov@linaro.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 9696960f
......@@ -171,9 +171,14 @@ static int venus_shutdown_no_tz(struct venus_core *core)
iommu = core->fw.iommu_domain;
unmapped = iommu_unmap(iommu, VENUS_FW_START_ADDR, mapped);
if (unmapped != mapped)
dev_err(dev, "failed to unmap firmware\n");
if (core->fw.mapped_mem_size && iommu) {
unmapped = iommu_unmap(iommu, VENUS_FW_START_ADDR, mapped);
if (unmapped != mapped)
dev_err(dev, "failed to unmap firmware\n");
else
core->fw.mapped_mem_size = 0;
}
return 0;
}
......@@ -305,7 +310,11 @@ void venus_firmware_deinit(struct venus_core *core)
iommu = core->fw.iommu_domain;
iommu_detach_device(iommu, core->fw.dev);
iommu_domain_free(iommu);
if (core->fw.iommu_domain) {
iommu_domain_free(iommu);
core->fw.iommu_domain = NULL;
}
platform_device_unregister(to_platform_device(core->fw.dev));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment