From: Franck LENORMAND franck.lenormand@nxp.com
[ Upstream commit f5f27b79eab80de0287c243a22169e4876b08d5e ]
The header of the message to send can be changed if the response is longer than the request: - 1st word, the header is sent - the remaining words of the message are sent - the response is received asynchronously during the execution of the loop, changing the size field in the header - the for loop test the termination condition using the corrupted header
It is the case for the API build_info which has just a header as request but 3 words in response.
This issue is fixed storing the header locally instead of using a pointer on it.
Fixes: edbee095fafb (firmware: imx: add SCU firmware driver support)
Signed-off-by: Franck LENORMAND franck.lenormand@nxp.com Reviewed-by: Leonard Crestez leonard.crestez@nxp.com Signed-off-by: Leonard Crestez leonard.crestez@nxp.com Cc: stable@vger.kernel.org Reviewed-by: Dong Aisheng aisheng.dong@nxp.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/imx/imx-scu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c index a92adb9fdad6..e48d971ffb61 100644 --- a/drivers/firmware/imx/imx-scu.c +++ b/drivers/firmware/imx/imx-scu.c @@ -158,7 +158,7 @@ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg) { - struct imx_sc_rpc_msg *hdr = msg; + struct imx_sc_rpc_msg hdr = *(struct imx_sc_rpc_msg *)msg; struct imx_sc_chan *sc_chan; u32 *data = msg; int ret; @@ -166,13 +166,13 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg) int i;
/* Check size */ - if (hdr->size > IMX_SC_RPC_MAX_MSG) + if (hdr.size > IMX_SC_RPC_MAX_MSG) return -EINVAL;
- dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr->svc, - hdr->func, hdr->size); + dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr.svc, + hdr.func, hdr.size);
- size = sc_ipc->fast_ipc ? 1 : hdr->size; + size = sc_ipc->fast_ipc ? 1 : hdr.size; for (i = 0; i < size; i++) { sc_chan = &sc_ipc->chans[i % 4];