summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMahesh Kallelil <kallelil@google.com>2024-03-26 20:30:51 -0700
committerMahesh Kallelil <kallelil@google.com>2024-03-29 00:25:45 -0700
commit88225d9768c912dec3561ecb2710d9ae3b0f3135 (patch)
tree168ee819095b4a44386d18e6bcafdc5a155bbb61
parent7f0242856ec9c64b0eb7ee0f82324754dc90f179 (diff)
downloadgs-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.c20
-rw-r--r--drivers/soc/google/cpif/link_device_memory_legacy.c13
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: