evm: prevent racing during tfm allocation
authorDmitry Kasatkin <dmitry.kasatkin@intel.com>
Mon, 5 Dec 2011 11:17:42 +0000 (13:17 +0200)
committerJames Morris <jmorris@namei.org>
Wed, 7 Dec 2011 23:06:12 +0000 (10:06 +1100)
There is a small chance of racing during tfm allocation.
This patch fixes it.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Acked-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
security/integrity/evm/evm_crypto.c

index 3b9f5a080e4f69b937b2c782f67142541811fba9..f1d4ad0cea2c081158805ba0bf0e2d0ff06fcbad 100644 (file)
@@ -28,9 +28,11 @@ static int evmkey_len = MAX_KEY_SIZE;
 struct crypto_shash *hmac_tfm;
 struct crypto_shash *hash_tfm;
 
+static DEFINE_MUTEX(mutex);
+
 static struct shash_desc *init_desc(const char type)
 {
-       int rc;
+       long rc;
        char *algo;
        struct crypto_shash **tfm;
        struct shash_desc *desc;
@@ -44,12 +46,15 @@ static struct shash_desc *init_desc(const char type)
        }
 
        if (*tfm == NULL) {
+               mutex_lock(&mutex);
+               if (*tfm)
+                       goto out;
                *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC);
                if (IS_ERR(*tfm)) {
-                       pr_err("Can not allocate %s (reason: %ld)\n",
-                              algo, PTR_ERR(*tfm));
                        rc = PTR_ERR(*tfm);
+                       pr_err("Can not allocate %s (reason: %ld)\n", algo, rc);
                        *tfm = NULL;
+                       mutex_unlock(&mutex);
                        return ERR_PTR(rc);
                }
                if (type == EVM_XATTR_HMAC) {
@@ -57,9 +62,12 @@ static struct shash_desc *init_desc(const char type)
                        if (rc) {
                                crypto_free_shash(*tfm);
                                *tfm = NULL;
+                               mutex_unlock(&mutex);
                                return ERR_PTR(rc);
                        }
                }
+out:
+               mutex_unlock(&mutex);
        }
 
        desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm),