[PATCH fixes v3] media: vivid: check for NULL dev in vivid_probe() control setup

From: Rohinthan P

Date: Sat Sep 26 2026 - 23:33:48 EST


In vivid_probe(), after creating instances, the driver iterates
through vivid_devs[0..n_devs-1] to populate HDMI and S-Video
'Connected To' controls. However, it dereferences dev->has_vid_out
without verifying that dev is non-NULL.

If an instance fails during creation, vivid_devs[i] remains NULL,
causing a general protection fault:

Oops: general protection fault
KASAN: probably user-memory-access in range
[0x0000000000005f38-0x0000000000005f3f]
RIP: 0010:vivid_probe+0x579/0x10d0

Add NULL pointer checks in both loops in vivid_probe() before accessing
vivid_devs[i].

Fixes: d7c969f37515 ("media: vivid: Add 'Is Connected To' menu controls")
Cc: stable@xxxxxxxxxxxxxxx
Reported-by: syzbot+caaca441bae2799984d3@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=caaca441bae2799984d3
Signed-off-by: Rohinthan P <rokinthanp03@xxxxxxxxx>
---
Changes in v3:
- Add "fixes" branch prefix to subject and base-commit info targeting
media-committers.git fixes branch to satisfy media-ci test-valid-ancestor check.
- Add Cc: stable@xxxxxxxxxxxxxxx for media-patchstyle check.

Changes in v2:
- Remove .suppress_bind_attrs = true so driver bind/unbind via sysfs
remains supported as required by the test-media test suite.
- Update author name to "Rohinthan P".

drivers/media/test-drivers/vivid/vivid-core.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c
index 62cfb5f..1860ad6 100644
--- a/drivers/media/test-drivers/vivid/vivid-core.c
+++ b/drivers/media/test-drivers/vivid/vivid-core.c
@@ -2116,17 +2116,19 @@ static int vivid_probe(struct platform_device *pdev)
for (int i = 0; i < n_devs; i++) {
struct vivid_dev *dev = vivid_devs[i];

+ if (!dev)
+ continue;
if (!dev->has_vid_out)
continue;
for (int j = 0; j < dev->num_outputs && hdmi_count < MAX_MENU_ITEMS; ++j) {
if (dev->output_type[j] == HDMI) {
- vivid_ctrl_hdmi_to_output_instance[hdmi_count] = vivid_devs[i];
+ vivid_ctrl_hdmi_to_output_instance[hdmi_count] = dev;
vivid_ctrl_hdmi_to_output_index[hdmi_count++] = j;
}
}
for (int j = 0; j < dev->num_outputs && svid_count < MAX_MENU_ITEMS; ++j) {
if (dev->output_type[j] == SVID) {
- vivid_ctrl_svid_to_output_instance[svid_count] = vivid_devs[i];
+ vivid_ctrl_svid_to_output_instance[svid_count] = dev;
vivid_ctrl_svid_to_output_index[svid_count++] = j;
}
}
@@ -2134,13 +2136,17 @@ static int vivid_probe(struct platform_device *pdev)
hdmi_count = min(hdmi_count, MAX_MENU_ITEMS);
svid_count = min(svid_count, MAX_MENU_ITEMS);
for (int i = 0; i < n_devs; i++) {
- for (int j = 0; j < vivid_devs[i]->num_hdmi_inputs; j++) {
- struct v4l2_ctrl *c = vivid_devs[i]->ctrl_hdmi_to_output[j];
+ struct vivid_dev *dev = vivid_devs[i];
+
+ if (!dev)
+ continue;
+ for (int j = 0; j < dev->num_hdmi_inputs; j++) {
+ struct v4l2_ctrl *c = dev->ctrl_hdmi_to_output[j];

v4l2_ctrl_modify_range(c, c->minimum, hdmi_count - 1, 0, c->default_value);
}
- for (int j = 0; j < vivid_devs[i]->num_svid_inputs; j++) {
- struct v4l2_ctrl *c = vivid_devs[i]->ctrl_svid_to_output[j];
+ for (int j = 0; j < dev->num_svid_inputs; j++) {
+ struct v4l2_ctrl *c = dev->ctrl_svid_to_output[j];

v4l2_ctrl_modify_range(c, c->minimum, svid_count - 1, 0, c->default_value);
}
--
2.53.0

base-commit: 2579cbe68005f46fc7f8f95364f6b101b07b9d1c