[PATCH] media: ipu6: isys: csi2: guard remote pad/subdev and zero link freq

Alexei Safin posted 1 patch 5 days, 14 hours ago
drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
[PATCH] media: ipu6: isys: csi2: guard remote pad/subdev and zero link freq
Posted by Alexei Safin 5 days, 14 hours ago
media_pad_remote_pad_first() may return NULL when the media link is absent
or disabled. The code dereferenced remote_pad->entity unconditionally in
ipu6_isys_csi2_enable_streams() and ipu6_isys_csi2_disable_streams(),
leading to a possible NULL dereference.

Guard the remote pad/subdev: in enable path return -ENOLINK/-ENODEV, in
disable path always shut down the local stream first and return 0 if the
remote side is missing. This keeps local shutdown semantics intact and
prevents a crash when the graph is partially torn down.

Also, ipu6_isys_csi2_calc_timing() passes link_freq into calc_timing()
where it is used as a divisor. v4l2_get_link_freq() may yield 0; add an
explicit check and return -EINVAL to avoid division by zero.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 3a5c59ad926b ("media: ipu6: Rework CSI-2 sub-device streaming control")
Cc: stable@vger.kernel.org
Signed-off-by: Alexei Safin <a.safin@rosa.ru>
---
 drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
index d1fece6210ab..58944918c344 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
@@ -171,6 +171,10 @@ ipu6_isys_csi2_calc_timing(struct ipu6_isys_csi2 *csi2,
 	if (link_freq < 0)
 		return link_freq;
 
+	/* Avoid division by zero in calc_timing() if link frequency is zero */
+	if (!link_freq)
+		return -EINVAL;
+
 	timing->ctermen = calc_timing(CSI2_CSI_RX_DLY_CNT_TERMEN_CLANE_A,
 				      CSI2_CSI_RX_DLY_CNT_TERMEN_CLANE_B,
 				      link_freq, accinv);
@@ -352,7 +356,12 @@ static int ipu6_isys_csi2_enable_streams(struct v4l2_subdev *sd,
 	int ret;
 
 	remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);
+	if (!remote_pad)
+		return -ENOLINK;
+
 	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+	if (!remote_sd)
+		return -ENODEV;
 
 	sink_streams =
 		v4l2_subdev_state_xlate_streams(state, pad, CSI2_PAD_SINK,
@@ -389,7 +398,16 @@ static int ipu6_isys_csi2_disable_streams(struct v4l2_subdev *sd,
 						&streams_mask);
 
 	remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);
+	if (!remote_pad) {
+		ipu6_isys_csi2_set_stream(sd, NULL, 0, false);
+		return 0;
+	}
+
 	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+	if (!remote_sd) {
+		ipu6_isys_csi2_set_stream(sd, NULL, 0, false);
+		return 0;
+	}
 
 	ipu6_isys_csi2_set_stream(sd, NULL, 0, false);
 
-- 
2.50.1 (Apple Git-155)