aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2018-09-05 09:17:45 -0400
committerMike Snitzer <snitzer@redhat.com>2018-09-06 13:31:09 -0400
commit432061b3da64e488be3403124a72a9250bbe96d4 (patch)
tree62cf9d433b59092b20daa55897dc60827940cbff
parente4b069e0945fa14c71cf8b5b89f8b1b2aa68dbc2 (diff)
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@vger.kernel.org Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--drivers/md/dm-crypt.c10
-rw-r--r--drivers/md/dm-integrity.c4
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
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -332,7 +332,7 @@ static int crypt_iv_essiv_init(struct crypt_config *cc)
332 int err; 332 int err;
333 333
334 desc->tfm = essiv->hash_tfm; 334 desc->tfm = essiv->hash_tfm;
335 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 335 desc->flags = 0;
336 336
337 err = crypto_shash_digest(desc, cc->key, cc->key_size, essiv->salt); 337 err = crypto_shash_digest(desc, cc->key, cc->key_size, essiv->salt);
338 shash_desc_zero(desc); 338 shash_desc_zero(desc);
@@ -606,7 +606,7 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv,
606 int i, r; 606 int i, r;
607 607
608 desc->tfm = lmk->hash_tfm; 608 desc->tfm = lmk->hash_tfm;
609 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 609 desc->flags = 0;
610 610
611 r = crypto_shash_init(desc); 611 r = crypto_shash_init(desc);
612 if (r) 612 if (r)
@@ -768,7 +768,7 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc,
768 768
769 /* calculate crc32 for every 32bit part and xor it */ 769 /* calculate crc32 for every 32bit part and xor it */
770 desc->tfm = tcw->crc32_tfm; 770 desc->tfm = tcw->crc32_tfm;
771 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 771 desc->flags = 0;
772 for (i = 0; i < 4; i++) { 772 for (i = 0; i < 4; i++) {
773 r = crypto_shash_init(desc); 773 r = crypto_shash_init(desc);
774 if (r) 774 if (r)
@@ -1251,7 +1251,7 @@ static void crypt_alloc_req_skcipher(struct crypt_config *cc,
1251 * requests if driver request queue is full. 1251 * requests if driver request queue is full.
1252 */ 1252 */
1253 skcipher_request_set_callback(ctx->r.req, 1253 skcipher_request_set_callback(ctx->r.req,
1254 CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 1254 CRYPTO_TFM_REQ_MAY_BACKLOG,
1255 kcryptd_async_done, dmreq_of_req(cc, ctx->r.req)); 1255 kcryptd_async_done, dmreq_of_req(cc, ctx->r.req));
1256} 1256}
1257 1257
@@ -1268,7 +1268,7 @@ static void crypt_alloc_req_aead(struct crypt_config *cc,
1268 * requests if driver request queue is full. 1268 * requests if driver request queue is full.
1269 */ 1269 */
1270 aead_request_set_callback(ctx->r.req_aead, 1270 aead_request_set_callback(ctx->r.req_aead,
1271 CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 1271 CRYPTO_TFM_REQ_MAY_BACKLOG,
1272 kcryptd_async_done, dmreq_of_req(cc, ctx->r.req_aead)); 1272 kcryptd_async_done, dmreq_of_req(cc, ctx->r.req_aead));
1273} 1273}
1274 1274
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
532 unsigned j, size; 532 unsigned j, size;
533 533
534 desc->tfm = ic->journal_mac; 534 desc->tfm = ic->journal_mac;
535 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 535 desc->flags = 0;
536 536
537 r = crypto_shash_init(desc); 537 r = crypto_shash_init(desc);
538 if (unlikely(r)) { 538 if (unlikely(r)) {
@@ -676,7 +676,7 @@ static void complete_journal_encrypt(struct crypto_async_request *req, int err)
676static bool do_crypt(bool encrypt, struct skcipher_request *req, struct journal_completion *comp) 676static bool do_crypt(bool encrypt, struct skcipher_request *req, struct journal_completion *comp)
677{ 677{
678 int r; 678 int r;
679 skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 679 skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
680 complete_journal_encrypt, comp); 680 complete_journal_encrypt, comp);
681 if (likely(encrypt)) 681 if (likely(encrypt))
682 r = crypto_skcipher_encrypt(req); 682 r = crypto_skcipher_encrypt(req);