]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: nxp: imx8-isi: Fix potential out-of-bounds issues
authorGuoniu Zhou <guoniu.zhou@nxp.com>
Mon, 23 Mar 2026 08:33:30 +0000 (16:33 +0800)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Thu, 21 May 2026 05:41:32 +0000 (07:41 +0200)
The maximum downscaling factor supported by ISI can be up to 16. Add
minimum value constraint before applying the setting to hardware.
Otherwise, the process will not respond even when Ctrl+C is executed.

Fixes: cf21f328fcaf ("media: nxp: Add i.MX8 ISI driver")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patch.msgid.link/20260323-isi-v3-1-8df53b24e622@oss.nxp.com
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h
drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c
drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c

index 14d63ec36416eb11a352afc75896f0a398b0a0a0..7547a6559d4c1103e1e44f0a81281ab519c829dd 100644 (file)
@@ -11,6 +11,7 @@
 #define __MXC_ISI_CORE_H__
 
 #include <linux/list.h>
+#include <linux/math.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
@@ -414,4 +415,19 @@ static inline void mxc_isi_debug_cleanup(struct mxc_isi_dev *isi)
 }
 #endif
 
+/*
+ * ISI scaling engine works in two parts: it performs pre-decimation of
+ * the image followed by bilinear filtering to achieve the desired
+ * downscaling factor.
+ *
+ * The decimation filter provides a maximum downscaling factor of 8, and
+ * the subsequent bilinear filter provides a maximum downscaling factor
+ * of 2. Combined, the maximum scaling factor can be up to 16.
+ */
+static inline unsigned int
+mxc_isi_clamp_downscale_16(unsigned int val, unsigned int max_val)
+{
+       return clamp(val, max(1U, DIV_ROUND_UP(max_val, 16)), max_val);
+}
+
 #endif /* __MXC_ISI_CORE_H__ */
index a39ad7a1ab18d542271b2fcef20b19200473d5a7..de398b232d747b4cb297441b1ccb4da3cb893704 100644 (file)
@@ -509,9 +509,14 @@ __mxc_isi_m2m_try_fmt_vid(struct mxc_isi_m2m_ctx *ctx,
                          const enum mxc_isi_video_type type)
 {
        if (type == MXC_ISI_VIDEO_M2M_CAP) {
-               /* Downscaling only  */
-               pix->width = min(pix->width, ctx->queues.out.format.width);
-               pix->height = min(pix->height, ctx->queues.out.format.height);
+               const struct v4l2_pix_format_mplane *format =
+                       &ctx->queues.out.format;
+
+               /* Downscaling only, by up to 16. */
+               pix->width = mxc_isi_clamp_downscale_16(pix->width,
+                                                       format->width);
+               pix->height = mxc_isi_clamp_downscale_16(pix->height,
+                                                        format->height);
        }
 
        return mxc_isi_format_try(ctx->m2m->pipe, pix, type);
index a59b9456b5907d3d5fb48738c2d501fd8c7572d2..2d0843c86534cc00d678fe096a6961e847c7b018 100644 (file)
@@ -641,16 +641,19 @@ static int mxc_isi_pipe_set_selection(struct v4l2_subdev *sd,
                        /* Composing is supported on the sink only. */
                        return -EINVAL;
 
-               /* The sink crop is bound by the sink format downscaling only). */
+               /*
+                * The ISI supports downscaling only, with a factor up to 16.
+                * Clamp the compose rectangle size accordingly.
+                */
                format = mxc_isi_pipe_get_pad_format(pipe, state,
                                                     MXC_ISI_PIPE_PAD_SINK);
 
                sel->r.left = 0;
                sel->r.top = 0;
-               sel->r.width = clamp(sel->r.width, MXC_ISI_MIN_WIDTH,
-                                    format->width);
-               sel->r.height = clamp(sel->r.height, MXC_ISI_MIN_HEIGHT,
-                                     format->height);
+               sel->r.width = mxc_isi_clamp_downscale_16(sel->r.width,
+                                                         format->width);
+               sel->r.height = mxc_isi_clamp_downscale_16(sel->r.height,
+                                                          format->height);
 
                rect = mxc_isi_pipe_get_pad_compose(pipe, state,
                                                    MXC_ISI_PIPE_PAD_SINK);