diff options
author | Lin Ma <linma@zju.edu.cn> | 2022-08-07 17:59:52 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-12-31 15:33:03 +0300 |
commit | 9945d05d6693710574f354c5dbddc47f5101eb77 (patch) | |
tree | c0399fc32964f22814d3b88c11d68e8776639280 /include/media | |
parent | 669fb90507dbaf419aa3871bf73160e93d50487f (diff) | |
download | linux-9945d05d6693710574f354c5dbddc47f5101eb77.tar.xz |
media: dvbdev: adopts refcnt to avoid UAF
[ Upstream commit 0fc044b2b5e2d05a1fa1fb0d7f270367a7855d79 ]
dvb_unregister_device() is known that prone to use-after-free.
That is, the cleanup from dvb_unregister_device() releases the dvb_device
even if there are pointers stored in file->private_data still refer to it.
This patch adds a reference counter into struct dvb_device and delays its
deallocation until no pointer refers to the object.
Link: https://lore.kernel.org/linux-media/20220807145952.10368-1-linma@zju.edu.cn
Signed-off-by: Lin Ma <linma@zju.edu.cn>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include/media')
-rw-r--r-- | include/media/dvbdev.h | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/include/media/dvbdev.h b/include/media/dvbdev.h index 2f6b0861322a..149b3d33c24b 100644 --- a/include/media/dvbdev.h +++ b/include/media/dvbdev.h @@ -156,6 +156,7 @@ struct dvb_adapter { */ struct dvb_device { struct list_head list_head; + struct kref ref; const struct file_operations *fops; struct dvb_adapter *adapter; enum dvb_device_type type; @@ -188,6 +189,20 @@ struct dvb_device { }; /** + * dvb_device_get - Increase dvb_device reference + * + * @dvbdev: pointer to struct dvb_device + */ +struct dvb_device *dvb_device_get(struct dvb_device *dvbdev); + +/** + * dvb_device_get - Decrease dvb_device reference + * + * @dvbdev: pointer to struct dvb_device + */ +void dvb_device_put(struct dvb_device *dvbdev); + +/** * dvb_register_adapter - Registers a new DVB adapter * * @adap: pointer to struct dvb_adapter @@ -231,29 +246,17 @@ int dvb_register_device(struct dvb_adapter *adap, /** * dvb_remove_device - Remove a registered DVB device * - * This does not free memory. To do that, call dvb_free_device(). + * This does not free memory. dvb_free_device() will do that when + * reference counter is empty * * @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 * - * 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 */ void dvb_unregister_device(struct dvb_device *dvbdev); |