summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilson Sung <wilsonsung@google.com>2019-07-12 12:10:57 +0800
committerWilson Sung <wilsonsung@google.com>2019-07-12 12:11:18 +0800
commit7a6d2aabd186bd97fc634533856955152d338dc9 (patch)
tree3057c3ffd80c018faa80c24a78ef3139850f277b
parent02ab6f9b4fa78f67e4d1b75f4614308e4303dc5c (diff)
parent3d24c5213d6d9ec48e932a6b61f3178d567c253c (diff)
downloadmsm-extra-android-msm-crosshatch-4.9-q-preview-6.tar.gz
SEP 2019.1 Bug: 136171028 Bug: 136170907 Change-Id: Ib93b92ee9ed7c61c4b9a3e70ec0e810624e6a4e0 Signed-off-by: Wilson Sung <wilsonsung@google.com>
-rw-r--r--asoc/msm-lsm-client.c45
-rw-r--r--dsp/q6asm.c278
-rw-r--r--dsp/q6lsm.c18
-rw-r--r--include/dsp/q6lsm.h4
4 files changed, 241 insertions, 104 deletions
diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c
index 72bdeaa2..4133e297 100644
--- a/asoc/msm-lsm-client.c
+++ b/asoc/msm-lsm-client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, 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
@@ -195,7 +195,8 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd,
}
static void lsm_event_handler(uint32_t opcode, uint32_t token,
- uint32_t *payload, void *priv)
+ uint32_t *payload, uint16_t client_size,
+ void *priv)
{
unsigned long flags;
struct lsm_priv *prtd = priv;
@@ -265,6 +266,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
}
case LSM_SESSION_EVENT_DETECTION_STATUS:
+ if (client_size < 3 * sizeof(uint8_t)) {
+ dev_err(rtd->dev,
+ "%s: client_size has invalid size[%d]\n",
+ __func__, client_size);
+ return;
+ }
status = (uint16_t)((uint8_t *)payload)[0];
payload_size = (uint16_t)((uint8_t *)payload)[2];
index = 4;
@@ -274,6 +281,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
break;
case LSM_SESSION_EVENT_DETECTION_STATUS_V2:
+ if (client_size < 2 * sizeof(uint8_t)) {
+ dev_err(rtd->dev,
+ "%s: client_size has invalid size[%d]\n",
+ __func__, client_size);
+ return;
+ }
status = (uint16_t)((uint8_t *)payload)[0];
payload_size = (uint16_t)((uint8_t *)payload)[1];
index = 2;
@@ -283,6 +296,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
break;
case LSM_SESSION_EVENT_DETECTION_STATUS_V3:
+ if (client_size < 2 * (sizeof(uint32_t) + sizeof(uint8_t))) {
+ dev_err(rtd->dev,
+ "%s: client_size has invalid size[%d]\n",
+ __func__, client_size);
+ return;
+ }
event_ts_lsw = ((uint32_t *)payload)[0];
event_ts_msw = ((uint32_t *)payload)[1];
status = (uint16_t)((uint8_t *)payload)[8];
@@ -322,12 +341,22 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
prtd->event_status->payload_size = payload_size;
if (likely(prtd->event_status)) {
- memcpy(prtd->event_status->payload,
- &((uint8_t *)payload)[index],
- payload_size);
- prtd->event_avail = 1;
- spin_unlock_irqrestore(&prtd->event_lock, flags);
- wake_up(&prtd->event_wait);
+ if (client_size >= (payload_size + index)) {
+ memcpy(prtd->event_status->payload,
+ &((uint8_t *)payload)[index],
+ payload_size);
+ prtd->event_avail = 1;
+ spin_unlock_irqrestore(&prtd->event_lock,
+ flags);
+ wake_up(&prtd->event_wait);
+ } else {
+ spin_unlock_irqrestore(&prtd->event_lock,
+ flags);
+ dev_err(rtd->dev,
+ "%s: Failed to copy memory with invalid size = %d\n",
+ __func__, payload_size);
+ return;
+ }
} else {
spin_unlock_irqrestore(&prtd->event_lock, flags);
dev_err(rtd->dev,
diff --git a/dsp/q6asm.c b/dsp/q6asm.c
index eadf1670..c7581f96 100644
--- a/dsp/q6asm.c
+++ b/dsp/q6asm.c
@@ -1696,14 +1696,14 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
return 0;
}
- if (data->payload_size > sizeof(int)) {
+ if (data->payload_size >= 2 * sizeof(uint32_t)) {
pr_debug("%s:ptr0[0x%x]ptr1[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n",
__func__, payload[0], payload[1], data->opcode,
data->token, data->payload_size, data->src_port,
data->dest_port, asm_token._token.session_id, dir);
pr_debug("%s:Payload = [0x%x] status[0x%x]\n",
__func__, payload[0], payload[1]);
- } else if (data->payload_size == sizeof(int)) {
+ } else if (data->payload_size == sizeof(uint32_t)) {
pr_debug("%s:ptr0[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n",
__func__, payload[0], data->opcode,
data->token, data->payload_size, data->src_port,
@@ -1717,7 +1717,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],
asm_token._token.session_id);
@@ -1735,8 +1736,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1)
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",
@@ -1765,8 +1770,14 @@ 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) == -1)
wake_up(&ac->mem_wait);
@@ -1775,8 +1786,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,
@@ -1928,8 +1943,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) {
switch (payload[0]) {
@@ -1973,29 +1992,41 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS:
case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED:
- pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n",
- __func__, ac->session,
- data->opcode, data->token,
- payload[0], payload[1],
- data->src_port, data->dest_port);
- if (payload[1] != 0) {
- pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
- __func__, payload[0], payload[1]);
- if (wakeup_flag) {
- if ((is_adsp_reg_event(payload[0]) >= 0)
- || (payload[0] ==
- ASM_STREAM_CMD_SET_PP_PARAMS_V2))
- atomic_set(&ac->cmd_state_pp,
+ if (data->payload_size >= 2 * sizeof(uint32_t)) {
+ pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n",
+ __func__, ac->session,
+ data->opcode, data->token,
+ payload[0], payload[1],
+ data->src_port, data->dest_port);
+ if (payload[1] != 0) {
+ pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
+ __func__, payload[0],
+ payload[1]);
+ if (wakeup_flag) {
+ if (
+ (is_adsp_reg_event(payload[0])
+ >=0) ||
+ (payload[0] ==
+ ASM_STREAM_CMD_SET_PP_PARAMS_V2
+ )
+ )
+ atomic_set(
+ &ac->cmd_state_pp,
payload[1]);
- else
- atomic_set(&ac->cmd_state,
+ else
+ atomic_set(
+ &ac->cmd_state,
payload[1]);
- wake_up(&ac->cmd_wait);
+ wake_up(&ac->cmd_wait);
+ }
+ spin_unlock_irqrestore(
+ &(session[session_id].session_lock),
+ flags);
+ return 0;
}
- spin_unlock_irqrestore(
- &(session[session_id].session_lock),
- flags);
- return 0;
+ } else {
+ pr_err("%s: payload size of %x is less than expected.\n",
+ __func__, data->payload_size);
}
if ((is_adsp_reg_event(payload[0]) >= 0) ||
(payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2)) {
@@ -2016,19 +2047,27 @@ 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) {
- pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
- __func__, payload[0], payload[1]);
- if (wakeup_flag) {
- atomic_set(&ac->mem_state, payload[1]);
- wake_up(&ac->mem_wait);
+ if (data->payload_size >= 2 * sizeof(uint32_t)) {
+ pr_debug("%s:Payload = [0x%x]stat[0x%x]\n",
+ __func__, payload[0],
+ payload[1]);
+ if (payload[1] != 0) {
+ pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
+ __func__, payload[0],
+ payload[1]);
+ if (wakeup_flag) {
+ atomic_set(&ac->mem_state,
+ payload[1]);
+ wake_up(&ac->mem_wait);
+ }
+ spin_unlock_irqrestore(
+ &(session[session_id].session_lock),
+ flags);
+ return 0;
}
- spin_unlock_irqrestore(
- &(session[session_id].session_lock),
- flags);
- return 0;
+ } else {
+ pr_err("%s: payload size of %x is less than expected.\n",
+ __func__, data->payload_size);
}
if (atomic_read(&ac->mem_state) && wakeup_flag) {
atomic_set(&ac->mem_state, 0);
@@ -2039,8 +2078,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
(uint32_t *)data->payload, ac->priv);
break;
case ASM_DATA_EVENT_WATERMARK: {
- pr_debug("%s: Watermark opcode[0x%x] status[0x%x]",
- __func__, payload[0], payload[1]);
+ if (data->payload_size >= 2 * sizeof(uint32_t))
+ pr_debug("%s: Watermark opcode[0x%x] status[0x%x]",
+ __func__, payload[0], payload[1]);
+ else
+ pr_err("%s: payload size of %x is less than expected.\n",
+ __func__, data->payload_size);
break;
}
case ASM_STREAM_CMD_GET_PP_PARAMS_V2:
@@ -2052,11 +2095,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;
case ASM_STREAM_CMD_REGISTER_PP_EVENTS:
@@ -2064,11 +2113,16 @@ 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);
- if (payload[1] != 0)
- pr_err("%s: ASM get param error = %d, resuming\n",
- __func__, payload[1]);
- atomic_set(&ac->cmd_state_pp, payload[1]);
- wake_up(&ac->cmd_wait);
+ 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]);
+ atomic_set(&ac->cmd_state_pp, payload[1]);
+ wake_up(&ac->cmd_wait);
+ } else {
+ pr_err("%s: payload size of %x is less than expected.\n",
+ __func__, data->payload_size);
+ }
break;
default:
pr_debug("%s: command[0x%x] not expecting rsp\n",
@@ -2084,10 +2138,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",
@@ -2103,22 +2160,24 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
pr_debug("%s: Invalid buffer index %u\n",
__func__, buf_index);
spin_unlock_irqrestore(&port->dsp_lock,
- dsp_flags);
+ dsp_flags);
spin_unlock_irqrestore(
&(session[session_id].session_lock),
flags);
return -EINVAL;
}
- if (lower_32_bits(port->buf[buf_index].phys) !=
- payload[0] ||
- msm_audio_populate_upper_32_bits(
- port->buf[buf_index].phys) != payload[1]) {
+ if (data->payload_size >= 2 * sizeof(uint32_t) &&
+ (lower_32_bits(port->buf[buf_index].phys) !=
+ payload[0] ||
+ msm_audio_populate_upper_32_bits(
+ port->buf[buf_index].phys)
+ != payload[1])) {
pr_debug("%s: Expected addr %pK\n",
- __func__, &port->buf[buf_index].phys);
+ __func__, &port->buf[buf_index].phys);
pr_err("%s: rxedl[0x%x] rxedu [0x%x]\n",
__func__, payload[0], payload[1]);
spin_unlock_irqrestore(&port->dsp_lock,
- dsp_flags);
+ dsp_flags);
spin_unlock_irqrestore(
&(session[session_id].session_lock),
flags);
@@ -2147,14 +2206,30 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
} else if (generic_get_data) {
generic_get_data->valid = 1;
if (generic_get_data->is_inband) {
- pr_debug("%s: payload[1] = 0x%x, payload[2]=0x%x, payload[3]=0x%x\n",
- __func__, payload[1], payload[2], payload[3]);
- generic_get_data->size_in_ints = payload[3]>>2;
- for (i = 0; i < payload[3]>>2; i++) {
- generic_get_data->ints[i] =
- payload[4+i];
- pr_debug("%s: ASM callback val %i = %i\n",
- __func__, i, payload[4+i]);
+ if (data->payload_size >= 4 * sizeof(uint32_t))
+ pr_debug("%s: payload[1] = 0x%x, payload[2]=0x%x, payload[3]=0x%x\n",
+ __func__, payload[1],
+ payload[2], payload[3]);
+ else
+ pr_err("%s: payload size of %x is less than expected.\n",
+ __func__,
+ data->payload_size);
+
+ if (data->payload_size >=
+ (4 + (payload[3]>>2)) * sizeof(uint32_t)
+ )
+ {generic_get_data->size_in_ints =
+ payload[3]>>2;
+ for (i = 0; i < payload[3]>>2; i++) {
+ generic_get_data->ints[i] =
+ payload[4+i];
+ pr_debug("%s: ASM callback val %i = %i\n",
+ __func__, i,
+ payload[4+i]);
+ }
+ } else {
+ pr_err("%s: payload size of %x is less than expected.\n",
+ __func__, data->payload_size);
}
pr_debug("%s: callback size in ints = %i\n",
__func__,
@@ -2251,11 +2326,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;
@@ -2265,10 +2346,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);
@@ -2276,8 +2361,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
case ASM_STREAM_PP_EVENT:
case ASM_STREAM_CMD_ENCDEC_EVENTS:
case ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE:
- pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]",
- __func__, payload[0], payload[1]);
+ if (data->payload_size >= 2 * sizeof(uint32_t))
+ pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]",
+ __func__, payload[0], payload[1]);
+ else
+ pr_debug("%s: payload size of %x is less than expected.\n",
+ __func__, data->payload_size);
i = is_adsp_raise_event(data->opcode);
if (i < 0) {
spin_unlock_irqrestore(
@@ -2318,16 +2407,25 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
&(session[session_id].session_lock), flags);
return 0;
case ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2:
- pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n",
- __func__, ac->session, payload[0], payload[2],
- payload[1]);
+ if (data->payload_size >= 3 * sizeof(uint32_t))
+ pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n",
+ __func__, ac->session, payload[0], payload[2],
+ payload[1]);
+ else
+ pr_err("%s: payload size of %x is less than expected.\n",
+ __func__, data->payload_size);
wake_up(&ac->cmd_wait);
break;
case ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2:
- pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n",
- __func__, ac->session, payload[0], payload[2],
- payload[1]);
- if (payload[0] == 0) {
+ if (data->payload_size >= 3 * sizeof(uint32_t))
+ pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n",
+ __func__, ac->session, payload[0],
+ payload[2],payload[1]);
+ else
+ pr_err("%s: payload size of %x is less than expected.\n",
+ __func__, data->payload_size);
+ if (payload[0] == 0 &&
+ data->payload_size >= 2 * sizeof(uint32_t)) {
atomic_set(&ac->cmd_state, 0);
/* ignore msw, as a delay that large shouldn't happen */
ac->path_delay = payload[1];
diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c
index cf3e81ca..9c153b11 100644
--- a/dsp/q6lsm.c
+++ b/dsp/q6lsm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 2019 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
@@ -175,7 +175,8 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv)
struct lsm_cmd_read_done read_done;
token = data->token;
- if (data->payload_size > sizeof(read_done)) {
+ if (data->payload_size > sizeof(read_done) ||
+ data->payload_size < 6 * sizeof(payload[0])) {
pr_err("%s: read done error payload size %d expected size %zd\n",
__func__, data->payload_size,
sizeof(read_done));
@@ -193,6 +194,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv)
if (client->cb)
client->cb(data->opcode, data->token,
(void *)&read_done,
+ sizeof(read_done),
client->priv);
return 0;
} else if (data->opcode == APR_BASIC_RSP_RESULT) {
@@ -218,6 +220,11 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv)
__func__, token, client->session);
return -EINVAL;
}
+ if (data->payload_size < 2 * sizeof(payload[0])) {
+ pr_err("%s: payload has invalid size[%d]\n",
+ __func__, data->payload_size);
+ return -EINVAL;
+ }
client->cmd_err_code = payload[1];
if (client->cmd_err_code)
pr_err("%s: cmd 0x%x failed status %d\n",
@@ -238,7 +245,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv)
if (client->cb)
client->cb(data->opcode, data->token, data->payload,
- client->priv);
+ data->payload_size, client->priv);
return 0;
}
@@ -1358,6 +1365,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv)
"proc 0x%x SID 0x%x\n", __func__, data->opcode,
data->reset_event, data->reset_proc, sid);
+ if (sid < LSM_MIN_SESSION_ID || sid > LSM_MAX_SESSION_ID)
+ pr_err("%s: Invalid session %d\n", __func__, sid);
apr_reset(lsm_common.apr);
lsm_common.apr = NULL;
atomic_set(&lsm_common.apr_users, 0);
@@ -1423,7 +1432,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv)
}
if (client->cb)
client->cb(data->opcode, data->token,
- data->payload, client->priv);
+ data->payload, data->payload_size,
+ client->priv);
return 0;
}
diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h
index efce3a6d..be0e9988 100644
--- a/include/dsp/q6lsm.h
+++ b/include/dsp/q6lsm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 2019 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
@@ -26,7 +26,7 @@
#define LSM_MAX_NUM_CHANNELS 8
typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token,
- uint32_t *payload, void *priv);
+ uint32_t *payload, uint16_t client_size, void *priv);
struct lsm_sound_model {
dma_addr_t phys;