Skip to content

Commit 02608e0

Browse files
labbottherbertx
authored andcommitted
crypto: testmgr - Use heap buffer for acomp test input
Christopher Covington reported a crash on aarch64 on recent Fedora kernels: kernel BUG at ./include/linux/scatterlist.h:140! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP Modules linked in: CPU: 2 PID: 752 Comm: cryptomgr_test Not tainted 4.9.0-11815-ge93b1cc #162 Hardware name: linux,dummy-virt (DT) task: ffff80007c650080 task.stack: ffff800008910000 PC is at sg_init_one+0xa0/0xb8 LR is at sg_init_one+0x24/0xb8 ... [<ffff000008398db8>] sg_init_one+0xa0/0xb8 [<ffff000008350a44>] test_acomp+0x10c/0x438 [<ffff000008350e20>] alg_test_comp+0xb0/0x118 [<ffff00000834f28c>] alg_test+0x17c/0x2f0 [<ffff00000834c6a4>] cryptomgr_test+0x44/0x50 [<ffff0000080dac70>] kthread+0xf8/0x128 [<ffff000008082ec0>] ret_from_fork+0x10/0x50 The test vectors used for input are part of the kernel image. These inputs are passed as a buffer to sg_init_one which eventually blows up with BUG_ON(!virt_addr_valid(buf)). On arm64, virt_addr_valid returns false for the kernel image since virt_to_page will not return the correct page. Fix this by copying the input vectors to heap buffer before setting up the scatterlist. Reported-by: Christopher Covington <[email protected]> Fixes: d7db7a8 ("crypto: acomp - update testmgr with support for acomp") Signed-off-by: Laura Abbott <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 7ce7d89 commit 02608e0

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

crypto/testmgr.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,16 +1461,25 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
14611461
for (i = 0; i < ctcount; i++) {
14621462
unsigned int dlen = COMP_BUF_SIZE;
14631463
int ilen = ctemplate[i].inlen;
1464+
void *input_vec;
14641465

1466+
input_vec = kmalloc(ilen, GFP_KERNEL);
1467+
if (!input_vec) {
1468+
ret = -ENOMEM;
1469+
goto out;
1470+
}
1471+
1472+
memcpy(input_vec, ctemplate[i].input, ilen);
14651473
memset(output, 0, dlen);
14661474
init_completion(&result.completion);
1467-
sg_init_one(&src, ctemplate[i].input, ilen);
1475+
sg_init_one(&src, input_vec, ilen);
14681476
sg_init_one(&dst, output, dlen);
14691477

14701478
req = acomp_request_alloc(tfm);
14711479
if (!req) {
14721480
pr_err("alg: acomp: request alloc failed for %s\n",
14731481
algo);
1482+
kfree(input_vec);
14741483
ret = -ENOMEM;
14751484
goto out;
14761485
}
@@ -1483,6 +1492,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
14831492
if (ret) {
14841493
pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
14851494
i + 1, algo, -ret);
1495+
kfree(input_vec);
14861496
acomp_request_free(req);
14871497
goto out;
14881498
}
@@ -1491,6 +1501,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
14911501
pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n",
14921502
i + 1, algo, req->dlen);
14931503
ret = -EINVAL;
1504+
kfree(input_vec);
14941505
acomp_request_free(req);
14951506
goto out;
14961507
}
@@ -1500,26 +1511,37 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
15001511
i + 1, algo);
15011512
hexdump(output, req->dlen);
15021513
ret = -EINVAL;
1514+
kfree(input_vec);
15031515
acomp_request_free(req);
15041516
goto out;
15051517
}
15061518

1519+
kfree(input_vec);
15071520
acomp_request_free(req);
15081521
}
15091522

15101523
for (i = 0; i < dtcount; i++) {
15111524
unsigned int dlen = COMP_BUF_SIZE;
15121525
int ilen = dtemplate[i].inlen;
1526+
void *input_vec;
1527+
1528+
input_vec = kmalloc(ilen, GFP_KERNEL);
1529+
if (!input_vec) {
1530+
ret = -ENOMEM;
1531+
goto out;
1532+
}
15131533

1534+
memcpy(input_vec, dtemplate[i].input, ilen);
15141535
memset(output, 0, dlen);
15151536
init_completion(&result.completion);
1516-
sg_init_one(&src, dtemplate[i].input, ilen);
1537+
sg_init_one(&src, input_vec, ilen);
15171538
sg_init_one(&dst, output, dlen);
15181539

15191540
req = acomp_request_alloc(tfm);
15201541
if (!req) {
15211542
pr_err("alg: acomp: request alloc failed for %s\n",
15221543
algo);
1544+
kfree(input_vec);
15231545
ret = -ENOMEM;
15241546
goto out;
15251547
}
@@ -1532,6 +1554,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
15321554
if (ret) {
15331555
pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n",
15341556
i + 1, algo, -ret);
1557+
kfree(input_vec);
15351558
acomp_request_free(req);
15361559
goto out;
15371560
}
@@ -1540,6 +1563,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
15401563
pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n",
15411564
i + 1, algo, req->dlen);
15421565
ret = -EINVAL;
1566+
kfree(input_vec);
15431567
acomp_request_free(req);
15441568
goto out;
15451569
}
@@ -1549,10 +1573,12 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
15491573
i + 1, algo);
15501574
hexdump(output, req->dlen);
15511575
ret = -EINVAL;
1576+
kfree(input_vec);
15521577
acomp_request_free(req);
15531578
goto out;
15541579
}
15551580

1581+
kfree(input_vec);
15561582
acomp_request_free(req);
15571583
}
15581584

0 commit comments

Comments
 (0)