[packages/kernel] - prevent deadlocks with xfs on dmcrypt in rare situations

arekm arekm at pld-linux.org
Fri Sep 7 08:11:37 CEST 2018


commit 8ac0885f2bca74ae597f51e980418d50c9598d6f
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Fri Sep 7 08:11:28 2018 +0200

    - prevent deadlocks with xfs on dmcrypt in rare situations

 kernel-small_fixes.patch | 107 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)
---
diff --git a/kernel-small_fixes.patch b/kernel-small_fixes.patch
index 7fdc8cde..6edbd9d9 100644
--- a/kernel-small_fixes.patch
+++ b/kernel-small_fixes.patch
@@ -9,3 +9,110 @@
  	echo 0
  	exit 1
  fi
+From 432061b3da64e488be3403124a72a9250bbe96d4 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka at redhat.com>
+Date: Wed, 5 Sep 2018 09:17:45 -0400
+Subject: dm: disable CRYPTO_TFM_REQ_MAY_SLEEP to fix a GFP_KERNEL recursion
+ deadlock
+
+There's a XFS on dm-crypt deadlock, recursing back to itself due to the
+crypto subsystems use of GFP_KERNEL, reported here:
+https://bugzilla.kernel.org/show_bug.cgi?id=200835
+
+* dm-crypt calls crypt_convert in xts mode
+* init_crypt from xts.c calls kmalloc(GFP_KERNEL)
+* kmalloc(GFP_KERNEL) recurses into the XFS filesystem, the filesystem
+	tries to submit some bios and wait for them, causing a deadlock
+
+Fix this by updating both the DM crypt and integrity targets to no
+longer use the CRYPTO_TFM_REQ_MAY_SLEEP flag, which will change the
+crypto allocations from GFP_KERNEL to GFP_ATOMIC, therefore they can't
+recurse into a filesystem.  A GFP_ATOMIC allocation can fail, but
+init_crypt() in xts.c handles the allocation failure gracefully - it
+will fall back to preallocated buffer if the allocation fails.
+
+The crypto API maintainer says that the crypto API only needs to
+allocate memory when dealing with unaligned buffers and therefore
+turning CRYPTO_TFM_REQ_MAY_SLEEP off is safe (see this discussion:
+https://www.redhat.com/archives/dm-devel/2018-August/msg00195.html )
+
+Cc: stable at vger.kernel.org
+Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
+Signed-off-by: Mike Snitzer <snitzer at redhat.com>
+---
+ drivers/md/dm-crypt.c     | 10 +++++-----
+ drivers/md/dm-integrity.c |  4 ++--
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index f266c81f396f..0481223b1deb 100644
+@@ -334,7 +334,7 @@ static int crypt_iv_essiv_init(struct cr
+ 
+ 	sg_init_one(&sg, cc->key, cc->key_size);
+ 	ahash_request_set_tfm(req, essiv->hash_tfm);
+-	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
++	ahash_request_set_callback(req, 0, NULL, NULL);
+ 	ahash_request_set_crypt(req, &sg, essiv->salt, cc->key_size);
+ 
+ 	err = crypto_ahash_digest(req);
+@@ -606,7 +606,7 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv,
+ 	int i, r;
+ 
+ 	desc->tfm = lmk->hash_tfm;
+-	desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
++	desc->flags = 0;
+ 
+ 	r = crypto_shash_init(desc);
+ 	if (r)
+@@ -768,7 +768,7 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc,
+ 
+ 	/* calculate crc32 for every 32bit part and xor it */
+ 	desc->tfm = tcw->crc32_tfm;
+-	desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
++	desc->flags = 0;
+ 	for (i = 0; i < 4; i++) {
+ 		r = crypto_shash_init(desc);
+ 		if (r)
+@@ -1251,7 +1251,7 @@ static void crypt_alloc_req_skcipher(struct crypt_config *cc,
+ 	 * requests if driver request queue is full.
+ 	 */
+ 	skcipher_request_set_callback(ctx->r.req,
+-	    CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
++	    CRYPTO_TFM_REQ_MAY_BACKLOG,
+ 	    kcryptd_async_done, dmreq_of_req(cc, ctx->r.req));
+ }
+ 
+@@ -1268,7 +1268,7 @@ static void crypt_alloc_req_aead(struct crypt_config *cc,
+ 	 * requests if driver request queue is full.
+ 	 */
+ 	aead_request_set_callback(ctx->r.req_aead,
+-	    CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
++	    CRYPTO_TFM_REQ_MAY_BACKLOG,
+ 	    kcryptd_async_done, dmreq_of_req(cc, ctx->r.req_aead));
+ }
+ 
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index 378878599466..89ccb64342de 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -532,7 +532,7 @@ static void section_mac(struct dm_integrity_c *ic, unsigned section, __u8 result
+ 	unsigned j, size;
+ 
+ 	desc->tfm = ic->journal_mac;
+-	desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
++	desc->flags = 0;
+ 
+ 	r = crypto_shash_init(desc);
+ 	if (unlikely(r)) {
+@@ -676,7 +676,7 @@ static void complete_journal_encrypt(struct crypto_async_request *req, int err)
+ static bool do_crypt(bool encrypt, struct skcipher_request *req, struct journal_completion *comp)
+ {
+ 	int r;
+-	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
++	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ 				      complete_journal_encrypt, comp);
+ 	if (likely(encrypt))
+ 		r = crypto_skcipher_encrypt(req);
+-- 
+cgit 1.2-0.3.lf.el7
+
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/kernel.git/commitdiff/8ac0885f2bca74ae597f51e980418d50c9598d6f



More information about the pld-cvs-commit mailing list