Hi Dave, Since v4: - Updated help_mod[] help page - User is notified if no tainted modules exists - Added the '-t' option, to display the hexadecimal value of a module's "taint" flag Examples: crash> mod -T NOTE: modules have changed on this system -- reinitializing NAME TAINT test GFO crash> mod -t NAME TAINT test 0x1002 crash> mod -T NAME TAINT vxfs P(U) vxspec P(U) dmpaa P(U) dmpap P(U) dmpjbod P(U) fdd P(U) vxportal P(U) vxdmp P(U) vxio P(U) llt P(U) gab P(U) vxfen P(U) amf P(U) vxodm P(U) crash> mod -t NAME TAINT vxfs 0x1 vxspec 0x1 dmpaa 0x1 dmpap 0x1 dmpjbod 0x1 fdd 0x1 vxportal 0x1 vxdmp 0x1 vxio 0x1 llt 0x1 gab 0x1 vxfen 0x1 amf 0x1 vxodm 0x1 Regards, Aaron ---8<--- help.c | 23 +++++++- kernel.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 202 insertions(+), 2 deletions(-)
diff --git a/help.c b/help.c index c9ae57e..ec905df 100755 --- a/help.c +++ b/help.c @@ -4495,7 +4495,7 @@ NULL char *help_mod[] = { "mod", "module information and loading of symbols and debugging data", -"-s module [objfile] | -d module | -S [directory] | -D | -r | -R | -o | -g", +"-s module [objfile] | -d module | -S [directory] | -D | -T | -t | -r | -R | -o | -g", " With no arguments, this command displays basic information of the currently", " installed modules, consisting of the module address, name, size, the", " object file name (if known), and whether the module was compiled with", @@ -4547,6 +4547,10 @@ char *help_mod[] = { " argument is appended, then the search will be restricted", " to that directory.", " -D Deletes the symbolic and debugging data of all modules.", +" -T Report modules that are \"tainted\" and display their", +" symbolic representation (for kernels with the tnts[]", +" array only).", +" -t Same as the above, but will display in hexadecimal.", " -r Passes the -readnow flag to the embedded gdb module,", " which will override the two-stage strategy that it uses", " for reading symbol tables from module object files.", @@ -4557,6 +4561,9 @@ char *help_mod[] = { " start and end addresses to its symbol list.", " -o Load module symbols with old mechanism.", " ", +" Where the -T (or -t) is used, the the relevant kernel sources should be", +" consulted for the meaning of either the letter(s) or hexadecimal bit-value(s).", +" ", " If the %s session was invoked with the \"--mod <directory>\" option, or", " a CRASH_MODULE_PATH environment variable exists, then /lib/modules/<release>", " will be overridden as the default directory tree that is searched for module", @@ -4673,6 +4680,20 @@ char *help_mod[] = { " c806e000 autofs 9316 (not loaded)", " c8072000 nfsd 151896 (not loaded)", " c80a1000 mdacon 3556 (not loaded)", +" ", +" Display modules that are \"tainted\" with their symbolic representation:", +" ", +" %s> mod -T", +" NAME TAINT", +" dm_mod G", +" scsi_tgt G", +" serio_raw G", +" dm_log G", +" ata_generic G", +" qla2xxx P(U)", +" dm_region_hash G", +" enclosure G", +" pata_acpi G", NULL }; diff --git a/kernel.c b/kernel.c index 2dac4ed..eb5f2a5 100755 --- a/kernel.c +++ b/kernel.c @@ -22,6 +22,7 @@ #include <ctype.h> static void do_module_cmd(ulong, char *, ulong, char *, char *); +static void show_module_taint(int); static char *find_module_objfile(char *, char *, char *); static char *module_objfile_search(char *, char *, char *); static char *get_loadavg(char *); @@ -3220,6 +3221,8 @@ irregularity: #define DELETE_ALL_MODULE_SYMBOLS (5) #define REMOTE_MODULE_SAVE_MSG (6) #define REINIT_MODULES (7) +#define LIST_ALL_MODULE_TAINT (8) +#define LIST_ALL_MODULE_TAINT_OLD (9) void cmd_mod(void) @@ -3294,7 +3297,7 @@ cmd_mod(void) address = 0; flag = LIST_MODULE_HDR; - while ((c = getopt(argcnt, args, "Rd:Ds:So")) != EOF) { + while ((c = getopt(argcnt, args, "Rd:Ds:SoTt")) != EOF) { switch(c) { case 'R': @@ -3365,6 +3368,20 @@ cmd_mod(void) cmd_usage(pc->curcmd, SYNOPSIS); break; + case 'T': + if (flag) + cmd_usage(pc->curcmd, SYNOPSIS); + else + flag = LIST_ALL_MODULE_TAINT; + break; + + case 't': + if (flag) + cmd_usage(pc->curcmd, SYNOPSIS); + else + flag = LIST_ALL_MODULE_TAINT_OLD; + break; + default: argerrs++; break; @@ -3485,6 +3502,163 @@ check_specified_module_tree(char *module, char *gdb_buffer) return retval; } +void +show_module_taint(int flag) +{ + int i, j, bx = 0; + struct load_module *lm; + int maxnamelen = 0; + char buf[BUFSIZE]; + char buf1[BUFSIZE]; + int gpgsig_ok, license_gplok; + struct syment *sp = NULL; + uint *taintsp, taints, tnt_struct = 0; + uint8_t tnt_bit; + char tnt_true, tnt_false; + int found = FALSE; + + if (flag != LIST_ALL_MODULE_TAINT_OLD && + !kernel_symbol_exists("tnts") && + !MEMBER_EXISTS("tnt", "bit") && + !MEMBER_EXISTS("tnt", "true") && + !MEMBER_EXISTS("tnt", "false")) + error(FATAL, + "tnts[] array does not exists in this kernel.\n"); + + if (!MEMBER_EXISTS("module", "taints") && + !MEMBER_EXISTS("module", "license_gplok")) + error(FATAL, + "neither taints nor license_gplok exists.\n"); + + i = 0; + do { + lm = &st->load_modules[i]; + + if (MEMBER_EXISTS("module", "taints")) { + readmem(lm->module_struct + MEMBER_OFFSET("module", "taints"), + KVADDR, &taints, sizeof(uint), "module taints", + FAULT_ON_ERROR); + + if (taints) + break; + } else { + readmem(lm->module_struct + MEMBER_OFFSET("module", "license_gplok"), + KVADDR, &license_gplok, sizeof(int), "module license_gplok", + FAULT_ON_ERROR); + + if (license_gplok) + break; + } + i++; + + if (i >= kt->mods_installed) + error(FATAL, "no tainted modules.\n"); + + } while (i < kt->mods_installed); + + if (symbol_exists("tnts") && + flag != LIST_ALL_MODULE_TAINT_OLD) { + sp = symbol_search("tnts"); + tnt_struct = STRUCT_SIZE("struct tnt"); + } + + for (i = 0; i < kt->mods_installed; i++) { + lm = &st->load_modules[i]; + maxnamelen = strlen(lm->mod_name) > maxnamelen ? + strlen(lm->mod_name) : maxnamelen; + } + + fprintf(fp, "%s TAINT\n", + mkstring(buf1, maxnamelen, LJUST, "NAME")); + + for (i = 0; i < st->mods_installed; i++) { + lm = &st->load_modules[i]; + + if (flag != LIST_ALL_MODULE_TAINT) { + + if (MEMBER_EXISTS("module", "license_gplok")) { + readmem(lm->module_struct + MEMBER_OFFSET("module", "license_gplok"), + KVADDR, &license_gplok, sizeof(int), "module license_gplok", + FAULT_ON_ERROR); + + if (license_gplok) + found = TRUE; + } else { + + readmem(lm->module_struct + MEMBER_OFFSET("module", "taints"), + KVADDR, &taints, sizeof(uint), "module taints", + FAULT_ON_ERROR); + + if (taints) + found = TRUE; + } + + } else { + + readmem(lm->module_struct + MEMBER_OFFSET("module", "taints"), + KVADDR, &taints, sizeof(uint), "module taints", + FAULT_ON_ERROR); + + taintsp = &taints; + + if (taints) { + for (j = 0; j < (get_array_length("tnts", NULL, 0)*tnt_struct); + j += tnt_struct) { + + readmem((sp->value + j) + MEMBER_OFFSET("tnt", "bit"), + KVADDR, &tnt_bit, sizeof(uint8_t), "tnt bit", + FAULT_ON_ERROR); + + if (NUM_IN_BITMAP(taintsp, tnt_bit)) { + readmem((sp->value + j) + MEMBER_OFFSET("tnt", "true"), + KVADDR, &tnt_true, sizeof(char), "tnt true", + FAULT_ON_ERROR); + + buf[bx++] = tnt_true; + found = TRUE; + } else { + readmem((sp->value + j) + MEMBER_OFFSET("tnt", "false"), + KVADDR, &tnt_false, sizeof(char), "tnt false", + FAULT_ON_ERROR); + + if (tnt_false != ' ' && tnt_false != '-') { + buf[bx++] = tnt_false; + found = TRUE; + } + } + + } + } + + if (MEMBER_EXISTS("module", "gpgsig_ok")) { + readmem(lm->module_struct + MEMBER_OFFSET("module", "gpgsig_ok"), + KVADDR, &gpgsig_ok, sizeof(int), "module gpgsig_ok", + FAULT_ON_ERROR); + + if (!gpgsig_ok) { + buf[bx++] = '('; + buf[bx++] = 'U'; + buf[bx++] = ')'; + found = TRUE; + } + } + buf[bx++] = '\0'; + bx = 0; + } + + if (found) { + if (flag != LIST_ALL_MODULE_TAINT_OLD) + fprintf(fp, "%s %s\n", mkstring(buf1, maxnamelen, + LJUST, lm->mod_name), buf); + else + fprintf(fp, "%s 0x%x\n", mkstring(buf1, maxnamelen, + LJUST, lm->mod_name), (MEMBER_EXISTS("module", "taints")) + ? taints : license_gplok); + + found = FALSE; + } + } +} /* * Do the simple list work for cmd_mod(). @@ -3655,6 +3829,11 @@ do_module_cmd(ulong flag, char *modref, ulong address, reinit_modules(); do_module_cmd(LIST_MODULE_HDR, NULL, 0, NULL, NULL); break; + + case LIST_ALL_MODULE_TAINT: + case LIST_ALL_MODULE_TAINT_OLD: + show_module_taint(flag); + break; } }
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility