diff options
author | Tien Fong Chee <tien.fong.chee@intel.com> | 2021-06-14 22:44:54 -0700 |
---|---|---|
committer | Lokanathan, Raaj <raaj.lokanathan@intel.com> | 2022-07-28 00:38:25 +0800 |
commit | 657397579859a1e09d4d97b332e3e393fefef3ca (patch) | |
tree | fc9ed5e9323dd179cf542924a2cdc932d085971b | |
parent | 7df7639aebe41bef77b5fc19c657991b396f6f85 (diff) | |
download | u-boot-socfpga-657397579859a1e09d4d97b332e3e393fefef3ca.tar.gz |
ddr: altera: n5x: Ensure 'cal->header.data_len' is validated
Klocwork reported the unvalidated integer value 'cal->header.data_len' is
used but this is not a issue because the proper value is calculated before
assigning 'cal->header.data_len' and CRC32 is generated before saving
this value into QSPI to ensure data integrity when reading this variable.
Adding checking on 'cal->header.data_len' to ensure the value is valid for
the sake of good coding practice.
Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
-rw-r--r-- | drivers/ddr/altera/sdram_n5x.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c index 29ea09a222..fe9f9bb390 100644 --- a/drivers/ddr/altera/sdram_n5x.c +++ b/drivers/ddr/altera/sdram_n5x.c @@ -1102,8 +1102,8 @@ static void phy_ocram(phys_addr_t phy_base, phys_addr_t phy_offset, } } -static void cal_data_ocram(phys_addr_t phy_base, u32 addr, - enum data_process proc) +static int cal_data_ocram(phys_addr_t phy_base, u32 addr, + enum data_process proc) { /* * This array variable contains a list of PHY registers required for @@ -1428,6 +1428,13 @@ static void cal_data_ocram(phys_addr_t phy_base, u32 addr, cal->header.ddrconfig_hash, CHUNKSZ_PER_WD_RESET); + if (SOC64_HANDOFF_BASE < ((uintptr_t)(&cal->data) + + cal->header.data_len)) { + debug("%s: Backup cal data overflow HPS handoff\n", + __func__); + return -ENOEXEC; + } + crc32_wd_buf((u8 *)&cal->data, cal->header.data_len, (u8 *)&cal->header.caldata_crc32, CHUNKSZ_PER_WD_RESET); @@ -1436,6 +1443,8 @@ static void cal_data_ocram(phys_addr_t phy_base, u32 addr, /* Isolate the APB access from internal CSRs */ setbits_le16(phy_base + DDR_PHY_APBONLY0_OFFSET, DDR_PHY_MICROCONTMUXSEL); + + return 0; } static bool is_ddrconfig_hash_match(const void *buffer) @@ -1552,6 +1561,12 @@ static bool is_cal_bak_data_valid(void) return false; } + if (SOC64_HANDOFF_BASE < (SOC64_OCRAM_PHY_BACKUP_BASE + + cal->header.data_len + sizeof(struct cal_header_t))) { + debug("%s: Backup cal data overflow HPS handoff\n", __func__); + return false; + } + /* Load header + DDR bak cal into OCRAM buffer */ ret = request_firmware_into_buf(dev, qspi_offset, @@ -1564,6 +1579,12 @@ static bool is_cal_bak_data_valid(void) return false; } + if (SOC64_HANDOFF_BASE < ((uintptr_t)(&cal->data) + + cal->header.data_len)) { + debug("%s: Backup cal data overflow HPS handoff\n", __func__); + return false; + } + crc32_wd_buf((u8 *)&cal->data, cal->header.data_len, (u8 *)&crc32, CHUNKSZ_PER_WD_RESET); debug("%s: crc32 %x for bak calibration data from QSPI\n", __func__, @@ -1623,9 +1644,11 @@ static int init_phy(struct ddr_handoff *ddr_handoff_info, ddr_handoff_info->phy_handoff_length, ddr_handoff_info->phy_base); } else { - cal_data_ocram(ddr_handoff_info->phy_base, - SOC64_OCRAM_PHY_BACKUP_BASE, LOADING); + ret = cal_data_ocram(ddr_handoff_info->phy_base, + SOC64_OCRAM_PHY_BACKUP_BASE, LOADING); + if (ret) + return ret; /* * Invalidate the section used for processing the PHY * backup calibration data @@ -2929,10 +2952,14 @@ int sdram_mmr_init_full(struct udevice *dev) * Backup calibration data to OCRAM first, these data * might be permanant stored to flash in later */ - if (is_ddr_retention_enabled(reg)) - cal_data_ocram(ddr_handoff_info.phy_base, - SOC64_OCRAM_PHY_BACKUP_BASE, - STORE); + if (is_ddr_retention_enabled(reg)) { + ret = cal_data_ocram(ddr_handoff_info.phy_base, + SOC64_OCRAM_PHY_BACKUP_BASE, + STORE); + + if (ret) + return ret; + } } else { /* Updating training result to DDR controller */ |