Merge "diag: dci: Validate pkt length before parsing for full header"
This commit is contained in:
commit
de6dd62c41
|
@ -726,29 +726,44 @@ int diag_dci_query_event_mask(struct diag_dci_client_tbl *entry,
|
||||||
return ((*event_mask_ptr & byte_mask) == byte_mask) ? 1 : 0;
|
return ((*event_mask_ptr & byte_mask) == byte_mask) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int diag_dci_filter_commands(struct diag_pkt_header_t *header)
|
static int diag_dci_filter_commands(struct diag_pkt_header_t *header,
|
||||||
|
int header_len)
|
||||||
{
|
{
|
||||||
if (!header)
|
if (!header)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
switch (header->cmd_code) {
|
if (header_len <= 0)
|
||||||
case 0x7d: /* Msg Mask Configuration */
|
return -EIO;
|
||||||
case 0x73: /* Log Mask Configuration */
|
|
||||||
case 0x81: /* Event Mask Configuration */
|
if (header_len) {
|
||||||
case 0x82: /* Event Mask Change */
|
switch (header->cmd_code) {
|
||||||
case 0x60: /* Event Mask Toggle */
|
case 0x7d: /* Msg Mask Configuration */
|
||||||
return 1;
|
case 0x73: /* Log Mask Configuration */
|
||||||
|
case 0x81: /* Event Mask Configuration */
|
||||||
|
case 0x82: /* Event Mask Change */
|
||||||
|
case 0x60: /* Event Mask Toggle */
|
||||||
|
DIAG_LOG(DIAG_DEBUG_DCI,
|
||||||
|
"diag: command not supported: %d\n",
|
||||||
|
header->cmd_code);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header->cmd_code == 0x4b && header->subsys_id == 0x12) {
|
if (header_len >= (3*sizeof(uint8_t))) {
|
||||||
switch (header->subsys_cmd_code) {
|
if (header->cmd_code == 0x4b && header->subsys_id == 0x12) {
|
||||||
case 0x60: /* Extended Event Mask Config */
|
switch (header->subsys_cmd_code) {
|
||||||
case 0x61: /* Extended Msg Mask Config */
|
case 0x60: /* Extended Event Mask Config */
|
||||||
case 0x62: /* Extended Log Mask Config */
|
case 0x61: /* Extended Msg Mask Config */
|
||||||
case 0x20C: /* Set current Preset ID */
|
case 0x62: /* Extended Log Mask Config */
|
||||||
case 0x20D: /* Get current Preset ID */
|
case 0x20C: /* Set current Preset ID */
|
||||||
case 0x218: /* HDLC Disabled Command */
|
case 0x20D: /* Get current Preset ID */
|
||||||
return 1;
|
case 0x218: /* HDLC Disabled Command */
|
||||||
|
DIAG_LOG(DIAG_DEBUG_DCI,
|
||||||
|
"diag: command not supported %d %d %d\n",
|
||||||
|
header->cmd_code, header->subsys_id,
|
||||||
|
header->subsys_cmd_code);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1800,22 +1815,26 @@ int diag_dci_send_handshake_pkt(int index)
|
||||||
|
|
||||||
static int diag_dci_process_apps_pkt(struct diag_pkt_header_t *pkt_header,
|
static int diag_dci_process_apps_pkt(struct diag_pkt_header_t *pkt_header,
|
||||||
unsigned char *req_buf, int req_len,
|
unsigned char *req_buf, int req_len,
|
||||||
int tag)
|
int tag, int pkt_header_len)
|
||||||
{
|
{
|
||||||
uint8_t cmd_code, subsys_id, i, goto_download = 0;
|
uint8_t cmd_code = 0, subsys_id = 0, i, goto_download = 0;
|
||||||
uint8_t header_len = sizeof(struct diag_dci_pkt_header_t);
|
uint8_t header_len = sizeof(struct diag_dci_pkt_header_t);
|
||||||
uint16_t ss_cmd_code;
|
uint16_t ss_cmd_code = 0;
|
||||||
uint32_t write_len = 0;
|
uint32_t write_len = 0;
|
||||||
unsigned char *dest_buf = driver->apps_dci_buf;
|
unsigned char *dest_buf = driver->apps_dci_buf;
|
||||||
unsigned char *payload_ptr = driver->apps_dci_buf + header_len;
|
unsigned char *payload_ptr = driver->apps_dci_buf + header_len;
|
||||||
struct diag_dci_pkt_header_t dci_header;
|
struct diag_dci_pkt_header_t dci_header;
|
||||||
|
|
||||||
if (!pkt_header || !req_buf || req_len <= 0 || tag < 0)
|
if (!pkt_header || !req_buf || req_len <= 0 || tag < 0 ||
|
||||||
|
pkt_header_len <= 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
cmd_code = pkt_header->cmd_code;
|
if (pkt_header_len >= (sizeof(uint8_t)))
|
||||||
subsys_id = pkt_header->subsys_id;
|
cmd_code = pkt_header->cmd_code;
|
||||||
ss_cmd_code = pkt_header->subsys_cmd_code;
|
if (pkt_header_len >= (2 * sizeof(uint8_t)))
|
||||||
|
subsys_id = pkt_header->subsys_id;
|
||||||
|
if (pkt_header_len >= (3 * sizeof(uint8_t)))
|
||||||
|
ss_cmd_code = pkt_header->subsys_cmd_code;
|
||||||
|
|
||||||
if (cmd_code == DIAG_CMD_DOWNLOAD) {
|
if (cmd_code == DIAG_CMD_DOWNLOAD) {
|
||||||
*payload_ptr = DIAG_CMD_DOWNLOAD;
|
*payload_ptr = DIAG_CMD_DOWNLOAD;
|
||||||
|
@ -1935,7 +1954,7 @@ fill_buffer:
|
||||||
static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
|
static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
|
||||||
{
|
{
|
||||||
int ret = DIAG_DCI_TABLE_ERR;
|
int ret = DIAG_DCI_TABLE_ERR;
|
||||||
int common_cmd = 0;
|
int common_cmd = 0, header_len = 0;
|
||||||
struct diag_pkt_header_t *header = NULL;
|
struct diag_pkt_header_t *header = NULL;
|
||||||
unsigned char *temp = buf;
|
unsigned char *temp = buf;
|
||||||
unsigned char *req_buf = NULL;
|
unsigned char *req_buf = NULL;
|
||||||
|
@ -1951,8 +1970,7 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
if (len < (sizeof(struct dci_pkt_req_t) +
|
if (len < sizeof(struct dci_pkt_req_t) ||
|
||||||
sizeof(struct diag_pkt_header_t)) ||
|
|
||||||
len > DCI_REQ_BUF_SIZE) {
|
len > DCI_REQ_BUF_SIZE) {
|
||||||
pr_err("diag: dci: Invalid length %d len in %s", len, __func__);
|
pr_err("diag: dci: Invalid length %d len in %s", len, __func__);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -1963,13 +1981,6 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
|
||||||
read_len += sizeof(struct dci_pkt_req_t);
|
read_len += sizeof(struct dci_pkt_req_t);
|
||||||
req_len -= sizeof(struct dci_pkt_req_t);
|
req_len -= sizeof(struct dci_pkt_req_t);
|
||||||
req_buf = temp; /* Start of the Request */
|
req_buf = temp; /* Start of the Request */
|
||||||
header = (struct diag_pkt_header_t *)temp;
|
|
||||||
read_len += sizeof(struct diag_pkt_header_t);
|
|
||||||
if (read_len >= DCI_REQ_BUF_SIZE) {
|
|
||||||
pr_err("diag: dci: In %s, invalid read_len: %d\n", __func__,
|
|
||||||
read_len);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&driver->dci_mutex);
|
mutex_lock(&driver->dci_mutex);
|
||||||
dci_entry = diag_dci_get_client_entry(req_hdr.client_id);
|
dci_entry = diag_dci_get_client_entry(req_hdr.client_id);
|
||||||
|
@ -1980,11 +1991,40 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
|
||||||
return DIAG_DCI_NO_REG;
|
return DIAG_DCI_NO_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header = (void *)temp;
|
||||||
|
header_len = len - sizeof(struct dci_pkt_req_t);
|
||||||
|
if (header_len <= 0) {
|
||||||
|
mutex_unlock(&driver->dci_mutex);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
if (header_len >= sizeof(uint8_t)) {
|
||||||
|
header->cmd_code = (uint16_t)(*(uint8_t *)temp);
|
||||||
|
read_len += sizeof(uint8_t);
|
||||||
|
}
|
||||||
|
if (header_len >= (2 * sizeof(uint8_t))) {
|
||||||
|
temp += sizeof(uint8_t);
|
||||||
|
header->subsys_id = (uint16_t)(*(uint8_t *)temp);
|
||||||
|
read_len += sizeof(uint8_t);
|
||||||
|
}
|
||||||
|
if (header_len == (3 * sizeof(uint8_t))) {
|
||||||
|
temp += sizeof(uint8_t);
|
||||||
|
header->subsys_cmd_code = (uint16_t)(*(uint8_t *)temp);
|
||||||
|
read_len += sizeof(uint8_t);
|
||||||
|
} else if (header_len >=
|
||||||
|
(2 * sizeof(uint8_t)) + sizeof(uint16_t)) {
|
||||||
|
temp += sizeof(uint8_t);
|
||||||
|
header->subsys_cmd_code = (uint16_t)(*(uint16_t *)temp);
|
||||||
|
read_len += sizeof(uint16_t);
|
||||||
|
}
|
||||||
|
if (read_len > DCI_REQ_BUF_SIZE) {
|
||||||
|
pr_err("diag: dci: In %s, invalid read_len: %d\n", __func__,
|
||||||
|
read_len);
|
||||||
|
mutex_unlock(&driver->dci_mutex);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if the command is allowed on DCI */
|
/* Check if the command is allowed on DCI */
|
||||||
if (diag_dci_filter_commands(header)) {
|
if (diag_dci_filter_commands(header, header_len)) {
|
||||||
pr_debug("diag: command not supported %d %d %d",
|
|
||||||
header->cmd_code, header->subsys_id,
|
|
||||||
header->subsys_cmd_code);
|
|
||||||
mutex_unlock(&driver->dci_mutex);
|
mutex_unlock(&driver->dci_mutex);
|
||||||
return DIAG_DCI_SEND_DATA_FAIL;
|
return DIAG_DCI_SEND_DATA_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -2038,14 +2078,18 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
|
||||||
|
|
||||||
/* Check if it is a dedicated Apps command */
|
/* Check if it is a dedicated Apps command */
|
||||||
ret = diag_dci_process_apps_pkt(header, req_buf, req_len,
|
ret = diag_dci_process_apps_pkt(header, req_buf, req_len,
|
||||||
req_entry->tag);
|
req_entry->tag, header_len);
|
||||||
if ((ret == DIAG_DCI_NO_ERROR && !common_cmd) || ret < 0)
|
if ((ret == DIAG_DCI_NO_ERROR && !common_cmd) || ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
reg_entry.cmd_code = header->cmd_code;
|
if (header_len >= (sizeof(uint8_t)))
|
||||||
reg_entry.subsys_id = header->subsys_id;
|
reg_entry.cmd_code = header->cmd_code;
|
||||||
reg_entry.cmd_code_hi = header->subsys_cmd_code;
|
if (header_len >= (2 * sizeof(uint8_t)))
|
||||||
reg_entry.cmd_code_lo = header->subsys_cmd_code;
|
reg_entry.subsys_id = header->subsys_id;
|
||||||
|
if (header_len >= (3 * sizeof(uint8_t))) {
|
||||||
|
reg_entry.cmd_code_hi = header->subsys_cmd_code;
|
||||||
|
reg_entry.cmd_code_lo = header->subsys_cmd_code;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(&driver->cmd_reg_mutex);
|
mutex_lock(&driver->cmd_reg_mutex);
|
||||||
temp_entry = diag_cmd_search(®_entry, ALL_PROC);
|
temp_entry = diag_cmd_search(®_entry, ALL_PROC);
|
||||||
|
|
Loading…
Reference in New Issue