mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
Merge "lsm: check payload size validity before using it as array index"
This commit is contained in:
commit
a077609404
3 changed files with 66 additions and 14 deletions
|
|
@ -196,7 +196,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;
|
||||
|
|
@ -279,15 +280,27 @@ 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;
|
||||
dev_dbg(rtd->dev,
|
||||
"%s: event detect status = %d payload size = %d\n",
|
||||
__func__, status, payload_size);
|
||||
break;
|
||||
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;
|
||||
|
|
@ -297,6 +310,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];
|
||||
|
|
@ -310,6 +329,13 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
|
|||
|
||||
case LSM_SESSION_DETECTION_ENGINE_GENERIC_EVENT: {
|
||||
struct snd_lsm_event_status *tmp;
|
||||
if (client_size < 2 * sizeof(uint16_t)) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: client_size has invalid size[%d]\n",
|
||||
__func__, client_size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
status = ((uint16_t *)payload)[0];
|
||||
payload_size = ((uint16_t *)payload)[1];
|
||||
|
|
@ -332,8 +358,16 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
|
|||
prtd->det_event = tmp;
|
||||
prtd->det_event->status = status;
|
||||
prtd->det_event->payload_size = payload_size;
|
||||
memcpy(prtd->det_event->payload, &((uint8_t *)payload)[4],
|
||||
payload_size);
|
||||
if (client_size >= payload_size + 4) {
|
||||
memcpy(prtd->det_event->payload,
|
||||
&((uint8_t *)payload)[4], payload_size);
|
||||
} 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;
|
||||
}
|
||||
prtd->event_avail = 1;
|
||||
spin_unlock_irqrestore(&prtd->event_lock, flags);
|
||||
wake_up(&prtd->event_wait);
|
||||
|
|
@ -375,12 +409,20 @@ 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,
|
||||
|
|
|
|||
16
dsp/q6lsm.c
16
dsp/q6lsm.c
|
|
@ -153,7 +153,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));
|
||||
|
|
@ -171,6 +172,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) {
|
||||
|
|
@ -198,6 +200,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",
|
||||
|
|
@ -218,7 +225,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;
|
||||
}
|
||||
|
|
@ -1793,6 +1800,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);
|
||||
|
|
@ -1857,7 +1866,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#define LSM_API_VERSION_V3 3
|
||||
|
||||
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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue