2006-09-29 02:10:47

by Randy Dunlap

[permalink] [raw]
Subject: [PATCH] list module taint flags in Oops/panic

From: Randy Dunlap <[email protected]>

When listing loaded modules during an oops or panic, also list each
module's Tainted flags if non-zero (P: Proprietary or F: Forced load only).

If a module is did not taint the kernel, it is just listed like
usbcore
but if it did taint the kernel, it is listed like
wizmodem(PF)

Example:
[ 3260.121718] Unable to handle kernel NULL pointer dereference at 0000000000000000 RIP:
[ 3260.121729] [<ffffffff8804c099>] :dump_test:proc_dump_test+0x99/0xc8
[ 3260.121742] PGD fe8d067 PUD 264a6067 PMD 0
[ 3260.121748] Oops: 0002 [1] SMP
[ 3260.121753] CPU 1
[ 3260.121756] Modules linked in: dump_test(P) snd_pcm_oss snd_mixer_oss snd_seq snd_seq_device ide_cd generic ohci1394 snd_hda_intel snd_hda_codec snd_pcm snd_timer snd ieee1394 snd_page_alloc piix ide_core arcmsr aic79xx scsi_transport_spi usblp
[ 3260.121785] Pid: 5556, comm: bash Tainted: P 2.6.18-git10 #1

[Alternatively, I can look into listing tainted flags with 'lsmod',
but that won't help in oopsen/panics so much.]

Signed-off-by: Randy Dunlap <[email protected]>
---
include/linux/module.h | 2 ++
kernel/module.c | 36 +++++++++++++++++++++++++++++++++---
2 files changed, 35 insertions(+), 3 deletions(-)

--- linux-2618-g10.orig/include/linux/module.h
+++ linux-2618-g10/include/linux/module.h
@@ -320,6 +320,8 @@ struct module
/* Am I GPL-compatible */
int license_gplok;

+ unsigned int taints; /* same bits as kernel:tainted */
+
#ifdef CONFIG_MODULE_UNLOAD
/* Reference counts */
struct module_ref ref[NR_CPUS];
--- linux-2618-g10.orig/kernel/module.c
+++ linux-2618-g10/kernel/module.c
@@ -851,6 +851,7 @@ static int check_version(Elf_Shdr *sechd
printk("%s: no version for \"%s\" found: kernel tainted.\n",
mod->name, symname);
add_taint(TAINT_FORCED_MODULE);
+ mod->taints |= TAINT_FORCED_MODULE;
}
return 1;
}
@@ -1325,6 +1326,7 @@ static void set_license(struct module *m
printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
mod->name, license);
add_taint(TAINT_PROPRIETARY_MODULE);
+ mod->taints |= TAINT_PROPRIETARY_MODULE;
}
}

@@ -1604,6 +1606,7 @@ static struct module *load_module(void _
/* This is allowed: modprobe --force will invalidate it. */
if (!modmagic) {
add_taint(TAINT_FORCED_MODULE);
+ mod->taints |= TAINT_FORCED_MODULE;
printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
mod->name);
} else if (!same_magic(modmagic, vermagic)) {
@@ -1697,10 +1700,14 @@ static struct module *load_module(void _
/* Set up license info based on the info section */
set_license(mod, get_modinfo(sechdrs, infoindex, "license"));

- if (strcmp(mod->name, "ndiswrapper") == 0)
+ if (strcmp(mod->name, "ndiswrapper") == 0) {
add_taint(TAINT_PROPRIETARY_MODULE);
- if (strcmp(mod->name, "driverloader") == 0)
+ mod->taints |= TAINT_PROPRIETARY_MODULE;
+ }
+ if (strcmp(mod->name, "driverloader") == 0) {
add_taint(TAINT_PROPRIETARY_MODULE);
+ mod->taints |= TAINT_PROPRIETARY_MODULE;
+ }

/* Set up MODINFO_ATTR fields */
setup_modinfo(mod, sechdrs, infoindex);
@@ -1746,6 +1753,7 @@ static struct module *load_module(void _
printk(KERN_WARNING "%s: No versions for exported symbols."
" Tainting kernel.\n", mod->name);
add_taint(TAINT_FORCED_MODULE);
+ mod->taints |= TAINT_FORCED_MODULE;
}
#endif

@@ -2212,6 +2220,28 @@ struct module *module_text_address(unsig
return mod;
}

+static char *taint_flags(unsigned int taints)
+{
+ static char buf[8];
+ int bx;
+
+ if (!taints)
+ return "";
+
+ buf[0] = '(';
+ bx = 1;
+ if (taints & TAINT_PROPRIETARY_MODULE)
+ buf [bx++] = 'P';
+ if (taints & TAINT_FORCED_MODULE)
+ buf [bx++] = 'F';
+ /* TAINT_FORCED_RMMOD: could be added */
+ /* TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE
+ * don't apply to modules */
+ buf[bx] = ')';
+
+ return buf;
+}
+
/* Don't grab lock, we're oopsing. */
void print_modules(void)
{
@@ -2219,7 +2249,7 @@ void print_modules(void)

printk("Modules linked in:");
list_for_each_entry(mod, &modules, list)
- printk(" %s", mod->name);
+ printk(" %s%s", mod->name, taint_flags(mod->taints));
printk("\n");
}



---


2006-09-29 20:31:46

by Alistair John Strachan

[permalink] [raw]
Subject: Re: [PATCH] list module taint flags in Oops/panic

On Friday 29 September 2006 03:12, Randy Dunlap wrote:
> From: Randy Dunlap <[email protected]>
>
> When listing loaded modules during an oops or panic, also list each
> module's Tainted flags if non-zero (P: Proprietary or F: Forced load only).
>
> If a module is did not taint the kernel, it is just listed like
> usbcore
> but if it did taint the kernel, it is listed like
> wizmodem(PF)
>
> Example:
> [ 3260.121718] Unable to handle kernel NULL pointer dereference at
> 0000000000000000 RIP: [ 3260.121729] [<ffffffff8804c099>]
> :dump_test:proc_dump_test+0x99/0xc8 [ 3260.121742] PGD fe8d067 PUD 264a6067
> PMD 0
> [ 3260.121748] Oops: 0002 [1] SMP
> [ 3260.121753] CPU 1
> [ 3260.121756] Modules linked in: dump_test(P) snd_pcm_oss snd_mixer_oss
> snd_seq snd_seq_device ide_cd generic ohci1394 snd_hda_intel snd_hda_codec
> snd_pcm snd_timer snd ieee1394 snd_page_alloc piix ide_core arcmsr aic79xx
> scsi_transport_spi usblp [ 3260.121785] Pid: 5556, comm: bash Tainted: P
> 2.6.18-git10 #1
>
> [Alternatively, I can look into listing tainted flags with 'lsmod',
> but that won't help in oopsen/panics so much.]

I think this is definitely a good start.

--
Cheers,
Alistair.

Final year Computer Science undergraduate.
1F2 55 South Clerk Street, Edinburgh, UK.

2006-10-03 03:04:09

by Florin Malita

[permalink] [raw]
Subject: Re: [PATCH] list module taint flags in Oops/panic

Randy Dunlap wrote:
> From: Randy Dunlap <[email protected]>
>
> When listing loaded modules during an oops or panic, also list each
> module's Tainted flags if non-zero (P: Proprietary or F: Forced load only).
>

Funny, I was playing with something very similar last weekend, then I
noticed your patch merged into mainline ;) So here are some comments...

> --- linux-2618-g10.orig/include/linux/module.h
> +++ linux-2618-g10/include/linux/module.h
> @@ -320,6 +320,8 @@ struct module
> /* Am I GPL-compatible */
> int license_gplok;
>
> + unsigned int taints; /* same bits as kernel:tainted */
>

No need to keep 'license_gplok' around anymore, it should be equivalent
to !(taints & TAINT_PROPRIETARY_MODULE).

> @@ -851,6 +851,7 @@ static int check_version(Elf_Shdr *sechd
> printk("%s: no version for \"%s\" found: kernel tainted.\n",
> mod->name, symname);
> add_taint(TAINT_FORCED_MODULE);
> + mod->taints |= TAINT_FORCED_MODULE;
> }
>

This seems wrong, it only dirties mod->taints if the kernel is not
already F-tainted (the branch is conditioned by !(tainted &
TAINT_FORCED_MODULE)). So only the first forcefully-loaded module gets
its F bit set, which is probably not the intention...

> @@ -1325,6 +1326,7 @@ static void set_license(struct module *m
> printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
> mod->name, license);
> add_taint(TAINT_PROPRIETARY_MODULE);
> + mod->taints |= TAINT_PROPRIETARY_MODULE;
> }
>

Similarly here, will only take the branch upon loading the first
proprietary module (conditional on !(tainted & TAINT_PROPRIETARY_MODULE)).

The currently merged version also has a problem in taint_flags():

static char *taint_flags(unsigned int taints, char *buf)
{
*buf = '\0';
if (taints) {
int bx;

buf[0] = '(';
bx = 1;
if (taints & TAINT_PROPRIETARY_MODULE)
buf[bx++] = 'P';
if (taints & TAINT_FORCED_MODULE)
buf[bx++] = 'F';
/*
* TAINT_FORCED_RMMOD: could be added.
* TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE
don't
* apply to modules.
*/
buf[bx] = ')';
}
return buf;
}

The buffer is not NULL-terminated after printing the flags.

Also, it would be nice to show per-module taint info in /proc/modules
too. So how about the following (applies on top of the merged
version/current git, tested):

Signed-off-by: Florin Malita <[email protected]>
---

include/linux/module.h | 3 -
kernel/module.c | 94 +++++++++++++++++++++++++------------------------
2 files changed, 49 insertions(+), 48 deletions(-)

diff --git a/include/linux/module.h b/include/linux/module.h
index 4b2d809..d1d00ce 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -317,9 +317,6 @@ struct module
/* Am I unsafe to unload? */
int unsafe;

- /* Am I GPL-compatible */
- int license_gplok;
-
unsigned int taints; /* same bits as kernel:tainted */

#ifdef CONFIG_MODULE_UNLOAD
diff --git a/kernel/module.c b/kernel/module.c
index 7c77a0a..a258cd5 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -87,6 +87,12 @@ static inline int strong_try_module_get(
return try_module_get(mod);
}

+static inline void add_taint_module(struct module *mod, unsigned flag)
+{
+ add_taint(flag);
+ mod->taints |= flag;
+}
+
/* A thread that wants to hold a reference to a module only while it
* is running can call ths to safely exit.
* nfsd and lockd use this.
@@ -847,12 +853,10 @@ static int check_version(Elf_Shdr *sechd
return 0;
}
/* Not in module's version table. OK, but that taints the kernel. */
- if (!(tainted & TAINT_FORCED_MODULE)) {
+ if (!(tainted & TAINT_FORCED_MODULE))
printk("%s: no version for \"%s\" found: kernel tainted.\n",
mod->name, symname);
- add_taint(TAINT_FORCED_MODULE);
- mod->taints |= TAINT_FORCED_MODULE;
- }
+ add_taint_module(mod, TAINT_FORCED_MODULE);
return 1;
}

@@ -910,7 +914,8 @@ static unsigned long resolve_symbol(Elf_
unsigned long ret;
const unsigned long *crc;

- ret = __find_symbol(name, &owner, &crc, mod->license_gplok);
+ ret = __find_symbol(name, &owner, &crc,
+ !(mod->taints & TAINT_PROPRIETARY_MODULE));
if (ret) {
/* use_module can fail due to OOM, or module unloading */
if (!check_version(sechdrs, versindex, name, mod, crc) ||
@@ -1335,12 +1340,11 @@ static void set_license(struct module *m
if (!license)
license = "unspecified";

- mod->license_gplok = license_is_gpl_compatible(license);
- if (!mod->license_gplok && !(tainted & TAINT_PROPRIETARY_MODULE)) {
- printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
- mod->name, license);
- add_taint(TAINT_PROPRIETARY_MODULE);
- mod->taints |= TAINT_PROPRIETARY_MODULE;
+ if (!license_is_gpl_compatible(license)) {
+ if (!(tainted & TAINT_PROPRIETARY_MODULE))
+ printk(KERN_WARNING "%s: module license '%s' taints"
+ "kernel.\n", mod->name, license);
+ add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
}
}

@@ -1619,8 +1623,7 @@ #endif
modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
/* This is allowed: modprobe --force will invalidate it. */
if (!modmagic) {
- add_taint(TAINT_FORCED_MODULE);
- mod->taints |= TAINT_FORCED_MODULE;
+ add_taint_module(mod, TAINT_FORCED_MODULE);
printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
mod->name);
} else if (!same_magic(modmagic, vermagic)) {
@@ -1714,14 +1717,10 @@ #endif
/* Set up license info based on the info section */
set_license(mod, get_modinfo(sechdrs, infoindex, "license"));

- if (strcmp(mod->name, "ndiswrapper") == 0) {
- add_taint(TAINT_PROPRIETARY_MODULE);
- mod->taints |= TAINT_PROPRIETARY_MODULE;
- }
- if (strcmp(mod->name, "driverloader") == 0) {
- add_taint(TAINT_PROPRIETARY_MODULE);
- mod->taints |= TAINT_PROPRIETARY_MODULE;
- }
+ if (strcmp(mod->name, "ndiswrapper") == 0)
+ add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+ if (strcmp(mod->name, "driverloader") == 0)
+ add_taint_module(mod, TAINT_PROPRIETARY_MODULE);

/* Set up MODINFO_ATTR fields */
setup_modinfo(mod, sechdrs, infoindex);
@@ -1766,8 +1765,7 @@ #ifdef CONFIG_MODVERSIONS
(mod->num_unused_gpl_syms && !unusedgplcrcindex)) {
printk(KERN_WARNING "%s: No versions for exported symbols."
" Tainting kernel.\n", mod->name);
- add_taint(TAINT_FORCED_MODULE);
- mod->taints |= TAINT_FORCED_MODULE;
+ add_taint_module(mod, TAINT_FORCED_MODULE);
}
#endif

@@ -2131,9 +2129,33 @@ static void m_stop(struct seq_file *m, v
mutex_unlock(&module_mutex);
}

+static char *taint_flags(unsigned int taints, char *buf)
+{
+ int bx = 0;
+
+ if (taints) {
+ buf[bx++] = '(';
+ if (taints & TAINT_PROPRIETARY_MODULE)
+ buf[bx++] = 'P';
+ if (taints & TAINT_FORCED_MODULE)
+ buf[bx++] = 'F';
+ /*
+ * TAINT_FORCED_RMMOD: could be added.
+ * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
+ * apply to modules.
+ */
+ buf[bx++] = ')';
+ }
+ buf[bx] = '\0';
+
+ return buf;
+}
+
static int m_show(struct seq_file *m, void *p)
{
struct module *mod = list_entry(p, struct module, list);
+ char buf[8];
+
seq_printf(m, "%s %lu",
mod->name, mod->init_size + mod->core_size);
print_unload_info(m, mod);
@@ -2146,6 +2168,10 @@ static int m_show(struct seq_file *m, vo
/* Used by oprofile and other similar tools. */
seq_printf(m, " 0x%p", mod->module_core);

+ /* Taints info */
+ if (mod->taints)
+ seq_printf(m, " %s", taint_flags(mod->taints, buf));
+
seq_printf(m, "\n");
return 0;
}
@@ -2234,28 +2260,6 @@ struct module *module_text_address(unsig
return mod;
}

-static char *taint_flags(unsigned int taints, char *buf)
-{
- *buf = '\0';
- if (taints) {
- int bx;
-
- buf[0] = '(';
- bx = 1;
- if (taints & TAINT_PROPRIETARY_MODULE)
- buf[bx++] = 'P';
- if (taints & TAINT_FORCED_MODULE)
- buf[bx++] = 'F';
- /*
- * TAINT_FORCED_RMMOD: could be added.
- * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
- * apply to modules.
- */
- buf[bx] = ')';
- }
- return buf;
-}
-
/* Don't grab lock, we're oopsing. */
void print_modules(void)
{


2006-10-03 18:30:34

by Randy Dunlap

[permalink] [raw]
Subject: Re: [PATCH] list module taint flags in Oops/panic

On Mon, 02 Oct 2006 23:04:32 -0400 Florin Malita wrote:

> Randy Dunlap wrote:
> > From: Randy Dunlap <[email protected]>
> >
> > When listing loaded modules during an oops or panic, also list each
> > module's Tainted flags if non-zero (P: Proprietary or F: Forced load only).
> >
>
> Funny, I was playing with something very similar last weekend, then I
> noticed your patch merged into mainline ;) So here are some comments...

Yep, all good. Thanks for the fixes.
Acked-by: Randy Dunlap <[email protected]>


> > --- linux-2618-g10.orig/include/linux/module.h
> > +++ linux-2618-g10/include/linux/module.h
> > @@ -320,6 +320,8 @@ struct module
> > /* Am I GPL-compatible */
> > int license_gplok;
> >
> > + unsigned int taints; /* same bits as kernel:tainted */
> >
>
> No need to keep 'license_gplok' around anymore, it should be equivalent
> to !(taints & TAINT_PROPRIETARY_MODULE).
>
> > @@ -851,6 +851,7 @@ static int check_version(Elf_Shdr *sechd
> > printk("%s: no version for \"%s\" found: kernel tainted.\n",
> > mod->name, symname);
> > add_taint(TAINT_FORCED_MODULE);
> > + mod->taints |= TAINT_FORCED_MODULE;
> > }
> >
>
> This seems wrong, it only dirties mod->taints if the kernel is not
> already F-tainted (the branch is conditioned by !(tainted &
> TAINT_FORCED_MODULE)). So only the first forcefully-loaded module gets
> its F bit set, which is probably not the intention...
>
> > @@ -1325,6 +1326,7 @@ static void set_license(struct module *m
> > printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
> > mod->name, license);
> > add_taint(TAINT_PROPRIETARY_MODULE);
> > + mod->taints |= TAINT_PROPRIETARY_MODULE;
> > }
> >
>
> Similarly here, will only take the branch upon loading the first
> proprietary module (conditional on !(tainted & TAINT_PROPRIETARY_MODULE)).
>
> The currently merged version also has a problem in taint_flags():
>
> static char *taint_flags(unsigned int taints, char *buf)
> {
> *buf = '\0';
> if (taints) {
> int bx;
>
> buf[0] = '(';
> bx = 1;
> if (taints & TAINT_PROPRIETARY_MODULE)
> buf[bx++] = 'P';
> if (taints & TAINT_FORCED_MODULE)
> buf[bx++] = 'F';
> /*
> * TAINT_FORCED_RMMOD: could be added.
> * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE
> don't
> * apply to modules.
> */
> buf[bx] = ')';
> }
> return buf;
> }
>
> The buffer is not NULL-terminated after printing the flags.
>
> Also, it would be nice to show per-module taint info in /proc/modules
> too. So how about the following (applies on top of the merged
> version/current git, tested):
>
> Signed-off-by: Florin Malita <[email protected]>
> ---
>
> include/linux/module.h | 3 -
> kernel/module.c | 94 +++++++++++++++++++++++++------------------------
> 2 files changed, 49 insertions(+), 48 deletions(-)
>
> diff --git a/include/linux/module.h b/include/linux/module.h
> index 4b2d809..d1d00ce 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -317,9 +317,6 @@ struct module
> /* Am I unsafe to unload? */
> int unsafe;
>
> - /* Am I GPL-compatible */
> - int license_gplok;
> -
> unsigned int taints; /* same bits as kernel:tainted */
>
> #ifdef CONFIG_MODULE_UNLOAD
> diff --git a/kernel/module.c b/kernel/module.c
> index 7c77a0a..a258cd5 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -87,6 +87,12 @@ static inline int strong_try_module_get(
> return try_module_get(mod);
> }
>
> +static inline void add_taint_module(struct module *mod, unsigned flag)
> +{
> + add_taint(flag);
> + mod->taints |= flag;
> +}
> +
> /* A thread that wants to hold a reference to a module only while it
> * is running can call ths to safely exit.
> * nfsd and lockd use this.
> @@ -847,12 +853,10 @@ static int check_version(Elf_Shdr *sechd
> return 0;
> }
> /* Not in module's version table. OK, but that taints the kernel. */
> - if (!(tainted & TAINT_FORCED_MODULE)) {
> + if (!(tainted & TAINT_FORCED_MODULE))
> printk("%s: no version for \"%s\" found: kernel tainted.\n",
> mod->name, symname);
> - add_taint(TAINT_FORCED_MODULE);
> - mod->taints |= TAINT_FORCED_MODULE;
> - }
> + add_taint_module(mod, TAINT_FORCED_MODULE);
> return 1;
> }
>
> @@ -910,7 +914,8 @@ static unsigned long resolve_symbol(Elf_
> unsigned long ret;
> const unsigned long *crc;
>
> - ret = __find_symbol(name, &owner, &crc, mod->license_gplok);
> + ret = __find_symbol(name, &owner, &crc,
> + !(mod->taints & TAINT_PROPRIETARY_MODULE));
> if (ret) {
> /* use_module can fail due to OOM, or module unloading */
> if (!check_version(sechdrs, versindex, name, mod, crc) ||
> @@ -1335,12 +1340,11 @@ static void set_license(struct module *m
> if (!license)
> license = "unspecified";
>
> - mod->license_gplok = license_is_gpl_compatible(license);
> - if (!mod->license_gplok && !(tainted & TAINT_PROPRIETARY_MODULE)) {
> - printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
> - mod->name, license);
> - add_taint(TAINT_PROPRIETARY_MODULE);
> - mod->taints |= TAINT_PROPRIETARY_MODULE;
> + if (!license_is_gpl_compatible(license)) {
> + if (!(tainted & TAINT_PROPRIETARY_MODULE))
> + printk(KERN_WARNING "%s: module license '%s' taints"
> + "kernel.\n", mod->name, license);
> + add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
> }
> }
>
> @@ -1619,8 +1623,7 @@ #endif
> modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
> /* This is allowed: modprobe --force will invalidate it. */
> if (!modmagic) {
> - add_taint(TAINT_FORCED_MODULE);
> - mod->taints |= TAINT_FORCED_MODULE;
> + add_taint_module(mod, TAINT_FORCED_MODULE);
> printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
> mod->name);
> } else if (!same_magic(modmagic, vermagic)) {
> @@ -1714,14 +1717,10 @@ #endif
> /* Set up license info based on the info section */
> set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
>
> - if (strcmp(mod->name, "ndiswrapper") == 0) {
> - add_taint(TAINT_PROPRIETARY_MODULE);
> - mod->taints |= TAINT_PROPRIETARY_MODULE;
> - }
> - if (strcmp(mod->name, "driverloader") == 0) {
> - add_taint(TAINT_PROPRIETARY_MODULE);
> - mod->taints |= TAINT_PROPRIETARY_MODULE;
> - }
> + if (strcmp(mod->name, "ndiswrapper") == 0)
> + add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
> + if (strcmp(mod->name, "driverloader") == 0)
> + add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
>
> /* Set up MODINFO_ATTR fields */
> setup_modinfo(mod, sechdrs, infoindex);
> @@ -1766,8 +1765,7 @@ #ifdef CONFIG_MODVERSIONS
> (mod->num_unused_gpl_syms && !unusedgplcrcindex)) {
> printk(KERN_WARNING "%s: No versions for exported symbols."
> " Tainting kernel.\n", mod->name);
> - add_taint(TAINT_FORCED_MODULE);
> - mod->taints |= TAINT_FORCED_MODULE;
> + add_taint_module(mod, TAINT_FORCED_MODULE);
> }
> #endif
>
> @@ -2131,9 +2129,33 @@ static void m_stop(struct seq_file *m, v
> mutex_unlock(&module_mutex);
> }
>
> +static char *taint_flags(unsigned int taints, char *buf)
> +{
> + int bx = 0;
> +
> + if (taints) {
> + buf[bx++] = '(';
> + if (taints & TAINT_PROPRIETARY_MODULE)
> + buf[bx++] = 'P';
> + if (taints & TAINT_FORCED_MODULE)
> + buf[bx++] = 'F';
> + /*
> + * TAINT_FORCED_RMMOD: could be added.
> + * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
> + * apply to modules.
> + */
> + buf[bx++] = ')';
> + }
> + buf[bx] = '\0';
> +
> + return buf;
> +}
> +
> static int m_show(struct seq_file *m, void *p)
> {
> struct module *mod = list_entry(p, struct module, list);
> + char buf[8];
> +
> seq_printf(m, "%s %lu",
> mod->name, mod->init_size + mod->core_size);
> print_unload_info(m, mod);
> @@ -2146,6 +2168,10 @@ static int m_show(struct seq_file *m, vo
> /* Used by oprofile and other similar tools. */
> seq_printf(m, " 0x%p", mod->module_core);
>
> + /* Taints info */
> + if (mod->taints)
> + seq_printf(m, " %s", taint_flags(mod->taints, buf));
> +
> seq_printf(m, "\n");
> return 0;
> }
> @@ -2234,28 +2260,6 @@ struct module *module_text_address(unsig
> return mod;
> }
>
> -static char *taint_flags(unsigned int taints, char *buf)
> -{
> - *buf = '\0';
> - if (taints) {
> - int bx;
> -
> - buf[0] = '(';
> - bx = 1;
> - if (taints & TAINT_PROPRIETARY_MODULE)
> - buf[bx++] = 'P';
> - if (taints & TAINT_FORCED_MODULE)
> - buf[bx++] = 'F';
> - /*
> - * TAINT_FORCED_RMMOD: could be added.
> - * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
> - * apply to modules.
> - */
> - buf[bx] = ')';
> - }
> - return buf;
> -}
> -
> /* Don't grab lock, we're oopsing. */
> void print_modules(void)
> {
>
>
> -

---
~Randy