summaryrefslogtreecommitdiffstats
path: root/crypto/testmgr.c
diff options
context:
space:
mode:
authorLaura Abbott <labbott@redhat.com>2016-12-21 15:32:54 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2016-12-27 04:32:11 -0500
commit02608e02fbec04fccf2eb0cc8d8082f65c0a4286 (patch)
tree37ff0410d130cfe77185f591b07cd6403f207f0c /crypto/testmgr.c
parent7ce7d89f48834cefece7804d38fc5d85382edf77 (diff)
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 <cov@codeaurora.org> Fixes: d7db7a882deb ("crypto: acomp - update testmgr with support for acomp") Signed-off-by: Laura Abbott <labbott@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r--crypto/testmgr.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index f616ad74cce7..44e888b0b041 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1461,16 +1461,25 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
1461 for (i = 0; i < ctcount; i++) { 1461 for (i = 0; i < ctcount; i++) {
1462 unsigned int dlen = COMP_BUF_SIZE; 1462 unsigned int dlen = COMP_BUF_SIZE;
1463 int ilen = ctemplate[i].inlen; 1463 int ilen = ctemplate[i].inlen;
1464 void *input_vec;
1464 1465
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);
1465 memset(output, 0, dlen); 1473 memset(output, 0, dlen);
1466 init_completion(&result.completion); 1474 init_completion(&result.completion);
1467 sg_init_one(&src, ctemplate[i].input, ilen); 1475 sg_init_one(&src, input_vec, ilen);
1468 sg_init_one(&dst, output, dlen); 1476 sg_init_one(&dst, output, dlen);
1469 1477
1470 req = acomp_request_alloc(tfm); 1478 req = acomp_request_alloc(tfm);
1471 if (!req) { 1479 if (!req) {
1472 pr_err("alg: acomp: request alloc failed for %s\n", 1480 pr_err("alg: acomp: request alloc failed for %s\n",
1473 algo); 1481 algo);
1482 kfree(input_vec);
1474 ret = -ENOMEM; 1483 ret = -ENOMEM;
1475 goto out; 1484 goto out;
1476 } 1485 }
@@ -1483,6 +1492,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
1483 if (ret) { 1492 if (ret) {
1484 pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n", 1493 pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
1485 i + 1, algo, -ret); 1494 i + 1, algo, -ret);
1495 kfree(input_vec);
1486 acomp_request_free(req); 1496 acomp_request_free(req);
1487 goto out; 1497 goto out;
1488 } 1498 }
@@ -1491,6 +1501,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
1491 pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n", 1501 pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n",
1492 i + 1, algo, req->dlen); 1502 i + 1, algo, req->dlen);
1493 ret = -EINVAL; 1503 ret = -EINVAL;
1504 kfree(input_vec);
1494 acomp_request_free(req); 1505 acomp_request_free(req);
1495 goto out; 1506 goto out;
1496 } 1507 }
@@ -1500,26 +1511,37 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
1500 i + 1, algo); 1511 i + 1, algo);
1501 hexdump(output, req->dlen); 1512 hexdump(output, req->dlen);
1502 ret = -EINVAL; 1513 ret = -EINVAL;
1514 kfree(input_vec);
1503 acomp_request_free(req); 1515 acomp_request_free(req);
1504 goto out; 1516 goto out;
1505 } 1517 }
1506 1518
1519 kfree(input_vec);
1507 acomp_request_free(req); 1520 acomp_request_free(req);
1508 } 1521 }
1509 1522
1510 for (i = 0; i < dtcount; i++) { 1523 for (i = 0; i < dtcount; i++) {
1511 unsigned int dlen = COMP_BUF_SIZE; 1524 unsigned int dlen = COMP_BUF_SIZE;
1512 int ilen = dtemplate[i].inlen; 1525 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 }
1513 1533
1534 memcpy(input_vec, dtemplate[i].input, ilen);
1514 memset(output, 0, dlen); 1535 memset(output, 0, dlen);
1515 init_completion(&result.completion); 1536 init_completion(&result.completion);
1516 sg_init_one(&src, dtemplate[i].input, ilen); 1537 sg_init_one(&src, input_vec, ilen);
1517 sg_init_one(&dst, output, dlen); 1538 sg_init_one(&dst, output, dlen);
1518 1539
1519 req = acomp_request_alloc(tfm); 1540 req = acomp_request_alloc(tfm);
1520 if (!req) { 1541 if (!req) {
1521 pr_err("alg: acomp: request alloc failed for %s\n", 1542 pr_err("alg: acomp: request alloc failed for %s\n",
1522 algo); 1543 algo);
1544 kfree(input_vec);
1523 ret = -ENOMEM; 1545 ret = -ENOMEM;
1524 goto out; 1546 goto out;
1525 } 1547 }
@@ -1532,6 +1554,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
1532 if (ret) { 1554 if (ret) {
1533 pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n", 1555 pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n",
1534 i + 1, algo, -ret); 1556 i + 1, algo, -ret);
1557 kfree(input_vec);
1535 acomp_request_free(req); 1558 acomp_request_free(req);
1536 goto out; 1559 goto out;
1537 } 1560 }
@@ -1540,6 +1563,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
1540 pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n", 1563 pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n",
1541 i + 1, algo, req->dlen); 1564 i + 1, algo, req->dlen);
1542 ret = -EINVAL; 1565 ret = -EINVAL;
1566 kfree(input_vec);
1543 acomp_request_free(req); 1567 acomp_request_free(req);
1544 goto out; 1568 goto out;
1545 } 1569 }
@@ -1549,10 +1573,12 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
1549 i + 1, algo); 1573 i + 1, algo);
1550 hexdump(output, req->dlen); 1574 hexdump(output, req->dlen);
1551 ret = -EINVAL; 1575 ret = -EINVAL;
1576 kfree(input_vec);
1552 acomp_request_free(req); 1577 acomp_request_free(req);
1553 goto out; 1578 goto out;
1554 } 1579 }
1555 1580
1581 kfree(input_vec);
1556 acomp_request_free(req); 1582 acomp_request_free(req);
1557 } 1583 }
1558 1584