From d1167202e6b5cd80909a1c83958e8f12f27091b5 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Singh Date: Fri, 1 Mar 2019 19:42:22 +0530 Subject: [PATCH] rpmsg: glink: smem: validate index before fifo read write We are not validating head and tail index of tx and rx fifo before using to read or write fifo. This can result in out of bound memory access if head and tail have incorrect values. This patch adds check for validation of head and tail index. CRs-Fixed: 2398099 Change-Id: Ia8725a731cc7a45f7e13b09e1e62842ff44d53f3 Signed-off-by: Deepak Kumar Singh --- drivers/rpmsg/qcom_glink_smem.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index 579bc4443f6d..8da9ace1b8a5 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -71,9 +71,14 @@ static size_t glink_smem_rx_avail(struct qcom_glink_pipe *np) tail = le32_to_cpu(*pipe->tail); if (head < tail) - return pipe->native.length - tail + head; + len = pipe->native.length - tail + head; else - return head - tail; + len = head - tail; + + if (WARN_ON_ONCE(len > pipe->native.length)) + len = 0; + + return len; } static void glink_smem_rx_peak(struct qcom_glink_pipe *np, @@ -84,6 +89,10 @@ static void glink_smem_rx_peak(struct qcom_glink_pipe *np, u32 tail; tail = le32_to_cpu(*pipe->tail); + + if (WARN_ON_ONCE(tail > pipe->native.length)) + return; + tail += offset; if (tail >= pipe->native.length) tail -= pipe->native.length; @@ -106,7 +115,7 @@ static void glink_smem_rx_advance(struct qcom_glink_pipe *np, tail += count; if (tail >= pipe->native.length) - tail -= pipe->native.length; + tail %= pipe->native.length; *pipe->tail = cpu_to_le32(tail); } @@ -131,6 +140,9 @@ static size_t glink_smem_tx_avail(struct qcom_glink_pipe *np) else avail -= FIFO_FULL_RESERVE + TX_BLOCKED_CMD_RESERVE; + if (WARN_ON_ONCE(avail > pipe->native.length)) + avail = 0; + return avail; } @@ -140,6 +152,9 @@ static unsigned int glink_smem_tx_write_one(struct glink_smem_pipe *pipe, { size_t len; + if (WARN_ON_ONCE(head > pipe->native.length)) + return head; + len = min_t(size_t, count, pipe->native.length - head); if (len) memcpy(pipe->fifo + head, data, len);