Blob Blame History Raw
From: Takashi Iwai <tiwai@suse.de>
Subject: media: dvb_frontend: kABI workaround
Patch-mainline: Never, kABI workaround
References: CVE-2022-45885 bsc#1205758

For keeping the kABI workaround, the newly introduced remove_mutex
of dvb_frontend to be a global one.  It's not urgent for performance,
so we can live with that.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/media/dvb-core/dvb_frontend.c |   23 ++++++++++++-----------
 include/media/dvb_frontend.h          |    4 ----
 2 files changed, 12 insertions(+), 15 deletions(-)

--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -90,6 +90,8 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wai
 
 static DEFINE_MUTEX(frontend_mutex);
 
+static DEFINE_MUTEX(remove_mutex);
+
 struct dvb_frontend_private {
 	/* thread/frontend values */
 	struct dvb_device *dvbdev;
@@ -817,20 +819,20 @@ static void dvb_frontend_stop(struct dvb
 
 	dev_dbg(fe->dvb->device, "%s:\n", __func__);
 
-	mutex_lock(&fe->remove_mutex);
+	mutex_lock(&remove_mutex);
 
 	if (fe->exit != DVB_FE_DEVICE_REMOVED)
 		fe->exit = DVB_FE_NORMAL_EXIT;
 	mb();
 
 	if (!fepriv->thread) {
-		mutex_unlock(&fe->remove_mutex);
+		mutex_unlock(&remove_mutex);
 		return;
 	}
 
 	kthread_stop(fepriv->thread);
 
-	mutex_unlock(&fe->remove_mutex);
+	mutex_unlock(&remove_mutex);
 
 	if (fepriv->dvbdev->users < -1) {
 		wait_event(fepriv->dvbdev->wait_queue,
@@ -2772,7 +2774,7 @@ static int dvb_frontend_open(struct inod
 	struct dvb_adapter *adapter = fe->dvb;
 	int ret;
 
-	mutex_lock(&fe->remove_mutex);
+	mutex_lock(&remove_mutex);
 
 	dev_dbg(fe->dvb->device, "%s:\n", __func__);
 	if (fe->exit == DVB_FE_DEVICE_REMOVED) {
@@ -2875,7 +2877,7 @@ static int dvb_frontend_open(struct inod
 	if (adapter->mfe_shared)
 		mutex_unlock(&adapter->mfe_lock);
 
-	mutex_unlock(&fe->remove_mutex);
+	mutex_unlock(&remove_mutex);
 	return ret;
 
 err3:
@@ -2899,7 +2901,7 @@ err0:
 		mutex_unlock(&adapter->mfe_lock);
 
 err_remove_mutex:
-	mutex_unlock(&fe->remove_mutex);
+	mutex_unlock(&remove_mutex);
 	return ret;
 }
 
@@ -2910,7 +2912,7 @@ static int dvb_frontend_release(struct i
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	int ret;
 
-	mutex_lock(&fe->remove_mutex);
+	mutex_lock(&remove_mutex);
 
 	dev_dbg(fe->dvb->device, "%s:\n", __func__);
 
@@ -2937,14 +2939,14 @@ static int dvb_frontend_release(struct i
 			fe->ops.ts_bus_ctrl(fe, 0);
 
 		if (fe->exit != DVB_FE_NO_EXIT) {
-			mutex_unlock(&fe->remove_mutex);
+			mutex_unlock(&remove_mutex);
 			wake_up(&dvbdev->wait_queue);
 		} else {
-			mutex_unlock(&fe->remove_mutex);
+			mutex_unlock(&remove_mutex);
 		}
 
 	} else {
-		mutex_unlock(&fe->remove_mutex);
+		mutex_unlock(&remove_mutex);
 	}
 
 	dvb_frontend_put(fe);
@@ -3041,7 +3043,6 @@ int dvb_register_frontend(struct dvb_ada
 	fepriv = fe->frontend_priv;
 
 	kref_init(&fe->refcount);
-	mutex_init(&fe->remove_mutex);
 
 	/*
 	 * After initialization, there need to be two references: one
--- a/include/media/dvb_frontend.h
+++ b/include/media/dvb_frontend.h
@@ -681,9 +681,6 @@ struct dtv_frontend_properties {
  * @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.
  */
 
 struct dvb_frontend {
@@ -701,7 +698,6 @@ struct dvb_frontend {
 	int (*callback)(void *adapter_priv, int component, int cmd, int arg);
 	int id;
 	unsigned int exit;
-	struct mutex remove_mutex;
 };
 
 /**