]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
V4L/DVB: Dvbdev: fix illegal re-usage of fileoperations struct
authorMarcel Siegert <mws@linuxtv.org>
Sun, 25 Feb 2007 23:38:10 +0000 (00:38 +0100)
committerAdrian Bunk <bunk@stusta.de>
Sun, 25 Feb 2007 23:38:10 +0000 (00:38 +0100)
Arjan van de Ven <arjan@infradead.org> reported an illegal re-usage of
the fileoperations struct if more than one dvb device (e.g. frontend) is
present.

This patch fixes this issue.

It allocates a new fileoperations struct each time a device is
registered and copies the default template fileops.

Signed-off-by: Marcel Siegert <mws@linuxtv.org>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
drivers/media/dvb/dvb-core/dvbdev.c

index 54f8b95717b0fd7740dcb7a4bcacd4fff80d869c..cb622bbf655d73f916c6abd17deebdba4501eaf6 100644 (file)
@@ -200,6 +200,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
                        const struct dvb_device *template, void *priv, int type)
 {
        struct dvb_device *dvbdev;
+       struct file_operations *dvbdevfops;
+
        int id;
 
        if (mutex_lock_interruptible(&dvbdev_register_lock))
@@ -221,12 +223,22 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 
        mutex_unlock(&dvbdev_register_lock);
 
+       dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
+
+       if (!dvbdevfops) {
+               kfree (dvbdev);
+               mutex_unlock(&dvbdev_register_lock);
+               return -ENOMEM;
+       }
+
        memcpy(dvbdev, template, sizeof(struct dvb_device));
        dvbdev->type = type;
        dvbdev->id = id;
        dvbdev->adapter = adap;
        dvbdev->priv = priv;
+       dvbdev->fops = dvbdevfops;
 
+       memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
        dvbdev->fops->owner = adap->module;
 
        list_add_tail (&dvbdev->list_head, &adap->device_list);
@@ -259,6 +271,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
                                        dvbdev->type, dvbdev->id)));
 
        list_del (&dvbdev->list_head);
+       kfree (dvbdev->fops);
        kfree (dvbdev);
 }
 EXPORT_SYMBOL(dvb_unregister_device);