--- kernel.c.orig	2013-02-14 20:38:54.000000000 +0000
+++ kernel.c	2013-04-05 12:52:34.364149700 +0100
@@ -3159,6 +3159,8 @@
 #define DELETE_ALL_MODULE_SYMBOLS     (5)
 #define REMOTE_MODULE_SAVE_MSG        (6)
 #define REINIT_MODULES                (7)
+#define LIST_ALL_MODULE_TAINT	       (8)
+#define LIST_SPECIFIED_MODULE_TAINT   (9)
 
 void
 cmd_mod(void)
@@ -3233,7 +3235,7 @@
 	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':
@@ -3304,6 +3306,25 @@
 				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_SPECIFIED_MODULE_TAINT;
+
+			if (is_module_name(optarg, &address, NULL))
+				modref = optarg;
+			else
+				cmd_usage(pc->curcmd, SYNOPSIS);
+			break;
+
 		default:
 			argerrs++;
 			break;
@@ -3424,6 +3445,125 @@
 	return retval;
 }
 
+#define MAXTAINTLEN 12
+
+int
+is_module_taint(struct load_module *lm, char *buf)
+{
+	int gpgsig_ok;
+	unsigned int taints;
+	int bx = 0;
+	int found = FALSE;
+
+	BZERO(buf, MAXTAINTLEN);
+
+	if (MEMBER_EXISTS("module", "taints")) {
+		readmem(lm->module_struct + MEMBER_OFFSET("module", "taints"),
+			KVADDR, &taints, sizeof(ulong), "module taints",
+				FAULT_ON_ERROR);
+
+		if (taints) {
+			buf[bx++] = '(';
+			if (taints & (1 << TAINT_PROPRIETARY_MODULE)) {
+				buf[bx++] = 'P';
+				found = TRUE;
+			}
+
+			if (taints & (1 << TAINT_OOT_MODULE)) {
+				buf[bx++] = 'O';
+				found = TRUE;
+			}
+
+			if (taints & (1 << TAINT_FORCED_MODULE)) {
+				buf[bx++] = 'F';
+				found = TRUE;
+			}
+
+			if (taints & (1 << TAINT_UNSIGNED_MODULE)) {
+				buf[bx++] = 'U';
+				found = TRUE;
+			}
+
+			if (taints & (1 << TAINT_CRAP)) {
+				buf[bx++] = 'C';
+				found = TRUE;
+			}
+
+			if (taints & (1 << TAINT_TECH_PREVIEW)) {
+				buf[bx++] = 'T';
+				found = TRUE;
+			}
+			buf[bx++] = ')';
+		}
+	}
+
+	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;
+		}
+	}
+	return found;
+}
+
+void
+show_module_taint(ulong addr)
+{
+	int i, bx = 0;
+	struct load_module *lm;
+	int maxnamelen = 0;
+	char buf[MAXTAINTLEN];
+	char buf1[BUFSIZE];
+	char buf2[BUFSIZE];
+	int found;
+
+	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, MAXTAINTLEN, LJUST, "TAINT"));
+
+	if (addr == ALL_MODULES) {
+		for (i = 0; i < st->mods_installed; i++) {
+			lm = &st->load_modules[i];
+
+			found = is_module_taint(lm, buf);
+
+			if (found) {
+				fprintf(fp, "%s  ", mkstring(buf1, maxnamelen,
+					LJUST, lm->mod_name));
+				fprintf(fp, "%s\n", mkstring(buf2, MAXTAINTLEN,
+					LJUST, buf));
+			}
+		}
+	} else {
+		for (i = 0; i < st->mods_installed; i++) {
+			lm = &st->load_modules[i];
+
+			if (lm->mod_base == addr) {
+				found = is_module_taint(lm, buf);
+
+				if (found) {
+					fprintf(fp, "%s  ", mkstring(buf1, maxnamelen,
+						LJUST, lm->mod_name));
+					fprintf(fp, "%s\n", mkstring(buf2, MAXTAINTLEN,
+						LJUST, buf));
+					break;
+				}
+			}
+		}
+	}
+}
 
 /*
  *  Do the simple list work for cmd_mod().
@@ -3594,6 +3734,14 @@
 		reinit_modules();
         	do_module_cmd(LIST_MODULE_HDR, NULL, 0, NULL, NULL);
 		break;
+
+	case LIST_ALL_MODULE_TAINT:
+		show_module_taint(ALL_MODULES);
+		break;
+
+	case LIST_SPECIFIED_MODULE_TAINT:
+		show_module_taint(address);
+		break;
 	}
 }
 
--- defs.h.orig	2013-02-14 20:38:54.000000000 +0000
+++ defs.h	2013-04-05 12:52:34.368149701 +0100
@@ -177,6 +177,17 @@
 };
 
 /*
+* Module taint flags
+*/
+
+#define TAINT_PROPRIETARY_MODULE        0
+#define TAINT_FORCED_MODULE             1
+#define TAINT_UNSIGNED_MODULE           6
+#define TAINT_CRAP                     10
+#define TAINT_OOT_MODULE               12
+#define TAINT_TECH_PREVIEW             29
+
+/*
  *  program_context flags
  */
 #define LIVE_SYSTEM                 (0x1ULL)
