lkml.org 
[lkml]   [2021]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 251/355] crypto: pcrypt - Delay write to padata->info
    Date
    From: Daniel Jordan <daniel.m.jordan@oracle.com>

    [ Upstream commit 68b6dea802cea0dbdd8bd7ccc60716b5a32a5d8a ]

    These three events can race when pcrypt is used multiple times in a
    template ("pcrypt(pcrypt(...))"):

    1. [taskA] The caller makes the crypto request via crypto_aead_encrypt()
    2. [kworkerB] padata serializes the inner pcrypt request
    3. [kworkerC] padata serializes the outer pcrypt request

    3 might finish before the call to crypto_aead_encrypt() returns in 1,
    resulting in two possible issues.

    First, a use-after-free of the crypto request's memory when, for
    example, taskA writes to the outer pcrypt request's padata->info in
    pcrypt_aead_enc() after kworkerC completes the request.

    Second, the outer pcrypt request overwrites the inner pcrypt request's
    return code with -EINPROGRESS, making a successful request appear to
    fail. For instance, kworkerB writes the outer pcrypt request's
    padata->info in pcrypt_aead_done() and then taskA overwrites it
    in pcrypt_aead_enc().

    Avoid both situations by delaying the write of padata->info until after
    the inner crypto request's return code is checked. This prevents the
    use-after-free by not touching the crypto request's memory after the
    next-inner crypto request is made, and stops padata->info from being
    overwritten.

    Fixes: 5068c7a883d16 ("crypto: pcrypt - Add pcrypt crypto parallelization wrapper")
    Reported-by: syzbot+b187b77c8474f9648fae@syzkaller.appspotmail.com
    Signed-off-by: Daniel Jordan <daniel.m.jordan@oracle.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    crypto/pcrypt.c | 12 ++++++++----
    1 file changed, 8 insertions(+), 4 deletions(-)

    diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
    index a4f3b3f342c8d..276d2fd9e911c 100644
    --- a/crypto/pcrypt.c
    +++ b/crypto/pcrypt.c
    @@ -79,12 +79,14 @@ static void pcrypt_aead_enc(struct padata_priv *padata)
    {
    struct pcrypt_request *preq = pcrypt_padata_request(padata);
    struct aead_request *req = pcrypt_request_ctx(preq);
    + int ret;

    - padata->info = crypto_aead_encrypt(req);
    + ret = crypto_aead_encrypt(req);

    - if (padata->info == -EINPROGRESS)
    + if (ret == -EINPROGRESS)
    return;

    + padata->info = ret;
    padata_do_serial(padata);
    }

    @@ -124,12 +126,14 @@ static void pcrypt_aead_dec(struct padata_priv *padata)
    {
    struct pcrypt_request *preq = pcrypt_padata_request(padata);
    struct aead_request *req = pcrypt_request_ctx(preq);
    + int ret;

    - padata->info = crypto_aead_decrypt(req);
    + ret = crypto_aead_decrypt(req);

    - if (padata->info == -EINPROGRESS)
    + if (ret == -EINPROGRESS)
    return;

    + padata->info = ret;
    padata_do_serial(padata);
    }

    --
    2.33.0


    \
     
     \ /
      Last update: 2021-11-15 19:13    [W:4.559 / U:0.588 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site