On Sun Apr 12 00:05:08 2026 +0000, Feng Ning wrote:
> Replace open-coded width * height * sizeof() multiplications with
> array3_size() to prevent integer overflow in buffer allocations.
> 
> The atomisp driver computes DVS, morphing table, shading table and
> statistics buffer sizes using unchecked arithmetic.  When dimensions
> are attacker-controlled or simply large, the product can silently wrap,
> causing kvmalloc() to allocate an undersized buffer.
> 
> array3_size() saturates to SIZE_MAX on overflow, so kvmalloc() returns
> NULL instead of succeeding with too few bytes.
> 
> Signed-off-by: Feng Ning <[email protected]>
> Signed-off-by: Sakari Ailus <[email protected]>

Patch committed.

Thanks,
Sakari Ailus

 .../staging/media/atomisp/pci/sh_css_param_dvs.c   | 11 ++++---
 .../media/atomisp/pci/sh_css_param_shading.c       |  4 ++-
 drivers/staging/media/atomisp/pci/sh_css_params.c  | 35 +++++++++++++---------
 3 files changed, 31 insertions(+), 19 deletions(-)

---

diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c 
b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
index 3d2cb2d25fdb..ad2a9b84e232 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2015, Intel Corporation.
  */
 
+#include <linux/overflow.h>
 #include "sh_css_param_dvs.h"
 #include <assert_support.h>
 #include <type_support.h>
@@ -48,7 +49,7 @@ alloc_dvs_6axis_table(const struct ia_css_resolution 
*frame_res,
                }
 
                /* Generate Y buffers  */
-               dvs_config->xcoords_y = kvmalloc(width_y * height_y * 
sizeof(uint32_t),
+               dvs_config->xcoords_y = kvmalloc(array3_size(width_y, height_y, 
sizeof(uint32_t)),
                                                 GFP_KERNEL);
                if (!dvs_config->xcoords_y) {
                        IA_CSS_ERROR("out of memory");
@@ -56,7 +57,7 @@ alloc_dvs_6axis_table(const struct ia_css_resolution 
*frame_res,
                        goto exit;
                }
 
-               dvs_config->ycoords_y = kvmalloc(width_y * height_y * 
sizeof(uint32_t),
+               dvs_config->ycoords_y = kvmalloc(array3_size(width_y, height_y, 
sizeof(uint32_t)),
                                                 GFP_KERNEL);
                if (!dvs_config->ycoords_y) {
                        IA_CSS_ERROR("out of memory");
@@ -67,7 +68,8 @@ alloc_dvs_6axis_table(const struct ia_css_resolution 
*frame_res,
                /* Generate UV buffers  */
                IA_CSS_LOG("UV W %d H %d", width_uv, height_uv);
 
-               dvs_config->xcoords_uv = kvmalloc(width_uv * height_uv * 
sizeof(uint32_t),
+               dvs_config->xcoords_uv = kvmalloc(array3_size(width_uv, 
height_uv,
+                                                             sizeof(uint32_t)),
                                                  GFP_KERNEL);
                if (!dvs_config->xcoords_uv) {
                        IA_CSS_ERROR("out of memory");
@@ -75,7 +77,8 @@ alloc_dvs_6axis_table(const struct ia_css_resolution 
*frame_res,
                        goto exit;
                }
 
-               dvs_config->ycoords_uv = kvmalloc(width_uv * height_uv * 
sizeof(uint32_t),
+               dvs_config->ycoords_uv = kvmalloc(array3_size(width_uv, 
height_uv,
+                                                             sizeof(uint32_t)),
                                                  GFP_KERNEL);
                if (!dvs_config->ycoords_uv) {
                        IA_CSS_ERROR("out of memory");
diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_shading.c 
b/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
index 083ac5713b6d..0ac85cdea010 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2015, Intel Corporation.
  */
 
+#include <linux/overflow.h>
 #include <linux/math.h>
 #include <linux/slab.h>
 
@@ -345,7 +346,8 @@ ia_css_shading_table_alloc(
        me->fraction_bits = 0;
        for (i = 0; i < IA_CSS_SC_NUM_COLORS; i++) {
                me->data[i] =
-                   kvmalloc(width * height * sizeof(*me->data[0]),
+                   kvmalloc(array3_size(width, height,
+                                        sizeof(*me->data[0])),
                             GFP_KERNEL);
                if (!me->data[i]) {
                        unsigned int j;
diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c 
b/drivers/staging/media/atomisp/pci/sh_css_params.c
index b8d492115196..1c8af03db1c7 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2015, Intel Corporation.
  */
 
+#include <linux/overflow.h>
 #include <linux/math.h>
 
 #include "gdc_device.h"                /* gdc_lut_store(), ... */
@@ -1377,11 +1378,11 @@ struct ia_css_morph_table *ia_css_morph_table_allocate(
        }
 
        for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) {
-               me->coordinates_x[i] = kvmalloc(height * width *
-                                               sizeof(*me->coordinates_x[i]),
+               me->coordinates_x[i] = kvmalloc(array3_size(height, width,
+                                                           
sizeof(*me->coordinates_x[i])),
                                                GFP_KERNEL);
-               me->coordinates_y[i] = kvmalloc(height * width *
-                                               sizeof(*me->coordinates_y[i]),
+               me->coordinates_y[i] = kvmalloc(array3_size(height, width,
+                                                           
sizeof(*me->coordinates_y[i])),
                                                GFP_KERNEL);
 
                if ((!me->coordinates_x[i]) ||
@@ -4198,13 +4199,17 @@ ia_css_dvs_statistics_allocate(const struct 
ia_css_dvs_grid_info *grid)
                goto err;
 
        me->grid = *grid;
-       me->hor_proj = kvmalloc(grid->height * IA_CSS_DVS_NUM_COEF_TYPES *
-                               sizeof(*me->hor_proj), GFP_KERNEL);
+       me->hor_proj = kvmalloc(array3_size(grid->height,
+                                           IA_CSS_DVS_NUM_COEF_TYPES,
+                                               sizeof(*me->hor_proj)),
+                               GFP_KERNEL);
        if (!me->hor_proj)
                goto err;
 
-       me->ver_proj = kvmalloc(grid->width * IA_CSS_DVS_NUM_COEF_TYPES *
-                               sizeof(*me->ver_proj), GFP_KERNEL);
+       me->ver_proj = kvmalloc(array3_size(grid->width,
+                                           IA_CSS_DVS_NUM_COEF_TYPES,
+                                               sizeof(*me->ver_proj)),
+                               GFP_KERNEL);
        if (!me->ver_proj)
                goto err;
 
@@ -4470,24 +4475,26 @@ ia_css_dvs2_6axis_config_allocate(const struct 
ia_css_stream *stream)
                                    
params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO]->height_uv;
        IA_CSS_LOG("table Y: W %d H %d", width_y, height_y);
        IA_CSS_LOG("table UV: W %d H %d", width_uv, height_uv);
-       dvs_config->xcoords_y = kvmalloc(width_y * height_y * sizeof(uint32_t),
+       dvs_config->xcoords_y = kvmalloc(array3_size(width_y, height_y,
+                                                    sizeof(uint32_t)),
                                         GFP_KERNEL);
        if (!dvs_config->xcoords_y)
                goto err;
 
-       dvs_config->ycoords_y = kvmalloc(width_y * height_y * sizeof(uint32_t),
+       dvs_config->ycoords_y = kvmalloc(array3_size(width_y, height_y,
+                                                    sizeof(uint32_t)),
                                         GFP_KERNEL);
        if (!dvs_config->ycoords_y)
                goto err;
 
-       dvs_config->xcoords_uv = kvmalloc(width_uv * height_uv *
-                                         sizeof(uint32_t),
+       dvs_config->xcoords_uv = kvmalloc(array3_size(width_uv, height_uv,
+                                                     sizeof(uint32_t)),
                                          GFP_KERNEL);
        if (!dvs_config->xcoords_uv)
                goto err;
 
-       dvs_config->ycoords_uv = kvmalloc(width_uv * height_uv *
-                                         sizeof(uint32_t),
+       dvs_config->ycoords_uv = kvmalloc(array3_size(width_uv, height_uv,
+                                                     sizeof(uint32_t)),
                                          GFP_KERNEL);
        if (!dvs_config->ycoords_uv)
                goto err;
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to