| From 85554b5bf7777c2c607064fb49ef4ef985124981 Mon Sep 17 00:00:00 2001 |
| From: Franck LENORMAND <franck.lenormand@nxp.com> |
| Date: Thu, 26 Mar 2020 00:00:05 +0200 |
| Subject: [PATCH] firmware: imx: scu: Fix corruption of header |
| |
| commit f5f27b79eab80de0287c243a22169e4876b08d5e upstream. |
| |
| 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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| 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]; |
| |
| -- |
| 2.27.0 |
| |