History

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.

Laura Abbott committed 9 years ago

Commit 02608e01 parent 7ce7d891 file · +28 −2Browse files

Unified · Split

crypto/testmgr.c+28−2
@@ -1461,16 +1461,25 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate, · 1460 unmodified lines
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, · 6 unmodified lines
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, · 2 unmodified lines
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, · 3 unmodified lines
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, · 6 unmodified lines
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, · 2 unmodified lines
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, · 3 unmodified lines
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