Merge "soc: qcom: smd: Validate read and write addresses"
diff --git a/arch/arm/mach-msm/include/mach/msm_smem.h b/arch/arm/mach-msm/include/mach/msm_smem.h
index 19f9c0e..670efe6 100644
--- a/arch/arm/mach-msm/include/mach/msm_smem.h
+++ b/arch/arm/mach-msm/include/mach/msm_smem.h
@@ -40,6 +40,17 @@
#define SMEM_NUM_SMD_STREAM_CHANNELS 64
+/**
+ * OVERFLOW_ADD_UNSIGNED() - check for unsigned overflow
+ *
+ * @type: type to check for overflow
+ * @a: left value to use
+ * @b: right value to use
+ * @returns: true if a + b will result in overflow; false otherwise
+ */
+#define OVERFLOW_ADD_UNSIGNED(type, a, b) \
+ (((type)~0 - (a)) < (b) ? true : false)
+
enum {
/* fixed items */
SMEM_PROC_COMM = 0,
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 1241e44..32f9b3b 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -1035,12 +1035,19 @@
{
unsigned head = ch->half_ch->get_head(ch->recv);
unsigned tail = ch->half_ch->get_tail(ch->recv);
- *ptr = (void *) (ch->recv_data + tail);
+ unsigned fifo_size = ch->fifo_size;
+ BUG_ON(fifo_size >= SZ_1M);
+ BUG_ON(head >= fifo_size);
+ BUG_ON(tail >= fifo_size);
+ BUG_ON(OVERFLOW_ADD_UNSIGNED(uintptr_t, (uintptr_t)ch->recv_data,
+ tail));
+
+ *ptr = (void *) (ch->recv_data + tail);
if (tail <= head)
return head - tail;
else
- return ch->fifo_size - tail;
+ return fifo_size - tail;
}
static int read_intr_blocked(struct smd_channel *ch)
@@ -1140,16 +1147,23 @@
{
unsigned head = ch->half_ch->get_head(ch->send);
unsigned tail = ch->half_ch->get_tail(ch->send);
- *ptr = (void *) (ch->send_data + head);
+ unsigned fifo_size = ch->fifo_size;
+ BUG_ON(fifo_size >= SZ_1M);
+ BUG_ON(head >= fifo_size);
+ BUG_ON(tail >= fifo_size);
+ BUG_ON(OVERFLOW_ADD_UNSIGNED(uintptr_t, (uintptr_t)ch->send_data,
+ head));
+
+ *ptr = (void *) (ch->send_data + head);
if (head < tail) {
return tail - head - SMD_FIFO_FULL_RESERVE;
} else {
if (tail < SMD_FIFO_FULL_RESERVE)
- return ch->fifo_size + tail - head
+ return fifo_size + tail - head
- SMD_FIFO_FULL_RESERVE;
else
- return ch->fifo_size - head;
+ return fifo_size - head;
}
}
diff --git a/arch/arm/mach-msm/smem.c b/arch/arm/mach-msm/smem.c
index f41240a..3c7cbeb 100644
--- a/arch/arm/mach-msm/smem.c
+++ b/arch/arm/mach-msm/smem.c
@@ -27,17 +27,6 @@
#include "smem_private.h"
-/**
- * OVERFLOW_ADD_UNSIGNED() - check for unsigned overflow
- *
- * @type: type to check for overflow
- * @a: left value to use
- * @b: right value to use
- * @returns: true if a + b will result in overflow; false otherwise
- */
-#define OVERFLOW_ADD_UNSIGNED(type, a, b) \
- (((type)~0 - (a)) < (b) ? true : false)
-
#define MODEM_SBL_VERSION_INDEX 7
#define SMEM_VERSION_INFO_SIZE (32 * 4)
#define SMEM_VERSION 0x000B