Linux SCSI subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Linlin Zhang" <linlin.zhang@oss.qualcomm.com>
Cc: linux-scsi@vger.kernel.org, conor+dt@kernel.org, robh@kernel.org,
	devicetree@vger.kernel.org
Subject: Re: [PATCH v1 05/11] blk-crypto: add slot-based inline encryption path
Date: Thu, 27 Aug 2026 16:26:58 +0000	[thread overview]
Message-ID: <20260827162658.CB0131F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260827160806.1295313-6-linlin.zhang@oss.qualcomm.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Critical] Multiple core block layer and driver functions unconditionally dereference the `bc_key` pointer in a bio's crypto context for slot-based bios, leading to kernel panics.
- [High] Standard block drivers fail to retrieve a keyslot for slot-path bios and silently drop encryption, leading to incorrectly encrypted data being written to disk.
- [High] Bio splitting causes silent Initialization Vector (IV) reuse and breaks cryptographic confidentiality if `data_unit_size_bits` is 0.
- [High] Missing bounds check on `data_unit_size_bits` causes Undefined Behavior during bit shift operations.
--

commit ecf24121b79d01c98765828aa3d5cd87595d9349
Author: linlzhan <linlin.zhang@oss.qualcomm.com>

blk-crypto: add slot-based inline encryption path

For the virtio-blk inline encryption use case, the guest kernel goes
through the normal blk_crypto_key programming flow via SMC call in a
virtual slot format before I/O starts.  It then requests the host to
handle that I/O with the key programmed into the corresponding physical
keyslot.

> diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h
> index 2c7a0446572aa..04035d237f039 100644
> --- a/block/blk-crypto-internal.h
> +++ b/block/blk-crypto-internal.h
> @@ -176,7 +176,7 @@ static inline void bio_crypt_do_front_merge(struct request *rq,
>  blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq);
>  static inline blk_status_t blk_crypto_rq_get_keyslot(struct request *rq)
>  {
> -	if (blk_crypto_rq_is_encrypted(rq))
> +	if (blk_crypto_rq_is_encrypted(rq) && rq->crypt_ctx->bc_key)
>  		return __blk_crypto_rq_get_keyslot(rq);
>  	return BLK_STS_OK;
>  }

[ ... ]

> diff --git a/block/blk-crypto.c b/block/blk-crypto.c
> index bc3a9f59574b1..2212d06d3c112 100644
> --- a/block/blk-crypto.c
> +++ b/block/blk-crypto.c
[ ... ]
> @@ -113,11 +113,31 @@ void bio_crypt_set_ctx(struct bio *bio, const struct blk_crypto_key *key,
[ ... ]
> +void bio_crypt_set_ctx_by_slot(struct bio *bio,
> +			       const struct blk_crypto_slot *slot,
> +			       const u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE],
> +			       gfp_t gfp_mask)
> +{
> +	struct bio_crypt_ctx *bc;
> +
> +	WARN_ON_ONCE(!(gfp_mask & __GFP_DIRECT_RECLAIM));
> +
> +	bc = mempool_alloc(bio_crypt_ctx_pool, gfp_mask);
> +
> +	bc->bc_key = NULL;

[Severity: Critical]
If we set bc_key to NULL here for slot-based bios, will this cause kernel
panics in core block layer and driver functions that unconditionally
dereference it?

For example, when submit_bio_noacct() calls blk_crypto_supported(), it
evaluates &bio->bi_crypt_context->bc_key->crypto_cfg and passes a NULL
pointer:

block/blk-crypto-internal.h:blk_crypto_supported() {
    ...
    return blk_crypto_config_supported_natively(bio->bi_bdev,
                    &bio->bi_crypt_context->bc_key->crypto_cfg);
}

The native configuration check then dereferences this config, causing an
immediate crash.

Similarly, won't functions like bio_split_io_at() in block/blk-merge.c
unconditionally dereference bc_key when constructing DMA alignment masks?

block/blk-merge.c:bio_split_io_at() {
    ...
    start_align_mask |= (bc->bc_key->crypto_cfg.data_unit_size - 1);
    ...
}

And virtblk_setup_cmd() in drivers/block/virtio_blk.c also appears to
blindly dereference it:

drivers/block/virtio_blk.c:virtblk_setup_cmd() {
    ...
    unsigned int data_unit_size_bits = req->crypt_ctx->bc_key->data_unit_size_bits;
    ...
}

Could a guest VM trigger this trivially via the host proxy?

> +	bc->bc_slot = *slot;
> +	memcpy(bc->bc_dun, dun, sizeof(bc->bc_dun));
> +
> +	bio->bi_crypt_context = bc;
> +}
> +EXPORT_SYMBOL_GPL(bio_crypt_set_ctx_by_slot);
> +

[ ... ]

> @@ -156,8 +176,12 @@ void __bio_crypt_advance(struct bio *bio, unsigned int bytes)
>  {
>  	struct bio_crypt_ctx *bc = bio->bi_crypt_context;
>  
> -	bio_crypt_dun_increment(bc->bc_dun,
> -				bytes >> bc->bc_key->data_unit_size_bits);
> +	if (bc->bc_key)
> +		bio_crypt_dun_increment(bc->bc_dun,
> +					bytes >> bc->bc_key->data_unit_size_bits);
> +	else if (bc->bc_slot.data_unit_size_bits)

[Severity: High]
If an untrusted guest proxy provides a data_unit_size_bits of 0, won't this
condition silently bypass incrementing the DUN array?

If a bio exceeds hardware limits, bio_split_io_at() splits it and calls
__bio_crypt_advance(). If the increment is bypassed, both halves of the
split bio would be submitted to hardware using the exact same Initialization
Vector (IV) for different data sectors. Does this silent IV reuse break
cryptographic confidentiality?

> +		bio_crypt_dun_increment(bc->bc_dun,
> +					bytes >> bc->bc_slot.data_unit_size_bits);

[Severity: High]
Additionally, is there a missing bounds check on data_unit_size_bits here?

If a guest provides a value of 32 or greater, this right shift on the 32-bit
bytes unsigned integer will trigger undefined behavior.

>  }

[ ... ]

> @@ -260,6 +296,19 @@ bool __blk_crypto_submit_bio(struct bio *bio)
>  		return false;
>  	}
>  
> +	if (!bc_key) {
> +		/*
> +		* Slot path: the ICE keyslot was pre-programmed by the
> +		* hypervisor. The target device must natively support inline
> +		* encryption; there is no fallback for slot-based crypto.
> +		*/
> +		if (!bdev_get_queue(bdev)->crypto_profile) {
> +			bio_endio_status(bio, BLK_STS_NOTSUPP);
> +			return false;
> +		}
> +		return true;

[Severity: High]
If we allow the bio to proceed to the low-level driver here, are standard
block drivers prepared to handle a NULL keyslot for slot-based bios?

Because blk_crypto_rq_get_keyslot() bypasses allocation when bc_key is
NULL, req->crypt_keyslot will be uninitialized. In drivers like MMC,
this NULL keyslot is ignored, failing to populate the physical keyslot index:

drivers/mmc/core/crypto.c:mmc_crypto_prepare_req() {
    ...
    keyslot = req->crypt_keyslot;
    if (keyslot)
        mrq->crypto_key_slot = blk_crypto_keyslot_index(keyslot);
    ...
}

This leaves the internal keyslot index defaulting to 0. Will this hardware
proceed encrypting with keyslot 0, leading to data corruption or a silent
leak of poorly encrypted data?

> +	}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com?part=5

  reply	other threads:[~2026-08-27 16:26 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-27 16:07 [PATCH v1 00/11] FBE virtualization: inline encryption for virtio-blk guests Linlin Zhang
2026-08-27 16:07 ` [PATCH v1 01/11] virtio_blk: add inline encryption support Linlin Zhang
2026-08-27 16:23   ` sashiko-bot
2026-08-27 16:07 ` [PATCH v1 02/11] soc: qcom: add crypto_virt backend for virtio-blk inline crypto Linlin Zhang
2026-08-27 16:24   ` sashiko-bot
2026-08-27 16:07 ` [PATCH v1 03/11] soc: qcom: crypto_virt: add support for create, prepare and import keys Linlin Zhang
2026-08-27 16:19   ` sashiko-bot
2026-08-27 16:07 ` [PATCH v1 04/11] dt-bindings: soc: qcom: add binding for qcom,crypto-virt Linlin Zhang
2026-08-27 16:14   ` sashiko-bot
2026-08-27 16:07 ` [PATCH v1 05/11] blk-crypto: add slot-based inline encryption path Linlin Zhang
2026-08-27 16:26   ` sashiko-bot [this message]
2026-08-27 16:07 ` [PATCH v1 06/11] scsi: ufs: core: add slot path to ufshcd_prepare_lrbp_crypto Linlin Zhang
2026-08-27 16:20   ` sashiko-bot
2026-08-27 16:07 ` [PATCH v1 07/11] blk-crypto: move bio_crypt_dun_increment() to the public header Linlin Zhang
2026-08-27 16:18   ` sashiko-bot
2026-08-27 16:07 ` [PATCH v1 08/11] block: add /dev/blk-crypto-proxy for host-side virtio-blk inline encryption Linlin Zhang
2026-08-27 16:24   ` sashiko-bot
2026-08-27 16:07 ` [PATCH v1 09/11] soc: qcom: add ICE keyslot partitioning driver for guest VMs Linlin Zhang
2026-08-27 16:17   ` sashiko-bot
2026-08-27 16:07 ` [PATCH v1 10/11] blk-crypto: add slot_offset to blk_crypto_profile Linlin Zhang
2026-08-27 16:23   ` sashiko-bot
2026-08-27 16:07 ` [PATCH v1 11/11] scsi: ufs: ufs-qcom: support ICE keyslot partitioning for guest VMs Linlin Zhang
2026-08-27 16:26   ` sashiko-bot
     [not found] ` <20260827184219.GB2137493@google.com>
2026-08-28 15:37   ` [PATCH v1 00/11] FBE virtualization: inline encryption for virtio-blk guests Linlin Zhang
2026-08-28 15:56     ` Linlin Zhang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260827162658.CB0131F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=linlin.zhang@oss.qualcomm.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox