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
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to