summaryrefslogtreecommitdiffstats
path: root/crypto/ahash.c
diff options
context:
space:
mode:
authorCorentin Labbe <clabbe@baylibre.com>2018-11-29 09:42:21 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2018-12-07 01:15:00 -0500
commitf7d76e05d058b832b373237566cc1af8251371b5 (patch)
tree1b445b1e5904b27f826fe363056d63823f5f4e83 /crypto/ahash.c
parent76d09ea7c22f2cabf1f66ffc287c23b19b120be9 (diff)
crypto: user - fix use_after_free of struct xxx_request
All crypto_stats functions use the struct xxx_request for feeding stats, but in some case this structure could already be freed. For fixing this, the needed parameters (len and alg) will be stored before the request being executed. Fixes: cac5818c25d0 ("crypto: user - Implement a generic crypto statistics") Reported-by: syzbot <syzbot+6939a606a5305e9e9799@syzkaller.appspotmail.com> Signed-off-by: Corentin Labbe <clabbe@baylibre.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/ahash.c')
-rw-r--r--crypto/ahash.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/crypto/ahash.c b/crypto/ahash.c
index 3a348fbcf8f9..5d320a811f75 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -364,20 +364,28 @@ static int crypto_ahash_op(struct ahash_request *req,
364 364
365int crypto_ahash_final(struct ahash_request *req) 365int crypto_ahash_final(struct ahash_request *req)
366{ 366{
367 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
368 struct crypto_alg *alg = tfm->base.__crt_alg;
369 unsigned int nbytes = req->nbytes;
367 int ret; 370 int ret;
368 371
372 crypto_stats_get(alg);
369 ret = crypto_ahash_op(req, crypto_ahash_reqtfm(req)->final); 373 ret = crypto_ahash_op(req, crypto_ahash_reqtfm(req)->final);
370 crypto_stat_ahash_final(req, ret); 374 crypto_stats_ahash_final(nbytes, ret, alg);
371 return ret; 375 return ret;
372} 376}
373EXPORT_SYMBOL_GPL(crypto_ahash_final); 377EXPORT_SYMBOL_GPL(crypto_ahash_final);
374 378
375int crypto_ahash_finup(struct ahash_request *req) 379int crypto_ahash_finup(struct ahash_request *req)
376{ 380{
381 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
382 struct crypto_alg *alg = tfm->base.__crt_alg;
383 unsigned int nbytes = req->nbytes;
377 int ret; 384 int ret;
378 385
386 crypto_stats_get(alg);
379 ret = crypto_ahash_op(req, crypto_ahash_reqtfm(req)->finup); 387 ret = crypto_ahash_op(req, crypto_ahash_reqtfm(req)->finup);
380 crypto_stat_ahash_final(req, ret); 388 crypto_stats_ahash_final(nbytes, ret, alg);
381 return ret; 389 return ret;
382} 390}
383EXPORT_SYMBOL_GPL(crypto_ahash_finup); 391EXPORT_SYMBOL_GPL(crypto_ahash_finup);
@@ -385,13 +393,16 @@ EXPORT_SYMBOL_GPL(crypto_ahash_finup);
385int crypto_ahash_digest(struct ahash_request *req) 393int crypto_ahash_digest(struct ahash_request *req)
386{ 394{
387 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); 395 struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
396 struct crypto_alg *alg = tfm->base.__crt_alg;
397 unsigned int nbytes = req->nbytes;
388 int ret; 398 int ret;
389 399
400 crypto_stats_get(alg);
390 if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) 401 if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
391 ret = -ENOKEY; 402 ret = -ENOKEY;
392 else 403 else
393 ret = crypto_ahash_op(req, tfm->digest); 404 ret = crypto_ahash_op(req, tfm->digest);
394 crypto_stat_ahash_final(req, ret); 405 crypto_stats_ahash_final(nbytes, ret, alg);
395 return ret; 406 return ret;
396} 407}
397EXPORT_SYMBOL_GPL(crypto_ahash_digest); 408EXPORT_SYMBOL_GPL(crypto_ahash_digest);