linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Liu Chao <liuchao741@huawei.com>,
	Eric Biggers <ebiggers@google.com>,
	Herbert Xu <herbert@gondor.apana.org.au>
Subject: [PATCH 4.18 16/22] crypto: blkcipher - fix crash flushing dcache in error path
Date: Thu, 16 Aug 2018 20:45:32 +0200	[thread overview]
Message-ID: <20180816171557.150919879@linuxfoundation.org> (raw)
In-Reply-To: <20180816171556.502583508@linuxfoundation.org>

4.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Biggers <ebiggers@google.com>

commit 0868def3e4100591e7a1fdbf3eed1439cc8f7ca3 upstream.

Like the skcipher_walk case:

scatterwalk_done() is only meant to be called after a nonzero number of
bytes have been processed, since scatterwalk_pagedone() will flush the
dcache of the *previous* page.  But in the error case of
blkcipher_walk_done(), e.g. if the input wasn't an integer number of
blocks, scatterwalk_done() was actually called after advancing 0 bytes.
This caused a crash ("BUG: unable to handle kernel paging request")
during '!PageSlab(page)' on architectures like arm and arm64 that define
ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE, provided that the input was
page-aligned as in that case walk->offset == 0.

Fix it by reorganizing blkcipher_walk_done() to skip the
scatterwalk_advance() and scatterwalk_done() if an error has occurred.

This bug was found by syzkaller fuzzing.

Reproducer, assuming ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE:

	#include <linux/if_alg.h>
	#include <sys/socket.h>
	#include <unistd.h>

	int main()
	{
		struct sockaddr_alg addr = {
			.salg_type = "skcipher",
			.salg_name = "ecb(aes-generic)",
		};
		char buffer[4096] __attribute__((aligned(4096))) = { 0 };
		int fd;

		fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
		bind(fd, (void *)&addr, sizeof(addr));
		setsockopt(fd, SOL_ALG, ALG_SET_KEY, buffer, 16);
		fd = accept(fd, NULL, NULL);
		write(fd, buffer, 15);
		read(fd, buffer, 15);
	}

Reported-by: Liu Chao <liuchao741@huawei.com>
Fixes: 5cde0af2a982 ("[CRYPTO] cipher: Added block cipher type")
Cc: <stable@vger.kernel.org> # v2.6.19+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 crypto/blkcipher.c |   54 +++++++++++++++++++++++++----------------------------
 1 file changed, 26 insertions(+), 28 deletions(-)

--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -70,19 +70,18 @@ static inline u8 *blkcipher_get_spot(u8
 	return max(start, end_page);
 }
 
-static inline unsigned int blkcipher_done_slow(struct blkcipher_walk *walk,
-					       unsigned int bsize)
+static inline void blkcipher_done_slow(struct blkcipher_walk *walk,
+				       unsigned int bsize)
 {
 	u8 *addr;
 
 	addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
 	addr = blkcipher_get_spot(addr, bsize);
 	scatterwalk_copychunks(addr, &walk->out, bsize, 1);
-	return bsize;
 }
 
-static inline unsigned int blkcipher_done_fast(struct blkcipher_walk *walk,
-					       unsigned int n)
+static inline void blkcipher_done_fast(struct blkcipher_walk *walk,
+				       unsigned int n)
 {
 	if (walk->flags & BLKCIPHER_WALK_COPY) {
 		blkcipher_map_dst(walk);
@@ -96,49 +95,48 @@ static inline unsigned int blkcipher_don
 
 	scatterwalk_advance(&walk->in, n);
 	scatterwalk_advance(&walk->out, n);
-
-	return n;
 }
 
 int blkcipher_walk_done(struct blkcipher_desc *desc,
 			struct blkcipher_walk *walk, int err)
 {
-	unsigned int nbytes = 0;
+	unsigned int n; /* bytes processed */
+	bool more;
 
-	if (likely(err >= 0)) {
-		unsigned int n = walk->nbytes - err;
+	if (unlikely(err < 0))
+		goto finish;
 
-		if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW)))
-			n = blkcipher_done_fast(walk, n);
-		else if (WARN_ON(err)) {
+	n = walk->nbytes - err;
+	walk->total -= n;
+	more = (walk->total != 0);
+
+	if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW))) {
+		blkcipher_done_fast(walk, n);
+	} else {
+		if (WARN_ON(err)) {
+			/* unexpected case; didn't process all bytes */
 			err = -EINVAL;
-			goto err;
-		} else
-			n = blkcipher_done_slow(walk, n);
-
-		nbytes = walk->total - n;
-		err = 0;
+			goto finish;
+		}
+		blkcipher_done_slow(walk, n);
 	}
 
-	scatterwalk_done(&walk->in, 0, nbytes);
-	scatterwalk_done(&walk->out, 1, nbytes);
-
-err:
-	walk->total = nbytes;
-	walk->nbytes = nbytes;
+	scatterwalk_done(&walk->in, 0, more);
+	scatterwalk_done(&walk->out, 1, more);
 
-	if (nbytes) {
+	if (more) {
 		crypto_yield(desc->flags);
 		return blkcipher_walk_next(desc, walk);
 	}
-
+	err = 0;
+finish:
+	walk->nbytes = 0;
 	if (walk->iv != desc->info)
 		memcpy(desc->info, walk->iv, walk->ivsize);
 	if (walk->buffer != walk->page)
 		kfree(walk->buffer);
 	if (walk->page)
 		free_page((unsigned long)walk->page);
-
 	return err;
 }
 EXPORT_SYMBOL_GPL(blkcipher_walk_done);



  parent reply	other threads:[~2018-08-16 18:51 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-16 18:45 [PATCH 4.18 00/22] 4.18.2-stable review Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 01/22] x86/l1tf: Fix build error seen if CONFIG_KVM_INTEL is disabled Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 02/22] x86: i8259: Add missing include file Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 03/22] x86/hyper-v: Check for VP_INVAL in hyperv_flush_tlb_others() Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 04/22] x86/platform/UV: Mark memblock related init code and data correctly Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 05/22] x86/mm/pti: Clear Global bit more aggressively Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 06/22] xen/pv: Call get_cpu_address_sizes to set x86_virt/phys_bits Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 07/22] x86/mm: Disable ioremap free page handling on x86-PAE Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 08/22] kbuild: verify that $DEPMOD is installed Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 09/22] crypto: ccree - fix finup Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 10/22] crypto: ccree - fix iv handling Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 11/22] crypto: ccp - Check for NULL PSP pointer at module unload Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 12/22] crypto: ccp - Fix command completion detection race Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 13/22] crypto: x86/sha256-mb - fix digest copy in sha256_mb_mgr_get_comp_job_avx2() Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 14/22] crypto: vmac - require a block cipher with 128-bit block size Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 15/22] crypto: vmac - separate tfm and request context Greg Kroah-Hartman
2018-08-16 18:45 ` Greg Kroah-Hartman [this message]
2018-08-16 18:45 ` [PATCH 4.18 17/22] crypto: ablkcipher - fix crash flushing dcache in error path Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 18/22] crypto: skcipher - fix aligning block size in skcipher_copy_iv() Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 19/22] crypto: skcipher - fix crash flushing dcache in error path Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 20/22] Bluetooth: hidp: buffer overflow in hidp_process_report Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 21/22] ioremap: Update pgtable free interfaces with addr Greg Kroah-Hartman
2018-08-16 18:45 ` [PATCH 4.18 22/22] x86/mm: Add TLB purge to free pmd/pte page interfaces Greg Kroah-Hartman
2018-08-17 17:18 ` [PATCH 4.18 00/22] 4.18.2-stable review Guenter Roeck
2018-08-17 17:25   ` Greg Kroah-Hartman
2018-08-18 14:21 ` Rafael David Tinoco
2018-08-18 15:22   ` Greg Kroah-Hartman

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=20180816171557.150919879@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=ebiggers@google.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liuchao741@huawei.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).