media: fix media devnode ioctl/syscall and unregister race
authorShuah Khan <shuahkh@osg.samsung.com>
Fri, 10 Jun 2016 17:37:23 +0000 (14:37 -0300)
committerBen Hutchings <ben@decadent.org.uk>
Tue, 28 Apr 2020 18:03:51 +0000 (19:03 +0100)
commit596ba660d5c010ca8c3f9e3f60d530423593bee7
treea8523390d53ff4a042a3a6f502c6a752a3eee785
parentf7b29039bda2db014c71d82aeb50da70ca09efe3
media: fix media devnode ioctl/syscall and unregister race

commit 6f0dd24a084a17f9984dd49dffbf7055bf123993 upstream.

Media devnode open/ioctl could be in progress when media device unregister
is initiated. System calls and ioctls check media device registered status
at the beginning, however, there is a window where unregister could be in
progress without changing the media devnode status to unregistered.

process 1 process 2
fd = open(/dev/media0)
media_devnode_is_registered()
(returns true here)

media_device_unregister()
(unregister is in progress
and devnode isn't
unregistered yet)
...
ioctl(fd, ...)
__media_ioctl()
media_devnode_is_registered()
(returns true here)
...
media_devnode_unregister()
...
(driver releases the media device
memory)

media_device_ioctl()
(By this point
devnode->media_dev does not
point to allocated memory.
use-after free in in mutex_lock_nested)

BUG: KASAN: use-after-free in mutex_lock_nested+0x79c/0x800 at addr
ffff8801ebe914f0

Fix it by clearing register bit when unregister starts to avoid the race.

process 1                               process 2
fd = open(/dev/media0)
media_devnode_is_registered()
        (could return true here)

                                        media_device_unregister()
                                                (clear the register bit,
 then start unregister.)
                                        ...
ioctl(fd, ...)
__media_ioctl()
media_devnode_is_registered()
        (return false here, ioctl
 returns I/O error, and
 will not access media
 device memory)
                                        ...
                                        media_devnode_unregister()
                                        ...
                                        (driver releases the media device
 memory)

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Suggested-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reported-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Tested-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
[bwh: Backported to 3.16: adjut filename, context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/media/media-device.c
drivers/media/media-devnode.c
include/media/media-devnode.h