summaryrefslogtreecommitdiff
path: root/drivers/crypto
diff options
context:
space:
mode:
authorAnilKumar Chimata <anilc@codeaurora.org>2019-02-08 15:42:48 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2020-04-21 00:43:37 -0700
commite8dee20786a900f096572e8c7ace2107baceac75 (patch)
treef99d06de8f79962f9d4e51b770c7db841db8f0be /drivers/crypto
parentd9add1d73d8fdbed8ee29108e24cd710b5d8cbe0 (diff)
crypto: qcedev: Fix out of memory issue
Fixes memory leak issue which is caused due to unfreed memory of req struct after processing the user space request , this happens for every client who are using from user space through ioctls. Change-Id: I2f267b960a2c73a65b85e72b0bff9a87df68b4e0 Signed-off-by: AnilKumar Chimata <anilc@codeaurora.org> Signed-off-by: Swetha Chikkaboraiah <schikk@codeaurora.org>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/msm/qcedev.c125
1 files changed, 81 insertions, 44 deletions
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index bbbb15fdd4f8..f4cd405717d1 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1618,12 +1618,15 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
if (podev == NULL || podev->magic != QCEDEV_MAGIC) {
pr_err("%s: invalid handle %pK\n",
__func__, podev);
- return -ENOENT;
+ err = -ENOENT;
+ goto exit_free_qcedev_areq;
}
/* Verify user arguments. */
- if (_IOC_TYPE(cmd) != QCEDEV_IOC_MAGIC)
- return -ENOTTY;
+ if (_IOC_TYPE(cmd) != QCEDEV_IOC_MAGIC) {
+ err = -ENOTTY;
+ goto exit_free_qcedev_areq;
+ }
init_completion(&qcedev_areq->complete);
pstat = &_qcedev_stat;
@@ -1633,21 +1636,27 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
case QCEDEV_IOCTL_DEC_REQ:
if (copy_from_user(&qcedev_areq->cipher_op_req,
(void __user *)arg,
- sizeof(struct qcedev_cipher_op_req)))
- return -EFAULT;
+ sizeof(struct qcedev_cipher_op_req))) {
+ err = -EFAULT;
+ goto exit_free_qcedev_areq;
+ }
qcedev_areq->op_type = QCEDEV_CRYPTO_OPER_CIPHER;
if (qcedev_check_cipher_params(&qcedev_areq->cipher_op_req,
- podev))
- return -EINVAL;
+ podev)) {
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
+ }
err = qcedev_vbuf_ablk_cipher(qcedev_areq, handle);
if (err)
- return err;
+ goto exit_free_qcedev_areq;
if (copy_to_user((void __user *)arg,
&qcedev_areq->cipher_op_req,
- sizeof(struct qcedev_cipher_op_req)))
- return -EFAULT;
+ sizeof(struct qcedev_cipher_op_req))) {
+ err = -EFAULT;
+ goto exit_free_qcedev_areq;
+ }
break;
case QCEDEV_IOCTL_SHA_INIT_REQ:
@@ -1656,41 +1665,51 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
if (copy_from_user(&qcedev_areq->sha_op_req,
(void __user *)arg,
- sizeof(struct qcedev_sha_op_req)))
- return -EFAULT;
+ sizeof(struct qcedev_sha_op_req))) {
+ err = -EFAULT;
+ goto exit_free_qcedev_areq;
+ }
mutex_lock(&hash_access_lock);
if (qcedev_check_sha_params(&qcedev_areq->sha_op_req, podev)) {
mutex_unlock(&hash_access_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
}
qcedev_areq->op_type = QCEDEV_CRYPTO_OPER_SHA;
err = qcedev_hash_init(qcedev_areq, handle, &sg_src);
if (err) {
mutex_unlock(&hash_access_lock);
- return err;
+ goto exit_free_qcedev_areq;
}
mutex_unlock(&hash_access_lock);
if (copy_to_user((void __user *)arg, &qcedev_areq->sha_op_req,
- sizeof(struct qcedev_sha_op_req)))
- return -EFAULT;
+ sizeof(struct qcedev_sha_op_req))) {
+ err = -EFAULT;
+ goto exit_free_qcedev_areq;
}
handle->sha_ctxt.init_done = true;
+ }
break;
case QCEDEV_IOCTL_GET_CMAC_REQ:
- if (!podev->ce_support.cmac)
- return -ENOTTY;
+ if (!podev->ce_support.cmac) {
+ err = -ENOTTY;
+ goto exit_free_qcedev_areq;
+ }
case QCEDEV_IOCTL_SHA_UPDATE_REQ:
{
struct scatterlist sg_src;
if (copy_from_user(&qcedev_areq->sha_op_req,
(void __user *)arg,
- sizeof(struct qcedev_sha_op_req)))
- return -EFAULT;
+ sizeof(struct qcedev_sha_op_req))) {
+ err = -EFAULT;
+ goto exit_free_qcedev_areq;
+ }
mutex_lock(&hash_access_lock);
if (qcedev_check_sha_params(&qcedev_areq->sha_op_req, podev)) {
mutex_unlock(&hash_access_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
}
qcedev_areq->op_type = QCEDEV_CRYPTO_OPER_SHA;
@@ -1698,18 +1717,19 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
err = qcedev_hash_cmac(qcedev_areq, handle, &sg_src);
if (err) {
mutex_unlock(&hash_access_lock);
- return err;
+ goto exit_free_qcedev_areq;
}
} else {
if (handle->sha_ctxt.init_done == false) {
pr_err("%s Init was not called\n", __func__);
mutex_unlock(&hash_access_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
}
err = qcedev_hash_update(qcedev_areq, handle, &sg_src);
if (err) {
mutex_unlock(&hash_access_lock);
- return err;
+ goto exit_free_qcedev_areq;
}
}
@@ -1717,7 +1737,8 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
pr_err("Invalid sha_ctxt.diglen %d\n",
handle->sha_ctxt.diglen);
mutex_unlock(&hash_access_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
}
memcpy(&qcedev_areq->sha_op_req.digest[0],
&handle->sha_ctxt.digest[0],
@@ -1725,7 +1746,8 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
mutex_unlock(&hash_access_lock);
if (copy_to_user((void __user *)arg, &qcedev_areq->sha_op_req,
sizeof(struct qcedev_sha_op_req)))
- return -EFAULT;
+ err = -EFAULT;
+ goto exit_free_qcedev_areq;
}
break;
@@ -1733,28 +1755,33 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
if (handle->sha_ctxt.init_done == false) {
pr_err("%s Init was not called\n", __func__);
- return -EINVAL;
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
}
if (copy_from_user(&qcedev_areq->sha_op_req,
(void __user *)arg,
- sizeof(struct qcedev_sha_op_req)))
- return -EFAULT;
+ sizeof(struct qcedev_sha_op_req))) {
+ err = -EFAULT;
+ goto exit_free_qcedev_areq;
+ }
mutex_lock(&hash_access_lock);
if (qcedev_check_sha_params(&qcedev_areq->sha_op_req, podev)) {
mutex_unlock(&hash_access_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
}
qcedev_areq->op_type = QCEDEV_CRYPTO_OPER_SHA;
err = qcedev_hash_final(qcedev_areq, handle);
if (err) {
mutex_unlock(&hash_access_lock);
- return err;
+ goto exit_free_qcedev_areq;
}
if (handle->sha_ctxt.diglen > QCEDEV_MAX_SHA_DIGEST) {
pr_err("Invalid sha_ctxt.diglen %d\n",
handle->sha_ctxt.diglen);
mutex_unlock(&hash_access_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
}
qcedev_areq->sha_op_req.diglen = handle->sha_ctxt.diglen;
memcpy(&qcedev_areq->sha_op_req.digest[0],
@@ -1762,8 +1789,10 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
handle->sha_ctxt.diglen);
mutex_unlock(&hash_access_lock);
if (copy_to_user((void __user *)arg, &qcedev_areq->sha_op_req,
- sizeof(struct qcedev_sha_op_req)))
- return -EFAULT;
+ sizeof(struct qcedev_sha_op_req))) {
+ err = -EFAULT;
+ goto exit_free_qcedev_areq;
+ }
handle->sha_ctxt.init_done = false;
break;
@@ -1773,30 +1802,34 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
if (copy_from_user(&qcedev_areq->sha_op_req,
(void __user *)arg,
- sizeof(struct qcedev_sha_op_req)))
- return -EFAULT;
+ sizeof(struct qcedev_sha_op_req))) {
+ err = -EFAULT;
+ goto exit_free_qcedev_areq;
+ }
mutex_lock(&hash_access_lock);
if (qcedev_check_sha_params(&qcedev_areq->sha_op_req, podev)) {
mutex_unlock(&hash_access_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
}
qcedev_areq->op_type = QCEDEV_CRYPTO_OPER_SHA;
qcedev_hash_init(qcedev_areq, handle, &sg_src);
err = qcedev_hash_update(qcedev_areq, handle, &sg_src);
if (err) {
mutex_unlock(&hash_access_lock);
- return err;
+ goto exit_free_qcedev_areq;
}
err = qcedev_hash_final(qcedev_areq, handle);
if (err) {
mutex_unlock(&hash_access_lock);
- return err;
+ goto exit_free_qcedev_areq;
}
if (handle->sha_ctxt.diglen > QCEDEV_MAX_SHA_DIGEST) {
pr_err("Invalid sha_ctxt.diglen %d\n",
handle->sha_ctxt.diglen);
mutex_unlock(&hash_access_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
}
qcedev_areq->sha_op_req.diglen = handle->sha_ctxt.diglen;
memcpy(&qcedev_areq->sha_op_req.digest[0],
@@ -1804,15 +1837,19 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
handle->sha_ctxt.diglen);
mutex_unlock(&hash_access_lock);
if (copy_to_user((void __user *)arg, &qcedev_areq->sha_op_req,
- sizeof(struct qcedev_sha_op_req)))
- return -EFAULT;
+ sizeof(struct qcedev_sha_op_req))) {
+ err = -EFAULT;
+ goto exit_free_qcedev_areq;
+ }
}
break;
-
default:
- return -ENOTTY;
+ err = -ENOTTY;
+ goto exit_free_qcedev_areq;
}
+exit_free_qcedev_areq:
+ kfree(qcedev_areq);
return err;
}
EXPORT_SYMBOL(qcedev_ioctl);