diff --git a/Documentation/admin-guide/tainted-kernels.rst b/Documentation/admin-guide/tainted-kernels.rst index 9ead927a37c0..abbf5e3dd749 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 #include #include +#include #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 892045d8409e..a4dbb6b8cd2b 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