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

Commit a829c542 authored by AnilKumar Chimata's avatar AnilKumar Chimata
Browse files

qcedev: Validate Source and Destination addresses



Source and Destination addresses passed by user space apps/clients
are validated independent of type of operation to mitigate kernel
address space exploitation.

Change-Id: I9ecb0103d7a73eedb2e0d1db1d5613b18dd77e59
Signed-off-by: default avatarAnilKumar Chimata <anilc@codeaurora.org>
parent 7c8a2f0c
Loading
Loading
Loading
Loading
+30 −38
Original line number Diff line number Diff line
@@ -1234,44 +1234,6 @@ static int qcedev_vbuf_ablk_cipher(struct qcedev_async_req *areq,
	struct qcedev_cipher_op_req *saved_req;
	struct	qcedev_cipher_op_req *creq = &areq->cipher_op_req;

	/* Verify Source Address's */
	for (i = 0; i < areq->cipher_op_req.entries; i++)
		if (!access_ok(VERIFY_READ,
			(void __user *)areq->cipher_op_req.vbuf.src[i].vaddr,
					areq->cipher_op_req.vbuf.src[i].len))
			return -EFAULT;

	/* Verify Destination Address's */
	if (creq->in_place_op != 1) {
		for (i = 0, total = 0; i < QCEDEV_MAX_BUFFERS; i++) {
			if ((areq->cipher_op_req.vbuf.dst[i].vaddr != 0) &&
						(total < creq->data_len)) {
				if (!access_ok(VERIFY_WRITE,
					(void __user *)creq->vbuf.dst[i].vaddr,
						creq->vbuf.dst[i].len)) {
					pr_err("%s:DST WR_VERIFY err %d=0x%lx\n",
						__func__, i, (uintptr_t)
						creq->vbuf.dst[i].vaddr);
					return -EFAULT;
				}
				total += creq->vbuf.dst[i].len;
			}
		}
	} else  {
		for (i = 0, total = 0; i < creq->entries; i++) {
			if (total < creq->data_len) {
				if (!access_ok(VERIFY_WRITE,
					(void __user *)creq->vbuf.src[i].vaddr,
						creq->vbuf.src[i].len)) {
					pr_err("%s:SRC WR_VERIFY err %d=0x%lx\n",
						__func__, i, (uintptr_t)
						creq->vbuf.src[i].vaddr);
					return -EFAULT;
				}
				total += creq->vbuf.src[i].len;
			}
		}
	}
	total = 0;

	if (areq->cipher_op_req.mode == QCEDEV_AES_MODE_CTR)
@@ -1569,6 +1531,36 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req,
			__func__, total, req->data_len);
		goto error;
	}
	/* Verify Source Address's */
	for (i = 0, total = 0; i < req->entries; i++) {
		if (total < req->data_len) {
			if (!access_ok(VERIFY_READ,
				(void __user *)req->vbuf.src[i].vaddr,
					req->vbuf.src[i].len)) {
					pr_err("%s:SRC RD_VERIFY err %d=0x%lx\n",
						__func__, i, (uintptr_t)
							req->vbuf.src[i].vaddr);
					goto error;
			}
			total += req->vbuf.src[i].len;
		}
	}

	/* Verify Destination Address's */
	for (i = 0, total = 0; i < QCEDEV_MAX_BUFFERS; i++) {
		if ((req->vbuf.dst[i].vaddr != 0) &&
			(total < req->data_len)) {
			if (!access_ok(VERIFY_WRITE,
				(void __user *)req->vbuf.dst[i].vaddr,
					req->vbuf.dst[i].len)) {
					pr_err("%s:DST WR_VERIFY err %d=0x%lx\n",
						__func__, i, (uintptr_t)
							req->vbuf.dst[i].vaddr);
					goto error;
			}
			total += req->vbuf.dst[i].len;
		}
	}
	return 0;
error:
	return -EINVAL;