From a829c54236b455885c3e9c7c77ac528b62045e79 Mon Sep 17 00:00:00 2001 From: AnilKumar Chimata Date: Wed, 31 Aug 2016 14:08:16 +0530 Subject: 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 --- drivers/crypto/msm/qcedev.c | 68 ++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c index e63f061..1402d3d 100644 --- a/drivers/crypto/msm/qcedev.c +++ b/drivers/crypto/msm/qcedev.c @@ -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; -- cgit v1.1