[PATCH v3] Show module taint flags

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Dave,


Sorry about the delay. I've finally found the time to attempt another version.

As per your request, I've updated *help_mod[] to document the -T option.
Also in this particular version, I omit ' ' and '-', when false, as I'm under 
the impression that we're only interested in true values as per module_flags()
(since 2.6.25).
I suspect that there shouldn't be a situation where a module isn't tainted since
every module is either proprietary license or GPL. However, if this is not 
acceptable I can change this behaviour. 

For module.gpgsig_ok case (as seen in kernel-2.6.32-1.el6), I've decided to follow
the same logic to highlight "(U)" to the user, as per print_modules().
With regards to module.sig_ok, this is handled, as seen under 3.8.9-200.fc18:

	nf_nat                   G 
	bnx2i                    G 
	ip6t_REJECT              G 
	nf_defrag_ipv6           G 
	be2iscsi                 G 
	tun                      G 
	test                     GFO
	
For pre 2.6.28 kernels, I'll work on a solution that simply displays the bit number
to then refer the user to the relevant kernel source for details on what the bit
number means, as per your suggestion. I just wanted to get this version out to the
mailing list for review.

Cheers,
Aaron

--8<--

 help.c   |   18 ++++++++-
 kernel.c |  124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 140 insertions(+), 2 deletion

diff --git a/help.c b/help.c
index c9ae57e..c5eba7e 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 | -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,7 @@ 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  Shows each module's taints flags (if supported).",
 "                   -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.",
@@ -4673,6 +4674,21 @@ char *help_mod[] = {
 "    c806e000  autofs       9316  (not loaded)",
 "    c8072000  nfsd       151896  (not loaded)",
 "    c80a1000  mdacon       3556  (not loaded)",
+" ",
+"  Display the taints flags for each module on kernels which support the",
+"  tnts[] array:",
+" ",
+"    %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..7b20247 100755
--- a/kernel.c
+++ b/kernel.c
@@ -22,6 +22,8 @@
 #include <ctype.h>
 
 static void do_module_cmd(ulong, char *, ulong, char *, char *);
+static void show_module_taint(void);
+static int is_module_taint(struct load_module *, char *, int *);
 static char *find_module_objfile(char *, char *, char *);
 static char *module_objfile_search(char *, char *, char *);
 static char *get_loadavg(char *);
@@ -3220,6 +3222,7 @@ irregularity:
 #define DELETE_ALL_MODULE_SYMBOLS     (5)
 #define REMOTE_MODULE_SAVE_MSG        (6)
 #define REINIT_MODULES                (7)
+#define LIST_ALL_MODULE_TAINT	       (8)
 
 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,13 @@ 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;
+
 		default:
 			argerrs++;
 			break;
@@ -3485,6 +3495,114 @@ check_specified_module_tree(char *module, char *gdb_buffer)
 	return retval;
 }
 
+int
+is_module_taint(struct load_module *lm, char *buf, int *maxtnts_len)
+{
+	int gpgsig_ok;
+	struct syment *sp = NULL;
+	ulong taints, tnts;
+	uint tnt_size;
+	ulong *taintsp;
+	uint8_t tnt_bit;
+	char tnt_true, tnt_false;
+	uint i, bx = 0;
+	int found = FALSE;
+
+	tnt_size = STRUCT_SIZE("struct tnt");
+	sp = symbol_search("tnts");
+
+	tnts = sp->value;
+
+	if (MEMBER_EXISTS("module", "taints")) {
+		readmem(lm->module_struct + MEMBER_OFFSET("module", "taints"),
+			KVADDR, &taints, sizeof(ulong), "module taints",
+			FAULT_ON_ERROR);
+
+		taintsp = &taints;
+
+		if (taints) {
+			for (i = 0; i < (get_array_length("tnts", NULL, 0)*tnt_size); i += tnt_size) {
+				readmem((tnts + i) + MEMBER_OFFSET("tnt", "bit"),
+					KVADDR, &tnt_bit, sizeof(uint8_t), "tnt bit",
+					FAULT_ON_ERROR);
+
+				if (NUM_IN_BITMAP(taintsp, tnt_bit)) {
+					readmem((tnts + i) + MEMBER_OFFSET("tnt", "true"),
+						KVADDR, &tnt_true, sizeof(char), "tnt true",
+						FAULT_ON_ERROR);
+					buf[bx++] = tnt_true;
+					found = TRUE;
+				} else {
+					readmem((tnts + i) + 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';
+	*maxtnts_len = bx;
+	return found;
+}
+
+void
+show_module_taint()
+{
+	int i;
+	struct load_module *lm;
+	int maxnamelen = 0;
+	int maxtnts_len = 0;
+	char buf1[BUFSIZE];
+	char buf2[BUFSIZE];
+
+	if (!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");
+	}
+
+	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  %s\n",
+		mkstring(buf1, maxnamelen, LJUST, "NAME"),
+		mkstring(buf2, 5, LJUST, "TAINT"));
+
+	for (i = 0; i < st->mods_installed; i++) {
+		lm = &st->load_modules[i];
+
+		if (is_module_taint(lm, buf2, &maxtnts_len)) {
+			fprintf(fp, "%s  ", mkstring(buf1, maxnamelen,
+				LJUST, lm->mod_name));
+			fprintf(fp, "%s\n", mkstring(buf2, maxtnts_len,
+				LJUST, buf2));
+		}
+	}
+}
 
 /*
  *  Do the simple list work for cmd_mod().
@@ -3655,6 +3773,10 @@ 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:
+		show_module_taint();
+		break;
 	}
 }
 
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux