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

Commit cd089cd5 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "qseecom: Add boundary checks for offset within message"

parents d52b7919 dcde6b6e
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) {