aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2018-03-20 03:52:45 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2018-03-30 13:32:58 -0400
commiteb02c38f019726ede53eb31c3c604fd77cfedc2e (patch)
treea59d515c38ef954c7e86a87054bbf6e7db0ba389 /crypto
parent3ca1e9948940230bd2c4b17e320bbab3367fc37b (diff)
crypto: api - Keep failed instances alive
This patch reverts commit 9c521a200bc3 ("crypto: api - remove instance when test failed") and fixes the underlying problem in a different way. To recap, prior to the reverted commit, an instance that fails a self-test is kept around. However, it would satisfy any new lookups against its name and therefore the system may accumlulate an unbounded number of failed instances for the same algorithm name. The reverted commit fixed it by unregistering the instance. Hoever, this still does not prevent the creation of the same failed instance over and over again each time the name is looked up. This patch fixes it by keeping the failed instance around, just as we would if it were a normal algorithm. However, the lookup code has been udpated so that we do not attempt to create another instance as long as this failed one is still registered. Of course, you could still force a new creation by deleting the instance from user-space. A new error (ELIBBAD) has been commandeered for this purpose and will be returned when all registered algorithm of a given name have failed the self-test. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/algapi.c8
-rw-r--r--crypto/api.c22
2 files changed, 13 insertions, 17 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 395b082d03a9..2a0271b5f62a 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -543,9 +543,6 @@ int crypto_register_instance(struct crypto_template *tmpl,
543 inst->alg.cra_module = tmpl->module; 543 inst->alg.cra_module = tmpl->module;
544 inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE; 544 inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
545 545
546 if (unlikely(!crypto_mod_get(&inst->alg)))
547 return -EAGAIN;
548
549 down_write(&crypto_alg_sem); 546 down_write(&crypto_alg_sem);
550 547
551 larval = __crypto_register_alg(&inst->alg); 548 larval = __crypto_register_alg(&inst->alg);
@@ -563,14 +560,9 @@ unlock:
563 goto err; 560 goto err;
564 561
565 crypto_wait_for_test(larval); 562 crypto_wait_for_test(larval);
566
567 /* Remove instance if test failed */
568 if (!(inst->alg.cra_flags & CRYPTO_ALG_TESTED))
569 crypto_unregister_instance(inst);
570 err = 0; 563 err = 0;
571 564
572err: 565err:
573 crypto_mod_put(&inst->alg);
574 return err; 566 return err;
575} 567}
576EXPORT_SYMBOL_GPL(crypto_register_instance); 568EXPORT_SYMBOL_GPL(crypto_register_instance);
diff --git a/crypto/api.c b/crypto/api.c
index bb9fe480f092..1d5290c67108 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -197,9 +197,16 @@ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
197 u32 mask) 197 u32 mask)
198{ 198{
199 struct crypto_alg *alg; 199 struct crypto_alg *alg;
200 u32 test = 0;
201
202 if (!((type | mask) & CRYPTO_ALG_TESTED))
203 test |= CRYPTO_ALG_TESTED;
200 204
201 down_read(&crypto_alg_sem); 205 down_read(&crypto_alg_sem);
202 alg = __crypto_alg_lookup(name, type, mask); 206 alg = __crypto_alg_lookup(name, type | test, mask | test);
207 if (!alg && test)
208 alg = __crypto_alg_lookup(name, type, mask) ?
209 ERR_PTR(-ELIBBAD) : NULL;
203 up_read(&crypto_alg_sem); 210 up_read(&crypto_alg_sem);
204 211
205 return alg; 212 return alg;
@@ -227,10 +234,12 @@ static struct crypto_alg *crypto_larval_lookup(const char *name, u32 type,
227 alg = crypto_alg_lookup(name, type, mask); 234 alg = crypto_alg_lookup(name, type, mask);
228 } 235 }
229 236
230 if (alg) 237 if (!IS_ERR_OR_NULL(alg) && crypto_is_larval(alg))
231 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; 238 alg = crypto_larval_wait(alg);
239 else if (!alg)
240 alg = crypto_larval_add(name, type, mask);
232 241
233 return crypto_larval_add(name, type, mask); 242 return alg;
234} 243}
235 244
236int crypto_probing_notify(unsigned long val, void *v) 245int crypto_probing_notify(unsigned long val, void *v)
@@ -253,11 +262,6 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
253 struct crypto_alg *larval; 262 struct crypto_alg *larval;
254 int ok; 263 int ok;
255 264
256 if (!((type | mask) & CRYPTO_ALG_TESTED)) {
257 type |= CRYPTO_ALG_TESTED;
258 mask |= CRYPTO_ALG_TESTED;
259 }
260
261 /* 265 /*
262 * If the internal flag is set for a cipher, require a caller to 266 * If the internal flag is set for a cipher, require a caller to
263 * to invoke the cipher with the internal flag to use that cipher. 267 * to invoke the cipher with the internal flag to use that cipher.