aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/crypto.c
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2013-08-13 18:02:27 -0400
committerTyler Hicks <tyhicks@canonical.com>2013-09-06 19:58:18 -0400
commitcb69f36ba1f8d5e73c46538e84a88178fb17f23d (patch)
treedf95c5e4d7c9697d22d21653571cc2f5960b5256 /fs/ecryptfs/crypto.c
parente6cbd6a44d8e263073808da9f295e502d15dc3fe (diff)
ecryptfs: avoid ctx initialization race
It might be possible for two callers to race the mutex lock after the NULL ctx check. Instead, move the lock above the check so there isn't the possibility of leaking a crypto ctx. Additionally, report the full algo name when failing. Signed-off-by: Kees Cook <keescook@chromium.org> [tyhicks: remove out label, which is no longer used] Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Diffstat (limited to 'fs/ecryptfs/crypto.c')
-rw-r--r--fs/ecryptfs/crypto.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 3bd35e24b9e9..c88e355f7635 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -614,30 +614,30 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
614 "key_size_bits = [%zd]\n", 614 "key_size_bits = [%zd]\n",
615 crypt_stat->cipher, (int)strlen(crypt_stat->cipher), 615 crypt_stat->cipher, (int)strlen(crypt_stat->cipher),
616 crypt_stat->key_size << 3); 616 crypt_stat->key_size << 3);
617 mutex_lock(&crypt_stat->cs_tfm_mutex);
617 if (crypt_stat->tfm) { 618 if (crypt_stat->tfm) {
618 rc = 0; 619 rc = 0;
619 goto out; 620 goto out_unlock;
620 } 621 }
621 mutex_lock(&crypt_stat->cs_tfm_mutex);
622 rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, 622 rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
623 crypt_stat->cipher, "cbc"); 623 crypt_stat->cipher, "cbc");
624 if (rc) 624 if (rc)
625 goto out_unlock; 625 goto out_unlock;
626 crypt_stat->tfm = crypto_alloc_ablkcipher(full_alg_name, 0, 0); 626 crypt_stat->tfm = crypto_alloc_ablkcipher(full_alg_name, 0, 0);
627 kfree(full_alg_name);
628 if (IS_ERR(crypt_stat->tfm)) { 627 if (IS_ERR(crypt_stat->tfm)) {
629 rc = PTR_ERR(crypt_stat->tfm); 628 rc = PTR_ERR(crypt_stat->tfm);
630 crypt_stat->tfm = NULL; 629 crypt_stat->tfm = NULL;
631 ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " 630 ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
632 "Error initializing cipher [%s]\n", 631 "Error initializing cipher [%s]\n",
633 crypt_stat->cipher); 632 full_alg_name);
634 goto out_unlock; 633 goto out_free;
635 } 634 }
636 crypto_ablkcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY); 635 crypto_ablkcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY);
637 rc = 0; 636 rc = 0;
637out_free:
638 kfree(full_alg_name);
638out_unlock: 639out_unlock:
639 mutex_unlock(&crypt_stat->cs_tfm_mutex); 640 mutex_unlock(&crypt_stat->cs_tfm_mutex);
640out:
641 return rc; 641 return rc;
642} 642}
643 643