media: em28xx: Fix race condition between open and init function
Subsystems (2)
RFC PATCH v2 1/1 media: em28xx: Fix race condition between open and init function
Fixes a race condition - for lack of a more precise term - between em28xx_v4l2_open and em28xx_v4l2_init, by detaching the v4l2_dev, media_pad and vdev structs from the em28xx_v4l2, and managing the lifetime of those objects more dynamicaly.
The race happens when a thread[1] - containing the em28xx_v4l2_init() code - calls the v4l2_mc_create_media_graph(), and it return a error, if a thread[2] - running v4l2_open() - pass the verification point and reaches the em28xx_v4l2_open() before the thread[1] finishes the deregistration of v4l2 subsystem, the thread[1] will free all resources before the em28xx_v4l2_open() can process their things, because the em28xx_v4l2_init() has the dev->lock. And all this lead the thread[2] to cause a user-after-free.
---
V2: Add v4l2_i2c_new_subdev null check
Deal with v4l2 subdevs dependencies
--- drivers/media/usb/em28xx/em28xx-camera.c | 4 +- drivers/media/usb/em28xx/em28xx-video.c | 298 +++++++++++++++-------- drivers/media/usb/em28xx/em28xx.h | 6 +- 3 files changed, 208 insertions(+), 100 deletions(-)
drivers/media/usb/em28xx/em28xx-camera.c +2 -2
@@ -340,7 +340,7 @@ int em28xx_init_camera(struct em28xx *dev) v4l2->sensor_xtal =4300000 ; pdata.xtal = v4l2->sensor_xtal;if (NULL == -v4l2_i2c_new_subdev_board (&v4l2->v4l2_dev, adap, +v4l2_i2c_new_subdev_board (v4l2->v4l2_dev, adap, &mt9v011_info,NULL ))return -ENODEV ; v4l2->vinmode =EM28XX_VINMODE_RGB8_GRBG ;
@@ -394,7 +394,7 @@ int em28xx_init_camera(struct em28xx *dev) v4l2->sensor_yres =480 ; subdev = -v4l2_i2c_new_subdev_board (&v4l2->v4l2_dev, adap, +v4l2_i2c_new_subdev_board (v4l2->v4l2_dev, adap, &ov2640_info,NULL );if (!subdev)return -ENODEV ;
drivers/media/usb/em28xx/em28xx-video.c +203 -95
580 lines not on this page · raw message
drivers/media/usb/em28xx/em28xx.h +3 -3
@@ -552,10 +552,10 @@ struct em28xx_v4l2 {struct kref ref;struct em28xx *dev; -struct v4l2_device v4l2_dev; +struct v4l2_device *v4l2_dev;struct v4l2_ctrl_handler ctrl_handler; -struct video_device vdev; +struct video_device *vdev;struct video_device vbi_dev;struct video_device radio_dev;
@@ -601,7 +601,7 @@ struct em28xx_v4l2 {unsigned int field_count;#ifdef CONFIG_MEDIA_CONTROLLER -struct media_pad video_pad, vbi_pad; +struct media_pad *video_pad, vbi_pad;struct media_entity *decoder;#endif };
Signature · 1 line
2.20.1
kernel test robot
build bot[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
Hi Igor,
[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on linuxtv-media/master]
[also build test ERROR on v5.12-rc7 next-20210414]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Igor-Matheus-Andrade-Torrente/media-em28xx-Fix-race-condition-between-open-and-init-function/20210415-001136 base: git://linuxtv.org/media_tree.git master config: mips-allmodconfig (attached as .config) compiler: mips-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/5ebc6ee36ab41ef33118579b1b4b8c2500041cb6
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Igor-Matheus-Andrade-Torrente/media-em28xx-Fix-race-condition-between-open-and-init-function/20210415-001136 git checkout 5ebc6ee36ab41ef33118579b1b4b8c2500041cb6
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 ARCH=mips
If you fix the issue, kindly add following tag as appropriate
All errors (new ones prefixed by >>, old ones prefixed by <<):
>> ERROR: modpost: "v4l2_i2c_subdev_unregister" [drivers/media/usb/em28xx/em28xx-v4l.ko] undefined! >> ERROR: modpost: "v4l2_spi_subdev_unregister" [drivers/media/usb/em28xx/em28xx-v4l.ko] undefined!
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org