diff options
author | Laura Abbott <labbott@redhat.com> | 2016-12-21 15:32:54 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-12-27 04:32:11 -0500 |
commit | 02608e02fbec04fccf2eb0cc8d8082f65c0a4286 (patch) | |
tree | 37ff0410d130cfe77185f591b07cd6403f207f0c /crypto/testmgr.c | |
parent | 7ce7d89f48834cefece7804d38fc5d85382edf77 (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.c | 30 |
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 | ||