* [PATCH] blk-crypto: fix NULL deref and UAF in __blk_crypto_evict_key()
@ 2026-10-13 9:51 Baokun Li
0 siblings, 0 replies; only message in thread
From: Baokun Li @ 2026-10-13 9:51 UTC (permalink / raw)
To: axboe, linux-block
Cc: ebiggers, linux-fscrypt, hch, bvanassche, dm-devel, mpatocka,
linlin.zhang, libaokun, stable, Sashiko
Sashiko reported a possible NULL pointer dereference, triggered by the
following flow:
dm-inlinecrypt ctor # first use of the fallback
├─ blk_crypto_init_key() # succeeds, ctx->key.size != 0
├─ blk_crypto_start_using_key()
│ ├─ return -EOPNOTSUPP # uninit profile, will NULL deref
│ └─ blk_crypto_fallback_start_using_key()
│ └─ blk_crypto_fallback_init() fails
│ └─ kfree(profile) # not NULLed, will UAF
├─ goto bad
└─ inlinecrypt_dtr() # evicts whenever key.size is set
└─ blk_crypto_evict_key()
└─ blk_crypto_config_supported_natively() = false
└─ blk_crypto_fallback_evict_key()
└─ __blk_crypto_evict_key(blk_crypto_fallback_profile)
└─ profile->num_slots # BOOM!!!
This issue can be reproduced using the following commands:
dd if=/dev/zero of=/tmp/backing bs=1M count=64
LOOP=$(losetup -f --show /tmp/backing)
SZ=$(blockdev --getsz $LOOP)
KEY=$(head -c 64 /dev/urandom | od -An -tx1 | tr -d ' \n')
dmsetup create ic --table "0 $SZ inlinecrypt aes-xts-plain64 \
$KEY 0 $LOOP 0 1 keytype:hw-wrapped"
And the following oops is triggered:
==================================================================
blk-crypto: loop0: no support for wrapped keys
Oops: general protection fault, probably for non-canonical address
0xdffffc000000000b: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000058-0x000000000000005f]
CPU: 5 UID: 0 PID: 901 Comm: dmsetup 7.3.0-rc3 #1 PREEMPT(lazy)
RIP: 0010:__blk_crypto_evict_key+0x2e/0x3b0
Call Trace:
blk_crypto_evict_key+0x24c/0x320
inlinecrypt_dtr+0xf6/0x160
inlinecrypt_ctr+0x2d3/0xbd0
dm_table_add_target+0x661/0xf40
table_load+0x1c4/0x490
ctl_ioctl+0x32f/0x5f0
dm_ctl_ioctl+0xe/0x20
==================================================================
Fix this by checking the profile for NULL in __blk_crypto_evict_key()
to avoid the NULL pointer dereference, and by clearing the profile
pointer after it is freed to avoid the use-after-free.
Fixes: e7f57d2c47e2 ("dm-inlinecrypt: add target for inline block device encryption")
Cc: stable@vger.kernel.org # v7.2+
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://patch.msgid.link/sashiko-outbox-167341@kernel.org
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
---
block/blk-crypto-fallback.c | 1 +
block/blk-crypto-profile.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c
index 2a8f40a65158..b7890ee1951c 100644
--- a/block/blk-crypto-fallback.c
+++ b/block/blk-crypto-fallback.c
@@ -605,6 +605,7 @@ static int blk_crypto_fallback_init(void)
blk_crypto_profile_destroy(blk_crypto_fallback_profile);
fail_free_profile:
kfree(blk_crypto_fallback_profile);
+ blk_crypto_fallback_profile = NULL;
fail_free_bioset:
bioset_exit(&enc_bio_set);
out:
diff --git a/block/blk-crypto-profile.c b/block/blk-crypto-profile.c
index 53126c091b0b..1c5feca3b856 100644
--- a/block/blk-crypto-profile.c
+++ b/block/blk-crypto-profile.c
@@ -346,6 +346,9 @@ int __blk_crypto_evict_key(struct blk_crypto_profile *profile,
struct blk_crypto_keyslot *slot;
int err;
+ if (!profile)
+ return 0;
+
if (profile->num_slots == 0) {
if (profile->ll_ops.keyslot_evict) {
blk_crypto_hw_enter(profile);
base-commit: fd73f4a6659897191fa0d40695fe370925dd3780
--
2.43.7
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-13 9:51 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 9:51 [PATCH] blk-crypto: fix NULL deref and UAF in __blk_crypto_evict_key() Baokun Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox