cryptodev: avoid untrusted user pointers
Konduri Praveen [Tue, 1 Aug 2017 12:05:58 +0000 (17:05 +0530)]
add algo variable for avoid the usage of
user space pointers

Bug 200286426

Change-Id: I7e208b45ba11348e7b89a429d457ae51ac29bde0
Signed-off-by: Konduri Praveen <kondurip@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1530560
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Mallikarjun Kasoju <mkasoju@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Tested-by: Bibek Basu <bbasu@nvidia.com>

drivers/misc/tegra-cryptodev.c

index 88c9cb2..d1fa004 100644 (file)
@@ -537,6 +537,7 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
        struct crypto_ahash *tfm;
        struct scatterlist sg[1];
        char result[64];
+       char algo[64];
        struct ahash_request *req;
        struct tegra_crypto_completion sha_complete;
        void *hash_buff;
@@ -548,17 +549,23 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
                return -EINVAL;
        }
 
-       tfm = crypto_alloc_ahash(sha_req->algo, 0, 0);
+               if (strncpy_from_user(algo, sha_req->algo, sizeof(algo)) < 0) {
+                       ret = -EFAULT;
+                       goto out_alloc;
+               }
+               algo[sizeof(algo) - 1] = '\0';
+
+               tfm = crypto_alloc_ahash(algo, 0, 0);
        if (IS_ERR(tfm)) {
                pr_err("alg:hash:Failed to load transform for %s:%ld\n",
-                       sha_req->algo, PTR_ERR(tfm));
+                       algo, PTR_ERR(tfm));
                goto out_alloc;
        }
 
        req = ahash_request_alloc(tfm, GFP_KERNEL);
        if (!req) {
                pr_err("alg:hash:Failed to allocate request for %s\n",
-                       sha_req->algo);
+                       algo);
                goto out_noreq;
        }
 
@@ -574,7 +581,14 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
 
        hash_buff = xbuf[0];
 
-       memcpy(hash_buff, sha_req->plaintext, sha_req->plaintext_sz);
+       ret = copy_from_user((void *)hash_buff,
+                               (void __user *)sha_req->plaintext,
+                               sha_req->plaintext_sz);
+       if (ret) {
+               ret = -EFAULT;
+               pr_err("%s: copy_from_user failed (%d)\n", __func__, ret);
+                       goto out;
+       }
        sg_init_one(&sg[0], hash_buff, sha_req->plaintext_sz);
 
        if (sha_req->keylen) {
@@ -583,7 +597,7 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
                                          sha_req->keylen);
                if (ret) {
                        pr_err("alg:hash:setkey failed on %s:ret=%d\n",
-                               sha_req->algo, ret);
+                               algo, ret);
 
                        goto out;
                }
@@ -594,21 +608,21 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
        ret = sha_async_hash_op(req, &sha_complete, crypto_ahash_init(req));
        if (ret) {
                pr_err("alg: hash: init failed for %s: ret=%d\n",
-                       sha_req->algo, ret);
+                       algo, ret);
                goto out;
        }
 
        ret = sha_async_hash_op(req, &sha_complete, crypto_ahash_update(req));
        if (ret) {
                pr_err("alg: hash: update failed for %s: ret=%d\n",
-                       sha_req->algo, ret);
+                       algo, ret);
                goto out;
        }
 
        ret = sha_async_hash_op(req, &sha_complete, crypto_ahash_final(req));
        if (ret) {
                pr_err("alg: hash: final failed for %s: ret=%d\n",
-                       sha_req->algo, ret);
+                       algo, ret);
                goto out;
        }
 
@@ -617,7 +631,7 @@ static int tegra_crypto_sha(struct tegra_sha_req *sha_req)
        if (ret) {
                ret = -EFAULT;
                pr_err("alg: hash: copy_to_user failed (%d) for %s\n",
-                               ret, sha_req->algo);
+                               ret, algo);
        }
 
 out: