mirror of https://gitee.com/openkylin/linux.git
V4L/DVB (5244): Dvbdev: fix illegal re-usage of fileoperations struct
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: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
e1af498063
commit
b619010247
|
@ -199,12 +199,14 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
||||||
const struct dvb_device *template, void *priv, int type)
|
const struct dvb_device *template, void *priv, int type)
|
||||||
{
|
{
|
||||||
struct dvb_device *dvbdev;
|
struct dvb_device *dvbdev;
|
||||||
|
struct file_operations *dvbdevfops;
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
if (mutex_lock_interruptible(&dvbdev_register_lock))
|
if (mutex_lock_interruptible(&dvbdev_register_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
if ((id = dvbdev_get_free_id (adap, type)) < 0) {
|
if ((id = dvbdev_get_free_id (adap, type)) < 0){
|
||||||
mutex_unlock(&dvbdev_register_lock);
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
*pdvbdev = NULL;
|
*pdvbdev = NULL;
|
||||||
printk ("%s: could get find free device id...\n", __FUNCTION__);
|
printk ("%s: could get find free device id...\n", __FUNCTION__);
|
||||||
|
@ -213,7 +215,15 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
||||||
|
|
||||||
*pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL);
|
*pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL);
|
||||||
|
|
||||||
if (!dvbdev) {
|
if (!dvbdev){
|
||||||
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!dvbdevfops){
|
||||||
|
kfree (dvbdev);
|
||||||
mutex_unlock(&dvbdev_register_lock);
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -223,7 +233,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
||||||
dvbdev->id = id;
|
dvbdev->id = id;
|
||||||
dvbdev->adapter = adap;
|
dvbdev->adapter = adap;
|
||||||
dvbdev->priv = priv;
|
dvbdev->priv = priv;
|
||||||
|
dvbdev->fops = dvbdevfops;
|
||||||
|
|
||||||
|
memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
|
||||||
dvbdev->fops->owner = adap->module;
|
dvbdev->fops->owner = adap->module;
|
||||||
|
|
||||||
list_add_tail (&dvbdev->list_head, &adap->device_list);
|
list_add_tail (&dvbdev->list_head, &adap->device_list);
|
||||||
|
@ -251,6 +263,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
|
||||||
dvbdev->type, dvbdev->id)));
|
dvbdev->type, dvbdev->id)));
|
||||||
|
|
||||||
list_del (&dvbdev->list_head);
|
list_del (&dvbdev->list_head);
|
||||||
|
kfree (dvbdev->fops);
|
||||||
kfree (dvbdev);
|
kfree (dvbdev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_unregister_device);
|
EXPORT_SYMBOL(dvb_unregister_device);
|
||||||
|
|
Loading…
Reference in New Issue