[PATCH v3 3/3] driver core: Disable driver overriding by default
From: Uwe Kleine-König
Date: Mon Sep 28 2026 - 13:02:44 EST
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 <u.kleine-koenig@xxxxxxxxxxxx>
---
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