summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKonduri Praveen <kondurip@nvidia.com>2017-05-02 14:50:40 +0530
committerWinnie Hsu <whsu@nvidia.com>2017-05-05 14:47:36 -0700
commit555a69ad03e354d20a7a9bd5eb4d966d5b25c7b5 (patch)
tree5b720e625397aa8f0fc7d74ddd17b1b304fde6fe /drivers
parentb16c5fd826c790df730665dcb0835ce9631ac5e1 (diff)
drivers: crypto: Avoid use of tainted scalar value
Copy from user may taint the scalar value members in the respective struct variables. Add check for verifying the validity of the scalar value members to avoid undefined behaviour. Bug 1903278 Signed-off-by: Konduri Praveen <kondurip@nvidia.com> Change-Id: Ic01c8d10886f9b02c61156f811b430acce8aca23 Reviewed-on: http://git-master/r/1473534 Reviewed-by: Winnie Hsu <whsu@nvidia.com> Tested-by: Winnie Hsu <whsu@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/tegra-cryptodev.c32
-rw-r--r--drivers/misc/tegra-cryptodev.h34
2 files changed, 47 insertions, 19 deletions
diff --git a/drivers/misc/tegra-cryptodev.c b/drivers/misc/tegra-cryptodev.c
index a5434b66cc30..88c9cb217880 100644
--- a/drivers/misc/tegra-cryptodev.c
+++ b/drivers/misc/tegra-cryptodev.c
@@ -40,6 +40,10 @@
#define XBUFSIZE 8
#define RNG_DRBG 1
#define RNG 0
+#define NUM_RSA_ALGO 4
+#define ECC_MODE_MIN_INDEX 7
+#define ECC_MODE_MAX_INDEX 13
+#define MAX_RSA_MSG_LEN 256
#define TEGRA_RSA512 0
#define TEGRA_RSA1024 1
@@ -658,6 +662,11 @@ static long tegra_crypto_dev_ioctl(struct file *filp,
ret = copy_from_user(&crypt_req_32, (void __user *)arg,
sizeof(crypt_req_32));
+ if (crypt_req_32.keylen > TEGRA_CRYPTO_MAX_KEY_SIZE) {
+ pr_err("key length %d exceeds max value %d\n",
+ crypt_req_32.keylen, TEGRA_CRYPTO_MAX_KEY_SIZE);
+ return -EINVAL;
+ }
crypt_req.op = crypt_req_32.op;
crypt_req.encrypt = crypt_req_32.encrypt;
crypt_req.skip_key = crypt_req_32.skip_key;
@@ -797,6 +806,11 @@ rng_out:
ret = copy_from_user(&sha_req_32, (void __user *)arg,
sizeof(sha_req_32));
+ if (sha_req_32.keylen > TEGRA_CRYPTO_MAX_KEY_SIZE) {
+ pr_err("key length %d not within the range [0,%d]\n",
+ sha_req_32.keylen, TEGRA_CRYPTO_MAX_KEY_SIZE);
+ return -EINVAL;
+ }
for (i = 0; i < sha_req_32.keylen; i++)
sha_req.key[i] = sha_req_32.key[i];
sha_req.keylen = sha_req_32.keylen;
@@ -821,7 +835,12 @@ rng_out:
__func__, ret);
return ret;
}
-
+ if (sha_req.keylen > TEGRA_CRYPTO_MAX_KEY_SIZE) {
+ pr_err("key length %d out of range [0,%d]\n",
+ sha_req.keylen
+ , TEGRA_CRYPTO_MAX_KEY_SIZE);
+ return -EINVAL;
+ }
ret = tegra_crypto_sha(&sha_req);
} else {
ret = -EINVAL;
@@ -861,7 +880,16 @@ rng_out:
pr_err("%s: copy_from_user fail(%d)\n", __func__, ret);
return ret;
}
-
+ if (rsa_req.msg_len > MAX_RSA_MSG_LEN) {
+ pr_err("Illegal message from user of length = %d\n",
+ rsa_req.msg_len);
+ return -EINVAL;
+ }
+ if (rsa_req.algo >= NUM_RSA_ALGO) {
+ pr_err("Invalid value of algo index %d\n",
+ rsa_req.algo);
+ return -EINVAL;
+ }
ret = tegra_crypt_rsa(ctx, &rsa_req);
break;
diff --git a/drivers/misc/tegra-cryptodev.h b/drivers/misc/tegra-cryptodev.h
index 706d0af25d57..e3ee4cacfb79 100644
--- a/drivers/misc/tegra-cryptodev.h
+++ b/drivers/misc/tegra-cryptodev.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2014, NVIDIA Corporation. All Rights Reserved.
+ * Copyright (c) 2010-2017, NVIDIA Corporation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@ struct tegra_crypt_req {
int op; /* e.g. TEGRA_CRYPTO_ECB */
bool encrypt;
char key[TEGRA_CRYPTO_MAX_KEY_SIZE];
- int keylen;
+ unsigned int keylen;
char iv[TEGRA_CRYPTO_IV_SIZE];
int ivlen;
u8 *plaintext;
@@ -67,7 +67,7 @@ struct tegra_crypt_req_32 {
int op; /* e.g. TEGRA_CRYPTO_ECB */
bool encrypt;
char key[TEGRA_CRYPTO_MAX_KEY_SIZE];
- int keylen;
+ unsigned int keylen;
char iv[TEGRA_CRYPTO_IV_SIZE];
int ivlen;
__u32 plaintext;
@@ -112,12 +112,12 @@ struct tegra_rsa_req {
char *key;
char *message;
char *result;
- int algo;
- int keylen;
- int msg_len;
- int modlen;
- int pub_explen;
- int prv_explen;
+ unsigned int algo;
+ unsigned int keylen;
+ unsigned int msg_len;
+ unsigned int modlen;
+ unsigned int pub_explen;
+ unsigned int prv_explen;
int skip_key;
};
#define TEGRA_CRYPTO_IOCTL_RSA_REQ \
@@ -128,12 +128,12 @@ struct tegra_rsa_req_32 {
__u32 key;
__u32 message;
__u32 result;
- int algo;
- int keylen;
- int msg_len;
- int modlen;
- int pub_explen;
- int prv_explen;
+ __u32 algo;
+ __u32 keylen;
+ __u32 msg_len;
+ __u32 modlen;
+ __u32 pub_explen;
+ __u32 prv_explen;
int skip_key;
};
#define TEGRA_CRYPTO_IOCTL_RSA_REQ_32 \
@@ -142,7 +142,7 @@ struct tegra_rsa_req_32 {
struct tegra_sha_req {
char key[TEGRA_CRYPTO_MAX_KEY_SIZE];
- int keylen;
+ unsigned int keylen;
unsigned char *algo;
unsigned char *plaintext;
unsigned char *result;
@@ -154,7 +154,7 @@ struct tegra_sha_req {
#ifdef CONFIG_COMPAT
struct tegra_sha_req_32 {
char key[TEGRA_CRYPTO_MAX_KEY_SIZE];
- int keylen;
+ unsigned int keylen;
__u32 algo;
__u32 plaintext;
__u32 result;