]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commit - drivers/media/dvb-core/dvb_frontend.c
[media] media: Protect enable_source and disable_source handler code paths
authorShuah Khan <shuahkh@osg.samsung.com>
Tue, 29 Nov 2016 23:59:54 +0000 (21:59 -0200)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Fri, 3 Feb 2017 09:39:35 +0000 (07:39 -0200)
commit90cd366bc61cd539c797b7ad957a9d749d97200f
treec26c3643a20164385c9916c200df7244c769f24c
parent92fbeb40b132f5b2ec335f644ba563a1a85ffd8b
[media] media: Protect enable_source and disable_source handler code paths

Drivers might try to access and run enable_source and disable_source
handlers when the driver that implements these handlers is clearing
the handlers during its unregister.

Fix the following race condition:

process 1 process 2

request video streaming unbind au0828
v4l2 checks if tuner is free
... ...

au0828_unregister_media_device()
... ...
(doesn't hold graph_mutex)
mdev->enable_source = NULL;
if (mdev && mdev->enable_source) mdev->disable_source = NULL;
mdev->enable_source()
(enable_source holds graph_mutex)

As shown above enable_source check is done without holding the graph_mutex.
If unbind happens to be in progress, au0828 could clear enable_source and
disable_source handlers leading to null pointer de-reference.

Fix it by protecting enable_source and disable_source set and clear and
protecting enable_source and disable_source handler access and the call
itself.

process 1 process 2

request video streaming unbind au0828
v4l2 checks if tuner is free
... ...

au0828_unregister_media_device()
... ...
(hold graph_mutex while clearing)
mdev->enable_source = NULL;
if (mdev) mdev->disable_source = NULL;
(hold graph_mutex to check and
 call enable_source)
    if (mdev->enable_source)
mdev->enable_source()

If graph_mutex is held to just heck for handler being null and needs to be
released before calling the handler, there will be another window for the
handlers to be cleared. Hence, enable_source and disable_source handlers
no longer hold the graph_mutex and expect callers to hold it to avoid
forcing them release the graph_mutex before calling the handlers.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/dvb-core/dvb_frontend.c
drivers/media/usb/au0828/au0828-core.c
drivers/media/v4l2-core/v4l2-mc.c
include/media/media-device.h