diff options
Diffstat (limited to 'CVE-2017-7618.patch')
-rw-r--r-- | CVE-2017-7618.patch | 254 |
1 files changed, 0 insertions, 254 deletions
diff --git a/CVE-2017-7618.patch b/CVE-2017-7618.patch deleted file mode 100644 index 4e06b1d9a..000000000 --- a/CVE-2017-7618.patch +++ /dev/null @@ -1,254 +0,0 @@ -From: Herbert Xu <herbert@gondor.apana.org.au> -Date: 2017-04-10 9:27:57 -Subject: [PATCH v2] crypto: ahash - Fix EINPROGRESS notification callback - -On Mon, Apr 10, 2017 at 11:21:27AM +0200, Sabrina Dubroca wrote: -> -> > Cc: <vger@stable.kernel.org> -> -> Should that be stable@vger.kernel.org? - -Oops :) - -> > Reported-by: Sabrina Dubroca <sdubroca@redhat.com> -> > Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> -> -> The definition of ahash_request_flags() was missing, so I added: -> -> static inline u32 ahash_request_flags(struct ahash_request *req) -> { -> return req->base.flags; -> } -> -> And with this, my tests seem fine. -> -> Tested-by: Sabrina Dubroca <sd@queasysnail.net> -> Could also you change the 'Reported-by:' to that email address? - -OK, here is v2. - ----8<--- -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> - -diff --git a/crypto/ahash.c b/crypto/ahash.c -index e58c497..1810feb 100644 ---- a/crypto/ahash.c -+++ b/crypto/ahash.c -@@ -32,6 +32,7 @@ struct ahash_request_priv { - crypto_completion_t complete; - void *data; - u8 *result; -+ u32 flags; - void *ubuf[] CRYPTO_MINALIGN_ATTR; - }; - -@@ -253,6 +254,8 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) - priv->result = req->result; - priv->complete = req->base.complete; - priv->data = req->base.data; -+ priv->flags = req->base.flags; -+ - /* - * WARNING: We do not backup req->priv here! The req->priv - * is for internal use of the Crypto API and the -@@ -267,38 +270,44 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) - return 0; - } - --static void ahash_restore_req(struct ahash_request *req) -+static void ahash_restore_req(struct ahash_request *req, int err) - { - struct ahash_request_priv *priv = req->priv; - -+ if (!err) -+ memcpy(priv->result, req->result, -+ crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); -+ - /* Restore the original crypto request. */ - req->result = priv->result; -- req->base.complete = priv->complete; -- req->base.data = priv->data; -+ -+ ahash_request_set_callback(req, priv->flags, -+ priv->complete, priv->data); - req->priv = NULL; - - /* Free the req->priv.priv from the ADJUSTED request. */ - kzfree(priv); - } - --static void ahash_op_unaligned_finish(struct ahash_request *req, int err) -+static void ahash_notify_einprogress(struct ahash_request *req) - { - struct ahash_request_priv *priv = req->priv; -+ struct crypto_async_request oreq; - -- if (err == -EINPROGRESS) -- return; -+ oreq.data = priv->data; - -- if (!err) -- memcpy(priv->result, req->result, -- crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); -- -- ahash_restore_req(req); -+ priv->complete(&oreq, -EINPROGRESS); - } - - static void ahash_op_unaligned_done(struct crypto_async_request *req, int err) - { - struct ahash_request *areq = req->data; - -+ if (err == -EINPROGRESS) { -+ ahash_notify_einprogress(areq); -+ return; -+ } -+ - /* - * Restore the original request, see ahash_op_unaligned() for what - * goes where. -@@ -309,7 +318,7 @@ static void ahash_op_unaligned_done(struct crypto_async_request *req, int err) - */ - - /* First copy req->result into req->priv.result */ -- ahash_op_unaligned_finish(areq, err); -+ ahash_restore_req(areq, err); - - /* Complete the ORIGINAL request. */ - areq->base.complete(&areq->base, err); -@@ -325,7 +334,12 @@ static int ahash_op_unaligned(struct ahash_request *req, - return err; - - err = op(req); -- ahash_op_unaligned_finish(req, err); -+ if (err == -EINPROGRESS || -+ (err == -EBUSY && (ahash_request_flags(req) & -+ CRYPTO_TFM_REQ_MAY_BACKLOG))) -+ return err; -+ -+ ahash_restore_req(req, err); - - return err; - } -@@ -360,25 +374,14 @@ int crypto_ahash_digest(struct ahash_request *req) - } - EXPORT_SYMBOL_GPL(crypto_ahash_digest); - --static void ahash_def_finup_finish2(struct ahash_request *req, int err) -+static void ahash_def_finup_done2(struct crypto_async_request *req, int err) - { -- struct ahash_request_priv *priv = req->priv; -+ struct ahash_request *areq = req->data; - - if (err == -EINPROGRESS) - return; - -- if (!err) -- memcpy(priv->result, req->result, -- crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); -- -- ahash_restore_req(req); --} -- --static void ahash_def_finup_done2(struct crypto_async_request *req, int err) --{ -- struct ahash_request *areq = req->data; -- -- ahash_def_finup_finish2(areq, err); -+ ahash_restore_req(areq, err); - - areq->base.complete(&areq->base, err); - } -@@ -389,11 +392,15 @@ static int ahash_def_finup_finish1(struct ahash_request *req, int err) - goto out; - - req->base.complete = ahash_def_finup_done2; -- req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; -+ - err = crypto_ahash_reqtfm(req)->final(req); -+ if (err == -EINPROGRESS || -+ (err == -EBUSY && (ahash_request_flags(req) & -+ CRYPTO_TFM_REQ_MAY_BACKLOG))) -+ return err; - - out: -- ahash_def_finup_finish2(req, err); -+ ahash_restore_req(req, err); - return err; - } - -@@ -401,7 +408,16 @@ static void ahash_def_finup_done1(struct crypto_async_request *req, int err) - { - struct ahash_request *areq = req->data; - -+ if (err == -EINPROGRESS) { -+ ahash_notify_einprogress(areq); -+ return; -+ } -+ -+ areq->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; -+ - err = ahash_def_finup_finish1(areq, err); -+ if (areq->priv) -+ return; - - areq->base.complete(&areq->base, err); - } -@@ -416,6 +432,11 @@ static int ahash_def_finup(struct ahash_request *req) - return err; - - err = tfm->update(req); -+ if (err == -EINPROGRESS || -+ (err == -EBUSY && (ahash_request_flags(req) & -+ CRYPTO_TFM_REQ_MAY_BACKLOG))) -+ return err; -+ - return ahash_def_finup_finish1(req, err); - } - -diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h -index 1d4f365..f6d9af3e 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) - { --- -Email: Herbert Xu <herbert@gondor.apana.org.au> -Home Page: http://gondor.apana.org.au/~herbert/ -PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt |