[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