diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-01-08 23:28:09 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-01-08 23:28:09 -0200 |
commit | fb1a0811d58fdbf564fa22b7fb268969c40af175 (patch) | |
tree | e437b71c61b1ef34b83aac12cd5868005337e51c /linux/drivers/media/dvb | |
parent | 783abc8c719e55654e22610d4ec128db8d576ba8 (diff) | |
download | mediapointer-dvb-s2-fb1a0811d58fdbf564fa22b7fb268969c40af175.tar.gz mediapointer-dvb-s2-fb1a0811d58fdbf564fa22b7fb268969c40af175.tar.bz2 |
backport changeset f41ced8f108cc80f16509b907cd7ac93944459bc
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Author: Laurent Pinchart <laurent.pinchart@skynet.be>
Check fops_get() return value
Several subsystem open handlers dereference the fops_get() return value
without checking it for nullness. This opens a race condition between the
open handler and module unloading.
A module can be marked as being unloaded (MODULE_STATE_GOING) before its
exit function is called and gets the chance to unregister the driver.
During that window open handlers can still be called, and fops_get() will
fail in try_module_get() and return a NULL pointer.
This change checks the fops_get() return value and returns -ENODEV if NULL.
kernel-sync:
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvbdev.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 4267b2b87..940114768 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -84,6 +84,10 @@ static int dvb_device_open(struct inode *inode, struct file *file) file->private_data = dvbdev; old_fops = file->f_op; file->f_op = fops_get(dvbdev->fops); + if (file->f_op == NULL) { + file->f_op = old_fops; + goto fail; + } if(file->f_op->open) err = file->f_op->open(inode,file); if (err) { @@ -95,6 +99,7 @@ static int dvb_device_open(struct inode *inode, struct file *file) unlock_kernel(); return err; } +fail: up_read(&minor_rwsem); unlock_kernel(); return -ENODEV; |