未验证 提交 665cd1e9 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!1486 [sync] PR-1452: media: dvb-core: Fix use-after-free due on race condition at dvb_net

Merge Pull Request from: @openeuler-sync-bot 
 

Origin pull request: 
https://gitee.com/openeuler/kernel/pulls/1452 
 
PR sync from: Cai Xinchen <caixinchen1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/KJPESWCJSTJOGG5KSTHLYL5PSDOGTFWW/ 
 
https://gitee.com/src-openeuler/kernel/issues/I635JD 
 
Link:https://gitee.com/openeuler/kernel/pulls/1486 

Reviewed-by: Jialin Zhang <zhangjialin11@huawei.com> 
Signed-off-by: Jialin Zhang <zhangjialin11@huawei.com> 
......@@ -1564,15 +1564,43 @@ static long dvb_net_ioctl(struct file *file,
return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl);
}
static int locked_dvb_net_open(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev = file->private_data;
struct dvb_net *dvbnet = dvbdev->priv;
int ret;
if (mutex_lock_interruptible(&dvbnet->remove_mutex))
return -ERESTARTSYS;
if (dvbnet->exit) {
mutex_unlock(&dvbnet->remove_mutex);
return -ENODEV;
}
ret = dvb_generic_open(inode, file);
mutex_unlock(&dvbnet->remove_mutex);
return ret;
}
static int dvb_net_close(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev = file->private_data;
struct dvb_net *dvbnet = dvbdev->priv;
mutex_lock(&dvbnet->remove_mutex);
dvb_generic_release(inode, file);
if(dvbdev->users == 1 && dvbnet->exit == 1)
if (dvbdev->users == 1 && dvbnet->exit == 1) {
mutex_unlock(&dvbnet->remove_mutex);
wake_up(&dvbdev->wait_queue);
} else {
mutex_unlock(&dvbnet->remove_mutex);
}
return 0;
}
......@@ -1580,7 +1608,7 @@ static int dvb_net_close(struct inode *inode, struct file *file)
static const struct file_operations dvb_net_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = dvb_net_ioctl,
.open = dvb_generic_open,
.open = locked_dvb_net_open,
.release = dvb_net_close,
.llseek = noop_llseek,
};
......@@ -1599,10 +1627,13 @@ void dvb_net_release (struct dvb_net *dvbnet)
{
int i;
mutex_lock(&dvbnet->remove_mutex);
dvbnet->exit = 1;
mutex_unlock(&dvbnet->remove_mutex);
if (dvbnet->dvbdev->users < 1)
wait_event(dvbnet->dvbdev->wait_queue,
dvbnet->dvbdev->users==1);
dvbnet->dvbdev->users == 1);
dvb_unregister_device(dvbnet->dvbdev);
......@@ -1621,6 +1652,7 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
int i;
mutex_init(&dvbnet->ioctl_mutex);
mutex_init(&dvbnet->remove_mutex);
dvbnet->demux = dmx;
for (i=0; i<DVB_NET_DEVICES_MAX; i++)
......
......@@ -41,6 +41,9 @@
* @exit: flag to indicate when the device is being removed.
* @demux: pointer to &struct dmx_demux.
* @ioctl_mutex: protect access to this struct.
* @remove_mutex: mutex that avoids a race condition between a callback
* called when the hardware is disconnected and the
* file_operations of dvb_net.
*
* Currently, the core supports up to %DVB_NET_DEVICES_MAX (10) network
* devices.
......@@ -53,6 +56,7 @@ struct dvb_net {
unsigned int exit:1;
struct dmx_demux *demux;
struct mutex ioctl_mutex;
struct mutex remove_mutex;
};
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册