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

Commit dcde6b6e authored by Mona Hossain's avatar Mona Hossain Committed by Mallikarjuna Reddy Amireddy
Browse files

qseecom: Add boundary checks for offset within message



Qseecom driver does not have boundary checks for offset within the
message. So this patch add checks to validate the offsets sent by
client to modify data within the command request message and it
should not exceed the memory allocated for that message.

Change-Id: I29bfbdc154eebb4f3f4bfbb31789562e37fa5886
Signed-off-by: default avatarMona Hossain <mhossain@codeaurora.org>
Signed-off-by: default avatarMallikarjuna Reddy Amireddy <mamire@codeaurora.org>
parent c5353f99
Loading
Loading
Loading
Loading
+71 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@

#define QSEECOM_SEND_CMD_CRYPTO_TIMEOUT	2000
#define QSEECOM_LOAD_APP_CRYPTO_TIMEOUT	2000
#define TWO 2

enum qseecom_clk_definitions {
	CLK_DFAB = 0,
@@ -1972,6 +1973,50 @@ static int qseecom_send_cmd(struct qseecom_dev_handle *data, void __user *argp)
	return ret;
}

int boundary_checks_offset(struct qseecom_send_modfd_cmd_req *req,
			struct qseecom_send_modfd_listener_resp *lstnr_resp,
			struct qseecom_dev_handle *data, bool qteec,
			int i) {
	int ret = 0;

	if ((data->type != QSEECOM_LISTENER_SERVICE) &&
						(req->ifd_data[i].fd > 0)) {
		if (qteec) {
			if (req->ifd_data[i].cmd_buf_offset >
				req->cmd_req_len - TWO * sizeof(uint32_t)) {
				pr_err("Invalid offset 0x%x\n",
					req->ifd_data[i].cmd_buf_offset);
				return ++ret;
			}
		} else {
			if (req->ifd_data[i].cmd_buf_offset >
				req->cmd_req_len - sizeof(uint32_t)) {
				pr_err("Invalid offset 0x%x\n",
					req->ifd_data[i].cmd_buf_offset);
				return ++ret;
			}
		}
	} else if ((data->type == QSEECOM_LISTENER_SERVICE) &&
					(lstnr_resp->ifd_data[i].fd > 0)) {
		if (qteec) {
			if (lstnr_resp->ifd_data[i].cmd_buf_offset >
				lstnr_resp->resp_len - TWO * sizeof(uint32_t)) {
				pr_err("Invalid offset 0x%x\n",
					lstnr_resp->ifd_data[i].cmd_buf_offset);
				return ++ret;
			}
		} else {
			if (lstnr_resp->ifd_data[i].cmd_buf_offset >
				lstnr_resp->resp_len - sizeof(uint32_t)) {
				pr_err("Invalid offset 0x%x\n",
					lstnr_resp->ifd_data[i].cmd_buf_offset);
				return ++ret;
			}
		}
	}
	return ret;
}

static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
			struct qseecom_dev_handle *data, bool qteec)
{
@@ -2049,6 +2094,10 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
		if (sg_ptr->nents == 1) {
			uint32_t *update;
			update = (uint32_t *) field;

			if (boundary_checks_offset(req, lstnr_resp, data,
								qteec, i))
				goto err;
			if (cleanup)
				*update = 0;
			else
@@ -2060,6 +2109,28 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
		} else {
			struct qseecom_sg_entry *update;
			int j = 0;

			if ((data->type != QSEECOM_LISTENER_SERVICE) &&
					(req->ifd_data[i].fd > 0)) {
				if (req->ifd_data[i].cmd_buf_offset >
					req->cmd_req_len -
					sizeof(struct qseecom_sg_entry)) {
					pr_err("Invalid offset = 0x%x\n",
						req->ifd_data[i].
						cmd_buf_offset);
					goto err;
				}
			} else if ((data->type == QSEECOM_LISTENER_SERVICE) &&
					(lstnr_resp->ifd_data[i].fd > 0)) {
				if (lstnr_resp->ifd_data[i].cmd_buf_offset >
							lstnr_resp->resp_len -
					sizeof(struct qseecom_sg_entry)) {
					pr_err("Invalid offset = 0x%x\n",
						lstnr_resp->ifd_data[i].
							cmd_buf_offset);
					goto err;
				}
			}
			update = (struct qseecom_sg_entry *) field;
			for (j = 0; j < sg_ptr->nents; j++) {
				if (cleanup) {