Thread (17 messages) 17 messages, 4 authors, 21d ago

[PATCH v3 3/3] driver core: Disable driver overriding by default

flat view
COLD21d

From: Uwe Kleine-König <hidden>
Date: 2026-09-28 16:46:22
Also in: driver-core, lkml
Subsystem: driver core, kobjects, debugfs and sysfs, the rest · Maintainers: Greg Kroah-Hartman, "Rafael J. Wysocki", Danilo Krummrich, Linus Torvalds

Driver overriding is useful only in a very limited set of situations
and then only with very few drivers that are designed to support that.

Disallow matching via driver_override unless the driver explicitly
allows it or the safe guard is disabled using the
"allow_driver_override" kernel parameter.

Implementation detail: device_match_driver_override() isn't a static
inline any more. It grew a certain complexity (e.g. a pr_info()) and so
was made a regular exported function.

Signed-off-by: Uwe Kleine-König <redacted>
---
 drivers/base/bus.c            | 43 +++++++++++++++++++++++++++++++++++
 include/linux/device.h        | 26 ++-------------------
 include/linux/device/driver.h |  2 ++
 3 files changed, 47 insertions(+), 24 deletions(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index c51ad96d4de4..d294c198ab0c 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -606,6 +606,49 @@ int bus_add_device(struct device *dev)
 	return error;
 }
 
+static int __read_mostly allow_driver_override;
+
+static int __init allow_driver_override_setup(char *str)
+{
+	allow_driver_override = 1;
+
+	return 1;
+}
+__setup("allow_driver_override", allow_driver_override_setup);
+
+/**
+ * device_match_driver_override() - Match a driver against the device's driver_override.
+ * @dev: device to check
+ * @drv: driver to match against
+ *
+ * Returns > 0 if a driver override is set and matches the given driver, 0 if a
+ * driver override is set but does not match, or < 0 if a driver override is not
+ * set at all.
+ */
+int device_match_driver_override(struct device *dev,
+				 const struct device_driver *drv)
+{
+	guard(spinlock)(&dev->driver_override.lock);
+	if (dev->driver_override.name) {
+		int ret = !strcmp(dev->driver_override.name, drv->name);
+
+		if (ret > 0) {
+			if (!allow_driver_override && !drv->support_driver_override) {
+				pr_info("Suppress driver override binding. Allow %ps to do overriding or boot with allow_driver_override on cmdline\n",
+					drv);
+				return -1;
+			}
+
+			add_taint_module(drv->owner,
+					 TAINT_DRIVER_OVERRIDE, LOCKDEP_STILL_OK);
+		}
+
+		return ret;
+	}
+	return -1;
+}
+EXPORT_SYMBOL_GPL(device_match_driver_override);
+
 /**
  * bus_probe_device - probe drivers for a new device
  * @dev: device to probe
diff --git a/include/linux/device.h b/include/linux/device.h
index 4dac5e09b74c..a142bf384f1e 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -892,30 +892,8 @@ static inline bool device_has_driver_override(struct device *dev)
 	return !!dev->driver_override.name;
 }
 
-/**
- * device_match_driver_override() - Match a driver against the device's driver_override.
- * @dev: device to check
- * @drv: driver to match against
- *
- * Returns > 0 if a driver override is set and matches the given driver, 0 if a
- * driver override is set but does not match, or < 0 if a driver override is not
- * set at all.
- */
-static inline int device_match_driver_override(struct device *dev,
-					       const struct device_driver *drv)
-{
-	guard(spinlock)(&dev->driver_override.lock);
-	if (dev->driver_override.name) {
-		int ret = !strcmp(dev->driver_override.name, drv->name);
-
-		if (ret > 0)
-			add_taint_module(drv->owner,
-					 TAINT_DRIVER_OVERRIDE, LOCKDEP_STILL_OK);
-
-		return ret;
-	}
-	return -1;
-}
+int device_match_driver_override(struct device *dev,
+				 const struct device_driver *drv);
 
 /**
  * device_iommu_mapped - Returns true when the device DMA is translated
diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h
index 29fbc01ef06f..0153cfcbe1b9 100644
--- a/include/linux/device/driver.h
+++ b/include/linux/device/driver.h
@@ -56,6 +56,7 @@ enum probe_type {
  * @bus:	The bus which the device of this driver belongs to.
  * @owner:	The module owner.
  * @mod_name:	Used for built-in modules.
+ * @support_driver_override: driver_override only works if this is true.
  * @suppress_bind_attrs: Disables bind/unbind via sysfs.
  * @probe_type:	Type of the probe (synchronous or asynchronous) to use.
  * @of_match_table: The open firmware table.
@@ -104,6 +105,7 @@ struct device_driver {
 	struct module		*owner;
 	const char		*mod_name;	/* used for built-in modules */
 
+	bool support_driver_override;
 	bool suppress_bind_attrs;	/* disables bind/unbind via sysfs */
 	enum probe_type probe_type;
 
-- 
2.47.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help