aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMarcel Siegert <mws@linuxtv.org>2007-02-13 07:46:55 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-02-21 10:35:31 -0500
commitb61901024776b25ce7b8edc31bb1757c7382a88e (patch)
treebebf31ba4a8cc2a121ca21b39e44cddb2ba7bfd6 /drivers
parente1af498063007cee5d7ec5af1e0cf25c088d05c7 (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 826b47f155a0..490337b5ee3e 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -199,12 +199,14 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
199 const struct dvb_device *template, void *priv, int type) 199 const struct dvb_device *template, void *priv, int type)
200{ 200{
201 struct dvb_device *dvbdev; 201 struct dvb_device *dvbdev;
202 struct file_operations *dvbdevfops;
203
202 int id; 204 int id;
203 205
204 if (mutex_lock_interruptible(&dvbdev_register_lock)) 206 if (mutex_lock_interruptible(&dvbdev_register_lock))
205 return -ERESTARTSYS; 207 return -ERESTARTSYS;
206 208
207 if ((id = dvbdev_get_free_id (adap, type)) < 0) { 209 if ((id = dvbdev_get_free_id (adap, type)) < 0){
208 mutex_unlock(&dvbdev_register_lock); 210 mutex_unlock(&dvbdev_register_lock);
209 *pdvbdev = NULL; 211 *pdvbdev = NULL;
210 printk ("%s: could get find free device id...\n", __FUNCTION__); 212 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,
213 215
214 *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL); 216 *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL);
215 217
216 if (!dvbdev) { 218 if (!dvbdev){
219 mutex_unlock(&dvbdev_register_lock);
220 return -ENOMEM;
221 }
222
223 dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
224
225 if (!dvbdevfops){
226 kfree (dvbdev);
217 mutex_unlock(&dvbdev_register_lock); 227 mutex_unlock(&dvbdev_register_lock);
218 return -ENOMEM; 228 return -ENOMEM;
219 } 229 }
@@ -223,7 +233,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
223 dvbdev->id = id; 233 dvbdev->id = id;
224 dvbdev->adapter = adap; 234 dvbdev->adapter = adap;
225 dvbdev->priv = priv; 235 dvbdev->priv = priv;
236 dvbdev->fops = dvbdevfops;
226 237
238 memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
227 dvbdev->fops->owner = adap->module; 239 dvbdev->fops->owner = adap->module;
228 240
229 list_add_tail (&dvbdev->list_head, &adap->device_list); 241 list_add_tail (&dvbdev->list_head, &adap->device_list);
@@ -251,6 +263,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
251 dvbdev->type, dvbdev->id))); 263 dvbdev->type, dvbdev->id)));
252 264
253 list_del (&dvbdev->list_head); 265 list_del (&dvbdev->list_head);
266 kfree (dvbdev->fops);
254 kfree (dvbdev); 267 kfree (dvbdev);
255} 268}
256EXPORT_SYMBOL(dvb_unregister_device); 269EXPORT_SYMBOL(dvb_unregister_device);