summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-05-08 18:49:42 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2019-05-08 18:49:42 -0700
commitcd6e1cd22ba4a16e022c888fe8fbecbcdddc4182 (patch)
tree2a5f59d05fce325c11ac3474ec44e13d7e13db49
parent7939ca71f88fc96db090556f7855e1c2aeca79a0 (diff)
parent061ce1d939fa47a9532035dab39d6ec5a6c90f58 (diff)
Merge "diag: Validate command length against size of command structure"
-rw-r--r--drivers/char/diag/diagfwd.c77
1 files changed, 49 insertions, 28 deletions
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 96ccd67c9216..75c68c903371 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -954,7 +954,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
struct diag_cmd_reg_t *reg_item = NULL;
struct diag_md_session_t *info = NULL;
- if (!buf)
+ if (!buf || len <= 0)
return -EIO;
/* Check if the command is a supported mask command */
@@ -965,18 +965,31 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
}
temp = buf;
- entry.cmd_code = (uint16_t)(*(uint8_t *)temp);
- temp += sizeof(uint8_t);
- entry.subsys_id = (uint16_t)(*(uint8_t *)temp);
- temp += sizeof(uint8_t);
- entry.cmd_code_hi = (uint16_t)(*(uint16_t *)temp);
- entry.cmd_code_lo = (uint16_t)(*(uint16_t *)temp);
- temp += sizeof(uint16_t);
-
- pr_debug("diag: In %s, received cmd %02x %02x %02x\n",
- __func__, entry.cmd_code, entry.subsys_id, entry.cmd_code_hi);
-
- if (*buf == DIAG_CMD_LOG_ON_DMND && driver->log_on_demand_support &&
+ if (len >= sizeof(uint8_t)) {
+ entry.cmd_code = (uint16_t)(*(uint8_t *)temp);
+ pr_debug("diag: received cmd_code %02x\n", entry.cmd_code);
+ }
+ if (len >= (2 * sizeof(uint8_t))) {
+ temp += sizeof(uint8_t);
+ entry.subsys_id = (uint16_t)(*(uint8_t *)temp);
+ pr_debug("diag: received subsys_id %02x\n", entry.subsys_id);
+ }
+ if (len == (3 * sizeof(uint8_t))) {
+ temp += sizeof(uint8_t);
+ entry.cmd_code_hi = (uint16_t)(*(uint8_t *)temp);
+ entry.cmd_code_lo = (uint16_t)(*(uint8_t *)temp);
+ pr_debug("diag: received cmd_code_hi %02x\n",
+ entry.cmd_code_hi);
+ } else if (len >= (2 * sizeof(uint8_t)) + sizeof(uint16_t)) {
+ temp += sizeof(uint8_t);
+ entry.cmd_code_hi = (uint16_t)(*(uint16_t *)temp);
+ entry.cmd_code_lo = (uint16_t)(*(uint16_t *)temp);
+ pr_debug("diag: received cmd_code_hi %02x\n",
+ entry.cmd_code_hi);
+ }
+
+ if ((len >= sizeof(uint8_t)) && *buf == DIAG_CMD_LOG_ON_DMND &&
+ driver->log_on_demand_support &&
driver->feature[PERIPHERAL_MODEM].rcvd_feature_mask) {
write_len = diag_cmd_log_on_demand(buf, len,
driver->apps_rsp_buf,
@@ -1016,14 +1029,16 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
#if defined(CONFIG_DIAG_OVER_USB)
/* Check for the command/respond msg for the maximum packet length */
- if ((*buf == 0x4b) && (*(buf+1) == 0x12) &&
+ if ((len >= (4 * sizeof(uint8_t))) &&
+ (*buf == 0x4b) && (*(buf+1) == 0x12) &&
(*(uint16_t *)(buf+2) == 0x0055)) {
for (i = 0; i < 4; i++)
*(driver->apps_rsp_buf+i) = *(buf+i);
*(uint32_t *)(driver->apps_rsp_buf+4) = DIAG_MAX_REQ_SIZE;
diag_send_rsp(driver->apps_rsp_buf, 8, pid);
return 0;
- } else if ((*buf == 0x4b) && (*(buf+1) == 0x12) &&
+ } else if ((len >= ((2 * sizeof(uint8_t)) + sizeof(uint16_t))) &&
+ (*buf == 0x4b) && (*(buf+1) == 0x12) &&
(*(uint16_t *)(buf+2) == DIAG_DIAG_STM)) {
len = diag_process_stm_cmd(buf, driver->apps_rsp_buf);
if (len > 0) {
@@ -1033,7 +1048,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return len;
}
/* Check for time sync query command */
- else if ((*buf == DIAG_CMD_DIAG_SUBSYS) &&
+ else if ((len >= ((2 * sizeof(uint8_t)) + sizeof(uint16_t))) &&
+ (*buf == DIAG_CMD_DIAG_SUBSYS) &&
(*(buf+1) == DIAG_SS_DIAG) &&
(*(uint16_t *)(buf+2) == DIAG_GET_TIME_API)) {
write_len = diag_process_time_sync_query_cmd(buf, len,
@@ -1044,7 +1060,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* Check for time sync switch command */
- else if ((*buf == DIAG_CMD_DIAG_SUBSYS) &&
+ else if ((len >= ((2 * sizeof(uint8_t)) + sizeof(uint16_t))) &&
+ (*buf == DIAG_CMD_DIAG_SUBSYS) &&
(*(buf+1) == DIAG_SS_DIAG) &&
(*(uint16_t *)(buf+2) == DIAG_SET_TIME_API)) {
write_len = diag_process_time_sync_switch_cmd(buf, len,
@@ -1055,7 +1072,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* Check for download command */
- else if ((chk_apps_master()) && (*buf == 0x3A)) {
+ else if ((len >= sizeof(uint8_t)) && (chk_apps_master()) &&
+ (*buf == 0x3A)) {
/* send response back */
driver->apps_rsp_buf[0] = *buf;
diag_send_rsp(driver->apps_rsp_buf, 1, pid);
@@ -1068,8 +1086,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* Check for polling for Apps only DIAG */
- else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
- (*(buf+2) == 0x03)) {
+ else if ((len >= (3 * sizeof(uint8_t))) &&
+ (*buf == 0x4b) && (*(buf+1) == 0x32) && (*(buf+2) == 0x03)) {
/* If no one has registered for polling */
if (chk_polling_response()) {
/* Respond to polling for Apps only DIAG */
@@ -1083,7 +1101,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
}
}
/* Return the Delayed Response Wrap Status */
- else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
+ else if ((len >= (4 * sizeof(uint8_t))) &&
+ (*buf == 0x4b) && (*(buf+1) == 0x32) &&
(*(buf+2) == 0x04) && (*(buf+3) == 0x0)) {
memcpy(driver->apps_rsp_buf, buf, 4);
driver->apps_rsp_buf[4] = wrap_enabled;
@@ -1091,7 +1110,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* Wrap the Delayed Rsp ID */
- else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
+ else if ((len >= (4 * sizeof(uint8_t))) &&
+ (*buf == 0x4b) && (*(buf+1) == 0x32) &&
(*(buf+2) == 0x05) && (*(buf+3) == 0x0)) {
wrap_enabled = true;
memcpy(driver->apps_rsp_buf, buf, 4);
@@ -1100,10 +1120,11 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* Mobile ID Rsp */
- else if ((*buf == DIAG_CMD_DIAG_SUBSYS) &&
- (*(buf+1) == DIAG_SS_PARAMS) &&
- (*(buf+2) == DIAG_EXT_MOBILE_ID) && (*(buf+3) == 0x0)) {
- write_len = diag_cmd_get_mobile_id(buf, len,
+ else if ((len >= (4 * sizeof(uint8_t))) &&
+ (*buf == DIAG_CMD_DIAG_SUBSYS) &&
+ (*(buf+1) == DIAG_SS_PARAMS) &&
+ (*(buf+2) == DIAG_EXT_MOBILE_ID) && (*(buf+3) == 0x0)) {
+ write_len = diag_cmd_get_mobile_id(buf, len,
driver->apps_rsp_buf,
DIAG_MAX_RSP_SIZE);
if (write_len > 0) {
@@ -1123,7 +1144,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
!(driver->diagfwd_cntl[PERIPHERAL_MODEM]->ch_open) &&
!(driver->feature[PERIPHERAL_MODEM].rcvd_feature_mask)) {
/* respond to 0x0 command */
- if (*buf == 0x00) {
+ if ((len >= sizeof(uint8_t)) && *buf == 0x00) {
for (i = 0; i < 55; i++)
driver->apps_rsp_buf[i] = 0;
@@ -1131,7 +1152,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* respond to 0x7c command */
- else if (*buf == 0x7c) {
+ else if ((len >= sizeof(uint8_t)) && *buf == 0x7c) {
driver->apps_rsp_buf[0] = 0x7c;
for (i = 1; i < 8; i++)
driver->apps_rsp_buf[i] = 0;