summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/gspca.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-11-18 19:52:31 +0100
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-11-24 15:01:23 +0100
commit5c4fa002b1c7b40f65fa911ae17a823ec9e26ab2 (patch)
treede334f5d2dcdb93fff14584957ed820f9fe57208 /drivers/media/video/gspca/gspca.c
parentV4L/DVB (9689): gspca: Memory leak when disconnect while streaming. (diff)
downloadlinux-5c4fa002b1c7b40f65fa911ae17a823ec9e26ab2.tar.xz
linux-5c4fa002b1c7b40f65fa911ae17a823ec9e26ab2.zip
V4L/DVB (9690): gspca: Lock the subdrivers via module_get/put.
The previous subdriver protection against rmmod was done via the file operations table in the device descriptor. On device disconnection while streaming, the device structure was freed at close time, and the module_put still used the module name in the freed area. Now, explicit module get/put are done on open and close. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
-rw-r--r--drivers/media/video/gspca/gspca.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index f28d2f4aceac..a565f3764837 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -874,6 +874,13 @@ static int dev_open(struct inode *inode, struct file *file)
ret = -EBUSY;
goto out;
}
+
+ /* protect the subdriver against rmmod */
+ if (!try_module_get(gspca_dev->module)) {
+ ret = -ENODEV;
+ goto out;
+ }
+
gspca_dev->users++;
/* one more user */
@@ -920,6 +927,7 @@ static int dev_close(struct inode *inode, struct file *file)
gspca_dev->memory = GSPCA_MEMORY_NO;
}
file->private_data = NULL;
+ module_put(gspca_dev->module);
mutex_unlock(&gspca_dev->queue_lock);
PDEBUG(D_STREAM, "close done");
@@ -1870,9 +1878,8 @@ int gspca_dev_probe(struct usb_interface *intf,
/* init video stuff */
memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
gspca_dev->vdev.parent = &dev->dev;
- memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops);
- gspca_dev->vdev.fops = &gspca_dev->fops;
- gspca_dev->fops.owner = module; /* module protection */
+ gspca_dev->vdev.fops = &dev_fops;
+ gspca_dev->module = module;
gspca_dev->present = 1;
ret = video_register_device(&gspca_dev->vdev,
VFL_TYPE_GRABBER,