From: Boojin Kim Date: Fri, 22 Mar 2019 04:49:15 +0000 (+0900) Subject: [RAMEN9610-13690] fmp: add invalid pointer check X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=e144ff142efa0103d262dcff3d78dc61238f5e90;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [RAMEN9610-13690] fmp: add invalid pointer check Change-Id: I331b878539a60c86b65c98196b2630963e4d1eb2 Signed-off-by: Boojin Kim --- diff --git a/crypto/diskcipher.c b/crypto/diskcipher.c index d5b0404ece3e..53f3f9f6b6e6 100644 --- a/crypto/diskcipher.c +++ b/crypto/diskcipher.c @@ -278,16 +278,16 @@ int crypto_diskcipher_set_crypt(struct crypto_diskcipher *tfm, void *req) struct crypto_tfm *base = crypto_diskcipher_tfm(tfm); struct diskcipher_alg *cra = NULL; - if (!base) { - pr_err("%s: doesn't exist cra. base:%p", __func__, base); + if (!base || (base && !virt_addr_valid(base))) { + pr_err("%s: doesn't exist base, tfm:%p, base:%p(vaild:%d)\n", + __func__, tfm, base, virt_addr_valid(base)); ret = -EINVAL; goto out; } cra = crypto_diskcipher_alg(base->__crt_alg); - if (!cra) { - pr_err("%s: doesn't exist cra. base:%p\n", __func__, base); + pr_err("%s: doesn't exist cra:%p base:%p\n",__func__, cra, base); ret = -EINVAL; goto out; } @@ -299,7 +299,6 @@ int crypto_diskcipher_set_crypt(struct crypto_diskcipher *tfm, void *req) } ret = cra->crypt(base, req); - #ifdef USE_FREE_REQ if (!list_empty(&cra->freectrl.freelist)) { if (!atomic_read(&cra->freectrl.freewq_active)) { @@ -321,16 +320,16 @@ int crypto_diskcipher_clear_crypt(struct crypto_diskcipher *tfm, void *req) struct crypto_tfm *base = crypto_diskcipher_tfm(tfm); struct diskcipher_alg *cra = NULL; - if (!base) { - pr_err("%s: doesn't exist base, tfm:%p\n", __func__, tfm); + if (!base || (base && !virt_addr_valid(base))) { + pr_err("%s: doesn't exist base, tfm:%p, base:%p(vaild:%d)\n", + __func__, tfm, base, virt_addr_valid(base)); ret = -EINVAL; goto out; } cra = crypto_diskcipher_alg(base->__crt_alg); - if (!cra) { - pr_err("%s: doesn't exist cra. base:%p\n", __func__, base); + pr_err("%s: doesn't exist cra:%p base:%p\n",__func__, cra, base); ret = -EINVAL; goto out; } @@ -493,7 +492,10 @@ void crypto_free_diskcipher(struct crypto_diskcipher *tfm) { crypto_diskcipher_debug(DISKC_API_FREE, 0); atomic_set(&tfm->status, DISKC_ST_FREE); - crypto_destroy_tfm(tfm, crypto_diskcipher_tfm(tfm)); + if (tfm && virt_addr_valid(tfm)) + crypto_destroy_tfm(tfm, crypto_diskcipher_tfm(tfm)); + else + pr_warn("%s: invalid tfm:%p(valid:%d)\n", __func__, tfm, virt_addr_valid(tfm)); } int crypto_register_diskcipher(struct diskcipher_alg *alg) diff --git a/drivers/crypto/fmp/fmp.c b/drivers/crypto/fmp/fmp.c index e09900ace080..67a82ce10ac6 100644 --- a/drivers/crypto/fmp/fmp.c +++ b/drivers/crypto/fmp/fmp.c @@ -101,7 +101,7 @@ static inline int check_aes_xts_key(char *key, int fmplib_set_algo_mode(struct fmp_table_setting *table, struct fmp_crypto_info *crypto, bool cmdq_enabled) { - int ret; + int ret = 0; enum fmp_crypto_algo_mode algo_mode = crypto->algo_mode; if (algo_mode == EXYNOS_FMP_ALGO_MODE_AES_XTS) { @@ -129,10 +129,9 @@ int fmplib_set_algo_mode(struct fmp_table_setting *table, default: pr_err("%s: Invalid fmp enc mode %d\n", __func__, crypto->enc_mode); - ret = -EINVAL; - break; + return -EINVAL; } - return 0; + return ret; } static int fmplib_set_file_key(struct fmp_table_setting *table, @@ -275,16 +274,32 @@ static int fmplib_set_iv(struct fmp_table_setting *table, return 0; } +static inline bool check_valid_address(void *va) +{ + if(!va || (va && !virt_addr_valid(va))) + return 1; + else + return 0; +} + int exynos_fmp_crypt(struct fmp_crypto_info *ci, void *priv) { - struct exynos_fmp *fmp = ci->ctx; + struct exynos_fmp *fmp; struct fmp_request *r = priv; int ret = 0; u8 iv[FMP_IV_SIZE_16]; bool test_mode = 0; - if (!r || !fmp) { - pr_err("%s: invalid req:%p, fmp:%p\n", __func__, r, fmp); + if (!r || check_valid_address(ci)) { + pr_err("%s: invalid req:%p(v:%d), ci:%p(v:%d)\n", + __func__, r, virt_addr_valid(r), ci, virt_addr_valid(ci)); + return -EINVAL; + } + + fmp = ci->ctx; + if (!fmp || !r->table) { + pr_err("%s: invalid fmp:%p(v:%d), r->table:%p(v:%d)\n", + __func__, fmp, virt_addr_valid(fmp), r->table, virt_addr_valid(r->table)); return -EINVAL; } @@ -322,8 +337,7 @@ int exynos_fmp_crypt(struct fmp_crypto_info *ci, void *priv) /* check crypto info & input param */ if (!ci->algo_mode || !is_supported_ivsize(r->ivsize) || !r->table || !r->iv) { - dev_err(fmp->dev, - "%s: invalid mode:%d iv:%p ivsize:%d table:%p\n", + pr_err("%s: invalid mode:%d iv:%p ivsize:%d table:%p\n", __func__, ci->algo_mode, r->iv, r->ivsize, r->table); ret = -EINVAL; goto out; @@ -332,7 +346,7 @@ int exynos_fmp_crypt(struct fmp_crypto_info *ci, void *priv) /* set algo & enc mode into table */ ret = fmplib_set_algo_mode(r->table, ci, r->cmdq_enabled); if (ret) { - dev_err(fmp->dev, "%s: Fail to set FMP encryption mode\n", + pr_err("%s: Fail to set FMP encryption mode\n", __func__); ret = -EINVAL; goto out; @@ -343,7 +357,7 @@ int exynos_fmp_crypt(struct fmp_crypto_info *ci, void *priv) case EXYNOS_FMP_FILE_ENC: ret = fmplib_set_file_key(r->table, ci); if (ret) { - dev_err(fmp->dev, "%s: Fail to set FMP key\n", + pr_err("%s: Fail to set FMP key\n", __func__); ret = -EINVAL; goto out; @@ -354,15 +368,14 @@ int exynos_fmp_crypt(struct fmp_crypto_info *ci, void *priv) exynos_smc(SMC_CMD_FMP_DISK_KEY_SET, 0, 0, 0); fmp->status_disk_key = KEY_SET; } else if (!is_set_fmp_disk_key(fmp)) { - dev_err(fmp->dev, - "%s: Cannot configure FMP because disk key is clear\n", + pr_err("%s: Cannot configure FMP because disk key is clear\n", __func__); ret = -EINVAL; goto out; } break; default: - dev_err(fmp->dev, "%s: Invalid fmp enc mode %d\n", __func__, + pr_err("%s: Invalid fmp enc mode %d\n", __func__, ci->enc_mode); ret = -EINVAL; goto out; @@ -371,7 +384,7 @@ int exynos_fmp_crypt(struct fmp_crypto_info *ci, void *priv) /* set key size into table */ ret = fmplib_set_key_size(r->table, ci, r->cmdq_enabled); if (ret) { - dev_err(fmp->dev, "%s: Fail to set FMP key size\n", __func__); + pr_err("%s: Fail to set FMP key size\n", __func__); ret = -EINVAL; goto out; } @@ -381,7 +394,7 @@ int exynos_fmp_crypt(struct fmp_crypto_info *ci, void *priv) memcpy(iv, r->iv, r->ivsize); ret = fmplib_set_iv(r->table, ci, iv); if (ret) { - dev_err(fmp->dev, "%s: Fail to set FMP IV\n", __func__); + pr_err("%s: Fail to set FMP IV\n", __func__); ret = -EINVAL; goto out; } @@ -403,22 +416,25 @@ int exynos_fmp_clear(struct fmp_crypto_info *ci, void *priv) { struct fmp_request *r = priv; #ifdef CONFIG_EXYNOS_FMP_FIPS - struct exynos_fmp *fmp = ci->ctx; + struct exynos_fmp *fmp; struct exynos_fmp_fips_test_vops *test_vops = fmp->test_vops; int ret; #endif - if (!r) { - pr_err("%s: Invalid input\n", __func__); + if (!r || check_valid_address(ci)) { + pr_err("%s: invalid req:%p(v:%d), ci:%p(v:%d)\n", + __func__, r, virt_addr_valid(r), ci, virt_addr_valid(ci)); return -EINVAL; } - if (!r->table) { - pr_err("%s: Invalid input table\n", __func__); +#ifdef CONFIG_EXYNOS_FMP_FIPS + fmp = ci->ctx; + if (!fmp || !r->table) { + pr_err("%s: invalid fmp:%p(v:%d), r->table:%p(v:%d)\n", + __func__, fmp, virt_addr_valid(fmp), r->table, virt_addr_valid(r->table)); return -EINVAL; } -#ifdef CONFIG_EXYNOS_FMP_FIPS if (test_vops) { ret = test_vops->zeroization(r->table, "before"); if (ret) diff --git a/drivers/scsi/ufs/ufs-exynos-fmp.c b/drivers/scsi/ufs/ufs-exynos-fmp.c index 3db922a89454..4cd9c85af14a 100644 --- a/drivers/scsi/ufs/ufs-exynos-fmp.c +++ b/drivers/scsi/ufs/ufs-exynos-fmp.c @@ -122,8 +122,9 @@ int exynos_ufs_fmp_cfg(struct ufs_hba *hba, return 0; dtfm = crypto_diskcipher_get(bio); - if (unlikely(IS_ERR(dtfm))) { - pr_warn("%s: fails to get crypt\n", __func__); + if (unlikely(IS_ERR(dtfm)) || (dtfm && !virt_addr_valid(dtfm))) { + pr_warn("%s: fails to get crypt: %p, valid:%d\n", __func__, dtfm, + virt_addr_valid(dtfm)); return -EINVAL; } else if (dtfm) { #ifdef CONFIG_CRYPTO_DISKCIPHER_DUN