dsp: asm: validate payload size before access
Payload size is not checked before payload access. Check size to avoid out-of-boundary memory access. Change-Id: Iaa39ee4ea5489bb5579e7b7d5dfada12d88c5809 Signed-off-by: Xiaojun Sang <xsang@codeaurora.org>
This commit is contained in:
parent
8dc3bb6ce4
commit
e02c7a7eed
|
@ -1396,7 +1396,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
|
|||
case ASM_CMD_SHARED_MEM_MAP_REGIONS:
|
||||
case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:
|
||||
case ASM_CMD_ADD_TOPOLOGIES:
|
||||
if (payload[1] != 0) {
|
||||
if (data->payload_size >= 2 * sizeof(uint32_t)
|
||||
&& payload[1] != 0) {
|
||||
pr_err("%s: cmd = 0x%x returned error = 0x%x sid:%d\n",
|
||||
__func__, payload[0], payload[1], sid);
|
||||
if (payload[0] ==
|
||||
|
@ -1413,8 +1414,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
|
|||
|
||||
if (atomic_cmpxchg(&ac->mem_state, 1, 0))
|
||||
wake_up(&ac->mem_wait);
|
||||
dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x]\n",
|
||||
if (data->payload_size >= 2 * sizeof(uint32_t))
|
||||
dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x]\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
else
|
||||
dev_vdbg(ac->dev, "%s: Payload size of %d is less than expected.\n",
|
||||
__func__, data->payload_size);
|
||||
break;
|
||||
default:
|
||||
pr_debug("%s: command[0x%x] not expecting rsp\n",
|
||||
|
@ -1451,8 +1456,13 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
|
|||
break;
|
||||
}
|
||||
case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:{
|
||||
pr_debug("%s: PL#0[0x%x]PL#1 [0x%x]\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
if (data->payload_size >= 2 * sizeof(uint32_t))
|
||||
pr_debug("%s: PL#0[0x%x]PL#1 [0x%x]\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
else
|
||||
pr_debug("%s: Payload size of %d is less than expected.\n",
|
||||
__func__, data->payload_size);
|
||||
|
||||
spin_lock_irqsave(&port->dsp_lock, dsp_flags);
|
||||
if (atomic_cmpxchg(&ac->mem_state, 1, 0))
|
||||
wake_up(&ac->mem_wait);
|
||||
|
@ -1461,8 +1471,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
pr_debug("%s: command[0x%x]success [0x%x]\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
if (data->payload_size >= 2 * sizeof(uint32_t))
|
||||
pr_debug("%s: command[0x%x]success [0x%x]\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
else
|
||||
pr_debug("%s: Payload size of %d is less than expected.\n",
|
||||
__func__, data->payload_size);
|
||||
}
|
||||
if (ac->cb)
|
||||
ac->cb(data->opcode, data->token,
|
||||
|
@ -1633,8 +1647,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
&(session[session_id].session_lock), flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n",
|
||||
__func__, payload[0], payload[1], data->opcode);
|
||||
if (data->payload_size >= 2 * sizeof(uint32_t))
|
||||
dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n",
|
||||
__func__, payload[0], payload[1], data->opcode);
|
||||
else
|
||||
dev_vdbg(ac->dev, "%s: Payload size of %d is less than expected.\n",
|
||||
__func__, data->payload_size);
|
||||
}
|
||||
if (data->opcode == APR_BASIC_RSP_RESULT) {
|
||||
token = data->token;
|
||||
|
@ -1700,11 +1718,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
(uint32_t *)data->payload, ac->priv);
|
||||
break;
|
||||
case ASM_CMD_ADD_TOPOLOGIES:
|
||||
pr_debug("%s:Payload = [0x%x]stat[0x%x]\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
if (payload[1] != 0) {
|
||||
if (data->payload_size >=
|
||||
2 * sizeof(uint32_t) &&
|
||||
payload[1] != 0) {
|
||||
pr_debug("%s:Payload = [0x%x]stat[0x%x]\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
__func__, payload[0], payload[1]);
|
||||
if (wakeup_flag) {
|
||||
atomic_set(&ac->mem_state, -payload[1]);
|
||||
wake_up(&ac->mem_wait);
|
||||
|
@ -1736,11 +1756,17 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
/* error or malformed APR packet. Otherwise */
|
||||
/* response will be returned as */
|
||||
/* ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 */
|
||||
if (payload[1] != 0) {
|
||||
pr_err("%s: ASM get param error = %d, resuming\n",
|
||||
__func__, payload[1]);
|
||||
rtac_make_asm_callback(ac->session, payload,
|
||||
if (data->payload_size >= 2 * sizeof(uint32_t)) {
|
||||
if (payload[1] != 0) {
|
||||
pr_err("%s: ASM get param error = %d, resuming\n",
|
||||
__func__, payload[1]);
|
||||
rtac_make_asm_callback(ac->session,
|
||||
payload,
|
||||
data->payload_size);
|
||||
}
|
||||
} else {
|
||||
pr_err("%s: payload size of %x is less than expected.\n",
|
||||
__func__, data->payload_size);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1757,9 +1783,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
switch (data->opcode) {
|
||||
case ASM_DATA_EVENT_WRITE_DONE_V2:{
|
||||
struct audio_port_data *port = &ac->port[IN];
|
||||
dev_vdbg(ac->dev, "%s: Rxed opcode[0x%x] status[0x%x] token[%d]",
|
||||
__func__, payload[0], payload[1],
|
||||
data->token);
|
||||
if (data->payload_size >= 2 * sizeof(uint32_t))
|
||||
dev_vdbg(ac->dev, "%s: Rxed opcode[0x%x] status[0x%x] token[%d]",
|
||||
__func__, payload[0], payload[1],
|
||||
data->token);
|
||||
else
|
||||
dev_err(ac->dev, "%s: payload size of %x is less than expected.\n",
|
||||
__func__, data->payload_size);
|
||||
if (ac->io_mode & SYNC_IO_MODE) {
|
||||
if (port->buf == NULL) {
|
||||
pr_err("%s: Unexpected Write Done\n",
|
||||
|
@ -1917,11 +1947,17 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
data->src_port, data->dest_port);
|
||||
break;
|
||||
case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3:
|
||||
dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n",
|
||||
__func__,
|
||||
payload[0], payload[1], payload[2]);
|
||||
ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) |
|
||||
payload[1]);
|
||||
if (data->payload_size >= 3 * sizeof(uint32_t)) {
|
||||
dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n",
|
||||
__func__,
|
||||
payload[0], payload[1], payload[2]);
|
||||
ac->time_stamp =
|
||||
(uint64_t)(((uint64_t)payload[2] << 32) |
|
||||
payload[1]);
|
||||
} else {
|
||||
dev_err(ac->dev, "%s: payload size of %x is less than expected.n",
|
||||
__func__, data->payload_size);
|
||||
}
|
||||
if (atomic_cmpxchg(&ac->time_flag, 1, 0))
|
||||
wake_up(&ac->time_wait);
|
||||
break;
|
||||
|
@ -1931,10 +1967,14 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
|||
__func__, ac->session,
|
||||
data->opcode, data->token,
|
||||
data->src_port, data->dest_port);
|
||||
pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n",
|
||||
__func__,
|
||||
payload[0], payload[1], payload[2],
|
||||
payload[3]);
|
||||
if (data->payload_size >= 4 * sizeof(uint32_t))
|
||||
pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n",
|
||||
__func__,
|
||||
payload[0], payload[1], payload[2],
|
||||
payload[3]);
|
||||
else
|
||||
pr_debug("%s: payload size of %x is less than expected.\n",
|
||||
__func__, data->payload_size);
|
||||
break;
|
||||
case ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2:
|
||||
q6asm_process_mtmx_get_param_rsp(ac, (void *) payload);
|
||||
|
|
Loading…
Reference in New Issue