diff options
author | Mahesh Kallelil <kallelil@google.com> | 2024-03-26 20:30:51 -0700 |
---|---|---|
committer | Mahesh Kallelil <kallelil@google.com> | 2024-03-29 00:25:45 -0700 |
commit | 88225d9768c912dec3561ecb2710d9ae3b0f3135 (patch) | |
tree | 168ee819095b4a44386d18e6bcafdc5a155bbb61 | |
parent | 7f0242856ec9c64b0eb7ee0f82324754dc90f179 (diff) | |
download | gs-88225d9768c912dec3561ecb2710d9ae3b0f3135.tar.gz |
RESTRICT AUTOMERGE: soc/google/cpif: Fix OOB read from legacy ipc channel
There are two instances where a pointer from CP shared memory is
used to read from the CP buffer. Without checking for bounds, we risk
OOB read from AP.
Bug: 321714444
Change-Id: I9af053638a85584a9f259c7e43edbf66ee7568ca
Signed-off-by: Mahesh Kallelil <kallelil@google.com>
-rw-r--r-- | drivers/soc/google/cpif/link_device.c | 20 | ||||
-rw-r--r-- | drivers/soc/google/cpif/link_device_memory_legacy.c | 13 |
2 files changed, 33 insertions, 0 deletions
diff --git a/drivers/soc/google/cpif/link_device.c b/drivers/soc/google/cpif/link_device.c index eee95a1a0..1da887334 100644 --- a/drivers/soc/google/cpif/link_device.c +++ b/drivers/soc/google/cpif/link_device.c @@ -1663,6 +1663,16 @@ static int legacy_ipc_rx_func_napi(struct mem_link_device *mld, struct legacy_ip int rcvd = 0; int err = 0; + /* Make sure the in, out pointers are within bounds to avoid overflow. + * These pointers are passed from CP shared memory and must be + * validated before dma_sync below. */ + if ((in > qsize) || (out > qsize)) { + mif_err("OOB error! in:%u, out:%u, qsize:%u\n", in, out, qsize); + link_trigger_cp_crash(mld, CRASH_REASON_MIF_RX_BAD_DATA, + "OOB error"); + return -EINVAL; + } + if (unlikely(circ_empty(in, out))) return 0; @@ -1746,6 +1756,16 @@ static int legacy_ipc_rx_func(struct mem_link_device *mld, struct legacy_ipc_dev int rcvd = 0; int err = 0; + /* Make sure the in, out pointers are within bounds to avoid overflow. + * These pointers are passed from CP shared memory and must be + * validated before dma_sync below. */ + if ((in > qsize) || (out > qsize)) { + mif_err("OOB error! in:%u, out:%u, qsize:%u\n", in, out, qsize); + link_trigger_cp_crash(mld, CRASH_REASON_MIF_RX_BAD_DATA, + "OOB error"); + return -EINVAL; + } + if (unlikely(circ_empty(in, out))) return 0; diff --git a/drivers/soc/google/cpif/link_device_memory_legacy.c b/drivers/soc/google/cpif/link_device_memory_legacy.c index e3c5e0a9d..ad9501fc3 100644 --- a/drivers/soc/google/cpif/link_device_memory_legacy.c +++ b/drivers/soc/google/cpif/link_device_memory_legacy.c @@ -346,6 +346,19 @@ struct sk_buff *recv_from_legacy_link(struct mem_link_device *mld, char hdr[EXYNOS_HEADER_SIZE]; char pr_buff[BAD_MSG_BUFFER_SIZE]; + /* Make sure out pointer is within bounds. This pointer is read + * from CP shared memory and must be validated before + * circ_read below. */ + if (out > qsize) { + mif_err("OOB err! out:%u, qsize:%u\n", out, qsize); + if (ld->link_trigger_cp_crash) { + ld->link_trigger_cp_crash(mld, + CRASH_REASON_MIF_RX_BAD_DATA, "OOB error"); + } + *ret = -EINVAL; + goto no_mem; + } + /* Copy the header in a frame to the header buffer */ switch (ld->protocol) { case PROTOCOL_SIPC: |