[PATCH] ddr: altera: n5x: Ensure 'cal->header.data_len' is validated
Jit Loon Lim
jit.loon.lim at intel.com
Wed Nov 23 16:21:41 CET 2022
From: Tien Fong Chee <tien.fong.chee at intel.com>
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 at intel.com>
Signed-off-by: Jit Loon Lim <jit.loon.lim at intel.com>
---
drivers/ddr/altera/sdram_n5x.c | 44 +++++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 8 deletions(-)
diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
index 0e944b7a15..8a5f0a3df4 100644
--- a/drivers/ddr/altera/sdram_n5x.c
+++ b/drivers/ddr/altera/sdram_n5x.c
@@ -1109,8 +1109,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
@@ -1435,6 +1435,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);
@@ -1443,6 +1450,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)
@@ -1559,6 +1568,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,
@@ -1571,6 +1586,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__,
@@ -1636,8 +1657,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
@@ -2955,10 +2979,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 */
--
2.26.2
More information about the U-Boot
mailing list