* [PATCH v3 1/3] docs: admin-guide: Handle TAINT_FORCED_BIND when parsing /proc/sys/kernel/tainted
2026-09-28 16:46 [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Uwe Kleine-König
@ 2026-09-28 16:46 ` Uwe Kleine-König
2026-09-28 17:25 ` Bradley Morgan
2026-09-28 16:46 ` [PATCH v3 2/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Uwe Kleine-König
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Uwe Kleine-König @ 2026-09-28 16:46 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Johan Hovold, Aaron Tomlin, Bradley Morgan, Danilo Krummrich,
Thierry Reding, David Lechner, Armin Wolf, linux-kernel,
driver-core, linux-trace-kernel, Randy Dunlap
tainted-kernels.rst contains a small script to check which taint bits
are set in /proc/sys/kernel/tainted. Add one more loop iteration to also
handle the newly added TAINT_FORCED_BIND bit.
Also simplify by starting the loop at 0 and save substracting 1 for each
usage of the loop counter.
Acked-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Randy Dunlap <rdunlap@infradead.org>
Fixes: fcbfaffee51a ("driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers")
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
Documentation/admin-guide/tainted-kernels.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/tainted-kernels.rst b/Documentation/admin-guide/tainted-kernels.rst
index abbf5e3dd749..a208811ad525 100644
--- a/Documentation/admin-guide/tainted-kernels.rst
+++ b/Documentation/admin-guide/tainted-kernels.rst
@@ -74,7 +74,7 @@ a particular type of taint. It's best to leave that to the aforementioned
script, but if you need something quick you can use this shell command to check
which bits are set::
- $ for i in $(seq 20); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done
+ $ for i in $(seq 0 20); do echo $i $(($(cat /proc/sys/kernel/tainted)>>$i&1));done
Table for decoding tainted state
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
2.47.3
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 1/3] docs: admin-guide: Handle TAINT_FORCED_BIND when parsing /proc/sys/kernel/tainted
2026-09-28 16:46 ` [PATCH v3 1/3] docs: admin-guide: Handle TAINT_FORCED_BIND when parsing /proc/sys/kernel/tainted Uwe Kleine-König
@ 2026-09-28 17:25 ` Bradley Morgan
0 siblings, 0 replies; 13+ messages in thread
From: Bradley Morgan @ 2026-09-28 17:25 UTC (permalink / raw)
To: Uwe Kleine-König, Greg Kroah-Hartman
Cc: Johan Hovold, Aaron Tomlin, Danilo Krummrich, Thierry Reding,
David Lechner, Armin Wolf, linux-kernel, driver-core,
linux-trace-kernel, Randy Dunlap
On 28 September 2026 17:46:02 BST, "Uwe Kleine-König"
<u.kleine-koenig@baylibre.com> wrote:
>tainted-kernels.rst contains a small script to check which taint bits
>are set in /proc/sys/kernel/tainted. Add one more loop iteration to also
>handle the newly added TAINT_FORCED_BIND bit.
>
>Also simplify by starting the loop at 0 and save substracting 1 for each
>usage of the loop counter.
>
>Acked-by: Randy Dunlap <rdunlap@infradead.org>
>Tested-by: Randy Dunlap <rdunlap@infradead.org>
>Fixes: fcbfaffee51a ("driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers")
>Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
>---
> Documentation/admin-guide/tainted-kernels.rst | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/Documentation/admin-guide/tainted-kernels.rst b/Documentation/admin-guide/tainted-kernels.rst
>index abbf5e3dd749..a208811ad525 100644
>--- a/Documentation/admin-guide/tainted-kernels.rst
>+++ b/Documentation/admin-guide/tainted-kernels.rst
>@@ -74,7 +74,7 @@ a particular type of taint. It's best to leave that to the aforementioned
> script, but if you need something quick you can use this shell command to
> check
> which bits are set::
>
>- $ for i in $(seq 20); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done
>+ $ for i in $(seq 0 20); do echo $i $(($(cat /proc/sys/kernel/tainted)>>$i&1));done
>
> Table for decoding tainted state
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Tested-by: Bradley Morgan <brads@mainlining.org> # Power10
--- Thanks!
"I'm not a very positive person" - Linus torvalds
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 2/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
2026-09-28 16:46 [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Uwe Kleine-König
2026-09-28 16:46 ` [PATCH v3 1/3] docs: admin-guide: Handle TAINT_FORCED_BIND when parsing /proc/sys/kernel/tainted Uwe Kleine-König
@ 2026-09-28 16:46 ` Uwe Kleine-König
2026-09-28 17:25 ` Bradley Morgan
2026-09-28 16:46 ` [PATCH v3 3/3] driver core: Disable driver overriding by default Uwe Kleine-König
` (2 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Uwe Kleine-König @ 2026-09-28 16:46 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Johan Hovold, Aaron Tomlin, Bradley Morgan, Danilo Krummrich,
Thierry Reding, David Lechner, Armin Wolf, linux-kernel,
driver-core, linux-trace-kernel
Commit fcbfaffee51a ("driver core: add TAINT_FORCED_BIND for when
userspace manually messes with devices and drivers") introduced a taint
for usage of bind/unbind sysfs files that manually trigger driver probe
and remove respectively.
For drivers that do their resource management correctly (which is also
needed for module unloading) bind and unbind for matching devices are
not critical operations. The thing that makes bind and unbind unsafe is
that drivers can be forced on devices that originally don't match using
driver_override. The result is that e.g. of_device_get_match_data()
returns NULL despite all .of_match_table entries having a non-NULL
.driver_data member which yields a NULL pointer exception for several
drivers. And given that after setting a driver_override a manual bind is
only one way a driver can be bound to an unexpected device, a separate
taint for such an override is justified.
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/driver-core/DLIL9H50MALI.3JROXYEEUM3KU@kernel.org/
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
Documentation/admin-guide/tainted-kernels.rst | 6 +++++-
include/linux/device.h | 11 +++++++++--
include/linux/panic.h | 3 ++-
include/trace/events/module.h | 3 ++-
kernel/panic.c | 3 ++-
tools/debugging/kernel-chktaint | 8 ++++++++
6 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/Documentation/admin-guide/tainted-kernels.rst b/Documentation/admin-guide/tainted-kernels.rst
index a208811ad525..9ccac96b1f75 100644
--- a/Documentation/admin-guide/tainted-kernels.rst
+++ b/Documentation/admin-guide/tainted-kernels.rst
@@ -74,7 +74,7 @@ a particular type of taint. It's best to leave that to the aforementioned
script, but if you need something quick you can use this shell command to check
which bits are set::
- $ for i in $(seq 0 20); do echo $i $(($(cat /proc/sys/kernel/tainted)>>$i&1));done
+ $ for i in $(seq 0 21); do echo $i $(($(cat /proc/sys/kernel/tainted)>>$i&1));done
Table for decoding tainted state
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -103,6 +103,7 @@ Bit Log Number Reason that got the kernel tainted
18 _/N 262144 an in-kernel test has been run
19 _/J 524288 userspace used a mutating debug operation in fwctl
20 _/Y 1048576 device was manually bound or unbound from a driver
+ 21 _/Z 2097152 a driver was forced on a non-matching device
=== === ======= ========================================================
Note: The character ``_`` is representing a blank in this table to make reading
@@ -193,3 +194,6 @@ More detailed explanation for tainting
20) ``Y`` If userspace wrote to the `bind` or `unbind` sysfs files and
successfully bound or removed a device from a driver.
+
+ 21) ``Z`` If userspace wrote to a `driver_override` sysfs file opening the gate
+ for unexpected driver binding.
diff --git a/include/linux/device.h b/include/linux/device.h
index 879eb758b5ee..4dac5e09b74c 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -905,8 +905,15 @@ 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)
- return !strcmp(dev->driver_override.name, drv->name);
+ 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;
}
diff --git a/include/linux/panic.h b/include/linux/panic.h
index 23976b1dfdb6..e6e24d8afcf7 100644
--- a/include/linux/panic.h
+++ b/include/linux/panic.h
@@ -90,7 +90,8 @@ static inline void set_arch_panic_timeout(int timeout, int arch_default_timeout)
#define TAINT_TEST 18
#define TAINT_FWCTL 19
#define TAINT_FORCED_BIND 20
-#define TAINT_FLAGS_COUNT 21
+#define TAINT_DRIVER_OVERRIDE 21
+#define TAINT_FLAGS_COUNT 22
#define TAINT_FLAGS_MAX ((1UL << TAINT_FLAGS_COUNT) - 1)
struct taint_flag {
diff --git a/include/trace/events/module.h b/include/trace/events/module.h
index 19df3e39bba4..c7cdb1f53bc6 100644
--- a/include/trace/events/module.h
+++ b/include/trace/events/module.h
@@ -27,7 +27,8 @@ struct module;
{ (1UL << TAINT_FORCED_MODULE), "F" }, \
{ (1UL << TAINT_CRAP), "C" }, \
{ (1UL << TAINT_UNSIGNED_MODULE), "E" }, \
- { (1UL << TAINT_FORCED_BIND), "Y" })
+ { (1UL << TAINT_FORCED_BIND), "Y" }, \
+ { (1UL << TAINT_DRIVER_OVERRIDE), "Z" })
TRACE_EVENT(module_load,
diff --git a/kernel/panic.c b/kernel/panic.c
index b824b68fcb08..a5d8743df496 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -826,6 +826,7 @@ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
TAINT_FLAG(TEST, 'N', ' '),
TAINT_FLAG(FWCTL, 'J', ' '),
TAINT_FLAG(FORCED_BIND, 'Y', ' '),
+ TAINT_FLAG(DRIVER_OVERRIDE, 'Z', ' '),
};
#undef TAINT_FLAG
@@ -862,7 +863,7 @@ static void print_tainted_seq(struct seq_buf *s, bool verbose)
* exact size is allocated dynamically; the initial buffer remains
* as a fallback if allocation fails.
*
- * The verbose taint string currently requires up to 344 characters.
+ * The verbose taint string currently requires up to 365 characters.
*/
#define INIT_TAINT_BUF_MAX 370
diff --git a/tools/debugging/kernel-chktaint b/tools/debugging/kernel-chktaint
index d8628be37214..14d8febd6b16 100755
--- a/tools/debugging/kernel-chktaint
+++ b/tools/debugging/kernel-chktaint
@@ -219,6 +219,14 @@ else
addout "Y"
echo " * device was manually bound or unbound from a driver (#20)"
fi
+
+T=`expr $T / 2`
+if [ `expr $T % 2` -eq 0 ]; then
+ addout " "
+else
+ addout "Z"
+ echo " * a driver was forced on a non-matching device (#21)"
+fi
echo "Raw taint value as int/string: $taint/'$out'"
# report on any tainted loadable modules
--
2.47.3
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 2/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
2026-09-28 16:46 ` [PATCH v3 2/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Uwe Kleine-König
@ 2026-09-28 17:25 ` Bradley Morgan
0 siblings, 0 replies; 13+ messages in thread
From: Bradley Morgan @ 2026-09-28 17:25 UTC (permalink / raw)
To: Uwe Kleine-König, Greg Kroah-Hartman
Cc: Johan Hovold, Aaron Tomlin, Danilo Krummrich, Thierry Reding,
David Lechner, Armin Wolf, linux-kernel, driver-core,
linux-trace-kernel
On 28 September 2026 17:46:03 BST, "Uwe Kleine-König"
<u.kleine-koenig@baylibre.com> wrote:
>Commit fcbfaffee51a ("driver core: add TAINT_FORCED_BIND for when
>userspace manually messes with devices and drivers") introduced a taint
>for usage of bind/unbind sysfs files that manually trigger driver probe
>and remove respectively.
>
>For drivers that do their resource management correctly (which is also
>needed for module unloading) bind and unbind for matching devices are
>not critical operations. The thing that makes bind and unbind unsafe is
>that drivers can be forced on devices that originally don't match using
>driver_override. The result is that e.g. of_device_get_match_data()
>returns NULL despite all .of_match_table entries having a non-NULL
>.driver_data member which yields a NULL pointer exception for several
>drivers. And given that after setting a driver_override a manual bind is
>only one way a driver can be bound to an unexpected device, a separate
>taint for such an override is justified.
>
>Suggested-by: Danilo Krummrich <dakr@kernel.org>
From a quick scroll, I don't find anything wrong,
Reviewed-by: Bradley Morgan <brads@mainlining.org>
I just know this'll be a famous last words moment
>Link: https://lore.kernel.org/driver-core/DLIL9H50MALI.3JROXYEEUM3KU@kernel.org/
>Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
>---
> Documentation/admin-guide/tainted-kernels.rst | 6 +++++-
> include/linux/device.h | 11 +++++++++--
> include/linux/panic.h | 3 ++-
> include/trace/events/module.h | 3 ++-
> kernel/panic.c | 3 ++-
> tools/debugging/kernel-chktaint | 8 ++++++++
> 6 files changed, 28 insertions(+), 6 deletions(-)
>
>diff --git a/Documentation/admin-guide/tainted-kernels.rst b/Documentation/admin-guide/tainted-kernels.rst
>index a208811ad525..9ccac96b1f75 100644
>--- a/Documentation/admin-guide/tainted-kernels.rst
>+++ b/Documentation/admin-guide/tainted-kernels.rst
>@@ -74,7 +74,7 @@ a particular type of taint. It's best to leave that to the aforementioned
> script, but if you need something quick you can use this shell command to
> check
> which bits are set::
>
>- $ for i in $(seq 0 20); do echo $i $(($(cat /proc/sys/kernel/tainted)>>$i&1));done
>+ $ for i in $(seq 0 21); do echo $i $(($(cat /proc/sys/kernel/tainted)>>$i&1));done
>
> Table for decoding tainted state
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>@@ -103,6 +103,7 @@ Bit Log Number Reason that got the kernel tainted
> 18 _/N 262144 an in-kernel test has been run
> 19 _/J 524288 userspace used a mutating debug operation in fwctl
> 20 _/Y 1048576 device was manually bound or unbound from a driver
>+ 21 _/Z 2097152 a driver was forced on a non-matching device
> === === =======
> ========================================================
>
> Note: The character ``_`` is representing a blank in this table to make reading
>@@ -193,3 +194,6 @@ More detailed explanation for tainting
>
> 20) ``Y`` If userspace wrote to the `bind` or `unbind` sysfs files and
> successfully bound or removed a device from a driver.
>+
>+ 21) ``Z`` If userspace wrote to a `driver_override` sysfs file opening the gate
>+ for unexpected driver binding.
>diff --git a/include/linux/device.h b/include/linux/device.h
>index 879eb758b5ee..4dac5e09b74c 100644
>--- a/include/linux/device.h
>+++ b/include/linux/device.h
>@@ -905,8 +905,15 @@ 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)
>- return !strcmp(dev->driver_override.name, drv->name);
>+ 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;
> }
>
>diff --git a/include/linux/panic.h b/include/linux/panic.h
>index 23976b1dfdb6..e6e24d8afcf7 100644
>--- a/include/linux/panic.h
>+++ b/include/linux/panic.h
>@@ -90,7 +90,8 @@ static inline void set_arch_panic_timeout(int timeout, int arch_default_timeout)
> #define TAINT_TEST 18
> #define TAINT_FWCTL 19
> #define TAINT_FORCED_BIND 20
>-#define TAINT_FLAGS_COUNT 21
>+#define TAINT_DRIVER_OVERRIDE 21
>+#define TAINT_FLAGS_COUNT 22
> #define TAINT_FLAGS_MAX ((1UL << TAINT_FLAGS_COUNT) - 1)
>
> struct taint_flag {
>diff --git a/include/trace/events/module.h b/include/trace/events/module.h
>index 19df3e39bba4..c7cdb1f53bc6 100644
>--- a/include/trace/events/module.h
>+++ b/include/trace/events/module.h
>@@ -27,7 +27,8 @@ struct module;
> { (1UL << TAINT_FORCED_MODULE), "F" }, \
> { (1UL << TAINT_CRAP), "C" }, \
> { (1UL << TAINT_UNSIGNED_MODULE), "E" }, \
>- { (1UL << TAINT_FORCED_BIND), "Y" })
>+ { (1UL << TAINT_FORCED_BIND), "Y" }, \
>+ { (1UL << TAINT_DRIVER_OVERRIDE), "Z" })
>
> TRACE_EVENT(module_load,
>
>diff --git a/kernel/panic.c b/kernel/panic.c
>index b824b68fcb08..a5d8743df496 100644
>--- a/kernel/panic.c
>+++ b/kernel/panic.c
>@@ -826,6 +826,7 @@ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
> TAINT_FLAG(TEST, 'N', ' '),
> TAINT_FLAG(FWCTL, 'J', ' '),
> TAINT_FLAG(FORCED_BIND, 'Y', ' '),
>+ TAINT_FLAG(DRIVER_OVERRIDE, 'Z', ' '),
> };
>
> #undef TAINT_FLAG
>@@ -862,7 +863,7 @@ static void print_tainted_seq(struct seq_buf *s, bool verbose)
> * exact size is allocated dynamically; the initial buffer remains
> * as a fallback if allocation fails.
> *
>- * The verbose taint string currently requires up to 344 characters.
>+ * The verbose taint string currently requires up to 365 characters.
> */
> #define INIT_TAINT_BUF_MAX 370
>
>diff --git a/tools/debugging/kernel-chktaint b/tools/debugging/kernel-chktaint
>index d8628be37214..14d8febd6b16 100755
>--- a/tools/debugging/kernel-chktaint
>+++ b/tools/debugging/kernel-chktaint
>@@ -219,6 +219,14 @@ else
> addout "Y"
> echo " * device was manually bound or unbound from a driver (#20)"
> fi
>+
>+T=`expr $T / 2`
>+if [ `expr $T % 2` -eq 0 ]; then
>+ addout " "
>+else
>+ addout "Z"
>+ echo " * a driver was forced on a non-matching device (#21)"
>+fi
> echo "Raw taint value as int/string: $taint/'$out'"
>
> # report on any tainted loadable modules
>
--- Thanks!
"I'm not a very positive person" - Linus torvalds
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 3/3] driver core: Disable driver overriding by default
2026-09-28 16:46 [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Uwe Kleine-König
2026-09-28 16:46 ` [PATCH v3 1/3] docs: admin-guide: Handle TAINT_FORCED_BIND when parsing /proc/sys/kernel/tainted Uwe Kleine-König
2026-09-28 16:46 ` [PATCH v3 2/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Uwe Kleine-König
@ 2026-09-28 16:46 ` Uwe Kleine-König
2026-09-28 17:26 ` Bradley Morgan
2026-09-28 17:15 ` [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Danilo Krummrich
2026-09-28 21:51 ` (subset) " Danilo Krummrich
4 siblings, 1 reply; 13+ messages in thread
From: Uwe Kleine-König @ 2026-09-28 16:46 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Johan Hovold, Aaron Tomlin, Bradley Morgan, Danilo Krummrich,
Thierry Reding, David Lechner, Armin Wolf, linux-kernel,
driver-core, linux-trace-kernel
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@baylibre.com>
---
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
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 3/3] driver core: Disable driver overriding by default
2026-09-28 16:46 ` [PATCH v3 3/3] driver core: Disable driver overriding by default Uwe Kleine-König
@ 2026-09-28 17:26 ` Bradley Morgan
0 siblings, 0 replies; 13+ messages in thread
From: Bradley Morgan @ 2026-09-28 17:26 UTC (permalink / raw)
To: Uwe Kleine-König, Greg Kroah-Hartman
Cc: Johan Hovold, Aaron Tomlin, Danilo Krummrich, Thierry Reding,
David Lechner, Armin Wolf, linux-kernel, driver-core,
linux-trace-kernel
On 28 September 2026 17:46:04 BST, "Uwe Kleine-König"
<u.kleine-koenig@baylibre.com> wrote:
>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@baylibre.com>
>---
> 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.
>+ */
Nice!
Reviewed-by: Bradley Morgan <brads@mainlining.org>
I mean, others may provide nits, but I'm rarely a nit guy
>+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;
>
>
--- Thanks!
"I'm not a very positive person" - Linus torvalds
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
2026-09-28 16:46 [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Uwe Kleine-König
` (2 preceding siblings ...)
2026-09-28 16:46 ` [PATCH v3 3/3] driver core: Disable driver overriding by default Uwe Kleine-König
@ 2026-09-28 17:15 ` Danilo Krummrich
2026-09-29 5:53 ` Uwe Kleine-König
2026-09-28 21:51 ` (subset) " Danilo Krummrich
4 siblings, 1 reply; 13+ messages in thread
From: Danilo Krummrich @ 2026-09-28 17:15 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Greg Kroah-Hartman, Johan Hovold, Aaron Tomlin, Bradley Morgan,
Thierry Reding, David Lechner, Armin Wolf, linux-kernel,
driver-core, linux-trace-kernel
On Mon Sep 28, 2026 at 6:46 PM CEST, Uwe Kleine-König wrote:
> Note that different to Danilo's suggestion I don't differentiate between
> driver_overrides setup in userspace and those setup in kernel space.
> IMHO all are bad and there are alternatives for the legitimate cases.
I agree that the implementation - i.e. (ab)using driver override - the affected
subsystems have chosen is wrong.
But, there is a difference between picking the wrong implementation and being
semantically wrong to a point that we need to taint the kernel.
So, yes this should be cleaned up, but we should not taint the kernel for
otherwise correct code. Otherwise we could as well taint the kernel for every
other abuse of an API.
> I think applying this complete patch set and keeping fcbfaffee51a ("driver
> core: add TAINT_FORCED_BIND for when userspace manually messes with devices and
> drivers") is too much, so this series serves mainly as discussion ground for
> choosing a sane way to prevent fuzzing results of only mild interest and stop
> patch sets harding drivers for driver_override handling.
> My preference would be to revert (or drop) fcbfaffee51a and then only
> apply patch #3. Maybe also keep patch #2 to taint if
> "allow_driver_override" is provided.
Agreed, but as mentioned in [1], I think it is also reasonable to only keep
TAINT_FORCED_BIND for buses that do not support hotplug in the first place.
[1] https://lore.kernel.org/driver-core/DLIL9H50MALI.3JROXYEEUM3KU@kernel.org/
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
2026-09-28 17:15 ` [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Danilo Krummrich
@ 2026-09-29 5:53 ` Uwe Kleine-König
2026-09-29 10:28 ` Danilo Krummrich
0 siblings, 1 reply; 13+ messages in thread
From: Uwe Kleine-König @ 2026-09-29 5:53 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Greg Kroah-Hartman, Johan Hovold, Aaron Tomlin, Bradley Morgan,
Thierry Reding, David Lechner, Armin Wolf, linux-kernel,
driver-core, linux-trace-kernel
[-- Attachment #1: Type: text/plain, Size: 1976 bytes --]
On Mon, Sep 28, 2026 at 07:15:12PM +0200, Danilo Krummrich wrote:
> On Mon Sep 28, 2026 at 6:46 PM CEST, Uwe Kleine-König wrote:
> > Note that different to Danilo's suggestion I don't differentiate between
> > driver_overrides setup in userspace and those setup in kernel space.
> > IMHO all are bad and there are alternatives for the legitimate cases.
>
> I agree that the implementation - i.e. (ab)using driver override - the affected
> subsystems have chosen is wrong.
>
> But, there is a difference between picking the wrong implementation and being
> semantically wrong to a point that we need to taint the kernel.
>
> So, yes this should be cleaned up, but we should not taint the kernel for
> otherwise correct code. Otherwise we could as well taint the kernel for every
> other abuse of an API.
My position on that is: Do the global change now and help the subsystems
to clean up the mess. In my experice waiting with changes until all
affected parties are smooth with it is a recipe for failure.
> > I think applying this complete patch set and keeping fcbfaffee51a ("driver
> > core: add TAINT_FORCED_BIND for when userspace manually messes with devices and
> > drivers") is too much, so this series serves mainly as discussion ground for
> > choosing a sane way to prevent fuzzing results of only mild interest and stop
> > patch sets harding drivers for driver_override handling.
> > My preference would be to revert (or drop) fcbfaffee51a and then only
> > apply patch #3. Maybe also keep patch #2 to taint if
> > "allow_driver_override" is provided.
>
> Agreed, but as mentioned in [1], I think it is also reasonable to only keep
> TAINT_FORCED_BIND for buses that do not support hotplug in the first place.
>
> [1] https://lore.kernel.org/driver-core/DLIL9H50MALI.3JROXYEEUM3KU@kernel.org/
Fine for me, that would mean to apply the whole series and restrict
TAINT_FORCED_BIND to "static" busses.
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
2026-09-29 5:53 ` Uwe Kleine-König
@ 2026-09-29 10:28 ` Danilo Krummrich
0 siblings, 0 replies; 13+ messages in thread
From: Danilo Krummrich @ 2026-09-29 10:28 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Greg Kroah-Hartman, Johan Hovold, Aaron Tomlin, Bradley Morgan,
Thierry Reding, David Lechner, Armin Wolf, linux-kernel,
driver-core, linux-trace-kernel
On Tue Sep 29, 2026 at 7:53 AM CEST, Uwe Kleine-König wrote:
> On Mon, Sep 28, 2026 at 07:15:12PM +0200, Danilo Krummrich wrote:
>> On Mon Sep 28, 2026 at 6:46 PM CEST, Uwe Kleine-König wrote:
>> > Note that different to Danilo's suggestion I don't differentiate between
>> > driver_overrides setup in userspace and those setup in kernel space.
>> > IMHO all are bad and there are alternatives for the legitimate cases.
>>
>> I agree that the implementation - i.e. (ab)using driver override - the affected
>> subsystems have chosen is wrong.
>>
>> But, there is a difference between picking the wrong implementation and being
>> semantically wrong to a point that we need to taint the kernel.
>>
>> So, yes this should be cleaned up, but we should not taint the kernel for
>> otherwise correct code. Otherwise we could as well taint the kernel for every
>> other abuse of an API.
>
> My position on that is: Do the global change now and help the subsystems
> to clean up the mess. In my experice waiting with changes until all
> affected parties are smooth with it is a recipe for failure.
I do see an advantage in having the taint in match() rather than store(), so I
prefer that too.
But again, I do not feel comfortable to taint the kernel for something that does
use the wrong API but otherwise behaves correctly and shouldn't taint the kernel
at all.
We have six users of device_set_driver_override() outside of a userspace
reachable scope. Did you have a look at how hard they are to fix? Do you plan to
provide patches?
>> > I think applying this complete patch set and keeping fcbfaffee51a ("driver
>> > core: add TAINT_FORCED_BIND for when userspace manually messes with devices and
>> > drivers") is too much, so this series serves mainly as discussion ground for
>> > choosing a sane way to prevent fuzzing results of only mild interest and stop
>> > patch sets harding drivers for driver_override handling.
>> > My preference would be to revert (or drop) fcbfaffee51a and then only
>> > apply patch #3. Maybe also keep patch #2 to taint if
>> > "allow_driver_override" is provided.
>>
>> Agreed, but as mentioned in [1], I think it is also reasonable to only keep
>> TAINT_FORCED_BIND for buses that do not support hotplug in the first place.
>>
>> [1] https://lore.kernel.org/driver-core/DLIL9H50MALI.3JROXYEEUM3KU@kernel.org/
>
> Fine for me, that would mean to apply the whole series and restrict
> TAINT_FORCED_BIND to "static" busses.
That sounds fine to me.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: (subset) [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
2026-09-28 16:46 [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Uwe Kleine-König
` (3 preceding siblings ...)
2026-09-28 17:15 ` [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override Danilo Krummrich
@ 2026-09-28 21:51 ` Danilo Krummrich
2026-09-28 21:53 ` Danilo Krummrich
4 siblings, 1 reply; 13+ messages in thread
From: Danilo Krummrich @ 2026-09-28 21:51 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Greg Kroah-Hartman, Johan Hovold, Aaron Tomlin, Bradley Morgan,
Danilo Krummrich, Thierry Reding, David Lechner, Armin Wolf,
linux-kernel, driver-core, linux-trace-kernel
On Mon, 28 Sep 2026 18:46:01 +0200, Uwe Kleine-König wrote:
> [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
Applied, thanks!
Branch: driver-core-testing
Tree: git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git
[1/3] docs: admin-guide: Handle TAINT_FORCED_BIND when parsing /proc/sys/kernel/tainted
commit: f1850e443b0e
[ Fix a typo in the commit message. - Danilo ]
The patch will appear in the next linux-next integration (typically within 24
hours on weekdays).
The patch is in the driver-core-testing branch and will be promoted to
driver-core-next after validation.
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: (subset) [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
2026-09-28 21:51 ` (subset) " Danilo Krummrich
@ 2026-09-28 21:53 ` Danilo Krummrich
2026-09-29 5:47 ` Uwe Kleine-König
0 siblings, 1 reply; 13+ messages in thread
From: Danilo Krummrich @ 2026-09-28 21:53 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Greg Kroah-Hartman, Johan Hovold, Aaron Tomlin, Bradley Morgan,
Thierry Reding, David Lechner, Armin Wolf, linux-kernel,
driver-core, linux-trace-kernel
On Mon Sep 28, 2026 at 11:51 PM CEST, Danilo Krummrich wrote:
> On Mon, 28 Sep 2026 18:46:01 +0200, Uwe Kleine-König wrote:
>> [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
>
> Applied, thanks!
>
> Branch: driver-core-testing
> Tree: git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git
>
> [1/3] docs: admin-guide: Handle TAINT_FORCED_BIND when parsing /proc/sys/kernel/tainted
> commit: f1850e443b0e
>
> [ Fix a typo in the commit message. - Danilo ]
>
> The patch will appear in the next linux-next integration (typically within 24
> hours on weekdays).
>
> The patch is in the driver-core-testing branch and will be promoted to
> driver-core-next after validation.
I've picked this up, as this fix is independent from the rest of the series.
Thanks,
Danilo
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: (subset) [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
2026-09-28 21:53 ` Danilo Krummrich
@ 2026-09-29 5:47 ` Uwe Kleine-König
0 siblings, 0 replies; 13+ messages in thread
From: Uwe Kleine-König @ 2026-09-29 5:47 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Greg Kroah-Hartman, Johan Hovold, Aaron Tomlin, Bradley Morgan,
Thierry Reding, David Lechner, Armin Wolf, linux-kernel,
driver-core, linux-trace-kernel
[-- Attachment #1: Type: text/plain, Size: 1063 bytes --]
Hello Danilo,
On Mon, Sep 28, 2026 at 11:53:03PM +0200, Danilo Krummrich wrote:
> On Mon Sep 28, 2026 at 11:51 PM CEST, Danilo Krummrich wrote:
> > On Mon, 28 Sep 2026 18:46:01 +0200, Uwe Kleine-König wrote:
> >> [PATCH v3 0/3] Add TAINT_DRIVER_OVERRIDE for usage of driver_override
> >
> > Applied, thanks!
> >
> > Branch: driver-core-testing
> > Tree: git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git
> >
> > [1/3] docs: admin-guide: Handle TAINT_FORCED_BIND when parsing /proc/sys/kernel/tainted
> > commit: f1850e443b0e
> >
> > [ Fix a typo in the commit message. - Danilo ]
Oh thanks.
> > The patch will appear in the next linux-next integration (typically within 24
> > hours on weekdays).
> >
> > The patch is in the driver-core-testing branch and will be promoted to
> > driver-core-next after validation.
>
> I've picked this up, as this fix is independent from the rest of the series.
That's great, I will make sure to base the next respin on top of that.
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread