This makes it easier to spot out-of-tree modules.  We have enough
bugs of our own to deal with, before supporting these.

Signed-off-by: Ben Hutchings <[email protected]>
---
I want to apply this to squeeze.  I've seen one too many panics with
VMware or VirtualBox modules in them, which appear to be worse than
anything in drivers/staging.

Ben.

 include/linux/kernel.h |    1 +
 kernel/module.c        |    8 +++++++-
 kernel/panic.c         |    2 ++
 scripts/mod/modpost.c  |    7 +++++++
 4 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f4e3184..3aeb221 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -334,6 +334,7 @@ extern enum system_states {
 #define TAINT_OVERRIDDEN_ACPI_TABLE    8
 #define TAINT_WARN                     9
 #define TAINT_CRAP                     10
+#define TAINT_OOT_MODULE               11
 
 extern void dump_stack(void) __cold;
 
diff --git a/kernel/module.c b/kernel/module.c
index 4b270e6..8d87d61 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2097,7 +2097,7 @@ static noinline struct module *load_module(void __user 
*umod,
        Elf_Ehdr *hdr;
        Elf_Shdr *sechdrs;
        char *secstrings, *args, *modmagic, *strtab = NULL;
-       char *staging;
+       char *intree, *staging;
        unsigned int i;
        unsigned int symindex = 0;
        unsigned int strindex = 0;
@@ -2208,6 +2208,10 @@ static noinline struct module *load_module(void __user 
*umod,
                goto free_hdr;
        }
 
+       intree = get_modinfo(sechdrs, infoindex, "intree");
+       if (!intree)
+               add_taint_module(mod, TAINT_OOT_MODULE);
+
        staging = get_modinfo(sechdrs, infoindex, "staging");
        if (staging) {
                add_taint_module(mod, TAINT_CRAP);
@@ -2893,6 +2897,8 @@ static char *module_flags(struct module *mod, char *buf)
                        buf[bx++] = 'F';
                if (mod->taints & (1 << TAINT_CRAP))
                        buf[bx++] = 'C';
+               if (mod->taints & (1 << TAINT_OOT_MODULE))
+                       buf[bx++] = 'O';
                /*
                 * TAINT_FORCED_RMMOD: could be added.
                 * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
diff --git a/kernel/panic.c b/kernel/panic.c
index 96b45d0..4464f61 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -161,6 +161,7 @@ static const struct tnt tnts[] = {
        { TAINT_OVERRIDDEN_ACPI_TABLE,  'A', ' ' },
        { TAINT_WARN,                   'W', ' ' },
        { TAINT_CRAP,                   'C', ' ' },
+       { TAINT_OOT_MODULE,             'O', ' ' },
 };
 
 /**
@@ -177,6 +178,7 @@ static const struct tnt tnts[] = {
  *  'A' - ACPI table overridden.
  *  'W' - Taint on warning.
  *  'C' - modules from drivers/staging are loaded.
+ *  'O' - Out-of-tree module has been loaded.
  *
  *     The string is overwritten by the next call to print_tainted().
  */
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 03efeab..d6671b0 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1746,6 +1746,12 @@ static void add_header(struct buffer *b, struct module 
*mod)
        buf_printf(b, "};\n");
 }
 
+static void add_intree_flag(struct buffer *b, int is_intree)
+{
+       if (is_intree)
+               buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
+}
+
 static void add_staging_flag(struct buffer *b, const char *name)
 {
        static const char *staging_dir = "drivers/staging";
@@ -2164,6 +2170,7 @@ int main(int argc, char **argv)
                buf.pos = 0;
 
                add_header(&buf, mod);
+               add_intree_flag(&buf, !external_module);
                add_staging_flag(&buf, mod->name);
                err |= add_versions(&buf, mod);
                add_depends(&buf, mod, modules);
-- 
1.7.2.3


Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to