aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-04-01 09:38:14 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2019-04-01 09:38:14 -0700
commitfd6251c31cece63b861d2c697ce4b214bc681ff8 (patch)
tree9018651c29bdbcd692cbc2dd96e2125ab81f2d8d
parent4ad71cb16137d20c4a9ce56d33dba53c4972137a (diff)
parent5a27fe1ce9a11f658761d940e55ce9a6a77f7e89 (diff)
Merge "soc: qcom: glink_spi_xprt: Validate fifo read index of remote side"LA.UM.6.6.2.r1-07000-89xx.0
-rw-r--r--drivers/soc/qcom/glink_spi_xprt.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/drivers/soc/qcom/glink_spi_xprt.c b/drivers/soc/qcom/glink_spi_xprt.c
index a08c4bfde4a2..efcd94cdda01 100644
--- a/drivers/soc/qcom/glink_spi_xprt.c
+++ b/drivers/soc/qcom/glink_spi_xprt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -484,6 +484,13 @@ static int glink_spi_xprt_rx_cmd(struct edge_info *einfo, void *dst,
int ret;
read_id = einfo->rx_fifo_read;
+ if ((read_id > (einfo->rx_fifo_start + einfo->fifo_size)) ||
+ (read_id < einfo->rx_fifo_start)) {
+ pr_err("%s: Invalid rx_fifo_read: %d, start: %d, size: %d\n",
+ __func__, read_id, einfo->rx_fifo_start,
+ einfo->fifo_size);
+ return -EINVAL;
+ }
do {
if ((read_id + size_to_read) >=
(einfo->rx_fifo_start + einfo->fifo_size))
@@ -722,11 +729,11 @@ static void process_rx_cmd(struct edge_info *einfo,
struct rx_short_data_desc {
unsigned char data[SHORT_PKT_SIZE];
};
- struct command *cmd;
+ struct command *cmd = NULL;
struct intent_desc *intents;
struct rx_desc *rx_descp;
struct rx_short_data_desc *rx_sd_descp;
- int offset = 0;
+ uint64_t offset = 0;
int rcu_id;
uint16_t rcid;
uint16_t name_len;
@@ -742,6 +749,8 @@ static void process_rx_cmd(struct edge_info *einfo,
}
while (offset < rx_size) {
+ if (offset + sizeof(*cmd) > rx_size)
+ goto err;
cmd = (struct command *)(rx_data + offset);
offset += sizeof(*cmd);
switch (cmd->id) {
@@ -760,7 +769,12 @@ static void process_rx_cmd(struct edge_info *einfo,
case OPEN_CMD:
rcid = cmd->param1;
name_len = (uint16_t)(cmd->param2 & 0xFFFF);
+ if (name_len > GLINK_NAME_SIZE)
+ goto err;
prio = (uint16_t)((cmd->param2 & 0xFFFF0000) >> 16);
+ if (offset + ALIGN(name_len, FIFO_ALIGNMENT) >
+ rx_size)
+ goto err;
name = (char *)(rx_data + offset);
offset += ALIGN(name_len, FIFO_ALIGNMENT);
einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_remote_open(
@@ -786,6 +800,8 @@ static void process_rx_cmd(struct edge_info *einfo,
case RX_INTENT_CMD:
for (i = 0; i < cmd->param2; i++) {
+ if (offset + sizeof(*intents) > rx_size)
+ goto err;
intents = (struct intent_desc *)
(rx_data + offset);
offset += sizeof(*intents);
@@ -821,6 +837,8 @@ static void process_rx_cmd(struct edge_info *einfo,
case TX_DATA_CONT_CMD:
case TRACER_PKT_CMD:
case TRACER_PKT_CONT_CMD:
+ if (offset + sizeof(*rx_descp) > rx_size)
+ goto err;
rx_descp = (struct rx_desc *)(rx_data + offset);
offset += sizeof(*rx_descp);
process_rx_data(einfo, cmd->id, cmd->param1,
@@ -830,6 +848,8 @@ static void process_rx_cmd(struct edge_info *einfo,
break;
case TX_SHORT_DATA_CMD:
+ if (offset + sizeof(*rx_sd_descp) > rx_size)
+ goto err;
rx_sd_descp = (struct rx_short_data_desc *)
(rx_data + offset);
offset += sizeof(*rx_sd_descp);
@@ -858,6 +878,13 @@ static void process_rx_cmd(struct edge_info *einfo,
}
}
srcu_read_unlock(&einfo->use_ref, rcu_id);
+ return;
+err:
+ srcu_read_unlock(&einfo->use_ref, rcu_id);
+ if (cmd)
+ pr_err("%s: invalid size of rx_data: %d, cmd : %d\n",
+ __func__, rx_size, cmd->id);
+ return;
}
/**