diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2017-04-10 11:27:57 +0200 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2017-04-10 13:09:18 +0200 |
commit | ef0579b64e93188710d48667cb5e014926af9f1b (patch) | |
tree | a2101da972309a21aa17ab489982c66836924c6f /include/crypto | |
parent | crypto: lrw - Fix use-after-free on EINPROGRESS (diff) | |
download | linux-ef0579b64e93188710d48667cb5e014926af9f1b.tar.xz linux-ef0579b64e93188710d48667cb5e014926af9f1b.zip |
crypto: ahash - Fix EINPROGRESS notification callback
The ahash API modifies the request's callback function in order
to clean up after itself in some corner cases (unaligned final
and missing finup).
When the request is complete ahash will restore the original
callback and everything is fine. However, when the request gets
an EBUSY on a full queue, an EINPROGRESS callback is made while
the request is still ongoing.
In this case the ahash API will incorrectly call its own callback.
This patch fixes the problem by creating a temporary request
object on the stack which is used to relay EINPROGRESS back to
the original completion function.
This patch also adds code to preserve the original flags value.
Fixes: ab6bf4e5e5e4 ("crypto: hash - Fix the pointer voodoo in...")
Cc: <stable@vger.kernel.org>
Reported-by: Sabrina Dubroca <sd@queasysnail.net>
Tested-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'include/crypto')
-rw-r--r-- | include/crypto/internal/hash.h | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 1d4f365d8f03..f6d9af3efa45 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -166,6 +166,16 @@ static inline struct ahash_instance *ahash_alloc_instance( return crypto_alloc_instance2(name, alg, ahash_instance_headroom()); } +static inline void ahash_request_complete(struct ahash_request *req, int err) +{ + req->base.complete(&req->base, err); +} + +static inline u32 ahash_request_flags(struct ahash_request *req) +{ + return req->base.flags; +} + static inline struct crypto_ahash *crypto_spawn_ahash( struct crypto_ahash_spawn *spawn) { |