From: Zhipeng Lu alexious@zju.edu.cn
mainline inclusion from mainline-v6.9-rc1 commit 8c64f4cdf4e6cc5682c52523713af8c39c94e6d5 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9L9MA CVE: CVE-2024-27043
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
------------------------------------------------------
In dvb_register_device, *pdvbdev is set equal to dvbdev, which is freed in several error-handling paths. However, *pdvbdev is not set to NULL after dvbdev's deallocation, causing use-after-frees in many places, for example, in the following call chain:
budget_register |-> dvb_dmxdev_init |-> dvb_register_device |-> dvb_dmxdev_release |-> dvb_unregister_device |-> dvb_remove_device |-> dvb_device_put |-> kref_put
When calling dvb_unregister_device, dmxdev->dvbdev (i.e. *pdvbdev in dvb_register_device) could point to memory that had been freed in dvb_register_device. Thereafter, this pointer is transferred to kref_put and triggering a use-after-free.
Link: https://lore.kernel.org/linux-media/20240203134046.3120099-1-alexious@zju.ed... Fixes: b61901024776 ("V4L/DVB (5244): Dvbdev: fix illegal re-usage of fileoperations struct") Signed-off-by: Zhipeng Lu alexious@zju.edu.cn Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: liwei liwei728@huawei.com --- drivers/media/dvb-core/dvbdev.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 2ff8a1b776fb..467be48b9004 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -502,6 +502,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL); if (!dvbdevfops) { kfree(dvbdev); + *pdvbdev = NULL; mutex_unlock(&dvbdev_register_lock); return -ENOMEM; } @@ -510,6 +511,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, if (!new_node) { kfree(dvbdevfops); kfree(dvbdev); + *pdvbdev = NULL; mutex_unlock(&dvbdev_register_lock); return -ENOMEM; } @@ -543,6 +545,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, } list_del (&dvbdev->list_head); kfree(dvbdev); + *pdvbdev = NULL; up_write(&minor_rwsem); mutex_unlock(&dvbdev_register_lock); return -EINVAL; @@ -565,6 +568,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvb_media_device_free(dvbdev); list_del (&dvbdev->list_head); kfree(dvbdev); + *pdvbdev = NULL; mutex_unlock(&dvbdev_register_lock); return ret; } @@ -583,6 +587,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvb_media_device_free(dvbdev); list_del (&dvbdev->list_head); kfree(dvbdev); + *pdvbdev = NULL; mutex_unlock(&dvbdev_register_lock); return PTR_ERR(clsdev); }
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/7013 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/R...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/7013 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/R...