media fixes for v6.4-rc7

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAmSK8uAACgkQCF8+vY7k
 4RWCbQ/9E9Va+mCFiujL6P+ttDy8nIPwxrwohh3hhJatoMmWFGW1JYBcNhByIHKM
 Cz9yaSnEuIeoHvvlj+G62cl4XZt6pw9h68FNSnt+i4Jti2I7qydgKWuEoep6OdgO
 FkHlcvJhsWnARD4uBtZb+kiimr9PSZljUYFyZYlnN1ehG9UbVRS/gVR5LBjIcepe
 1b/KTiD01dKHII+WLmxf15gZnkxmfQsXIRuqih7o1nlSGCGlf7YVv1nh4Tg+VDkN
 IlyRPHwRP14L719pmUUfFIrtAyzgCnbCRdkwRDqK9USFiFthvmbKO7bUjlrRjtJR
 2ZtM3xPT4knnEjiHOhbhct+um6yEATL9TkEJCO6WqYlyXJ5SN0Hkon7fb6/+Avcy
 U5xPm367uzjcyjWUYjjhflT9qdoiBMy/heqfm9+fCr4rkVubTo/B3XX8w+WAIOC6
 zNLqa9IvBFAYVfDsVXBL+rrzYqubPRBVmsQdMts0C8LpCXW2SQDnyeGl26VPw8Bl
 nwVQI0Tf9n8Vpcm7wIhgX038tCCDiRoC72ArPUoGOs2+fYAvmNqZep0yzOTEyFwk
 m3QlnoqSl4d7Lt9tYUUxr1e6u7h5JuQvHF0U6BCub9CQt4trj8EFpQb8FI5v8PfX
 EHL3acMRIN0fwHwE2OAoIfjaKr2mc+4B8hRPFSX3PCmJxYy8WH8=
 =+TC4
 -----END PGP SIGNATURE-----

Merge tag 'media/v6.4-6' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media fixes from Mauro Carvalho Chehab:
 "A fix for dvb-core to avoid a race condition during DVB board
  registration"

* tag 'media/v6.4-6' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  Revert "media: dvb-core: Fix use-after-free on race condition at dvb_frontend"
This commit is contained in:
Linus Torvalds 2023-06-15 19:13:45 -07:00
commit c926a55f65
2 changed files with 10 additions and 49 deletions

View file

@ -817,26 +817,15 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s:\n", __func__);
mutex_lock(&fe->remove_mutex);
if (fe->exit != DVB_FE_DEVICE_REMOVED)
fe->exit = DVB_FE_NORMAL_EXIT;
mb();
if (!fepriv->thread) {
mutex_unlock(&fe->remove_mutex);
if (!fepriv->thread)
return;
}
kthread_stop(fepriv->thread);
mutex_unlock(&fe->remove_mutex);
if (fepriv->dvbdev->users < -1) {
wait_event(fepriv->dvbdev->wait_queue,
fepriv->dvbdev->users == -1);
}
sema_init(&fepriv->sem, 1);
fepriv->state = FESTATE_IDLE;
@ -2780,13 +2769,9 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
struct dvb_adapter *adapter = fe->dvb;
int ret;
mutex_lock(&fe->remove_mutex);
dev_dbg(fe->dvb->device, "%s:\n", __func__);
if (fe->exit == DVB_FE_DEVICE_REMOVED) {
ret = -ENODEV;
goto err_remove_mutex;
}
if (fe->exit == DVB_FE_DEVICE_REMOVED)
return -ENODEV;
if (adapter->mfe_shared == 2) {
mutex_lock(&adapter->mfe_lock);
@ -2794,8 +2779,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
if (adapter->mfe_dvbdev &&
!adapter->mfe_dvbdev->writers) {
mutex_unlock(&adapter->mfe_lock);
ret = -EBUSY;
goto err_remove_mutex;
return -EBUSY;
}
adapter->mfe_dvbdev = dvbdev;
}
@ -2818,10 +2802,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
while (mferetry-- && (mfedev->users != -1 ||
mfepriv->thread)) {
if (msleep_interruptible(500)) {
if (signal_pending(current)) {
ret = -EINTR;
goto err_remove_mutex;
}
if (signal_pending(current))
return -EINTR;
}
}
@ -2833,8 +2815,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
if (mfedev->users != -1 ||
mfepriv->thread) {
mutex_unlock(&adapter->mfe_lock);
ret = -EBUSY;
goto err_remove_mutex;
return -EBUSY;
}
adapter->mfe_dvbdev = dvbdev;
}
@ -2893,8 +2874,6 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
if (adapter->mfe_shared)
mutex_unlock(&adapter->mfe_lock);
mutex_unlock(&fe->remove_mutex);
return ret;
err3:
@ -2916,9 +2895,6 @@ err1:
err0:
if (adapter->mfe_shared)
mutex_unlock(&adapter->mfe_lock);
err_remove_mutex:
mutex_unlock(&fe->remove_mutex);
return ret;
}
@ -2929,8 +2905,6 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
struct dvb_frontend_private *fepriv = fe->frontend_priv;
int ret;
mutex_lock(&fe->remove_mutex);
dev_dbg(fe->dvb->device, "%s:\n", __func__);
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
@ -2952,18 +2926,10 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
}
mutex_unlock(&fe->dvb->mdev_lock);
#endif
if (fe->exit != DVB_FE_NO_EXIT)
wake_up(&dvbdev->wait_queue);
if (fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl(fe, 0);
if (fe->exit != DVB_FE_NO_EXIT) {
mutex_unlock(&fe->remove_mutex);
wake_up(&dvbdev->wait_queue);
} else {
mutex_unlock(&fe->remove_mutex);
}
} else {
mutex_unlock(&fe->remove_mutex);
}
dvb_frontend_put(fe);
@ -3064,7 +3030,6 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
fepriv = fe->frontend_priv;
kref_init(&fe->refcount);
mutex_init(&fe->remove_mutex);
/*
* After initialization, there need to be two references: one

View file

@ -686,10 +686,7 @@ struct dtv_frontend_properties {
* @id: Frontend ID
* @exit: Used to inform the DVB core that the frontend
* thread should exit (usually, means that the hardware
* got disconnected).
* @remove_mutex: mutex that avoids a race condition between a callback
* called when the hardware is disconnected and the
* file_operations of dvb_frontend.
* got disconnected.
*/
struct dvb_frontend {
@ -707,7 +704,6 @@ struct dvb_frontend {
int (*callback)(void *adapter_priv, int component, int cmd, int arg);
int id;
unsigned int exit;
struct mutex remove_mutex;
};
/**