media-device: dynamically allocate struct media_devnode
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>
Wed, 27 Apr 2016 22:28:26 +0000 (19:28 -0300)
committerBen Hutchings <ben@decadent.org.uk>
Tue, 28 Apr 2020 18:03:50 +0000 (19:03 +0100)
commita682f7a2f662e4e997a94c2e130ae42cd16b1da3
tree301c4918d1540827be401394bafa205f0bb73dca
parentc49a8aea912ca8b7cb5a2c2e3c0ae3674948533c
media-device: dynamically allocate struct media_devnode

commit a087ce704b802becbb4b0f2a20f2cb3f6911802e upstream.

struct media_devnode is currently embedded at struct media_device.

While this works fine during normal usage, it leads to a race
condition during devnode unregister. the problem is that drivers
assume that, after calling media_device_unregister(), the struct
that contains media_device can be freed. This is not true, as it
can't be freed until userspace closes all opened /dev/media devnodes.

In other words, if the media devnode is still open, and media_device
gets freed, any call to an ioctl will make the core to try to access
struct media_device, with will cause an use-after-free and even GPF.

Fix this by dynamically allocating the struct media_devnode and only
freeing it when it is safe.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
[bwh: Backported to 3.16:
 - Drop change in au0828
 - Include <linux/slab.h> in media-device.c
 - Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/media/media-device.c
drivers/media/media-devnode.c
drivers/media/usb/uvc/uvc_driver.c
include/media/media-device.h
include/media/media-devnode.h