[RAMEN9610-13690] fmp: add invalid pointer check
authorBoojin Kim <boojin.kim@samsung.com>
Fri, 22 Mar 2019 04:49:15 +0000 (13:49 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:23:21 +0000 (20:23 +0300)
Change-Id: I331b878539a60c86b65c98196b2630963e4d1eb2
Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
crypto/diskcipher.c
drivers/crypto/fmp/fmp.c
drivers/scsi/ufs/ufs-exynos-fmp.c

index d5b0404ece3e0d66faf17f10090f5864c9058f76..53f3f9f6b6e69d44508e62bdb8d67bd653ba4dfc 100644 (file)
@@ -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)
index e09900ace080b452bd9ec40ad9344cf2c8a72c46..67a82ce10ac64f88ac0f35015c65baf959e86a18 100644 (file)
@@ -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)
index 3db922a89454df38ba497443c091af00dfb82d54..4cd9c85af14abc2c3070cdc86831976d36874ffe 100644 (file)
@@ -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