Commit 1f4ed6cd authored by Max Kellermann's avatar Max Kellermann Committed by Mauro Carvalho Chehab

[media] dvbdev: split dvb_unregister_device()

dvb_unregister_device() has a major problem: it combines unregistering
with memory disposal.  Sometimes, it is necessary to unregister a
device, but no memory can be freed yet, because a process still has a
(stale) file handle.  Therefore, we need to split
dvb_unregister_device().  This will allow sanitizing a few callers.

With my new design, dvb_unregister_device() appears misnamed, but to
reduce patch noise, I'm not renaming it just yet.
Signed-off-by: default avatarMax Kellermann <max.kellermann@gmail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent bd336e63
...@@ -528,7 +528,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, ...@@ -528,7 +528,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
EXPORT_SYMBOL(dvb_register_device); EXPORT_SYMBOL(dvb_register_device);
void dvb_unregister_device(struct dvb_device *dvbdev) void dvb_remove_device(struct dvb_device *dvbdev)
{ {
if (!dvbdev) if (!dvbdev)
return; return;
...@@ -542,9 +542,26 @@ void dvb_unregister_device(struct dvb_device *dvbdev) ...@@ -542,9 +542,26 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
list_del (&dvbdev->list_head); list_del (&dvbdev->list_head);
}
EXPORT_SYMBOL(dvb_remove_device);
void dvb_free_device(struct dvb_device *dvbdev)
{
if (!dvbdev)
return;
kfree (dvbdev->fops); kfree (dvbdev->fops);
kfree (dvbdev); kfree (dvbdev);
} }
EXPORT_SYMBOL(dvb_free_device);
void dvb_unregister_device(struct dvb_device *dvbdev)
{
dvb_remove_device(dvbdev);
dvb_free_device(dvbdev);
}
EXPORT_SYMBOL(dvb_unregister_device); EXPORT_SYMBOL(dvb_unregister_device);
......
...@@ -211,9 +211,32 @@ int dvb_register_device(struct dvb_adapter *adap, ...@@ -211,9 +211,32 @@ int dvb_register_device(struct dvb_adapter *adap,
int type, int type,
int demux_sink_pads); int demux_sink_pads);
/**
* dvb_remove_device - Remove a registered DVB device
*
* This does not free memory. To do that, call dvb_free_device().
*
* @dvbdev: pointer to struct dvb_device
*/
void dvb_remove_device(struct dvb_device *dvbdev);
/**
* dvb_free_device - Free memory occupied by a DVB device.
*
* Call dvb_unregister_device() before calling this function.
*
* @dvbdev: pointer to struct dvb_device
*/
void dvb_free_device(struct dvb_device *dvbdev);
/** /**
* dvb_unregister_device - Unregisters a DVB device * dvb_unregister_device - Unregisters a DVB device
* *
* This is a combination of dvb_remove_device() and dvb_free_device().
* Using this function is usually a mistake, and is often an indicator
* for a use-after-free bug (when a userspace process keeps a file
* handle to a detached device).
*
* @dvbdev: pointer to struct dvb_device * @dvbdev: pointer to struct dvb_device
*/ */
void dvb_unregister_device(struct dvb_device *dvbdev); void dvb_unregister_device(struct dvb_device *dvbdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment