[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