|
@@ -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,
|