mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
platform: nvadsp: check evp address before copying
When ADSP OS is loaded from adsp.elf, it loads two sections : adsp os and the vector table. The vector table is copied to a local buffer before writing to the EVP registers. There is a probability that, if the adsp.elf is hacked / modified by an attacker, it can write to other APE register spaces. Hence, the destination address obtained from the elf is checked with evp base before copying. Also, this fixes out of array-bound writing to evp buffer. Bug 1684844 Change-Id: I8981dc5a5db8e0c0653ff46a1576df2c82e420be Signed-off-by: Ajay Nandakumar <anandakumarm@nvidia.com> Reviewed-on: http://git-master/r/1118936 (cherry picked from commit 9f7120e03e66b5f6e2bf67f09063da20945be238) Reviewed-on: http://git-master/r/1458894 Signed-off-by: Nitin Kumbhar <nkumbhar@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1537317 Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
Laxman Dewangan
parent
a37d2fe7e3
commit
34470e65b4
@@ -159,6 +159,15 @@ static int __init nvadsp_parse_dt(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
for (iter = 0; iter < ADSP_EVP_END; iter++) {
|
||||
if (of_property_read_u32_index(dev->of_node,
|
||||
"nvidia,adsp-evp-base",
|
||||
iter, &drv_data->evp_base[iter])) {
|
||||
dev_err(dev, "adsp memory dt %d not found\n", iter);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
drv_data->adsp_unit_fpga = of_property_read_bool(dev->of_node,
|
||||
"nvidia,adsp_unit_fpga");
|
||||
|
||||
@@ -178,6 +187,11 @@ static int __init nvadsp_parse_dt(struct platform_device *pdev)
|
||||
}
|
||||
nvadsp_parse_clk_entries(pdev);
|
||||
|
||||
drv_data->state.evp = devm_kzalloc(dev,
|
||||
drv_data->evp_base[ADSP_EVP_SIZE], GFP_KERNEL);
|
||||
if (!drv_data->state.evp)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,12 @@
|
||||
#include "amc.h"
|
||||
#include "os.h"
|
||||
|
||||
enum adsp_evp_dt {
|
||||
ADSP_EVP_BASE,
|
||||
ADSP_EVP_SIZE,
|
||||
ADSP_EVP_END,
|
||||
};
|
||||
|
||||
enum adsp_unit_fpga_reset {
|
||||
ADSP_ASSERT,
|
||||
ADSP_DEASSERT,
|
||||
@@ -71,7 +77,7 @@ struct nvadsp_pm_state {
|
||||
u32 aram[AMC_ARAM_WSIZE];
|
||||
uint32_t amc_regs[AMC_REGS];
|
||||
uint32_t amisc_regs[AMISC_REGS];
|
||||
u32 evp[AMC_EVP_WSIZE];
|
||||
u32 *evp;
|
||||
void *evp_ptr;
|
||||
};
|
||||
|
||||
@@ -140,6 +146,7 @@ struct nvadsp_drv_data {
|
||||
int agic_irqs[NVADSP_VIRQ_MAX];
|
||||
|
||||
struct tegra_bwmgr_client *bwmgr;
|
||||
u32 evp_base[ADSP_EVP_END];
|
||||
};
|
||||
|
||||
#define ADSP_CONFIG 0x04
|
||||
|
||||
@@ -559,12 +559,20 @@ static int nvadsp_os_elf_load(const struct firmware *fw)
|
||||
|
||||
/* put the segment where the remote processor expects it */
|
||||
if (filesz) {
|
||||
if (!is_adsp_dram_addr(da)) {
|
||||
if (is_adsp_dram_addr(da))
|
||||
memcpy(va, elf_data + offset, filesz);
|
||||
else if ((da == drv_data->evp_base[ADSP_EVP_BASE]) &&
|
||||
(filesz == drv_data->evp_base[ADSP_EVP_SIZE])) {
|
||||
|
||||
drv_data->state.evp_ptr = va;
|
||||
memcpy(drv_data->state.evp,
|
||||
elf_data + offset, filesz);
|
||||
} else
|
||||
memcpy(va, elf_data + offset, filesz);
|
||||
elf_data + offset, filesz);
|
||||
} else {
|
||||
dev_err(dev, "can't load mem pa:0x%x va:%p\n",
|
||||
da, va);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user