[Crash-utility] [PATCH V2 1/2] Fix show_kernel_taints() for kernel version > 4.9

Pratyush Anand panand at redhat.com
Thu Jan 5 15:17:35 UTC 2017


Following kernel commit removed "struct tnt".

commit 7fd8329ba502ef76dd91db561c7aed696b2c7720
Author: Petr Mladek <pmladek at suse.com>
Date:   Wed Sep 21 13:47:22 2016 +0200

    taint/module: Clean up global and module taint flags handling

Now "struct taint_flag" has tainted character information.

Without this patch we see following error on a kernel version v4.10-rc1.

    crash: invalid structure size: tnt
           FILE: kernel.c  LINE: 10459  FUNCTION: show_kernel_taints()

    [./crash] error trace: 4cb49c => 4c7cd0 => 50f4e0 => 50f464

      50f464: SIZE_verify.part.29+72
      50f4e0: store_module_kallsyms_v1.part.30+0
      4c7cd0: show_kernel_taints+352
      4cb49c: is_livepatch+44

Signed-off-by: Pratyush Anand <panand at redhat.com>
---
 defs.h    |  1 +
 kernel.c  | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 symbols.c |  2 ++
 3 files changed, 59 insertions(+)

diff --git a/defs.h b/defs.h
index 31a4dc490ed4..8f4c6e24bcc7 100644
--- a/defs.h
+++ b/defs.h
@@ -2120,6 +2120,7 @@ struct size_table {         /* stash of commonly-used sizes */
 	long trace_print_flags;
 	long task_struct_flags;
 	long timer_base;
+	long taint_flag;
 };
 
 struct array_table {
diff --git a/kernel.c b/kernel.c
index bdd0d05eed97..cef8583ef503 100644
--- a/kernel.c
+++ b/kernel.c
@@ -10416,6 +10416,56 @@ dump_variable_length_record(void)
 }
 
 static void
+show_kernel_taints_v4_10(char *buf, int verbose)
+{
+	int i, bx;
+	char tnt_true, tnt_false;
+	int tnts_len;
+	ulong tnts_addr;
+	ulong tainted_mask, *tainted_mask_ptr;
+	struct syment *sp;
+
+	if (!VALID_STRUCT(taint_flag)) {
+		STRUCT_SIZE_INIT(taint_flag, "taint_flag");
+		MEMBER_OFFSET_INIT(tnt_true, "taint_flag", "true");
+		MEMBER_OFFSET_INIT(tnt_false, "taint_flag", "false");
+	}
+
+	tnts_len = get_array_length("taint_flags", NULL, 0);
+	sp = symbol_search("taint_flags");
+	tnts_addr = sp->value;
+
+	bx = 0;
+	buf[0] = '\0';
+
+	get_symbol_data("tainted_mask", sizeof(ulong), &tainted_mask);
+	tainted_mask_ptr = &tainted_mask;
+
+	for (i = 0; i < tnts_len; i++) {
+		if (NUM_IN_BITMAP(tainted_mask_ptr, i)) {
+			readmem((tnts_addr + i * SIZE(taint_flag)) +
+					OFFSET(tnt_true),
+				KVADDR, &tnt_true, sizeof(char),
+				"tnt true", FAULT_ON_ERROR);
+				buf[bx++] = tnt_true;
+		} else {
+			readmem((tnts_addr + i * SIZE(taint_flag)) +
+					OFFSET(tnt_false),
+				KVADDR, &tnt_false, sizeof(char),
+				"tnt false", FAULT_ON_ERROR);
+			if (tnt_false != ' ' && tnt_false != '-' &&
+			    tnt_false != 'G')
+				buf[bx++] = tnt_false;
+		}
+	}
+
+	buf[bx++] = '\0';
+
+	if (verbose)
+		fprintf(fp, "TAINTED_MASK: %lx  %s\n", tainted_mask, buf);
+}
+
+static void
 show_kernel_taints(char *buf, int verbose)
 {
 	int i, bx;
@@ -10427,6 +10477,12 @@ show_kernel_taints(char *buf, int verbose)
 	int tainted;
 	struct syment *sp;
 
+	if (kernel_symbol_exists("taint_flags") &&
+			STRUCT_EXISTS("taint_flag")) {
+		show_kernel_taints_v4_10(buf, verbose);
+		return;
+	}
+
 	if (!VALID_STRUCT(tnt)) { 
                 STRUCT_SIZE_INIT(tnt, "tnt");
                 MEMBER_OFFSET_INIT(tnt_bit, "tnt", "bit");
diff --git a/symbols.c b/symbols.c
index b23807c4d6a0..7d66d9d1d0a4 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10348,6 +10348,8 @@ dump_offset_table(char *spec, ulong makestruct)
 		SIZE(timer_base));
 	fprintf(fp, "                           tnt: %ld\n",
 		SIZE(tnt));
+	fprintf(fp, "                           taint_flag: %ld\n",
+		SIZE(taint_flag));
 
         fprintf(fp, "\n                   array_table:\n");
 	/*
-- 
2.7.4




More information about the Crash-utility mailing list