Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0776094 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "lsm: check payload size validity before using it as array index"

parents ec7ab4c4 16e53596
Loading
Loading
Loading
Loading
+52 −10
Original line number Diff line number Diff line
@@ -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,6 +280,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;
@@ -288,6 +295,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;
@@ -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)) {
			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,
+13 −3
Original line number Diff line number Diff line
@@ -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;
}

+1 −1
Original line number Diff line number Diff line
@@ -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;