All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
To: "Ondrej Mosnáček" <omosnacek+linux-crypto@gmail.com>
Cc: omosnace@redhat.com, Herbert Xu <herbert@gondor.apana.org.au>,
	linux-crypto@vger.kernel.org,
	Stephan Mueller <smueller@chronox.de>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	Michael Ellerman <mpe@ellerman.id.au>,
	leo.barbosa@canonical.com, stable@vger.kernel.org,
	Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>,
	linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH] crypto: vmx - Fix sleep-in-atomic bugs
Date: Tue, 21 Aug 2018 13:41:26 -0300	[thread overview]
Message-ID: <20180821164126.GF28751@gallifrey> (raw)
In-Reply-To: <CAAUqJDu1ib4Rfr6fnV2L001Uf3frkv6KQ-WJz6UvQ=R0VuXipg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 7943 bytes --]

On Tue, Aug 21, 2018 at 05:24:45PM +0200, Ondrej Mosnáček wrote:
> CC: Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>,
> linuxppc-dev@lists.ozlabs.org
> 
> (Sorry, sent this before reading new e-mails in the thread...)
> 
> ut 21. 8. 2018 o 17:18 Ondrej Mosnacek <omosnace@redhat.com> napísal(a):
> >
> > This patch fixes sleep-in-atomic bugs in AES-CBC and AES-XTS VMX
> > implementations. The problem is that the blkcipher_* functions should
> > not be called in atomic context.
> >
> > The bugs can be reproduced via the AF_ALG interface by trying to
> > encrypt/decrypt sufficiently large buffers (at least 64 KiB) using the
> > VMX implementations of 'cbc(aes)' or 'xts(aes)'. Such operations then
> > trigger BUG in crypto_yield():
> >
> > [  891.863680] BUG: sleeping function called from invalid context at include/crypto/algapi.h:424
> > [  891.864622] in_atomic(): 1, irqs_disabled(): 0, pid: 12347, name: kcapi-enc
> > [  891.864739] 1 lock held by kcapi-enc/12347:
> > [  891.864811]  #0: 00000000f5d42c46 (sk_lock-AF_ALG){+.+.}, at: skcipher_recvmsg+0x50/0x530
> > [  891.865076] CPU: 5 PID: 12347 Comm: kcapi-enc Not tainted 4.19.0-0.rc0.git3.1.fc30.ppc64le #1
> > [  891.865251] Call Trace:
> > [  891.865340] [c0000003387578c0] [c000000000d67ea4] dump_stack+0xe8/0x164 (unreliable)
> > [  891.865511] [c000000338757910] [c000000000172a58] ___might_sleep+0x2f8/0x310
> > [  891.865679] [c000000338757990] [c0000000006bff74] blkcipher_walk_done+0x374/0x4a0
> > [  891.865825] [c0000003387579e0] [d000000007e73e70] p8_aes_cbc_encrypt+0x1c8/0x260 [vmx_crypto]
> > [  891.865993] [c000000338757ad0] [c0000000006c0ee0] skcipher_encrypt_blkcipher+0x60/0x80
> > [  891.866128] [c000000338757b10] [c0000000006ec504] skcipher_recvmsg+0x424/0x530
> > [  891.866283] [c000000338757bd0] [c000000000b00654] sock_recvmsg+0x74/0xa0
> > [  891.866403] [c000000338757c10] [c000000000b00f64] ___sys_recvmsg+0xf4/0x2f0
> > [  891.866515] [c000000338757d90] [c000000000b02bb8] __sys_recvmsg+0x68/0xe0
> > [  891.866631] [c000000338757e30] [c00000000000bbe4] system_call+0x5c/0x70
> >
> > Fixes: 8c755ace357c ("crypto: vmx - Adding CBC routines for VMX module")
> > Fixes: c07f5d3da643 ("crypto: vmx - Adding support for XTS")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
> > ---
> > This patch should fix the issue, but I didn't test it. (I'll see if I
> > can find some time tomorrow to try and recompile the kernel on a PPC
> > machine... in the meantime please review :)
> >
> >  drivers/crypto/vmx/aes_cbc.c | 30 ++++++++++++++----------------
> >  drivers/crypto/vmx/aes_xts.c | 19 ++++++++++++-------
> >  2 files changed, 26 insertions(+), 23 deletions(-)
> >
> > diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c
> > index 5285ece4f33a..b71895871be3 100644
> > --- a/drivers/crypto/vmx/aes_cbc.c
> > +++ b/drivers/crypto/vmx/aes_cbc.c
> > @@ -107,24 +107,23 @@ static int p8_aes_cbc_encrypt(struct blkcipher_desc *desc,
> >                 ret = crypto_skcipher_encrypt(req);
> >                 skcipher_request_zero(req);
> >         } else {
> > -               preempt_disable();
> > -               pagefault_disable();
> > -               enable_kernel_vsx();
> > -
> >                 blkcipher_walk_init(&walk, dst, src, nbytes);
> >                 ret = blkcipher_walk_virt(desc, &walk);
> >                 while ((nbytes = walk.nbytes)) {
> > +                       preempt_disable();
> > +                       pagefault_disable();
> > +                       enable_kernel_vsx();
> >                         aes_p8_cbc_encrypt(walk.src.virt.addr,
> >                                            walk.dst.virt.addr,
> >                                            nbytes & AES_BLOCK_MASK,
> >                                            &ctx->enc_key, walk.iv, 1);
> > +                       disable_kernel_vsx();
> > +                       pagefault_enable();
> > +                       preempt_enable();
> > +
> >                         nbytes &= AES_BLOCK_SIZE - 1;
> >                         ret = blkcipher_walk_done(desc, &walk, nbytes);
> >                 }
> > -
> > -               disable_kernel_vsx();
> > -               pagefault_enable();
> > -               preempt_enable();
> >         }
> >
> >         return ret;
> > @@ -147,24 +146,23 @@ static int p8_aes_cbc_decrypt(struct blkcipher_desc *desc,
> >                 ret = crypto_skcipher_decrypt(req);
> >                 skcipher_request_zero(req);
> >         } else {
> > -               preempt_disable();
> > -               pagefault_disable();
> > -               enable_kernel_vsx();
> > -
> >                 blkcipher_walk_init(&walk, dst, src, nbytes);
> >                 ret = blkcipher_walk_virt(desc, &walk);
> >                 while ((nbytes = walk.nbytes)) {
> > +                       preempt_disable();
> > +                       pagefault_disable();
> > +                       enable_kernel_vsx();
> >                         aes_p8_cbc_encrypt(walk.src.virt.addr,
> >                                            walk.dst.virt.addr,
> >                                            nbytes & AES_BLOCK_MASK,
> >                                            &ctx->dec_key, walk.iv, 0);
> > +                       disable_kernel_vsx();
> > +                       pagefault_enable();
> > +                       preempt_enable();
> > +
> >                         nbytes &= AES_BLOCK_SIZE - 1;
> >                         ret = blkcipher_walk_done(desc, &walk, nbytes);
> >                 }
> > -
> > -               disable_kernel_vsx();
> > -               pagefault_enable();
> > -               preempt_enable();
> >         }
> >
> >         return ret;
> > diff --git a/drivers/crypto/vmx/aes_xts.c b/drivers/crypto/vmx/aes_xts.c
> > index 8bd9aff0f55f..016ef52390c9 100644
> > --- a/drivers/crypto/vmx/aes_xts.c
> > +++ b/drivers/crypto/vmx/aes_xts.c
> > @@ -116,13 +116,14 @@ static int p8_aes_xts_crypt(struct blkcipher_desc *desc,
> >                 ret = enc? crypto_skcipher_encrypt(req) : crypto_skcipher_decrypt(req);
> >                 skcipher_request_zero(req);
> >         } else {
> > +               blkcipher_walk_init(&walk, dst, src, nbytes);
> > +
> > +               ret = blkcipher_walk_virt(desc, &walk);
> > +
> >                 preempt_disable();
> >                 pagefault_disable();
> >                 enable_kernel_vsx();
> >
> > -               blkcipher_walk_init(&walk, dst, src, nbytes);
> > -
> > -               ret = blkcipher_walk_virt(desc, &walk);
> >                 iv = walk.iv;
> >                 memset(tweak, 0, AES_BLOCK_SIZE);
> >                 aes_p8_encrypt(iv, tweak, &ctx->tweak_key);
> > @@ -135,13 +136,17 @@ static int p8_aes_xts_crypt(struct blkcipher_desc *desc,
> >                                 aes_p8_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
> >                                                 nbytes & AES_BLOCK_MASK, &ctx->dec_key, NULL, tweak);
> >
> > +                       disable_kernel_vsx();
> > +                       pagefault_enable();
> > +                       preempt_enable();
> > +
> >                         nbytes &= AES_BLOCK_SIZE - 1;
> >                         ret = blkcipher_walk_done(desc, &walk, nbytes);
> > -               }
> >
> > -               disable_kernel_vsx();
> > -               pagefault_enable();
> > -               preempt_enable();
> > +                       preempt_disable();
> > +                       pagefault_disable();
> > +                       enable_kernel_vsx();
> > +               }

That doesn't seem right. It would leave preemption disabled when
leaving the function.


> >         }
> >         return ret;
> >  }
> > --
> > 2.17.1
> >

WARNING: multiple messages have this Message-ID (diff)
From: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
To: "Ondrej Mosnáček" <omosnacek+linux-crypto@gmail.com>
Cc: omosnace@redhat.com, Herbert Xu <herbert@gondor.apana.org.au>,
	linux-crypto@vger.kernel.org,
	Stephan Mueller <smueller@chronox.de>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	Michael Ellerman <mpe@ellerman.id.au>,
	leo.barbosa@canonical.com, stable@vger.kernel.org,
	Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>,
	linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH] crypto: vmx - Fix sleep-in-atomic bugs
Date: Tue, 21 Aug 2018 13:41:26 -0300	[thread overview]
Message-ID: <20180821164126.GF28751@gallifrey> (raw)
In-Reply-To: <CAAUqJDu1ib4Rfr6fnV2L001Uf3frkv6KQ-WJz6UvQ=R0VuXipg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 7970 bytes --]

On Tue, Aug 21, 2018 at 05:24:45PM +0200, Ondrej Mosnáček wrote:
> CC: Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>,
> linuxppc-dev@lists.ozlabs.org
> 
> (Sorry, sent this before reading new e-mails in the thread...)
> 
> ut 21. 8. 2018 o 17:18 Ondrej Mosnacek <omosnace@redhat.com> napísal(a):
> >
> > This patch fixes sleep-in-atomic bugs in AES-CBC and AES-XTS VMX
> > implementations. The problem is that the blkcipher_* functions should
> > not be called in atomic context.
> >
> > The bugs can be reproduced via the AF_ALG interface by trying to
> > encrypt/decrypt sufficiently large buffers (at least 64 KiB) using the
> > VMX implementations of 'cbc(aes)' or 'xts(aes)'. Such operations then
> > trigger BUG in crypto_yield():
> >
> > [  891.863680] BUG: sleeping function called from invalid context at include/crypto/algapi.h:424
> > [  891.864622] in_atomic(): 1, irqs_disabled(): 0, pid: 12347, name: kcapi-enc
> > [  891.864739] 1 lock held by kcapi-enc/12347:
> > [  891.864811]  #0: 00000000f5d42c46 (sk_lock-AF_ALG){+.+.}, at: skcipher_recvmsg+0x50/0x530
> > [  891.865076] CPU: 5 PID: 12347 Comm: kcapi-enc Not tainted 4.19.0-0.rc0.git3.1.fc30.ppc64le #1
> > [  891.865251] Call Trace:
> > [  891.865340] [c0000003387578c0] [c000000000d67ea4] dump_stack+0xe8/0x164 (unreliable)
> > [  891.865511] [c000000338757910] [c000000000172a58] ___might_sleep+0x2f8/0x310
> > [  891.865679] [c000000338757990] [c0000000006bff74] blkcipher_walk_done+0x374/0x4a0
> > [  891.865825] [c0000003387579e0] [d000000007e73e70] p8_aes_cbc_encrypt+0x1c8/0x260 [vmx_crypto]
> > [  891.865993] [c000000338757ad0] [c0000000006c0ee0] skcipher_encrypt_blkcipher+0x60/0x80
> > [  891.866128] [c000000338757b10] [c0000000006ec504] skcipher_recvmsg+0x424/0x530
> > [  891.866283] [c000000338757bd0] [c000000000b00654] sock_recvmsg+0x74/0xa0
> > [  891.866403] [c000000338757c10] [c000000000b00f64] ___sys_recvmsg+0xf4/0x2f0
> > [  891.866515] [c000000338757d90] [c000000000b02bb8] __sys_recvmsg+0x68/0xe0
> > [  891.866631] [c000000338757e30] [c00000000000bbe4] system_call+0x5c/0x70
> >
> > Fixes: 8c755ace357c ("crypto: vmx - Adding CBC routines for VMX module")
> > Fixes: c07f5d3da643 ("crypto: vmx - Adding support for XTS")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
> > ---
> > This patch should fix the issue, but I didn't test it. (I'll see if I
> > can find some time tomorrow to try and recompile the kernel on a PPC
> > machine... in the meantime please review :)
> >
> >  drivers/crypto/vmx/aes_cbc.c | 30 ++++++++++++++----------------
> >  drivers/crypto/vmx/aes_xts.c | 19 ++++++++++++-------
> >  2 files changed, 26 insertions(+), 23 deletions(-)
> >
> > diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c
> > index 5285ece4f33a..b71895871be3 100644
> > --- a/drivers/crypto/vmx/aes_cbc.c
> > +++ b/drivers/crypto/vmx/aes_cbc.c
> > @@ -107,24 +107,23 @@ static int p8_aes_cbc_encrypt(struct blkcipher_desc *desc,
> >                 ret = crypto_skcipher_encrypt(req);
> >                 skcipher_request_zero(req);
> >         } else {
> > -               preempt_disable();
> > -               pagefault_disable();
> > -               enable_kernel_vsx();
> > -
> >                 blkcipher_walk_init(&walk, dst, src, nbytes);
> >                 ret = blkcipher_walk_virt(desc, &walk);
> >                 while ((nbytes = walk.nbytes)) {
> > +                       preempt_disable();
> > +                       pagefault_disable();
> > +                       enable_kernel_vsx();
> >                         aes_p8_cbc_encrypt(walk.src.virt.addr,
> >                                            walk.dst.virt.addr,
> >                                            nbytes & AES_BLOCK_MASK,
> >                                            &ctx->enc_key, walk.iv, 1);
> > +                       disable_kernel_vsx();
> > +                       pagefault_enable();
> > +                       preempt_enable();
> > +
> >                         nbytes &= AES_BLOCK_SIZE - 1;
> >                         ret = blkcipher_walk_done(desc, &walk, nbytes);
> >                 }
> > -
> > -               disable_kernel_vsx();
> > -               pagefault_enable();
> > -               preempt_enable();
> >         }
> >
> >         return ret;
> > @@ -147,24 +146,23 @@ static int p8_aes_cbc_decrypt(struct blkcipher_desc *desc,
> >                 ret = crypto_skcipher_decrypt(req);
> >                 skcipher_request_zero(req);
> >         } else {
> > -               preempt_disable();
> > -               pagefault_disable();
> > -               enable_kernel_vsx();
> > -
> >                 blkcipher_walk_init(&walk, dst, src, nbytes);
> >                 ret = blkcipher_walk_virt(desc, &walk);
> >                 while ((nbytes = walk.nbytes)) {
> > +                       preempt_disable();
> > +                       pagefault_disable();
> > +                       enable_kernel_vsx();
> >                         aes_p8_cbc_encrypt(walk.src.virt.addr,
> >                                            walk.dst.virt.addr,
> >                                            nbytes & AES_BLOCK_MASK,
> >                                            &ctx->dec_key, walk.iv, 0);
> > +                       disable_kernel_vsx();
> > +                       pagefault_enable();
> > +                       preempt_enable();
> > +
> >                         nbytes &= AES_BLOCK_SIZE - 1;
> >                         ret = blkcipher_walk_done(desc, &walk, nbytes);
> >                 }
> > -
> > -               disable_kernel_vsx();
> > -               pagefault_enable();
> > -               preempt_enable();
> >         }
> >
> >         return ret;
> > diff --git a/drivers/crypto/vmx/aes_xts.c b/drivers/crypto/vmx/aes_xts.c
> > index 8bd9aff0f55f..016ef52390c9 100644
> > --- a/drivers/crypto/vmx/aes_xts.c
> > +++ b/drivers/crypto/vmx/aes_xts.c
> > @@ -116,13 +116,14 @@ static int p8_aes_xts_crypt(struct blkcipher_desc *desc,
> >                 ret = enc? crypto_skcipher_encrypt(req) : crypto_skcipher_decrypt(req);
> >                 skcipher_request_zero(req);
> >         } else {
> > +               blkcipher_walk_init(&walk, dst, src, nbytes);
> > +
> > +               ret = blkcipher_walk_virt(desc, &walk);
> > +
> >                 preempt_disable();
> >                 pagefault_disable();
> >                 enable_kernel_vsx();
> >
> > -               blkcipher_walk_init(&walk, dst, src, nbytes);
> > -
> > -               ret = blkcipher_walk_virt(desc, &walk);
> >                 iv = walk.iv;
> >                 memset(tweak, 0, AES_BLOCK_SIZE);
> >                 aes_p8_encrypt(iv, tweak, &ctx->tweak_key);
> > @@ -135,13 +136,17 @@ static int p8_aes_xts_crypt(struct blkcipher_desc *desc,
> >                                 aes_p8_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
> >                                                 nbytes & AES_BLOCK_MASK, &ctx->dec_key, NULL, tweak);
> >
> > +                       disable_kernel_vsx();
> > +                       pagefault_enable();
> > +                       preempt_enable();
> > +
> >                         nbytes &= AES_BLOCK_SIZE - 1;
> >                         ret = blkcipher_walk_done(desc, &walk, nbytes);
> > -               }
> >
> > -               disable_kernel_vsx();
> > -               pagefault_enable();
> > -               preempt_enable();
> > +                       preempt_disable();
> > +                       pagefault_disable();
> > +                       enable_kernel_vsx();
> > +               }

That doesn't seem right. It would leave preemption disabled when
leaving the function.


> >         }
> >         return ret;
> >  }
> > --
> > 2.17.1
> >

--
Regards,
Marcelo

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

  reply	other threads:[~2018-08-21 16:41 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CAAUqJDvErj0Y4=GBtXgvBRON7MEic7_-jBZNvjacwcOd0TF_2g@mail.gmail.com>
     [not found] ` <3627129.cWTIy1uDMC@tauon.chronox.de>
     [not found]   ` <CAAUqJDt_y04ts7Aq0U0fhXYRus2ckkEohBTkga0pjqfoQaBOCA@mail.gmail.com>
2018-08-21 15:03     ` BUG: libkcapi tests trigger sleep-in-atomic bug in VMX code (ppc64) Christophe LEROY
2018-08-21 15:03       ` Christophe LEROY
2018-08-21 15:12       ` Marcelo Henrique Cerri
2018-08-21 15:12         ` Marcelo Henrique Cerri
2018-08-21 15:16     ` [PATCH] crypto: vmx - Fix sleep-in-atomic bugs Ondrej Mosnacek
2018-08-21 15:24       ` Ondrej Mosnáček
2018-08-21 15:24         ` Ondrej Mosnáček
2018-08-21 16:41         ` Marcelo Henrique Cerri [this message]
2018-08-21 16:41           ` Marcelo Henrique Cerri
2018-08-22  6:05           ` Ondrej Mosnáček
2018-08-22  6:05             ` Ondrej Mosnáček
2018-08-22  6:26     ` [PATCH v2] " Ondrej Mosnacek
2018-08-23  0:04       ` Marcelo Henrique Cerri
2018-08-23 20:34         ` Paulo Flabiano Smorigo
2018-08-24 19:47           ` Paulo Flabiano Smorigo
2018-08-24 20:01             ` Ondrej Mosnacek
2018-08-25 13:28       ` Herbert Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180821164126.GF28751@gallifrey \
    --to=marcelo.cerri@canonical.com \
    --cc=benh@kernel.crashing.org \
    --cc=herbert@gondor.apana.org.au \
    --cc=leo.barbosa@canonical.com \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=omosnace@redhat.com \
    --cc=omosnacek+linux-crypto@gmail.com \
    --cc=paulus@samba.org \
    --cc=pfsmorigo@linux.vnet.ibm.com \
    --cc=smueller@chronox.de \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.