<div dir="ltr"><div dir="ltr">You're right. Initially, I considered the case where sg_data_total +<br>buf_cnt < blk_sz, in which the subtraction could underflow. But such<br>a state is unreachable in kmb_ocs_dma_prepare():<br><br>  - kmb_ocs_hcu_update() calls into the DMA path only when<br>    sg_data_total + buf_cnt > sizeof(rctx->buffer) = 256; otherwise<br>    it goes through flush_sg_to_ocs_buffer().<br>  - flush_sg_to_ocs_buffer() rejects buf_cnt > 256.<br><br>Since 256 is a multiple of both supported block sizes (64 and 128),<br>for sg_data_total < blk_sz the modulo (sg_data_total + buf_cnt) % blk_sz<br>reduces to sg_data_total + buf_cnt - 256. For sg_data_total >= blk_sz,<br>underflow is impossible anyway. In both cases,<br><br>    sg_data_total - remainder = 256 - buf_cnt >= 0.<br><br>Thus, the subtraction cannot underflow, regardless of whether<br>sg_data_total is less than, equal to, or greater than blk_sz. The<br>added check is dead code. No patch is needed.<br><br>Thanks for the review.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">пт, 18 сент. 2026 г. в 11:49, Herbert Xu <<a href="mailto:herbert@gondor.apana.org.au" target="_blank">herbert@gondor.apana.org.au</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Tue, Sep 08, 2026 at 05:34:47PM +0300, Dmitriy Okunev wrote:<br>
> In the kmb_ocs_dma_prepare() function, the `remainder` is calculated<br>
> as `total % blk_sz`, where `total = sg_data_total + buf_cnt`. In<br>
> update requests, if `buf_cnt` is large and `total` is less than<br>
> `rctx->blk_sz`, the `remainder` may exceed `sg_data_total`, which<br>
> will lead to an overflow of `sg_data_total - remainder`. This results<br>
> in an incorrect large value being passed to the `sg_nents_for_len()`<br>
> function, which can lead to memory corruption.<br>
> <br>
> Add a check to return -EINVAL if `sg_data_total < remainder`,<br>
> so that the subtraction is always safe.<br>
> <br>
> Found by Linux Verification Center (<a href="http://linuxtesting.org" rel="noreferrer" target="_blank">linuxtesting.org</a>) with SVACE.<br>
> <br>
> Fixes: 472b04444cd3 ("crypto: keembay - Add Keem Bay OCS HCU driver")<br>
> Signed-off-by: Dmitriy Okunev <<a href="mailto:dokunevdmitriy@gmail.com" target="_blank">dokunevdmitriy@gmail.com</a>><br>
> ---<br>
>  drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c | 5 ++++-<br>
>  1 file changed, 4 insertions(+), 1 deletion(-)<br>
> <br>
> diff --git a/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c b/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c<br>
> index 9a67bb4ecc82..92f2d9ff6f83 100644<br>
> --- a/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c<br>
> +++ b/drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c<br>
> @@ -246,8 +246,11 @@ static int kmb_ocs_dma_prepare(struct ahash_request *req)<br>
>        * HCU must be aligned to the block size; compute the remainder data to<br>
>        * be processed in the next request.<br>
>        */<br>
> -     if (!(rctx->flags & REQ_FINAL))<br>
> +     if (!(rctx->flags & REQ_FINAL)) {<br>
>               remainder = total % rctx->blk_sz;<br>
> +             if (rctx->sg_data_total < remainder)<br>
> +                     return -EINVAL;<br>
> +     }<br>
<br>
This driver buffers data less than block size, so how can it get<br>
here with sg_data_total less than block size?<br>
<br>
Thanks,<br>
-- <br>
Email: Herbert Xu <<a href="mailto:herbert@gondor.apana.org.au" target="_blank">herbert@gondor.apana.org.au</a>><br>
Home Page: <a href="http://gondor.apana.org.au/~herbert/" rel="noreferrer" target="_blank">http://gondor.apana.org.au/~herbert/</a><br>
PGP Key: <a href="http://gondor.apana.org.au/~herbert/pubkey.txt" rel="noreferrer" target="_blank">http://gondor.apana.org.au/~herbert/pubkey.txt</a><br>
</blockquote></div>
</div>