Merge "diag: Validate command length against size of command structure"

This commit is contained in:
Linux Build Service Account 2019-05-09 15:11:36 -07:00 committed by Gerrit - the friendly Code Review server
commit 1d08efb430

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -952,7 +952,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
struct diag_cmd_reg_t *reg_item = NULL; struct diag_cmd_reg_t *reg_item = NULL;
struct diag_md_session_t *info = NULL; struct diag_md_session_t *info = NULL;
if (!buf) if (!buf || len <= 0)
return -EIO; return -EIO;
/* Check if the command is a supported mask command */ /* Check if the command is a supported mask command */
@ -963,18 +963,31 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
} }
temp = buf; temp = buf;
entry.cmd_code = (uint16_t)(*(uint8_t *)temp); if (len >= sizeof(uint8_t)) {
temp += sizeof(uint8_t); entry.cmd_code = (uint16_t)(*(uint8_t *)temp);
entry.subsys_id = (uint16_t)(*(uint8_t *)temp); pr_debug("diag: received cmd_code %02x\n", entry.cmd_code);
temp += sizeof(uint8_t); }
entry.cmd_code_hi = (uint16_t)(*(uint16_t *)temp); if (len >= (2 * sizeof(uint8_t))) {
entry.cmd_code_lo = (uint16_t)(*(uint16_t *)temp); temp += sizeof(uint8_t);
temp += sizeof(uint16_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);
}
pr_debug("diag: In %s, received cmd %02x %02x %02x\n", if ((len >= sizeof(uint8_t)) && *buf == DIAG_CMD_LOG_ON_DMND &&
__func__, entry.cmd_code, entry.subsys_id, entry.cmd_code_hi); driver->log_on_demand_support &&
if (*buf == DIAG_CMD_LOG_ON_DMND && driver->log_on_demand_support &&
driver->feature[PERIPHERAL_MODEM].rcvd_feature_mask) { driver->feature[PERIPHERAL_MODEM].rcvd_feature_mask) {
write_len = diag_cmd_log_on_demand(buf, len, write_len = diag_cmd_log_on_demand(buf, len,
driver->apps_rsp_buf, driver->apps_rsp_buf,
@ -1014,14 +1027,16 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
#if defined(CONFIG_DIAG_OVER_USB) #if defined(CONFIG_DIAG_OVER_USB)
/* Check for the command/respond msg for the maximum packet length */ /* 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)) { (*(uint16_t *)(buf+2) == 0x0055)) {
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
*(driver->apps_rsp_buf+i) = *(buf+i); *(driver->apps_rsp_buf+i) = *(buf+i);
*(uint32_t *)(driver->apps_rsp_buf+4) = DIAG_MAX_REQ_SIZE; *(uint32_t *)(driver->apps_rsp_buf+4) = DIAG_MAX_REQ_SIZE;
diag_send_rsp(driver->apps_rsp_buf, 8, pid); diag_send_rsp(driver->apps_rsp_buf, 8, pid);
return 0; 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)) { (*(uint16_t *)(buf+2) == DIAG_DIAG_STM)) {
len = diag_process_stm_cmd(buf, driver->apps_rsp_buf); len = diag_process_stm_cmd(buf, driver->apps_rsp_buf);
if (len > 0) { if (len > 0) {
@ -1031,7 +1046,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return len; return len;
} }
/* Check for time sync query command */ /* 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) && (*(buf+1) == DIAG_SS_DIAG) &&
(*(uint16_t *)(buf+2) == DIAG_GET_TIME_API)) { (*(uint16_t *)(buf+2) == DIAG_GET_TIME_API)) {
write_len = diag_process_time_sync_query_cmd(buf, len, write_len = diag_process_time_sync_query_cmd(buf, len,
@ -1042,7 +1058,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0; return 0;
} }
/* Check for time sync switch command */ /* 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) && (*(buf+1) == DIAG_SS_DIAG) &&
(*(uint16_t *)(buf+2) == DIAG_SET_TIME_API)) { (*(uint16_t *)(buf+2) == DIAG_SET_TIME_API)) {
write_len = diag_process_time_sync_switch_cmd(buf, len, write_len = diag_process_time_sync_switch_cmd(buf, len,
@ -1053,7 +1070,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0; return 0;
} }
/* Check for download command */ /* 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 */ /* send response back */
driver->apps_rsp_buf[0] = *buf; driver->apps_rsp_buf[0] = *buf;
diag_send_rsp(driver->apps_rsp_buf, 1, pid); diag_send_rsp(driver->apps_rsp_buf, 1, pid);
@ -1066,8 +1084,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0; return 0;
} }
/* Check for polling for Apps only DIAG */ /* Check for polling for Apps only DIAG */
else if ((*buf == 0x4b) && (*(buf+1) == 0x32) && else if ((len >= (3 * sizeof(uint8_t))) &&
(*(buf+2) == 0x03)) { (*buf == 0x4b) && (*(buf+1) == 0x32) && (*(buf+2) == 0x03)) {
/* If no one has registered for polling */ /* If no one has registered for polling */
if (chk_polling_response()) { if (chk_polling_response()) {
/* Respond to polling for Apps only DIAG */ /* Respond to polling for Apps only DIAG */
@ -1081,7 +1099,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
} }
} }
/* Return the Delayed Response Wrap Status */ /* 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)) { (*(buf+2) == 0x04) && (*(buf+3) == 0x0)) {
memcpy(driver->apps_rsp_buf, buf, 4); memcpy(driver->apps_rsp_buf, buf, 4);
driver->apps_rsp_buf[4] = wrap_enabled; driver->apps_rsp_buf[4] = wrap_enabled;
@ -1089,7 +1108,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0; return 0;
} }
/* Wrap the Delayed Rsp ID */ /* 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)) { (*(buf+2) == 0x05) && (*(buf+3) == 0x0)) {
wrap_enabled = true; wrap_enabled = true;
memcpy(driver->apps_rsp_buf, buf, 4); memcpy(driver->apps_rsp_buf, buf, 4);
@ -1098,10 +1118,11 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0; return 0;
} }
/* Mobile ID Rsp */ /* Mobile ID Rsp */
else if ((*buf == DIAG_CMD_DIAG_SUBSYS) && else if ((len >= (4 * sizeof(uint8_t))) &&
(*(buf+1) == DIAG_SS_PARAMS) && (*buf == DIAG_CMD_DIAG_SUBSYS) &&
(*(buf+2) == DIAG_EXT_MOBILE_ID) && (*(buf+3) == 0x0)) { (*(buf+1) == DIAG_SS_PARAMS) &&
write_len = diag_cmd_get_mobile_id(buf, len, (*(buf+2) == DIAG_EXT_MOBILE_ID) && (*(buf+3) == 0x0)) {
write_len = diag_cmd_get_mobile_id(buf, len,
driver->apps_rsp_buf, driver->apps_rsp_buf,
DIAG_MAX_RSP_SIZE); DIAG_MAX_RSP_SIZE);
if (write_len > 0) { if (write_len > 0) {
@ -1121,7 +1142,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
!(driver->diagfwd_cntl[PERIPHERAL_MODEM]->ch_open) && !(driver->diagfwd_cntl[PERIPHERAL_MODEM]->ch_open) &&
!(driver->feature[PERIPHERAL_MODEM].rcvd_feature_mask)) { !(driver->feature[PERIPHERAL_MODEM].rcvd_feature_mask)) {
/* respond to 0x0 command */ /* respond to 0x0 command */
if (*buf == 0x00) { if ((len >= sizeof(uint8_t)) && *buf == 0x00) {
for (i = 0; i < 55; i++) for (i = 0; i < 55; i++)
driver->apps_rsp_buf[i] = 0; driver->apps_rsp_buf[i] = 0;
@ -1129,7 +1150,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0; return 0;
} }
/* respond to 0x7c command */ /* respond to 0x7c command */
else if (*buf == 0x7c) { else if ((len >= sizeof(uint8_t)) && *buf == 0x7c) {
driver->apps_rsp_buf[0] = 0x7c; driver->apps_rsp_buf[0] = 0x7c;
for (i = 1; i < 8; i++) for (i = 1; i < 8; i++)
driver->apps_rsp_buf[i] = 0; driver->apps_rsp_buf[i] = 0;