[PATCH v1 0/4] media: atomisp: prevent integer overflow in DVS table allocations

Siho Lee posted 4 patches 1 week, 4 days ago
Only 0 patches received!
drivers/staging/media/atomisp/pci/sh_css_param_dvs.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
[PATCH v1 0/4] media: atomisp: prevent integer overflow in DVS table allocations
Posted by Siho Lee 1 week, 4 days ago
From 8955328f674e82dea60f6c9982f20623b10a3619 Mon Sep 17 00:00:00 2001
From: Siho Lee <25esihoya@gmail.com>
Date: Tue, 26 May 2026 00:29:26 +0900
Subject: [PATCH v1 0/4] media: atomisp: prevent integer overflow in
DVS table allocations

CVE-2022-50399 (commit 51b8dc5163d2) fixed an integer overflow in
sh_css_set_black_frame() by using array3_size(). However, the same
overflow pattern exists in 9 other locations that were not updated.

The most critical is in alloc_dvs_6axis_table() (sh_css_param_dvs.c)
where width_y * height_y multiplication overflows on 32-bit arithmetic
when the user sets a large resolution via VIDIOC_S_FMT. ATOM_ISP_MAX_WIDTH
is set to UINT_MAX which imposes no limit.

For example, with frame_res width=16777216, width_y becomes 262145:
    262145 * 262145 = 524289 (32-bit, overflowed)
    262145 * 262145 = 68720001025 (64-bit, actual)

This causes kvmalloc() to allocate only ~2 MB instead of the required
~64 GB, leading to an out-of-bounds write in
init_dvs_6axis_table_from_default() that triggers a kernel panic.

Patches 1-3 use array3_size() to prevent overflow at the remaining
locations. Patch 4 reduces ATOM_ISP_MAX_WIDTH/HEIGHT from UINT_MAX
to 8192 as a hard limit (mathematically: DVS_BLOCKDIM=64, max blocks
129*129, 129*129*sizeof(u32)=66564 bytes which cannot overflow u32).

Tested on: 5.15.0 (hardware), 6.8.0 (hardware), v7.0.10 stable (QEMU),
v7.1-rc5 mainline (static analysis). No Intel Atom ISP hardware
available for V4L2 ioctl path verification.

Siho Lee (4):
  staging: atomisp: prevent integer overflow in DVS 6-axis allocation
  staging: atomisp: prevent integer overflow in sh_css_params DVS
    allocation
  staging: atomisp: prevent integer overflow in shading table allocation
  staging: atomisp: add resolution limits to prevent DVS overflow

 drivers/staging/media/atomisp/pci/atomisp_internal.h     | 4 ++--
 drivers/staging/media/atomisp/pci/sh_css_param_dvs.c     | 8 ++++----
 drivers/staging/media/atomisp/pci/sh_css_param_shading.c | 2 +-
 drivers/staging/media/atomisp/pci/sh_css_params.c        | 8 ++++----
 4 files changed, 11 insertions(+), 11 deletions(-)

-- 
2.43.0



From 99ca51470fb296b4b33283a106d9388521646cb3 Mon Sep 17 00:00:00 2001
From: Siho Lee <25esihoya@gmail.com>
Date: Tue, 26 May 2026 00:28:35 +0900
Subject: [PATCH v1 1/4] staging: atomisp: prevent integer overflow in DVS
 6-axis allocation

The width_y * height_y multiplication in alloc_dvs_6axis_table() can
overflow on 32-bit arithmetic when the user sets a large resolution via
VIDIOC_S_FMT, since ATOM_ISP_MAX_WIDTH = UINT_MAX imposes no limit.

For example, with frame_res width=16777216, width_y becomes 262145 and:
    262145 * 262145 = 524289 (32-bit, overflowed)
    262145 * 262145 = 68720001025 (64-bit, actual)

This causes kvmalloc() to allocate only 2 MB instead of the required
256 GB, leading to an out-of-bounds write in
init_dvs_6axis_table_from_default() that triggers a kernel panic.

Use array3_size() to prevent the overflow, consistent with the
CVE-2022-50399 fix in sh_css_set_black_frame().

Fixes: a49d25364dfb ("staging/atomisp: add support for DVS")
Cc: stable@vger.kernel.org
Signed-off-by: Siho Lee <25esihoya@gmail.com>
---
 drivers/staging/media/atomisp/pci/sh_css_param_dvs.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 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 9ccdb66de..3ea707528 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c
@@ -48,7 +48,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 +56,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 +67,7 @@ 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 +75,7 @@ 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");
-- 
2.43.0



From 6205ae2498aea5944d41cae04135daf4912e0a2f Mon Sep 17 00:00:00 2001
From: Siho Lee <25esihoya@gmail.com>
Date: Tue, 26 May 2026 00:28:56 +0900
Subject: [PATCH v1 2/4] staging: atomisp: prevent integer overflow in
 sh_css_params DVS allocation

Same integer overflow pattern as the previous commit, in the same file
where CVE-2022-50399 was fixed (line 954) but these four locations
(lines 4481, 4486, 4491, 4497) were missed.

Fixes: a49d25364dfb ("staging/atomisp: add support for DVS")
Cc: stable@vger.kernel.org
Signed-off-by: Siho Lee <25esihoya@gmail.com>
---
 drivers/staging/media/atomisp/pci/sh_css_params.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c
b/drivers/staging/media/atomisp/pci/sh_css_params.c
index fcebace11..52ac15df1 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
@@ -4478,23 +4478,23 @@ 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 *
+	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 *
+	dvs_config->ycoords_uv = kvmalloc(array3_size(width_uv, height_uv,
 					  sizeof(uint32_t),
 					  GFP_KERNEL);
 	if (!dvs_config->ycoords_uv)
-- 
2.43.0



From e9c253be79c1f78008c27514f4d01230c8a260f5 Mon Sep 17 00:00:00 2001
From: Siho Lee <25esihoya@gmail.com>
Date: Tue, 26 May 2026 00:29:08 +0900
Subject: [PATCH v1 3/4] staging: atomisp: prevent integer overflow in shading
 table allocation

The width * height multiplication in ia_css_shading_table_alloc() can
overflow on 32-bit arithmetic when width and height are large, causing
an undersized kvmalloc() and subsequent out-of-bounds write.

Use array3_size() to prevent the overflow, consistent with the
CVE-2022-50399 fix and the previous commits.

Fixes: 3c4efab94858 ("staging/atomisp: allocate shading table separately")
Cc: stable@vger.kernel.org
Signed-off-by: Siho Lee <25esihoya@gmail.com>
---
 drivers/staging/media/atomisp/pci/sh_css_param_shading.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 9105334c7..2a8756f1f 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
@@ -339,7 +339,7 @@ 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;
-- 
2.43.0



From 8955328f674e82dea60f6c9982f20623b10a3619 Mon Sep 17 00:00:00 2001
From: Siho Lee <25esihoya@gmail.com>
Date: Tue, 26 May 2026 00:29:20 +0900
Subject: [PATCH v1 4/4] staging: atomisp: add resolution limits to prevent DVS
 overflow

ATOM_ISP_MAX_WIDTH and ATOM_ISP_MAX_HEIGHT are set to UINT_MAX, which
allows userspace to set arbitrarily large resolutions via VIDIOC_S_FMT.
This is the root enabler for the integer overflow in DVS table allocation
fixed in the previous commits.

Add reasonable limits (8192x8192) as a defense-in-depth measure. The
Intel Atom ISP hardware does not support resolutions beyond 8192x8192,
so this should not affect any real use case.

Fixes: a49d25364dfb ("staging/atomisp: add support for DVS")
Cc: stable@vger.kernel.org
Signed-off-by: Siho Lee <25esihoya@gmail.com>
---
 drivers/staging/media/atomisp/pci/atomisp_internal.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h
b/drivers/staging/media/atomisp/pci/atomisp_internal.h
index 5a69580b8..bb2367d19 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_internal.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h
@@ -55,8 +55,8 @@

 #define ATOM_ISP_MIN_WIDTH	4
 #define ATOM_ISP_MIN_HEIGHT	4
-#define ATOM_ISP_MAX_WIDTH	UINT_MAX
-#define ATOM_ISP_MAX_HEIGHT	UINT_MAX
+#define ATOM_ISP_MAX_WIDTH	8192
+#define ATOM_ISP_MAX_HEIGHT	8192

 /* sub-QCIF resolution */
 #define ATOM_RESOLUTION_SUBQCIF_WIDTH	128
-- 
2.43.0