media_pad_remote_pad_first() may return NULL when the media link is absent or disabled. The code dereferenced remote_pad->entity unconditionally, leading to a possible NULL dereference.
On the disable path, always shut down the local stream when the remote pad or subdev is missing and then return 0, preserving local shutdown semantics and avoiding a crash.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 3a5c59ad926b ("media: ipu6: Rework CSI-2 sub-device streaming control") Signed-off-by: Alexei Safin a.safin@rosa.ru --- drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c index 08148bfc2b4b..4a75b0b6c525 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c +++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c @@ -358,7 +358,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, @@ -395,7 +400,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);