Linux USB
 help / color / mirror / Atom feed
* [PATCH 0/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
@ 2026-08-26  9:19 Greg Kroah-Hartman
  2026-08-26  9:19 ` [PATCH 1/2] module: pull out add_taint_module() to be public Greg Kroah-Hartman
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-26  9:19 UTC (permalink / raw)
  To: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers
  Cc: linux-modules, linux-kernel, linux-doc, linux-usb, driver-core,
	linux-trace-kernel, Greg Kroah-Hartman

The ability to add and remove devices from a driver through the sysfs
"bind" and "unbind" files was created all those decades ago as a way
that kernel developers can iterate faster, and provide a debugging way
for users to attempt to add a new device to a driver without having to
rebuild their kernel.

This api over the years has been abused and recently come under a major
fuzzing "attack" through tools like syzbot which decided that it would
attempt to just randomly bind any driver to any type of device, causing
loads of unneeded errors and pointless kernel patches to be generated by
unsuspecting new developers.

Handle all of this by adding a new taint flag, TAINT_FORCED_BIND, which
will be set on the driver if the bind/unbind sysfs files are ever
successfully written to.  This lets kernel developers "know" that a user
is attempting to do something that is not normal, and as such, if the
kernel breaks they get to keep the shiny pieces laying around on the
floor.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Greg Kroah-Hartman (2):
      module: pull out add_taint_module() to be public
      driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers

 Documentation/admin-guide/tainted-kernels.rst | 52 ++++++++++++++-------------
 drivers/base/bus.c                            |  3 ++
 include/linux/module.h                        |  8 +++++
 include/linux/panic.h                         |  3 +-
 include/trace/events/module.h                 |  3 +-
 kernel/module/main.c                          | 13 +++++--
 kernel/panic.c                                |  5 +--
 tools/debugging/kernel-chktaint               |  8 +++++
 8 files changed, 65 insertions(+), 30 deletions(-)
---
base-commit: 45c13f3f9e3bb15fd89ff2864c6f627a3b4b4229
change-id: 20260825-bind_taint-d4077b870bc4

Best regards,
--  
Greg Kroah-Hartman <gregkh@linuxfoundation.org>


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 1/2] module: pull out add_taint_module() to be public
  2026-08-26  9:19 [PATCH 0/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers Greg Kroah-Hartman
@ 2026-08-26  9:19 ` Greg Kroah-Hartman
  2026-08-26 11:13   ` Aaron Tomlin
  2026-08-27 13:36   ` Johan Hovold
  2026-08-26  9:19 ` [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers Greg Kroah-Hartman
  2026-08-26 13:33 ` [PATCH 0/2] " Michal Pecio
  2 siblings, 2 replies; 17+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-26  9:19 UTC (permalink / raw)
  To: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers
  Cc: linux-modules, linux-kernel, linux-doc, linux-usb, driver-core,
	linux-trace-kernel, Greg Kroah-Hartman

Other kernel code might want to call add_taint_module() so pull it out
and make it global.  If modules are not enabled, this defaults to a call
to add_taint(), so all is fine.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/module.h |  8 ++++++++
 kernel/module/main.c   | 13 +++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/linux/module.h b/include/linux/module.h
index 96cc98568eea..25221539e645 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -29,6 +29,7 @@
 #include <linux/srcu.h>
 #include <linux/static_call_types.h>
 #include <linux/dynamic_debug.h>
+#include <linux/panic.h>
 
 #include <linux/percpu.h>
 #include <asm/module.h>
@@ -770,6 +771,8 @@ static inline bool is_livepatch_module(struct module *mod)
 
 void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data);
 
+void add_taint_module(struct module *mod, unsigned flag, enum lockdep_ok);
+
 #else /* !CONFIG_MODULES... */
 
 static inline struct module *__module_address(unsigned long addr)
@@ -877,6 +880,11 @@ static inline bool module_is_coming(struct module *mod)
 static inline void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data)
 {
 }
+
+static inline void add_taint_module(struct module *mod, unsigned flag, enum lockdep_ok)
+{
+	add_taint(flag, lockdep_ok);
+}
 #endif /* CONFIG_MODULES */
 
 #ifdef CONFIG_SYSFS
diff --git a/kernel/module/main.c b/kernel/module/main.c
index d0e1e0bd2ad0..99cedb961898 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -191,8 +191,17 @@ static inline int strong_try_module_get(struct module *mod)
 		return -ENOENT;
 }
 
-static inline void add_taint_module(struct module *mod, unsigned flag,
-				    enum lockdep_ok lockdep_ok)
+/**
+ * add_taint_module: add a taint flag if not already set for a specific module
+ * @mod: pointer to the module that caused the problem
+ * @flag: one of the TAINT_* constants.
+ * @lockdep_ok: whether lock debugging is still OK.
+ *
+ * If something bad has gone wrong, you'll want @lockdebug_ok = false, but for
+ * some noteworthy-but-not-corrupting cases, it can be set to true.
+ */
+void add_taint_module(struct module *mod, unsigned flag,
+		      enum lockdep_ok lockdep_ok)
 {
 	add_taint(flag, lockdep_ok);
 	set_bit(flag, &mod->taints);

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26  9:19 [PATCH 0/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers Greg Kroah-Hartman
  2026-08-26  9:19 ` [PATCH 1/2] module: pull out add_taint_module() to be public Greg Kroah-Hartman
@ 2026-08-26  9:19 ` Greg Kroah-Hartman
  2026-08-26 11:58   ` Bradley Morgan
  2026-08-27 13:33   ` Johan Hovold
  2026-08-26 13:33 ` [PATCH 0/2] " Michal Pecio
  2 siblings, 2 replies; 17+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-26  9:19 UTC (permalink / raw)
  To: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers
  Cc: linux-modules, linux-kernel, linux-doc, linux-usb, driver-core,
	linux-trace-kernel, Greg Kroah-Hartman

The ability to add and remove devices from a driver through the sysfs
"bind" and "unbind" files was created all those decades ago as a way
that kernel developers can iterate faster, and provide a debugging way
for users to attempt to add a new device to a driver without having to
rebuild their kernel.

This api over the years has been abused and recently come under a major
fuzzing "attack" through tools like syzbot which decided that it would
attempt to just randomly bind any driver to any type of device, causing
loads of unneeded errors and pointless kernel patches to be generated by
unsuspecting new developers.

Handle all of this by adding a new taint flag, TAINT_FORCED_BIND, which
will be set on the driver if the bind/unbind sysfs files are ever
successfully written to.  This lets kernel developers "know" that a user
is attempting to do something that is not normal, and as such, if the
kernel breaks they get to keep the shiny pieces laying around on the
floor.

Note, the taint flag gets set _BEFORE_ the bind/unbind callback happens,
as many times crashes/oops/warnings/failures happen within the callback,
and the taint flag needs to be there to show what was being attempted.
If it were to be set after the callback happens, the oops report would
not properly reflect what foolishness was being attempted.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/admin-guide/tainted-kernels.rst | 52 ++++++++++++++-------------
 drivers/base/bus.c                            |  3 ++
 include/linux/panic.h                         |  3 +-
 include/trace/events/module.h                 |  3 +-
 kernel/panic.c                                |  5 +--
 tools/debugging/kernel-chktaint               |  8 +++++
 6 files changed, 46 insertions(+), 28 deletions(-)

diff --git a/Documentation/admin-guide/tainted-kernels.rst b/Documentation/admin-guide/tainted-kernels.rst
index 9ead927a37c0..d4ca8b9e3819 100644
--- a/Documentation/admin-guide/tainted-kernels.rst
+++ b/Documentation/admin-guide/tainted-kernels.rst
@@ -79,30 +79,31 @@ which bits are set::
 Table for decoding tainted state
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-===  ===  ======  ========================================================
-Bit  Log  Number  Reason that got the kernel tainted
-===  ===  ======  ========================================================
-  0  G/P       1  proprietary module was loaded
-  1  _/F       2  module was force loaded
-  2  _/S       4  kernel running on an out of specification system
-  3  _/R       8  module was force unloaded
-  4  _/M      16  processor reported a Machine Check Exception (MCE)
-  5  _/B      32  bad page referenced or some unexpected page flags
-  6  _/U      64  taint requested by userspace application
-  7  _/D     128  kernel died recently, i.e. there was an OOPS or BUG
-  8  _/A     256  ACPI table overridden by user
-  9  _/W     512  kernel issued warning
- 10  _/C    1024  staging driver was loaded
- 11  _/I    2048  workaround for bug in platform firmware applied
- 12  _/O    4096  externally-built ("out-of-tree") module was loaded
- 13  _/E    8192  unsigned module was loaded
- 14  _/L   16384  soft lockup occurred
- 15  _/K   32768  kernel has been live patched
- 16  _/X   65536  auxiliary taint, defined for and used by distros
- 17  _/T  131072  kernel was built with the struct randomization plugin
- 18  _/N  262144  an in-kernel test has been run
- 19  _/J  524288  userspace used a mutating debug operation in fwctl
-===  ===  ======  ========================================================
+===  ===   ======  ========================================================
+Bit  Log   Number  Reason that got the kernel tainted
+===  ===   ======  ========================================================
+  0  G/P        1  proprietary module was loaded
+  1  _/F        2  module was force loaded
+  2  _/S        4  kernel running on an out of specification system
+  3  _/R        8  module was force unloaded
+  4  _/M       16  processor reported a Machine Check Exception (MCE)
+  5  _/B       32  bad page referenced or some unexpected page flags
+  6  _/U       64  taint requested by userspace application
+  7  _/D      128  kernel died recently, i.e. there was an OOPS or BUG
+  8  _/A      256  ACPI table overridden by user
+  9  _/W      512  kernel issued warning
+ 10  _/C     1024  staging driver was loaded
+ 11  _/I     2048  workaround for bug in platform firmware applied
+ 12  _/O     4096  externally-built ("out-of-tree") module was loaded
+ 13  _/E     8192  unsigned module was loaded
+ 14  _/L    16384  soft lockup occurred
+ 15  _/K    32768  kernel has been live patched
+ 16  _/X    65536  auxiliary taint, defined for and used by distros
+ 17  _/T   131072  kernel was built with the struct randomization plugin
+ 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
+===  ===  =======  ========================================================
 
 Note: The character ``_`` is representing a blank in this table to make reading
 easier.
@@ -189,3 +190,6 @@ More detailed explanation for tainting
  19) ``J`` if userspace opened /dev/fwctl/* and performed a FWTCL_RPC_DEBUG_WRITE
      to use the devices debugging features. Device debugging features could
      cause the device to malfunction in undefined ways.
+
+ 20) ``Y`` If userspace wrote to the `bind` or `unbind` sysfs files and
+     successfully bound or removed a device from a driver.
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index d17bd91490ee..c51ad96d4de4 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -19,6 +19,7 @@
 #include <linux/string.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/panic.h>
 #include "base.h"
 #include "power/power.h"
 
@@ -241,6 +242,7 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf,
 
 	dev = bus_find_device_by_name(bus, NULL, buf);
 	if (dev && dev->driver == drv) {
+		add_taint_module(drv->owner, TAINT_FORCED_BIND, LOCKDEP_STILL_OK);
 		device_driver_detach(dev);
 		err = count;
 	}
@@ -264,6 +266,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf,
 
 	dev = bus_find_device_by_name(bus, NULL, buf);
 	if (dev && driver_match_device(drv, dev)) {
+		add_taint_module(drv->owner, TAINT_FORCED_BIND, LOCKDEP_STILL_OK);
 		err = device_driver_attach(drv, dev);
 		if (!err) {
 			/* success */
diff --git a/include/linux/panic.h b/include/linux/panic.h
index f1dd417e54b2..8e7250b0e913 100644
--- a/include/linux/panic.h
+++ b/include/linux/panic.h
@@ -88,7 +88,8 @@ static inline void set_arch_panic_timeout(int timeout, int arch_default_timeout)
 #define TAINT_RANDSTRUCT		17
 #define TAINT_TEST			18
 #define TAINT_FWCTL			19
-#define TAINT_FLAGS_COUNT		20
+#define TAINT_FORCED_BIND		20
+#define TAINT_FLAGS_COUNT		21
 #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 e5a006be9dc6..19df3e39bba4 100644
--- a/include/trace/events/module.h
+++ b/include/trace/events/module.h
@@ -26,7 +26,8 @@ struct module;
 	{ (1UL << TAINT_OOT_MODULE),		"O" },		\
 	{ (1UL << TAINT_FORCED_MODULE),		"F" },		\
 	{ (1UL << TAINT_CRAP),			"C" },		\
-	{ (1UL << TAINT_UNSIGNED_MODULE),	"E" })
+	{ (1UL << TAINT_UNSIGNED_MODULE),	"E" },		\
+	{ (1UL << TAINT_FORCED_BIND),		"Y" })
 
 TRACE_EVENT(module_load,
 
diff --git a/kernel/panic.c b/kernel/panic.c
index 213725b612aa..6bf60f9dd120 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -826,6 +826,7 @@ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
 	TAINT_FLAG(RANDSTRUCT,			'T', ' '),
 	TAINT_FLAG(TEST,			'N', ' '),
 	TAINT_FLAG(FWCTL,			'J', ' '),
+	TAINT_FLAG(FORCED_BIND,			'Y', ' '),
 };
 
 #undef TAINT_FLAG
@@ -862,9 +863,9 @@ 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 327 characters.
+ * The verbose taint string currently requires up to 344 characters.
  */
-#define INIT_TAINT_BUF_MAX 350
+#define INIT_TAINT_BUF_MAX 370
 
 static char init_taint_buf[INIT_TAINT_BUF_MAX] __initdata;
 static char *taint_buf __refdata = init_taint_buf;
diff --git a/tools/debugging/kernel-chktaint b/tools/debugging/kernel-chktaint
index e1571c04afb5..d8628be37214 100755
--- a/tools/debugging/kernel-chktaint
+++ b/tools/debugging/kernel-chktaint
@@ -211,6 +211,14 @@ else
 	addout "J"
 	echo " * fwctl's mutating debug interface was used (#19)"
 fi
+
+T=`expr $T / 2`
+if [ `expr $T % 2` -eq 0 ]; then
+	addout " "
+else
+	addout "Y"
+	echo " * device was manually bound or unbound from a driver (#20)"
+fi
 echo "Raw taint value as int/string: $taint/'$out'"
 
 # report on any tainted loadable modules

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 1/2] module: pull out add_taint_module() to be public
  2026-08-26  9:19 ` [PATCH 1/2] module: pull out add_taint_module() to be public Greg Kroah-Hartman
@ 2026-08-26 11:13   ` Aaron Tomlin
  2026-08-26 11:54     ` Greg Kroah-Hartman
  2026-08-27 13:36   ` Johan Hovold
  1 sibling, 1 reply; 17+ messages in thread
From: Aaron Tomlin @ 2026-08-26 11:13 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Jonathan Corbet, Shuah Khan, Randy Dunlap, Rafael J. Wysocki,
	Danilo Krummrich, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, linux-modules, linux-kernel, linux-doc,
	linux-usb, driver-core, linux-trace-kernel

On Wed, Aug 26, 2026 at 11:19:32AM +0200, Greg Kroah-Hartman wrote:
> Other kernel code might want to call add_taint_module() so pull it out
> and make it global.  If modules are not enabled, this defaults to a call
> to add_taint(), so all is fine.
> 
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>  include/linux/module.h |  8 ++++++++
>  kernel/module/main.c   | 13 +++++++++++--
>  2 files changed, 19 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/module.h b/include/linux/module.h
> index 96cc98568eea..25221539e645 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -29,6 +29,7 @@
>  #include <linux/srcu.h>
>  #include <linux/static_call_types.h>
>  #include <linux/dynamic_debug.h>
> +#include <linux/panic.h>
>  
>  #include <linux/percpu.h>
>  #include <asm/module.h>
> @@ -770,6 +771,8 @@ static inline bool is_livepatch_module(struct module *mod)
>  
>  void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data);
>  
> +void add_taint_module(struct module *mod, unsigned flag, enum lockdep_ok);
> +
>  #else /* !CONFIG_MODULES... */
>  
>  static inline struct module *__module_address(unsigned long addr)
> @@ -877,6 +880,11 @@ static inline bool module_is_coming(struct module *mod)
>  static inline void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data)
>  {
>  }
> +
> +static inline void add_taint_module(struct module *mod, unsigned flag, enum lockdep_ok)
> +{
> +	add_taint(flag, lockdep_ok);
> +}
>  #endif /* CONFIG_MODULES */
>  
>  #ifdef CONFIG_SYSFS
> diff --git a/kernel/module/main.c b/kernel/module/main.c
> index d0e1e0bd2ad0..99cedb961898 100644
> --- a/kernel/module/main.c
> +++ b/kernel/module/main.c
> @@ -191,8 +191,17 @@ static inline int strong_try_module_get(struct module *mod)
>  		return -ENOENT;
>  }
>  
> -static inline void add_taint_module(struct module *mod, unsigned flag,
> -				    enum lockdep_ok lockdep_ok)
> +/**
> + * add_taint_module: add a taint flag if not already set for a specific module
> + * @mod: pointer to the module that caused the problem
> + * @flag: one of the TAINT_* constants.
> + * @lockdep_ok: whether lock debugging is still OK.
> + *
> + * If something bad has gone wrong, you'll want @lockdebug_ok = false, but for
> + * some noteworthy-but-not-corrupting cases, it can be set to true.
> + */
> +void add_taint_module(struct module *mod, unsigned flag,
> +		      enum lockdep_ok lockdep_ok)
>  {
>  	add_taint(flag, lockdep_ok);
>  	set_bit(flag, &mod->taints);
> 
> -- 
> 2.55.0
> 

Hi Greg,

I believe Sashiko [1] found a few valid concerns.

[1]: https://sashiko.dev/#/message/20260826102921.5B81B1F000E9%40smtp.kernel.org

Kind regards,
-- 
Aaron Tomlin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 1/2] module: pull out add_taint_module() to be public
  2026-08-26 11:13   ` Aaron Tomlin
@ 2026-08-26 11:54     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 17+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-26 11:54 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Jonathan Corbet, Shuah Khan, Randy Dunlap, Rafael J. Wysocki,
	Danilo Krummrich, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, linux-modules, linux-kernel, linux-doc,
	linux-usb, driver-core, linux-trace-kernel

On Wed, Aug 26, 2026 at 07:13:36AM -0400, Aaron Tomlin wrote:
> On Wed, Aug 26, 2026 at 11:19:32AM +0200, Greg Kroah-Hartman wrote:
> > Other kernel code might want to call add_taint_module() so pull it out
> > and make it global.  If modules are not enabled, this defaults to a call
> > to add_taint(), so all is fine.
> > 
> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > ---
> >  include/linux/module.h |  8 ++++++++
> >  kernel/module/main.c   | 13 +++++++++++--
> >  2 files changed, 19 insertions(+), 2 deletions(-)
> > 
> > diff --git a/include/linux/module.h b/include/linux/module.h
> > index 96cc98568eea..25221539e645 100644
> > --- a/include/linux/module.h
> > +++ b/include/linux/module.h
> > @@ -29,6 +29,7 @@
> >  #include <linux/srcu.h>
> >  #include <linux/static_call_types.h>
> >  #include <linux/dynamic_debug.h>
> > +#include <linux/panic.h>
> >  
> >  #include <linux/percpu.h>
> >  #include <asm/module.h>
> > @@ -770,6 +771,8 @@ static inline bool is_livepatch_module(struct module *mod)
> >  
> >  void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data);
> >  
> > +void add_taint_module(struct module *mod, unsigned flag, enum lockdep_ok);
> > +
> >  #else /* !CONFIG_MODULES... */
> >  
> >  static inline struct module *__module_address(unsigned long addr)
> > @@ -877,6 +880,11 @@ static inline bool module_is_coming(struct module *mod)
> >  static inline void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data)
> >  {
> >  }
> > +
> > +static inline void add_taint_module(struct module *mod, unsigned flag, enum lockdep_ok)
> > +{
> > +	add_taint(flag, lockdep_ok);
> > +}
> >  #endif /* CONFIG_MODULES */
> >  
> >  #ifdef CONFIG_SYSFS
> > diff --git a/kernel/module/main.c b/kernel/module/main.c
> > index d0e1e0bd2ad0..99cedb961898 100644
> > --- a/kernel/module/main.c
> > +++ b/kernel/module/main.c
> > @@ -191,8 +191,17 @@ static inline int strong_try_module_get(struct module *mod)
> >  		return -ENOENT;
> >  }
> >  
> > -static inline void add_taint_module(struct module *mod, unsigned flag,
> > -				    enum lockdep_ok lockdep_ok)
> > +/**
> > + * add_taint_module: add a taint flag if not already set for a specific module
> > + * @mod: pointer to the module that caused the problem
> > + * @flag: one of the TAINT_* constants.
> > + * @lockdep_ok: whether lock debugging is still OK.
> > + *
> > + * If something bad has gone wrong, you'll want @lockdebug_ok = false, but for
> > + * some noteworthy-but-not-corrupting cases, it can be set to true.
> > + */
> > +void add_taint_module(struct module *mod, unsigned flag,
> > +		      enum lockdep_ok lockdep_ok)
> >  {
> >  	add_taint(flag, lockdep_ok);
> >  	set_bit(flag, &mod->taints);
> > 
> > -- 
> > 2.55.0
> > 
> 
> Hi Greg,
> 
> I believe Sashiko [1] found a few valid concerns.
> 
> [1]: https://sashiko.dev/#/message/20260826102921.5B81B1F000E9%40smtp.kernel.org
> 

Yes it did, will fix that up for v2.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26  9:19 ` [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers Greg Kroah-Hartman
@ 2026-08-26 11:58   ` Bradley Morgan
  2026-08-26 13:10     ` Greg KH
  2026-08-26 14:26     ` Steven Rostedt
  2026-08-27 13:33   ` Johan Hovold
  1 sibling, 2 replies; 17+ messages in thread
From: Bradley Morgan @ 2026-08-26 11:58 UTC (permalink / raw)
  To: gregkh
  Cc: atomlin, corbet, da.gomez, dakr, driver-core, linux-doc,
	linux-kernel, linux-modules, linux-trace-kernel, linux-usb,
	mathieu.desnoyers, mcgrof, mhiramat, petr.pavlu, rafael, rdunlap,
	rostedt, samitolvanen, skhan

On 26 August 2026 10:19:33 BST, Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>The ability to add and remove devices from a driver through the sysfs
>"bind" and "unbind" files was created all those decades ago as a way
>that kernel developers can iterate faster, and provide a debugging way
>for users to attempt to add a new device to a driver without having to
>rebuild their kernel.
>
>This api over the years has been abused and recently come under a major
>fuzzing "attack" through tools like syzbot which decided that it would
>attempt to just randomly bind any driver to any type of device, causing
>loads of unneeded errors and pointless kernel patches to be generated by
>unsuspecting new developers.
>
>Handle all of this by adding a new taint flag, TAINT_FORCED_BIND, which
>will be set on the driver if the bind/unbind sysfs files are ever
>successfully written to.  This lets kernel developers "know" that a user
>is attempting to do something that is not normal, and as such, if the
>kernel breaks they get to keep the shiny pieces laying around on the
>floor.
>
>Note, the taint flag gets set _BEFORE_ the bind/unbind callback happens,
>as many times crashes/oops/warnings/failures happen within the callback,
>and the taint flag needs to be there to show what was being attempted.
>If it were to be set after the callback happens, the oops report would
>not properly reflect what foolishness was being attempted.
>

sashiko found a couple valid concerns for 2/2


>Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>---
> Documentation/admin-guide/tainted-kernels.rst | 52
> ++++++++++++++-------------
> drivers/base/bus.c                            |  3 ++
> include/linux/panic.h                         |  3 +-
> include/trace/events/module.h                 |  3 +-
> kernel/panic.c                                |  5 +--
> tools/debugging/kernel-chktaint               |  8 +++++
> 6 files changed, 46 insertions(+), 28 deletions(-)
>
>diff --git a/Documentation/admin-guide/tainted-kernels.rst b/Documentation/admin-guide/tainted-kernels.rst
>index 9ead927a37c0..d4ca8b9e3819 100644
>--- a/Documentation/admin-guide/tainted-kernels.rst
>+++ b/Documentation/admin-guide/tainted-kernels.rst
>@@ -79,30 +79,31 @@ which bits are set::
> Table for decoding tainted state
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
>-===  ===  ======  ========================================================
>-Bit  Log  Number  Reason that got the kernel tainted
>-===  ===  ======  ========================================================
>-  0  G/P       1  proprietary module was loaded
>-  1  _/F       2  module was force loaded
>-  2  _/S       4  kernel running on an out of specification system
>-  3  _/R       8  module was force unloaded
>-  4  _/M      16  processor reported a Machine Check Exception (MCE)
>-  5  _/B      32  bad page referenced or some unexpected page flags
>-  6  _/U      64  taint requested by userspace application
>-  7  _/D     128  kernel died recently, i.e. there was an OOPS or BUG
>-  8  _/A     256  ACPI table overridden by user
>-  9  _/W     512  kernel issued warning
>- 10  _/C    1024  staging driver was loaded
>- 11  _/I    2048  workaround for bug in platform firmware applied
>- 12  _/O    4096  externally-built ("out-of-tree") module was loaded
>- 13  _/E    8192  unsigned module was loaded
>- 14  _/L   16384  soft lockup occurred
>- 15  _/K   32768  kernel has been live patched
>- 16  _/X   65536  auxiliary taint, defined for and used by distros
>- 17  _/T  131072  kernel was built with the struct randomization plugin
>- 18  _/N  262144  an in-kernel test has been run
>- 19  _/J  524288  userspace used a mutating debug operation in fwctl
>-===  ===  ======  ========================================================
>+===  ===   ======  ========================================================
>+Bit  Log   Number  Reason that got the kernel tainted
>+===  ===   ======  ========================================================
>+  0  G/P        1  proprietary module was loaded
>+  1  _/F        2  module was force loaded
>+  2  _/S        4  kernel running on an out of specification system
>+  3  _/R        8  module was force unloaded
>+  4  _/M       16  processor reported a Machine Check Exception (MCE)
>+  5  _/B       32  bad page referenced or some unexpected page flags
>+  6  _/U       64  taint requested by userspace application
>+  7  _/D      128  kernel died recently, i.e. there was an OOPS or BUG
>+  8  _/A      256  ACPI table overridden by user
>+  9  _/W      512  kernel issued warning
>+ 10  _/C     1024  staging driver was loaded
>+ 11  _/I     2048  workaround for bug in platform firmware applied
>+ 12  _/O     4096  externally-built ("out-of-tree") module was loaded
>+ 13  _/E     8192  unsigned module was loaded
>+ 14  _/L    16384  soft lockup occurred
>+ 15  _/K    32768  kernel has been live patched
>+ 16  _/X    65536  auxiliary taint, defined for and used by distros
>+ 17  _/T   131072  kernel was built with the struct randomization plugin
>+ 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
>+===  ===  =======  ========================================================
> 
> Note: The character ``_`` is representing a blank in this table to make reading
> easier.
>@@ -189,3 +190,6 @@ More detailed explanation for tainting
>  19) ``J`` if userspace opened /dev/fwctl/* and performed a FWTCL_RPC_DEBUG_WRITE
>      to use the devices debugging features. Device debugging features could
>      cause the device to malfunction in undefined ways.
>+
>+ 20) ``Y`` If userspace wrote to the `bind` or `unbind` sysfs files and
>+     successfully bound or removed a device from a driver.
>diff --git a/drivers/base/bus.c b/drivers/base/bus.c
>index d17bd91490ee..c51ad96d4de4 100644
>--- a/drivers/base/bus.c
>+++ b/drivers/base/bus.c
>@@ -19,6 +19,7 @@
> #include <linux/string.h>
> #include <linux/mutex.h>
> #include <linux/sysfs.h>
>+#include <linux/panic.h>
> #include "base.h"
> #include "power/power.h"
> 
>@@ -241,6 +242,7 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf,
> 
> 	dev = bus_find_device_by_name(bus, NULL, buf);
> 	if (dev && dev->driver == drv) {
>+		add_taint_module(drv->owner, TAINT_FORCED_BIND, LOCKDEP_STILL_OK);
> 		device_driver_detach(dev);
> 		err = count;
> 	}
>@@ -264,6 +266,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf,
> 
> 	dev = bus_find_device_by_name(bus, NULL, buf);
> 	if (dev && driver_match_device(drv, dev)) {
>+		add_taint_module(drv->owner, TAINT_FORCED_BIND, LOCKDEP_STILL_OK);
> 		err = device_driver_attach(drv, dev);
> 		if (!err) {
> 			/* success */
>diff --git a/include/linux/panic.h b/include/linux/panic.h
>index f1dd417e54b2..8e7250b0e913 100644
>--- a/include/linux/panic.h
>+++ b/include/linux/panic.h
>@@ -88,7 +88,8 @@ static inline void set_arch_panic_timeout(int timeout, int arch_default_timeout)
> #define TAINT_RANDSTRUCT		17
> #define TAINT_TEST			18
> #define TAINT_FWCTL			19
>-#define TAINT_FLAGS_COUNT		20
>+#define TAINT_FORCED_BIND		20
>+#define TAINT_FLAGS_COUNT		21
> #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 e5a006be9dc6..19df3e39bba4 100644
>--- a/include/trace/events/module.h
>+++ b/include/trace/events/module.h
>@@ -26,7 +26,8 @@ struct module;
> 	{ (1UL << TAINT_OOT_MODULE),		"O" },		\
> 	{ (1UL << TAINT_FORCED_MODULE),		"F" },		\
> 	{ (1UL << TAINT_CRAP),			"C" },		\
>-	{ (1UL << TAINT_UNSIGNED_MODULE),	"E" })
>+	{ (1UL << TAINT_UNSIGNED_MODULE),	"E" },		\
>+	{ (1UL << TAINT_FORCED_BIND),		"Y" })
> 
> TRACE_EVENT(module_load,
> 
>diff --git a/kernel/panic.c b/kernel/panic.c
>index 213725b612aa..6bf60f9dd120 100644
>--- a/kernel/panic.c
>+++ b/kernel/panic.c
>@@ -826,6 +826,7 @@ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
> 	TAINT_FLAG(RANDSTRUCT,			'T', ' '),
> 	TAINT_FLAG(TEST,			'N', ' '),
> 	TAINT_FLAG(FWCTL,			'J', ' '),
>+	TAINT_FLAG(FORCED_BIND,			'Y', ' '),
> };
> 
> #undef TAINT_FLAG
>@@ -862,9 +863,9 @@ 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 327 characters.
>+ * The verbose taint string currently requires up to 344 characters.
>  */
>-#define INIT_TAINT_BUF_MAX 350
>+#define INIT_TAINT_BUF_MAX 370
> 
> static char init_taint_buf[INIT_TAINT_BUF_MAX] __initdata;
> static char *taint_buf __refdata = init_taint_buf;
>diff --git a/tools/debugging/kernel-chktaint b/tools/debugging/kernel-chktaint
>index e1571c04afb5..d8628be37214 100755
>--- a/tools/debugging/kernel-chktaint
>+++ b/tools/debugging/kernel-chktaint
>@@ -211,6 +211,14 @@ else
> 	addout "J"
> 	echo " * fwctl's mutating debug interface was used (#19)"
> fi
>+
>+T=`expr $T / 2`
>+if [ `expr $T % 2` -eq 0 ]; then
>+	addout " "
>+else
>+	addout "Y"
>+	echo " * device was manually bound or unbound from a driver (#20)"
>+fi
> echo "Raw taint value as int/string: $taint/'$out'"
> 
> # report on any tainted loadable modules
>
>

--- Thanks!
https://lore.kernel.org/all/EE579805-42F2-4C58-B752-F28779EEB717@grrlz.net/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26 11:58   ` Bradley Morgan
@ 2026-08-26 13:10     ` Greg KH
  2026-08-26 14:26     ` Steven Rostedt
  1 sibling, 0 replies; 17+ messages in thread
From: Greg KH @ 2026-08-26 13:10 UTC (permalink / raw)
  To: Bradley Morgan
  Cc: atomlin, corbet, da.gomez, dakr, driver-core, linux-doc,
	linux-kernel, linux-modules, linux-trace-kernel, linux-usb,
	mathieu.desnoyers, mcgrof, mhiramat, petr.pavlu, rafael, rdunlap,
	rostedt, samitolvanen, skhan

On Wed, Aug 26, 2026 at 12:58:00PM +0100, Bradley Morgan wrote:
> On 26 August 2026 10:19:33 BST, Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >The ability to add and remove devices from a driver through the sysfs
> >"bind" and "unbind" files was created all those decades ago as a way
> >that kernel developers can iterate faster, and provide a debugging way
> >for users to attempt to add a new device to a driver without having to
> >rebuild their kernel.
> >
> >This api over the years has been abused and recently come under a major
> >fuzzing "attack" through tools like syzbot which decided that it would
> >attempt to just randomly bind any driver to any type of device, causing
> >loads of unneeded errors and pointless kernel patches to be generated by
> >unsuspecting new developers.
> >
> >Handle all of this by adding a new taint flag, TAINT_FORCED_BIND, which
> >will be set on the driver if the bind/unbind sysfs files are ever
> >successfully written to.  This lets kernel developers "know" that a user
> >is attempting to do something that is not normal, and as such, if the
> >kernel breaks they get to keep the shiny pieces laying around on the
> >floor.
> >
> >Note, the taint flag gets set _BEFORE_ the bind/unbind callback happens,
> >as many times crashes/oops/warnings/failures happen within the callback,
> >and the taint flag needs to be there to show what was being attempted.
> >If it were to be set after the callback happens, the oops report would
> >not properly reflect what foolishness was being attempted.
> >
> 
> sashiko found a couple valid concerns for 2/2

Yes, will fix that for v2.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 0/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26  9:19 [PATCH 0/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers Greg Kroah-Hartman
  2026-08-26  9:19 ` [PATCH 1/2] module: pull out add_taint_module() to be public Greg Kroah-Hartman
  2026-08-26  9:19 ` [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers Greg Kroah-Hartman
@ 2026-08-26 13:33 ` Michal Pecio
  2026-08-26 14:25   ` Greg Kroah-Hartman
  2 siblings, 1 reply; 17+ messages in thread
From: Michal Pecio @ 2026-08-26 13:33 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-modules, linux-kernel,
	linux-doc, linux-usb, driver-core, linux-trace-kernel

On Wed, 26 Aug 2026 11:19:31 +0200, Greg Kroah-Hartman wrote:
> The ability to add and remove devices from a driver through the sysfs
> "bind" and "unbind" files was created all those decades ago as a way
> that kernel developers can iterate faster, and provide a debugging way
> for users to attempt to add a new device to a driver without having to
> rebuild their kernel.
> 
> This api over the years has been abused and recently come under a major
> fuzzing "attack" through tools like syzbot which decided that it would
> attempt to just randomly bind any driver to any type of device, causing
> loads of unneeded errors and pointless kernel patches to be generated by
> unsuspecting new developers.

Hi Greg,

I think you confused 'bind' / 'unbind' with the likes of 'new_id' and
'driver_override'. Try binding xhci_hcd to NVMe, you won't get far.

FYI, besides being footguns, the latter are apparently used to assign
any random PCI device to some VM drivers for passthrough or whatnot.

The former hardly are footguns and have further common uses, such as
removing kernel drivers to make VM / USBFS work or "turn it off and on
again" when a driver doesn't implement recovery. I've seen a published
script which does this automatically when xhci goes belly up...


I am also not convinced that fuzzing 'unbind' alone is a bad thing.
How is that different from 'rmmod' or pulling out a USB-C plug, which
may have a bunch of USB *and* PCI devices behind it, mid-operation?

Regards,
Michal

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 0/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26 13:33 ` [PATCH 0/2] " Michal Pecio
@ 2026-08-26 14:25   ` Greg Kroah-Hartman
  2026-08-26 15:35     ` Michal Pecio
  0 siblings, 1 reply; 17+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-26 14:25 UTC (permalink / raw)
  To: Michal Pecio
  Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-modules, linux-kernel,
	linux-doc, linux-usb, driver-core, linux-trace-kernel

On Wed, Aug 26, 2026 at 03:33:11PM +0200, Michal Pecio wrote:
> On Wed, 26 Aug 2026 11:19:31 +0200, Greg Kroah-Hartman wrote:
> > The ability to add and remove devices from a driver through the sysfs
> > "bind" and "unbind" files was created all those decades ago as a way
> > that kernel developers can iterate faster, and provide a debugging way
> > for users to attempt to add a new device to a driver without having to
> > rebuild their kernel.
> > 
> > This api over the years has been abused and recently come under a major
> > fuzzing "attack" through tools like syzbot which decided that it would
> > attempt to just randomly bind any driver to any type of device, causing
> > loads of unneeded errors and pointless kernel patches to be generated by
> > unsuspecting new developers.
> 
> Hi Greg,
> 
> I think you confused 'bind' / 'unbind' with the likes of 'new_id' and
> 'driver_override'. Try binding xhci_hcd to NVMe, you won't get far.

It seems to result in a failure report that people keep sending random
patches for :(

> FYI, besides being footguns, the latter are apparently used to assign
> any random PCI device to some VM drivers for passthrough or whatnot.

Which should be fixed.

> The former hardly are footguns and have further common uses, such as
> removing kernel drivers to make VM / USBFS work or "turn it off and on
> again" when a driver doesn't implement recovery. I've seen a published
> script which does this automatically when xhci goes belly up...

And we should fix the root cause here.

> I am also not convinced that fuzzing 'unbind' alone is a bad thing.
> How is that different from 'rmmod' or pulling out a USB-C plug, which
> may have a bunch of USB *and* PCI devices behind it, mid-operation?

rmmod too is something that is never guaranteed to work, and is for
developers.  "luckily" syzbot doesn't seem to want to do that just yet
:)

This is to stem the tide of foolish patches where people/syzbot is
attempting to bind any random device to any random driver and then
reporting a "bug" for when things go wrong.  It is also here to mark a
kernel as "hey, something was manually overridden" if a normal user does
this and then attempts to ask for support for us.  Both are good things
for developers to know about.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26 11:58   ` Bradley Morgan
  2026-08-26 13:10     ` Greg KH
@ 2026-08-26 14:26     ` Steven Rostedt
  2026-08-26 14:34       ` Bradley Morgan
  1 sibling, 1 reply; 17+ messages in thread
From: Steven Rostedt @ 2026-08-26 14:26 UTC (permalink / raw)
  To: Bradley Morgan
  Cc: gregkh, atomlin, corbet, da.gomez, dakr, driver-core, linux-doc,
	linux-kernel, linux-modules, linux-trace-kernel, linux-usb,
	mathieu.desnoyers, mcgrof, mhiramat, petr.pavlu, rafael, rdunlap,
	samitolvanen, skhan

On Wed, 26 Aug 2026 12:58:00 +0100
Bradley Morgan <brads@mainlining.org> wrote:

> sashiko found a couple valid concerns for 2/2

Sashiko will respond to the email if it Cc'd linux-trace-kernel, which Greg
did. No need to mention Sashiko. It can speak for itself ;-)

-- Steve

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26 14:26     ` Steven Rostedt
@ 2026-08-26 14:34       ` Bradley Morgan
  0 siblings, 0 replies; 17+ messages in thread
From: Bradley Morgan @ 2026-08-26 14:34 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: gregkh, atomlin, corbet, da.gomez, dakr, driver-core, linux-doc,
	linux-kernel, linux-modules, linux-trace-kernel, linux-usb,
	mathieu.desnoyers, mcgrof, mhiramat, petr.pavlu, rafael, rdunlap,
	samitolvanen, skhan

On 26 August 2026 15:26:46 BST, Steven Rostedt <rostedt@goodmis.org> wrote:
>On Wed, 26 Aug 2026 12:58:00 +0100
>Bradley Morgan <brads@mainlining.org> wrote:
>
>> sashiko found a couple valid concerns for 2/2
>
>Sashiko will respond to the email if it Cc'd linux-trace-kernel, which
>Greg
>did. No need to mention Sashiko. It can speak for itself ;-)

Soz, wanted to get CC'ed to V2, if I didn't say anything, I wouldn't get
CCed, simple

I'll review it in V2, it looks fine to me but with a couple nits, I wanna
see Greg's V2 first.

>
>-- Steve

--- Thanks!
https://lore.kernel.org/all/EE579805-42F2-4C58-B752-F28779EEB717@grrlz.net/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 0/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26 14:25   ` Greg Kroah-Hartman
@ 2026-08-26 15:35     ` Michal Pecio
  2026-08-26 15:44       ` Greg Kroah-Hartman
  0 siblings, 1 reply; 17+ messages in thread
From: Michal Pecio @ 2026-08-26 15:35 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-modules, linux-kernel,
	linux-doc, linux-usb, driver-core, linux-trace-kernel

On Wed, 26 Aug 2026 16:25:42 +0200, Greg Kroah-Hartman wrote:
> > I think you confused 'bind' / 'unbind' with the likes of 'new_id'
> > and 'driver_override'. Try binding xhci_hcd to NVMe, you won't get
> > far.  
> 
> It seems to result in a failure report that people keep sending random
> patches for :(

It results in write() returning -ENODEV.

You can't bind random drivers to random devices out of the box,
you need ID overrides. And then you don't need to bind manually,
the kernel will happily select the wrong driver by default.

Authors of the recent xhci and thunderbolt patches admitted that
'driver_override' was involved in both cases.


Meanwhile, Syzbot also found a stupid write to freed memory in USB
core when HCs are unbound. You may say it doesn't matter, but:

* USB HCs are hotpluggable thunderbolt "gadgets" these days
* there were plans to alter this code so that UAF is triggered by
  hot removal of the USB device, not its parent HC

IMO the actually meaningful change would be to taint driver ID
overrides, because that's the known risky and crash-prone madness.
bind/unbind taint is noise that will be ignored.

Regards,
Michal

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 0/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26 15:35     ` Michal Pecio
@ 2026-08-26 15:44       ` Greg Kroah-Hartman
  2026-08-26 17:09         ` Michal Pecio
  0 siblings, 1 reply; 17+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-26 15:44 UTC (permalink / raw)
  To: Michal Pecio
  Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-modules, linux-kernel,
	linux-doc, linux-usb, driver-core, linux-trace-kernel

On Wed, Aug 26, 2026 at 05:35:49PM +0200, Michal Pecio wrote:
> On Wed, 26 Aug 2026 16:25:42 +0200, Greg Kroah-Hartman wrote:
> > > I think you confused 'bind' / 'unbind' with the likes of 'new_id'
> > > and 'driver_override'. Try binding xhci_hcd to NVMe, you won't get
> > > far.  
> > 
> > It seems to result in a failure report that people keep sending random
> > patches for :(
> 
> It results in write() returning -ENODEV.
> 
> You can't bind random drivers to random devices out of the box,
> you need ID overrides. And then you don't need to bind manually,
> the kernel will happily select the wrong driver by default.
> 
> Authors of the recent xhci and thunderbolt patches admitted that
> 'driver_override' was involved in both cases.

I'll be glad to taint if driver_override is also written to, but it's
bind() that triggers the actual action happening.  Or so the traces
show.

> Meanwhile, Syzbot also found a stupid write to freed memory in USB
> core when HCs are unbound. You may say it doesn't matter, but:
> 
> * USB HCs are hotpluggable thunderbolt "gadgets" these days

We support PCI devices being removed, but that falls under the PCI
hotplug rules/requirements, right?  Anyway, sure, we can fix those bugs
when found, but that's not the majority of what we are seeing at the
moment.  Look at all of the dumb platform drivers that are getting hit
with this on the syzbot reports...

> * there were plans to alter this code so that UAF is triggered by
>   hot removal of the USB device, not its parent HC

I don't understand what you mean by this.

> IMO the actually meaningful change would be to taint driver ID
> overrides, because that's the known risky and crash-prone madness.
> bind/unbind taint is noise that will be ignored.

it's not going to be ignored if panic_on_taint is enabled in syzbot,
which the authors have said they will do :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 0/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26 15:44       ` Greg Kroah-Hartman
@ 2026-08-26 17:09         ` Michal Pecio
  0 siblings, 0 replies; 17+ messages in thread
From: Michal Pecio @ 2026-08-26 17:09 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-modules, linux-kernel,
	linux-doc, linux-usb, driver-core, linux-trace-kernel

On Wed, 26 Aug 2026 17:44:06 +0200, Greg Kroah-Hartman wrote:
> On Wed, Aug 26, 2026 at 05:35:49PM +0200, Michal Pecio wrote:
> > You can't bind random drivers to random devices out of the box,
> > you need ID overrides. And then you don't need to bind manually,
> > the kernel will happily select the wrong driver by default.
> > 
> > Authors of the recent xhci and thunderbolt patches admitted that
> > 'driver_override' was involved in both cases.  
> 
> I'll be glad to taint if driver_override is also written to, but it's
> bind() that triggers the actual action happening.  Or so the traces
> show.

Well, I suppose probe() is the first victim to crash in such cases.

But if Syzbot is binding random drivers to random devices, the obvious
solution is to ban 'driver_override'. Using that is just cheating.

If it still manages to crash drivers by binding them to appropriate
devices then I would say it will finally be doing its job right :)

> > Meanwhile, Syzbot also found a stupid write to freed memory in USB
> > core when HCs are unbound. You may say it doesn't matter, but:
> > 
> > * USB HCs are hotpluggable thunderbolt "gadgets" these days  
> 
> We support PCI devices being removed, but that falls under the PCI
> hotplug rules/requirements, right?  Anyway, sure, we can fix those bugs
> when found, but that's not the majority of what we are seeing at the
> moment.  Look at all of the dumb platform drivers that are getting hit
> with this on the syzbot reports...
> 
> > * there were plans to alter this code so that UAF is triggered by
> >   hot removal of the USB device, not its parent HC  
> 
> I don't understand what you mean by this.

There are ideas to change some code to use per-device data instead of
per-HCD data. Coincidentally, Syzbot found that this use races with
freeing the HCD and it would also race with freeing the device, making
the UAF easier to trigger after proposed changes.

I gave it as an example of Syzbot doing something useful with 'unbind'
when it isn't wasting time on driver overrides.

Regards,
Michal

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers
  2026-08-26  9:19 ` [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers Greg Kroah-Hartman
  2026-08-26 11:58   ` Bradley Morgan
@ 2026-08-27 13:33   ` Johan Hovold
  1 sibling, 0 replies; 17+ messages in thread
From: Johan Hovold @ 2026-08-27 13:33 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-modules, linux-kernel,
	linux-doc, linux-usb, driver-core, linux-trace-kernel

On Wed, Aug 26, 2026 at 11:19:33AM +0200, Greg Kroah-Hartman wrote:
> The ability to add and remove devices from a driver through the sysfs
> "bind" and "unbind" files was created all those decades ago as a way
> that kernel developers can iterate faster, and provide a debugging way
> for users to attempt to add a new device to a driver without having to
> rebuild their kernel.
> 
> This api over the years has been abused and recently come under a major
> fuzzing "attack" through tools like syzbot which decided that it would
> attempt to just randomly bind any driver to any type of device, causing
> loads of unneeded errors and pointless kernel patches to be generated by
> unsuspecting new developers.
> 
> Handle all of this by adding a new taint flag, TAINT_FORCED_BIND, which
> will be set on the driver if the bind/unbind sysfs files are ever
> successfully written to.  This lets kernel developers "know" that a user
> is attempting to do something that is not normal, and as such, if the
> kernel breaks they get to keep the shiny pieces laying around on the
> floor.
> 
> Note, the taint flag gets set _BEFORE_ the bind/unbind callback happens,
> as many times crashes/oops/warnings/failures happen within the callback,
> and the taint flag needs to be there to show what was being attempted.
> If it were to be set after the callback happens, the oops report would
> not properly reflect what foolishness was being attempted.
> 
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

This makes it clear that this is a development tool, and it is a good
compromise preferable to adding unnecessary complexity or suppressing
the attributes completely just to prevent root from shooting themselves
in the foot:

Reviewed-by: Johan Hovold <johan@kernel.org>
Tested-by: Johan Hovold <johan@kernel.org>

Johan

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 1/2] module: pull out add_taint_module() to be public
  2026-08-26  9:19 ` [PATCH 1/2] module: pull out add_taint_module() to be public Greg Kroah-Hartman
  2026-08-26 11:13   ` Aaron Tomlin
@ 2026-08-27 13:36   ` Johan Hovold
  2026-08-27 14:30     ` Greg Kroah-Hartman
  1 sibling, 1 reply; 17+ messages in thread
From: Johan Hovold @ 2026-08-27 13:36 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-modules, linux-kernel,
	linux-doc, linux-usb, driver-core, linux-trace-kernel

On Wed, Aug 26, 2026 at 11:19:32AM +0200, Greg Kroah-Hartman wrote:
> Other kernel code might want to call add_taint_module() so pull it out
> and make it global.  If modules are not enabled, this defaults to a call
> to add_taint(), so all is fine.
> 
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

> -static inline void add_taint_module(struct module *mod, unsigned flag,
> -				    enum lockdep_ok lockdep_ok)
> +/**
> + * add_taint_module: add a taint flag if not already set for a specific module
> + * @mod: pointer to the module that caused the problem
> + * @flag: one of the TAINT_* constants.
> + * @lockdep_ok: whether lock debugging is still OK.
> + *
> + * If something bad has gone wrong, you'll want @lockdebug_ok = false, but for
> + * some noteworthy-but-not-corrupting cases, it can be set to true.
> + */
> +void add_taint_module(struct module *mod, unsigned flag,
> +		      enum lockdep_ok lockdep_ok)
>  {
>  	add_taint(flag, lockdep_ok);

>  	set_bit(flag, &mod->taints);

As has been pointed out, this crashes with built-in drivers. If you go
with a simple mod NULL check before this call (and updated kernel-doc)
you can add my:

Reviewed-by: Johan Hovold <johan@kernel.org>
Tested-by: Johan Hovold <johan@kernel.org>

Johan

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 1/2] module: pull out add_taint_module() to be public
  2026-08-27 13:36   ` Johan Hovold
@ 2026-08-27 14:30     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 17+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-27 14:30 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Jonathan Corbet, Shuah Khan, Randy Dunlap,
	Rafael J. Wysocki, Danilo Krummrich, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-modules, linux-kernel,
	linux-doc, linux-usb, driver-core, linux-trace-kernel

On Thu, Aug 27, 2026 at 03:36:41PM +0200, Johan Hovold wrote:
> On Wed, Aug 26, 2026 at 11:19:32AM +0200, Greg Kroah-Hartman wrote:
> > Other kernel code might want to call add_taint_module() so pull it out
> > and make it global.  If modules are not enabled, this defaults to a call
> > to add_taint(), so all is fine.
> > 
> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> 
> > -static inline void add_taint_module(struct module *mod, unsigned flag,
> > -				    enum lockdep_ok lockdep_ok)
> > +/**
> > + * add_taint_module: add a taint flag if not already set for a specific module
> > + * @mod: pointer to the module that caused the problem
> > + * @flag: one of the TAINT_* constants.
> > + * @lockdep_ok: whether lock debugging is still OK.
> > + *
> > + * If something bad has gone wrong, you'll want @lockdebug_ok = false, but for
> > + * some noteworthy-but-not-corrupting cases, it can be set to true.
> > + */
> > +void add_taint_module(struct module *mod, unsigned flag,
> > +		      enum lockdep_ok lockdep_ok)
> >  {
> >  	add_taint(flag, lockdep_ok);
> 
> >  	set_bit(flag, &mod->taints);
> 
> As has been pointed out, this crashes with built-in drivers. If you go
> with a simple mod NULL check before this call (and updated kernel-doc)
> you can add my:

Yeah, I've fixed this locally and will be resolved in v2.

> Reviewed-by: Johan Hovold <johan@kernel.org>
> Tested-by: Johan Hovold <johan@kernel.org>

Thanks!

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2026-08-27 14:32 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-26  9:19 [PATCH 0/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers Greg Kroah-Hartman
2026-08-26  9:19 ` [PATCH 1/2] module: pull out add_taint_module() to be public Greg Kroah-Hartman
2026-08-26 11:13   ` Aaron Tomlin
2026-08-26 11:54     ` Greg Kroah-Hartman
2026-08-27 13:36   ` Johan Hovold
2026-08-27 14:30     ` Greg Kroah-Hartman
2026-08-26  9:19 ` [PATCH 2/2] driver core: add TAINT_FORCED_BIND for when userspace manually messes with devices and drivers Greg Kroah-Hartman
2026-08-26 11:58   ` Bradley Morgan
2026-08-26 13:10     ` Greg KH
2026-08-26 14:26     ` Steven Rostedt
2026-08-26 14:34       ` Bradley Morgan
2026-08-27 13:33   ` Johan Hovold
2026-08-26 13:33 ` [PATCH 0/2] " Michal Pecio
2026-08-26 14:25   ` Greg Kroah-Hartman
2026-08-26 15:35     ` Michal Pecio
2026-08-26 15:44       ` Greg Kroah-Hartman
2026-08-26 17:09         ` Michal Pecio

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox