[PATCH v5 1/2] firmware: zynqmp: fix write to an uninitialised pointer in xilinx_pm_request

Adrian Fiergolski adrian.fiergolski at fastree3d.com
Thu Oct 14 14:43:49 CEST 2021


When a caller is not interested in the returned message, the ret_payload pointer
is set to NULL in the u-boot-sources. In this case, under EL3, the memory from
address 0x0 would be overwritten by xilinx_pm_request with the returned IPI
message, damaging the original data under this address. The patch, in case
ret_payload is NULL, assigns the pointer to the array holding the IPI message
being sent.

Signed-off-by: Adrian Fiergolski <adrian.fiergolski at fastree3d.com>
---
Fix casting of ret (ingore v4).
 drivers/firmware/firmware-zynqmp.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index d4dc856baf..8273437dd9 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -154,6 +154,8 @@ U_BOOT_DRIVER(zynqmp_power) = {
 int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
 				     u32 arg3, u32 *ret_payload)
 {
+	int ret;
+	
 	debug("%s at EL%d, API ID: 0x%0x\n", __func__, current_el(), api_id);
 
 	if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
@@ -165,6 +167,12 @@ int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
 		 */
 		u32 regs[] = {api_id, arg0, arg1, arg2, arg3};
 
+		/*
+		 * Use regs array in case ret_payload is NULL
+		 */
+		if (ret_payload == NULL)
+			ret_payload = regs;
+
 		if (api_id == PM_FPGA_LOAD) {
 			/* Swap addr_hi/low because of incompatibility */
 			u32 temp = regs[1];
@@ -174,6 +182,8 @@ int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
 		}
 
 		ipi_req(regs, PAYLOAD_ARG_CNT, ret_payload, PAYLOAD_ARG_CNT);
+
+		ret = (int)ret_payload[0];
 #else
 		return -EPERM;
 #endif
@@ -198,8 +208,9 @@ int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
 			ret_payload[4] = (u32)regs.regs[2];
 		}
 
+		ret = (ret_payload) ? ret_payload[0] : 0;
 	}
-	return (ret_payload) ? ret_payload[0] : 0;
+	return ret;
 }
 
 static const struct udevice_id zynqmp_firmware_ids[] = {
-- 
2.33.0



More information about the U-Boot mailing list