Skip to content

Commit c808f1d

Browse files
Mikulas Patockagregkh
authored andcommitted
dm integrity: don't store cipher request on the stack
commit 717f4b1 upstream. Some asynchronous cipher implementations may use DMA. The stack may be mapped in the vmalloc area that doesn't support DMA. Therefore, the cipher request and initialization vector shouldn't be on the stack. Fix this by allocating the request and iv with kmalloc. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 5f12c33 commit c808f1d

1 file changed

Lines changed: 37 additions & 12 deletions

File tree

drivers/md/dm-integrity.c

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2558,7 +2558,8 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
25582558
int r = 0;
25592559
unsigned i;
25602560
__u64 journal_pages, journal_desc_size, journal_tree_size;
2561-
unsigned char *crypt_data = NULL;
2561+
unsigned char *crypt_data = NULL, *crypt_iv = NULL;
2562+
struct skcipher_request *req = NULL;
25622563

25632564
ic->commit_ids[0] = cpu_to_le64(0x1111111111111111ULL);
25642565
ic->commit_ids[1] = cpu_to_le64(0x2222222222222222ULL);
@@ -2616,9 +2617,20 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
26162617

26172618
if (blocksize == 1) {
26182619
struct scatterlist *sg;
2619-
SKCIPHER_REQUEST_ON_STACK(req, ic->journal_crypt);
2620-
unsigned char iv[ivsize];
2621-
skcipher_request_set_tfm(req, ic->journal_crypt);
2620+
2621+
req = skcipher_request_alloc(ic->journal_crypt, GFP_KERNEL);
2622+
if (!req) {
2623+
*error = "Could not allocate crypt request";
2624+
r = -ENOMEM;
2625+
goto bad;
2626+
}
2627+
2628+
crypt_iv = kmalloc(ivsize, GFP_KERNEL);
2629+
if (!crypt_iv) {
2630+
*error = "Could not allocate iv";
2631+
r = -ENOMEM;
2632+
goto bad;
2633+
}
26222634

26232635
ic->journal_xor = dm_integrity_alloc_page_list(ic);
26242636
if (!ic->journal_xor) {
@@ -2640,9 +2652,9 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
26402652
sg_set_buf(&sg[i], va, PAGE_SIZE);
26412653
}
26422654
sg_set_buf(&sg[i], &ic->commit_ids, sizeof ic->commit_ids);
2643-
memset(iv, 0x00, ivsize);
2655+
memset(crypt_iv, 0x00, ivsize);
26442656

2645-
skcipher_request_set_crypt(req, sg, sg, PAGE_SIZE * ic->journal_pages + sizeof ic->commit_ids, iv);
2657+
skcipher_request_set_crypt(req, sg, sg, PAGE_SIZE * ic->journal_pages + sizeof ic->commit_ids, crypt_iv);
26462658
init_completion(&comp.comp);
26472659
comp.in_flight = (atomic_t)ATOMIC_INIT(1);
26482660
if (do_crypt(true, req, &comp))
@@ -2658,19 +2670,29 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
26582670
crypto_free_skcipher(ic->journal_crypt);
26592671
ic->journal_crypt = NULL;
26602672
} else {
2661-
SKCIPHER_REQUEST_ON_STACK(req, ic->journal_crypt);
2662-
unsigned char iv[ivsize];
26632673
unsigned crypt_len = roundup(ivsize, blocksize);
26642674

2675+
req = skcipher_request_alloc(ic->journal_crypt, GFP_KERNEL);
2676+
if (!req) {
2677+
*error = "Could not allocate crypt request";
2678+
r = -ENOMEM;
2679+
goto bad;
2680+
}
2681+
2682+
crypt_iv = kmalloc(ivsize, GFP_KERNEL);
2683+
if (!crypt_iv) {
2684+
*error = "Could not allocate iv";
2685+
r = -ENOMEM;
2686+
goto bad;
2687+
}
2688+
26652689
crypt_data = kmalloc(crypt_len, GFP_KERNEL);
26662690
if (!crypt_data) {
26672691
*error = "Unable to allocate crypt data";
26682692
r = -ENOMEM;
26692693
goto bad;
26702694
}
26712695

2672-
skcipher_request_set_tfm(req, ic->journal_crypt);
2673-
26742696
ic->journal_scatterlist = dm_integrity_alloc_journal_scatterlist(ic, ic->journal);
26752697
if (!ic->journal_scatterlist) {
26762698
*error = "Unable to allocate sg list";
@@ -2694,12 +2716,12 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
26942716
struct skcipher_request *section_req;
26952717
__u32 section_le = cpu_to_le32(i);
26962718

2697-
memset(iv, 0x00, ivsize);
2719+
memset(crypt_iv, 0x00, ivsize);
26982720
memset(crypt_data, 0x00, crypt_len);
26992721
memcpy(crypt_data, &section_le, min((size_t)crypt_len, sizeof(section_le)));
27002722

27012723
sg_init_one(&sg, crypt_data, crypt_len);
2702-
skcipher_request_set_crypt(req, &sg, &sg, crypt_len, iv);
2724+
skcipher_request_set_crypt(req, &sg, &sg, crypt_len, crypt_iv);
27032725
init_completion(&comp.comp);
27042726
comp.in_flight = (atomic_t)ATOMIC_INIT(1);
27052727
if (do_crypt(true, req, &comp))
@@ -2757,6 +2779,9 @@ static int create_journal(struct dm_integrity_c *ic, char **error)
27572779
}
27582780
bad:
27592781
kfree(crypt_data);
2782+
kfree(crypt_iv);
2783+
skcipher_request_free(req);
2784+
27602785
return r;
27612786
}
27622787

0 commit comments

Comments
 (0)