Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: caam - fix use-after-free KASAN issue for HASH algorithms

Here's the KASAN report:
BUG: KASAN: use-after-free in ahash_done+0xdc/0x3b8
Read of size 1 at addr ffff00002303f010 by task swapper/0/0

CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.6.0-rc1-00162-gfcb90d5 #59
Hardware name: LS1046A RDB Board (DT)
Call trace:
dump_backtrace+0x0/0x260
show_stack+0x14/0x20
dump_stack+0xe8/0x144
print_address_description.isra.11+0x64/0x348
__kasan_report+0x11c/0x230
kasan_report+0xc/0x18
__asan_load1+0x5c/0x68
ahash_done+0xdc/0x3b8
caam_jr_dequeue+0x390/0x608
tasklet_action_common.isra.13+0x1ec/0x230
tasklet_action+0x24/0x30
efi_header_end+0x1a4/0x370
irq_exit+0x114/0x128
__handle_domain_irq+0x80/0xe0
gic_handle_irq+0x50/0xa0
el1_irq+0xb8/0x180
cpuidle_enter_state+0xa4/0x490
cpuidle_enter+0x48/0x70
call_cpuidle+0x44/0x70
do_idle+0x304/0x338
cpu_startup_entry+0x24/0x40
rest_init+0xf8/0x10c
arch_call_rest_init+0xc/0x14
start_kernel+0x774/0x7b4

Allocated by task 263:
save_stack+0x24/0xb0
__kasan_kmalloc.isra.10+0xc4/0xe0
kasan_kmalloc+0xc/0x18
__kmalloc+0x178/0x2b8
ahash_edesc_alloc+0x58/0x1f8
ahash_final_no_ctx+0x94/0x6e8
ahash_final+0x24/0x30
crypto_ahash_op+0x58/0xb0
crypto_ahash_final+0x30/0x40
do_ahash_op+0x2c/0xa0
test_ahash_vec_cfg+0x894/0x9e0
test_hash_vec_cfg+0x6c/0x88
test_hash_vec+0xfc/0x1e0
__alg_test_hash+0x1ac/0x368
alg_test_hash+0xf8/0x1c8
alg_test.part.44+0x114/0x4a0
alg_test+0x1c/0x60
cryptomgr_test+0x34/0x58
kthread+0x1b8/0x1c0
ret_from_fork+0x10/0x18

Freed by task 0:
save_stack+0x24/0xb0
__kasan_slab_free+0x10c/0x188
kasan_slab_free+0x10/0x18
kfree+0x7c/0x298
ahash_done+0xd4/0x3b8
caam_jr_dequeue+0x390/0x608
tasklet_action_common.isra.13+0x1ec/0x230
tasklet_action+0x24/0x30
efi_header_end+0x1a4/0x370

The buggy address belongs to the object at ffff00002303f000
which belongs to the cache dma-kmalloc-128 of size 128
The buggy address is located 16 bytes inside of
128-byte region [ffff00002303f000, ffff00002303f080)
The buggy address belongs to the page:
page:fffffe00006c0fc0 refcount:1 mapcount:0 mapping:ffff00093200c000 index:0x0
flags: 0xffff00000000200(slab)
raw: 0ffff00000000200 dead000000000100 dead000000000122 ffff00093200c000
raw: 0000000000000000 0000000080100010 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
ffff00002303ef00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ffff00002303ef80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>ffff00002303f000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff00002303f080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff00002303f100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc

Fixes: 21b014f038d3 ("crypto: caam - add crypto_engine support for HASH algorithms")
Signed-off-by: Iuliana Prodan <iuliana.prodan@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Iuliana Prodan and committed by
Herbert Xu
63db32e6 5ed1e8b8

+6 -2
+6 -2
drivers/crypto/caam/caamhash.c
··· 583 583 struct caam_hash_state *state = ahash_request_ctx(req); 584 584 struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); 585 585 int ecode = 0; 586 + bool has_bklog; 586 587 587 588 dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); 588 589 589 590 edesc = state->edesc; 591 + has_bklog = edesc->bklog; 590 592 591 593 if (err) 592 594 ecode = caam_jr_strstatus(jrdev, err); ··· 605 603 * If no backlog flag, the completion of the request is done 606 604 * by CAAM, not crypto engine. 607 605 */ 608 - if (!edesc->bklog) 606 + if (!has_bklog) 609 607 req->base.complete(&req->base, ecode); 610 608 else 611 609 crypto_finalize_hash_request(jrp->engine, req, ecode); ··· 634 632 struct caam_hash_state *state = ahash_request_ctx(req); 635 633 int digestsize = crypto_ahash_digestsize(ahash); 636 634 int ecode = 0; 635 + bool has_bklog; 637 636 638 637 dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); 639 638 640 639 edesc = state->edesc; 640 + has_bklog = edesc->bklog; 641 641 if (err) 642 642 ecode = caam_jr_strstatus(jrdev, err); 643 643 ··· 667 663 * If no backlog flag, the completion of the request is done 668 664 * by CAAM, not crypto engine. 669 665 */ 670 - if (!edesc->bklog) 666 + if (!has_bklog) 671 667 req->base.complete(&req->base, ecode); 672 668 else 673 669 crypto_finalize_hash_request(jrp->engine, req, ecode);