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: AnilKumar Chimata <anilc@codeaurora.org>
This commit is contained in:
AnilKumar Chimata 2016-08-31 14:08:16 +05:30 committed by Gerrit - the friendly Code Review server
parent 313ee32d17
commit 6923314bf1
1 changed files with 30 additions and 38 deletions

View File

@ -1261,44 +1261,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)
@ -1596,6 +1558,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;