Patchwork crypto: api - fix finding algorithm currently being tested

login
register
mail settings
Submitter Eric Biggers
Date April 16, 2018, 11:59 p.m.
Message ID <20180416235913.41164-1-ebiggers3@gmail.com>
Download mbox | patch
Permalink /patch/10344063/
State Accepted
Delegated to: Herbert Xu
Headers show

Comments

Eric Biggers - April 16, 2018, 11:59 p.m.
From: Eric Biggers <ebiggers@google.com>

Commit eb02c38f0197 ("crypto: api - Keep failed instances alive") is
making allocating crypto transforms sometimes fail with ELIBBAD, when
multiple processes try to access encrypted files with fscrypt for the
first time since boot.  The problem is that the "request larval" for the
algorithm is being mistaken for an algorithm which failed its tests.

Fix it by only returning ELIBBAD for "non-larval" algorithms.  Also
don't leak a reference to the algorithm.

Fixes: eb02c38f0197 ("crypto: api - Keep failed instances alive")
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 crypto/api.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
Herbert Xu - April 20, 2018, 5:06 p.m.
On Mon, Apr 16, 2018 at 04:59:13PM -0700, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Commit eb02c38f0197 ("crypto: api - Keep failed instances alive") is
> making allocating crypto transforms sometimes fail with ELIBBAD, when
> multiple processes try to access encrypted files with fscrypt for the
> first time since boot.  The problem is that the "request larval" for the
> algorithm is being mistaken for an algorithm which failed its tests.
> 
> Fix it by only returning ELIBBAD for "non-larval" algorithms.  Also
> don't leak a reference to the algorithm.
> 
> Fixes: eb02c38f0197 ("crypto: api - Keep failed instances alive")
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Patch applied.  Thanks.

Patch

diff --git a/crypto/api.c b/crypto/api.c
index 1d5290c67108..0ee632bba064 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -204,9 +204,14 @@  static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
 
 	down_read(&crypto_alg_sem);
 	alg = __crypto_alg_lookup(name, type | test, mask | test);
-	if (!alg && test)
-		alg = __crypto_alg_lookup(name, type, mask) ?
-		      ERR_PTR(-ELIBBAD) : NULL;
+	if (!alg && test) {
+		alg = __crypto_alg_lookup(name, type, mask);
+		if (alg && !crypto_is_larval(alg)) {
+			/* Test failed */
+			crypto_mod_put(alg);
+			alg = ERR_PTR(-ELIBBAD);
+		}
+	}
 	up_read(&crypto_alg_sem);
 
 	return alg;