[PATCH 1/2] hw/virtio/virtio-crypto: verify asym request size

zhenwei pi posted 2 patches 1 month, 3 weeks ago
Maintainers: "Gonglei (Arei)" <arei.gonglei@huawei.com>, zhenwei pi <zhenwei.pi@linux.dev>, "Michael S. Tsirkin" <mst@redhat.com>
There is a newer version of this series
[PATCH 1/2] hw/virtio/virtio-crypto: verify asym request size
Posted by zhenwei pi 1 month, 3 weeks ago
The total lenght of request is limited by cryptodev config, verify it
to avoid unexpected request from guest.

Fixes: 0e660a6f90a ("crypto: Introduce RSA algorithm")
Reported-by: AM 이재영 <nakamurajames123@gmail.com>
Signed-off-by: zhenwei pi <zhenwei.pi@linux.dev>
---
 hw/virtio/virtio-crypto.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 517f2089c5..94dbf9d92d 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -767,11 +767,18 @@ virtio_crypto_handle_asym_req(VirtIOCrypto *vcrypto,
     uint32_t len;
     uint8_t *src = NULL;
     uint8_t *dst = NULL;
+    uint64_t max_len;
 
     asym_op_info = g_new0(CryptoDevBackendAsymOpInfo, 1);
     src_len = ldl_le_p(&req->para.src_data_len);
     dst_len = ldl_le_p(&req->para.dst_data_len);
 
+    max_len = src_len + dst_len;
+    if (unlikely(max_len > vcrypto->conf.max_size)) {
+        virtio_error(vdev, "virtio-crypto asym too big length");
+        goto err;
+    }
+
     if (src_len > 0) {
         src = g_malloc0(src_len);
         len = iov_to_buf(iov, out_num, 0, src, src_len);
-- 
2.43.0


Re: [PATCH 1/2] hw/virtio/virtio-crypto: verify asym request size
Posted by Michael Tokarev 1 month, 2 weeks ago
On 12/14/25 12:09, zhenwei pi wrote:
> The total lenght of request is limited by cryptodev config, verify it
> to avoid unexpected request from guest.
> 
> Fixes: 0e660a6f90a ("crypto: Introduce RSA algorithm")
> Reported-by: AM 이재영 <nakamurajames123@gmail.com>
> Signed-off-by: zhenwei pi <zhenwei.pi@linux.dev>
> ---
>   hw/virtio/virtio-crypto.c | 7 +++++++
>   1 file changed, 7 insertions(+)
> 
> diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
> index 517f2089c5..94dbf9d92d 100644
> --- a/hw/virtio/virtio-crypto.c
> +++ b/hw/virtio/virtio-crypto.c
> @@ -767,11 +767,18 @@ virtio_crypto_handle_asym_req(VirtIOCrypto *vcrypto,
>       uint32_t len;
>       uint8_t *src = NULL;
>       uint8_t *dst = NULL;
> +    uint64_t max_len;
>   
>       asym_op_info = g_new0(CryptoDevBackendAsymOpInfo, 1);
>       src_len = ldl_le_p(&req->para.src_data_len);
>       dst_len = ldl_le_p(&req->para.dst_data_len);
>   
> +    max_len = src_len + dst_len;

I believe this can be overflown when calculating the sum, while
both args are uint32_t.

       max_len = (uint64_t)src_len + dst_len;

might be better.  This is what's used in other places in this
file too.

I wonder if modern compilers can warn about such overflow
possibilities, and what's the better way to write such
expressions.  Something like

    max_len = src_len; max_len += dst_len

maybe? :)

> +    if (unlikely(max_len > vcrypto->conf.max_size)) {
> +        virtio_error(vdev, "virtio-crypto asym too big length");

"virtio-crypto asym request is too large" ?

Thanks,

/mjt

Re: [PATCH 1/2] hw/virtio/virtio-crypto: verify asym request size
Posted by Mauro Matteo Cascella 1 month, 3 weeks ago
On Sun, Dec 14, 2025 at 10:19 AM zhenwei pi <zhenwei.pi@linux.dev> wrote:
>
> The total lenght of request is limited by cryptodev config, verify it
> to avoid unexpected request from guest.

CVE-2025-14876 has been assigned to this bug.

Thanks,

> Fixes: 0e660a6f90a ("crypto: Introduce RSA algorithm")
> Reported-by: AM 이재영 <nakamurajames123@gmail.com>
> Signed-off-by: zhenwei pi <zhenwei.pi@linux.dev>
> ---
>  hw/virtio/virtio-crypto.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
> index 517f2089c5..94dbf9d92d 100644
> --- a/hw/virtio/virtio-crypto.c
> +++ b/hw/virtio/virtio-crypto.c
> @@ -767,11 +767,18 @@ virtio_crypto_handle_asym_req(VirtIOCrypto *vcrypto,
>      uint32_t len;
>      uint8_t *src = NULL;
>      uint8_t *dst = NULL;
> +    uint64_t max_len;
>
>      asym_op_info = g_new0(CryptoDevBackendAsymOpInfo, 1);
>      src_len = ldl_le_p(&req->para.src_data_len);
>      dst_len = ldl_le_p(&req->para.dst_data_len);
>
> +    max_len = src_len + dst_len;
> +    if (unlikely(max_len > vcrypto->conf.max_size)) {
> +        virtio_error(vdev, "virtio-crypto asym too big length");
> +        goto err;
> +    }
> +
>      if (src_len > 0) {
>          src = g_malloc0(src_len);
>          len = iov_to_buf(iov, out_num, 0, src, src_len);
> --
> 2.43.0
>


-- 
Mauro Matteo Cascella
Red Hat Product Security
PGP-Key ID: BB3410B0
Re: [PATCH 1/2] hw/virtio/virtio-crypto: verify asym request size
Posted by zhenwei pi 1 month, 3 weeks ago

On 12/18/25 18:43, Mauro Matteo Cascella wrote:
> On Sun, Dec 14, 2025 at 10:19 AM zhenwei pi <zhenwei.pi@linux.dev> wrote:
>>
>> The total lenght of request is limited by cryptodev config, verify it
>> to avoid unexpected request from guest.
> 
> CVE-2025-14876 has been assigned to this bug.
> 
> Thanks,
> 

OK, I suggest the two patches are tagged with this CVE. This root reason 
of this issue:
- the lack of limitation from hw akcipher (this fix)
- so huge limitation (almost LONG_MAX bytes) from backend builtin driver 
(the next fix)

>> Fixes: 0e660a6f90a ("crypto: Introduce RSA algorithm")
>> Reported-by: AM 이재영 <nakamurajames123@gmail.com>
>> Signed-off-by: zhenwei pi <zhenwei.pi@linux.dev>
>> ---
>>   hw/virtio/virtio-crypto.c | 7 +++++++
>>   1 file changed, 7 insertions(+)
>>
>> diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
>> index 517f2089c5..94dbf9d92d 100644
>> --- a/hw/virtio/virtio-crypto.c
>> +++ b/hw/virtio/virtio-crypto.c
>> @@ -767,11 +767,18 @@ virtio_crypto_handle_asym_req(VirtIOCrypto *vcrypto,
>>       uint32_t len;
>>       uint8_t *src = NULL;
>>       uint8_t *dst = NULL;
>> +    uint64_t max_len;
>>
>>       asym_op_info = g_new0(CryptoDevBackendAsymOpInfo, 1);
>>       src_len = ldl_le_p(&req->para.src_data_len);
>>       dst_len = ldl_le_p(&req->para.dst_data_len);
>>
>> +    max_len = src_len + dst_len;
>> +    if (unlikely(max_len > vcrypto->conf.max_size)) {
>> +        virtio_error(vdev, "virtio-crypto asym too big length");
>> +        goto err;
>> +    }
>> +
>>       if (src_len > 0) {
>>           src = g_malloc0(src_len);
>>           len = iov_to_buf(iov, out_num, 0, src, src_len);
>> --
>> 2.43.0
>>
> 
>