linux/drivers/media/v4l2-core
Hans Verkuil be7e8af98f media: v4l2-ctrls.c: fix race condition in hdl->requests list
When a request is re-inited it will release all control handler
objects that are still in the request. It does that by unbinding
and putting all those objects. When the object is unbound the
obj->req pointer is set to NULL, and the object's unbind op is
called. When the object it put the object's release op is called
to free the memory.

For a request object that contains a control handler that means
that v4l2_ctrl_handler_free() is called in the release op.

A control handler used in a request has a pointer to the main
control handler that is created by the driver and contains the
current state of all controls. If the device is unbound (due to
rmmod or a forced unbind), then that main handler is freed, again
by calling v4l2_ctrl_handler_free(), and any outstanding request
objects that refer to that main handler have to be unbound and put
as well.

It does that by this test:

	if (!hdl->req_obj.req && !list_empty(&hdl->requests)) {

I.e. the handler has no pointer to a request, so is the main
handler, and one or more request objects refer to this main
handler.

However, this test is wrong since hdl->req_obj.req is actually
NULL when re-initing a request (the object unbind will set req to
NULL), and the only reason this seemingly worked is that the
requests list is typically empty since the request's unbind op
will remove the handler from the requests list.

But if another thread is at the same time adding a new control
to a request, then there is a race condition where one thread
is removing a control handler object from the requests list and
another thread is adding one. The result is that hdl->requests
is no longer empty and the code thinks that a main handler is
being freed instead of a control handler that is part of a request.

There are two bugs here: first the test for hdl->req_obj.req: this
should be hdl->req_obj.ops since only the main control handler will
have a NULL pointer there.

The second is that adding or deleting request objects from the
requests list of the main handler isn't protected by taking the
main handler's lock.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Reported-by: John Cox <jc@kynesim.co.uk>
Fixes: 6fa6f831f0 ("media: v4l2-ctrls: add core request support")
Tested-by: John Cox <jc@kynesim.co.uk>
Reported-by: John Cox <jc@kynesim.co.uk>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2021-04-06 16:05:33 +02:00
..
Kconfig media: v4l2-core: Add helpers to build the H264 P/B0/B1 reflists 2020-04-21 13:46:40 +02:00
Makefile media: Remove the legacy v4l2-clk API 2021-02-06 09:39:44 +01:00
tuner-core.c treewide: Add SPDX license identifier for more missed files 2019-05-21 10:50:45 +02:00
v4l2-async.c media: v4l2-async: Improve v4l2_async_notifier_add_*_subdev() API 2021-02-06 09:18:53 +01:00
v4l2-common.c media: v4l: common: v4l2_get_link_freq: add printing a warning 2021-03-11 11:59:43 +01:00
v4l2-compat-ioctl32.c media: v4l2-compat-ioctl32.c: add missing #ifdef CONFIG_COMPAT_32BIT_TIMEs 2020-11-17 07:14:46 +01:00
v4l2-ctrls.c media: v4l2-ctrls.c: fix race condition in hdl->requests list 2021-04-06 16:05:33 +02:00
v4l2-dev.c media: v4l2-dev.c: show which events are requested by poll() 2021-03-22 11:54:31 +01:00
v4l2-device.c media: v4l: subdev: Set sd->devnode before registering the subdev 2020-12-02 15:55:44 +01:00
v4l2-dv-timings.c media: v4l2-dv-timings: Use DIV_ROUND_CLOSEST directly to make it readable 2019-11-05 08:49:22 -03:00
v4l2-event.c media: v4l2-dev/event: add v4l2_event_wake_all() 2021-01-04 13:14:25 +01:00
v4l2-fh.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174 2019-05-30 11:26:41 -07:00
v4l2-flash-led-class.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
v4l2-fwnode.c media: v4l: fwnode: Rename v4l2_async_register_subdev_sensor_common 2021-04-06 14:36:54 +02:00
v4l2-h264.c media: uapi: h264: Clean slice invariants syntax elements 2020-09-01 14:13:28 +02:00
v4l2-i2c.c media: v4l2-core: v4l2-i2c: convert to new API with ERRPTR 2020-02-24 15:21:52 +01:00
v4l2-ioctl.c media: v4l2-ioctl.c: fix timestamp format 2021-03-22 11:55:32 +01:00
v4l2-jpeg.c media: Avoid parsing quantization and huffman tables 2021-03-22 10:40:13 +01:00
v4l2-mc.c media: v4l2-mc: fix a warning message 2021-03-22 13:06:39 +01:00
v4l2-mem2mem.c media: v4l2-mem2mem: always call poll_wait() on queues 2021-01-04 13:13:15 +01:00
v4l2-spi.c v4l2-core: fix coding style for the two new c files 2019-08-26 11:01:25 -03:00
v4l2-subdev.c media: v4l: subdev: Improve link format validation debug messages 2020-11-16 10:31:14 +01:00
v4l2-trace.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
videobuf-core.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
videobuf-dma-contig.c mmap locking API: use coccinelle to convert mmap_sem rwsem call sites 2020-06-09 09:39:14 -07:00
videobuf-dma-sg.c media: videobuf-dma-sg: number of pages should be unsigned long 2020-09-03 11:12:20 +02:00
videobuf-vmalloc.c mm: reorder includes after introduction of linux/pgtable.h 2020-06-09 09:39:13 -07:00