[PATCH] block: Use size_add() and array_size() for safe memory allocation

Fushuai Wang posted 1 patch 6 days, 10 hours ago
block/bio.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
[PATCH] block: Use size_add() and array_size() for safe memory allocation
Posted by Fushuai Wang 6 days, 10 hours ago
Dynamic size calculations should not be performed in memory
allocator due to the risk of overflowing. So use size_add()
and array_size(), which have overflow checks, in bio_kmalloc()
for safe size calculation.

Signed-off-by: Fushuai Wang <wangfushuai@baidu.com>
---
 block/bio.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index b3a79285c278..c7789469c892 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -617,8 +617,9 @@ struct bio *bio_kmalloc(unsigned short nr_vecs, gfp_t gfp_mask)
 
 	if (nr_vecs > BIO_MAX_INLINE_VECS)
 		return NULL;
-	return kmalloc(sizeof(*bio) + nr_vecs * sizeof(struct bio_vec),
-			gfp_mask);
+	return kmalloc(size_add(sizeof(*bio),
+				array_size(nr_vecs, sizeof(struct bio_vec))),
+		       gfp_mask);
 }
 EXPORT_SYMBOL(bio_kmalloc);
 
-- 
2.36.1
Re: [PATCH] block: Use size_add() and array_size() for safe memory allocation
Posted by Caleb Sander Mateos 6 days, 7 hours ago
On Tue, Nov 25, 2025 at 5:09 AM Fushuai Wang <fushuai.wang@linux.dev> wrote:
>
> Dynamic size calculations should not be performed in memory
> allocator due to the risk of overflowing. So use size_add()

nr_vecs is an unsigned short and sizeof(struct bio_vec) is 16. I don't
see how the multiplication could possibly overflow a size_t.

> and array_size(), which have overflow checks, in bio_kmalloc()
> for safe size calculation.
>
> Signed-off-by: Fushuai Wang <wangfushuai@baidu.com>
> ---
>  block/bio.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/block/bio.c b/block/bio.c
> index b3a79285c278..c7789469c892 100644
> --- a/block/bio.c
> +++ b/block/bio.c
> @@ -617,8 +617,9 @@ struct bio *bio_kmalloc(unsigned short nr_vecs, gfp_t gfp_mask)
>
>         if (nr_vecs > BIO_MAX_INLINE_VECS)
>                 return NULL;
> -       return kmalloc(sizeof(*bio) + nr_vecs * sizeof(struct bio_vec),
> -                       gfp_mask);
> +       return kmalloc(size_add(sizeof(*bio),
> +                               array_size(nr_vecs, sizeof(struct bio_vec))),
> +                      gfp_mask);
>  }
>  EXPORT_SYMBOL(bio_kmalloc);
>
> --
> 2.36.1
>
>