diff mbox series

[1/1] media: v4l: async: Fix notifier list entry init

Message ID 20240307142452.3685103-1-alexander.stein@ew.tq-group.com (mailing list archive)
State New, archived
Headers show
Series [1/1] media: v4l: async: Fix notifier list entry init | expand

Commit Message

Alexander Stein March 7, 2024, 2:24 p.m. UTC
struct v4l2_async_notifier has several list_head members, but only
waiting_list and done_list are initialized. notifier_entry was kept
'zeroed' leading to an uninitialized list_head.
This results in a NULL-pointer dereference if csi2_async_register() fails,
e.g. node for remote endpoint is disabled, and returns -ENOTCONN.
The following calls to v4l2_async_nf_unregister() results in a NULL
pointer dereference.
Add the missing list head initializer.

Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
---
Due to all the renames over time, it's hard to find a proper
Fixes tag. If I see it correctly it was missing from the initial commit
e9e310491bdbc ("[media] V4L2: support asynchronous subdevice registration").

The backtrace is left outside of commit message due to size.
Note: Needs CONFIG_DEBUG_LIST to be enabled.

------------[ cut here ]------------
WARNING: CPU: 1 PID: 133 at lib/list_debug.c:52 __list_del_entry_valid_or_report+0x7c/0x148
list_del corruption, c33b9558->next is NULL
Modules linked in: imx6_mipi_csi2(C+) v4l2_fwnode snd_soc_imx_audmux snd_soc_tlv320aic32x4_i2c ci_hdrc_imx(+) coda_vpu snd_soc_tlv320aic32x4 imx6_media(C) ci_hdrc snd_soc_fsl_ssi snd_soc_fsl_asrc imx_pcm_dma v4l2_jpeg imx_media_common(C) videobuf2_vmalloc udc_core snd_soc_core videobuf2_dma_contig roles dw_hdmi_imx imx_vdoa videobuf2_memops dw_hdmi caam usbmisc_imx v4l2_mem2mem imx_sdma drm_display_helper error videobuf2_v4l2 snd_pcm_dmaengine virt_dma video_mux imxdrm videobuf2_common snd_pcm v4l2_async mux_mmio drm_dma_helper mux_core videodev drm_kms_helper snd_timer snd etnaviv mc soundcore imx_ipu_v3 gpu_sched gpio_keys gpio_beeper drm drm_panel_orientation_quirks configfs
CPU: 1 PID: 133 Comm: systemd-udevd Tainted: G        WC         6.8.0-rc7-next-20240307+ #438
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Call trace: 
 unwind_backtrace from show_stack+0x10/0x14
 show_stack from dump_stack_lvl+0x50/0x64
 dump_stack_lvl from __warn+0x98/0xc4
 __warn from warn_slowpath_fmt+0x11c/0x1b4
 warn_slowpath_fmt from __list_del_entry_valid_or_report+0x7c/0x148
 __list_del_entry_valid_or_report from __v4l2_async_nf_unregister.part.0+0x38/0x78 [v4l2_async]
 __v4l2_async_nf_unregister.part.0 [v4l2_async] from v4l2_async_nf_unregister+0x44/0x4c [v4l2_async]
 v4l2_async_nf_unregister [v4l2_async] from csi2_probe+0x20c/0x2b4 [imx6_mipi_csi2]
 csi2_probe [imx6_mipi_csi2] from platform_probe+0x5c/0xb0
 platform_probe from really_probe+0xd0/0x3cc
 really_probe from __driver_probe_device+0x8c/0x120
 __driver_probe_device from driver_probe_device+0x30/0xc0
 driver_probe_device from __driver_attach+0xd8/0x1b0
 __driver_attach from bus_for_each_dev+0x70/0xc0
 bus_for_each_dev from bus_add_driver+0xf0/0x1f4
 bus_add_driver from driver_register+0x7c/0x118
 driver_register from do_one_initcall+0x44/0x174
 do_one_initcall from do_init_module+0xa4/0x2a8
 do_init_module from init_module_from_file+0x94/0x134
 init_module_from_file from idempotent_init_module+0xec/0x240
 idempotent_init_module from sys_finit_module+0x64/0xc4
 sys_finit_module from ret_fast_syscall+0x0/0x1c
Exception stack(0xf0d45fa8 to 0xf0d45ff0)
5fa0:                   00000000 00000000 0000000f b6cfb624 00000000 00020000
5fc0: 00000000 00000000 00000000 0000017b 00000000 b6eaff5b 00000000 0239e688
5fe0: bea33658 bea33648 b6cf65ab b6c2b112
---[ end trace 0000000000000000 ]---

 drivers/media/v4l2-core/v4l2-async.c | 2 ++
 1 file changed, 2 insertions(+)
diff mbox series

Patch

diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 3ec323bd528b1..6a7dcf43d7125 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -563,6 +563,7 @@  void v4l2_async_nf_init(struct v4l2_async_notifier *notifier,
 {
 	INIT_LIST_HEAD(&notifier->waiting_list);
 	INIT_LIST_HEAD(&notifier->done_list);
+	INIT_LIST_HEAD(&notifier->notifier_entry);
 	notifier->v4l2_dev = v4l2_dev;
 }
 EXPORT_SYMBOL(v4l2_async_nf_init);
@@ -572,6 +573,7 @@  void v4l2_async_subdev_nf_init(struct v4l2_async_notifier *notifier,
 {
 	INIT_LIST_HEAD(&notifier->waiting_list);
 	INIT_LIST_HEAD(&notifier->done_list);
+	INIT_LIST_HEAD(&notifier->notifier_entry);
 	notifier->sd = sd;
 }
 EXPORT_SYMBOL_GPL(v4l2_async_subdev_nf_init);