commit 7fd8329ba502ef76dd91db561c7aed696b2c7720 simplified module taint
flags handling. Modify crash code to cater the kernel changes.
Signed-off-by: Pratyush Anand <panand(a)redhat.com>
---
defs.h | 1 +
kernel.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
symbols.c | 1 +
3 files changed, 102 insertions(+)
diff --git a/defs.h b/defs.h
index 8f4c6e24bcc7..e45b667064a0 100644
--- a/defs.h
+++ b/defs.h
@@ -1977,6 +1977,7 @@ struct offset_table { /* stash of commonly-used
offsets */
long blk_mq_ctx_rq_dispatched;
long blk_mq_ctx_rq_completed;
long task_struct_stack;
+ long tnt_mod;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/kernel.c b/kernel.c
index cef8583ef503..56cfd99c4fbc 100644
--- a/kernel.c
+++ b/kernel.c
@@ -21,6 +21,7 @@
#include <elf.h>
#include <libgen.h>
#include <ctype.h>
+#include <stdbool.h>
static void do_module_cmd(ulong, char *, ulong, char *, char *);
static void show_module_taint(void);
@@ -3963,6 +3964,99 @@ check_specified_module_tree(char *module, char *gdb_buffer)
}
static void
+show_module_taint_4_10(void)
+{
+ int i, j, bx;
+ struct load_module *lm;
+ int maxnamelen;
+ int found;
+ char buf1[BUFSIZE];
+ char buf2[BUFSIZE];
+ struct syment *sp;
+ uint *taintsp, taints;
+ bool tnt_mod;
+ char tnt_true;
+ int tnts_len;
+ ulong tnts_addr;
+ char *modbuf;
+
+ if (INVALID_MEMBER(module_taints)) {
+ MEMBER_OFFSET_INIT(module_taints, "module", "taints");
+ STRUCT_SIZE_INIT(taint_flag, "taint_flag");
+ MEMBER_OFFSET_INIT(tnt_true, "taint_flag", "true");
+ MEMBER_OFFSET_INIT(tnt_mod, "taint_flag", "module");
+ }
+
+ modbuf = GETBUF(SIZE(module));
+
+ for (i = found = maxnamelen = 0; i < kt->mods_installed; i++) {
+ lm = &st->load_modules[i];
+
+ readmem(lm->module_struct, KVADDR, modbuf, SIZE(module),
+ "module struct", FAULT_ON_ERROR);
+
+ taints = ULONG(modbuf + OFFSET(module_taints));
+
+ if (taints) {
+ found++;
+ maxnamelen = strlen(lm->mod_name) > maxnamelen ?
+ strlen(lm->mod_name) : maxnamelen;
+ }
+ }
+
+ if (!found) {
+ fprintf(fp, "no tainted modules\n");
+ FREEBUF(modbuf);
+ return;
+ }
+
+ tnts_len = get_array_length("taint_flags", NULL, 0);
+ sp = symbol_search("taint_flags");
+ tnts_addr = sp->value;
+
+ fprintf(fp, "%s %s\n",
+ mkstring(buf2, maxnamelen, LJUST, "NAME"), "TAINTS");
+
+ for (i = 0; i < st->mods_installed; i++) {
+
+ lm = &st->load_modules[i];
+ bx = 0;
+ buf1[0] = '\0';
+
+ readmem(lm->module_struct, KVADDR, modbuf, SIZE(module),
+ "module struct", FAULT_ON_ERROR);
+
+ taints = ULONG(modbuf + OFFSET(module_taints));
+ if (!taints)
+ continue;
+ taintsp = &taints;
+
+ for (j = 0; j < tnts_len; j++) {
+ readmem((tnts_addr + j * SIZE(taint_flag)) +
+ OFFSET(tnt_mod),
+ KVADDR, &tnt_mod, sizeof(bool),
+ "tnt mod", FAULT_ON_ERROR);
+ if (!tnt_mod)
+ continue;
+ if (NUM_IN_BITMAP(taintsp, j)) {
+ readmem((tnts_addr + j * SIZE(taint_flag)) +
+ OFFSET(tnt_true),
+ KVADDR, &tnt_true, sizeof(char),
+ "tnt true", FAULT_ON_ERROR);
+ buf1[bx++] = tnt_true;
+ }
+ }
+
+ buf1[bx++] = '\0';
+
+ fprintf(fp, "%s %s\n", mkstring(buf2, maxnamelen,
+ LJUST, lm->mod_name), buf1);
+ }
+
+ FREEBUF(modbuf);
+}
+
+static void
show_module_taint(void)
{
int i, j, bx;
@@ -3980,6 +4074,12 @@ show_module_taint(void)
ulong tnts_addr;
char *modbuf;
+ if (kernel_symbol_exists("taint_flags") &&
+ STRUCT_EXISTS("taint_flag")) {
+ show_module_taint_4_10();
+ return;
+ }
+
if (INVALID_MEMBER(module_taints) &&
INVALID_MEMBER(module_license_gplok)) {
MEMBER_OFFSET_INIT(module_taints, "module", "taints");
diff --git a/symbols.c b/symbols.c
index 7d66d9d1d0a4..ceeba709ae5e 100644
--- a/symbols.c
+++ b/symbols.c
@@ -8897,6 +8897,7 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " tnt_bit: %ld\n", OFFSET(tnt_bit));
fprintf(fp, " tnt_true: %ld\n", OFFSET(tnt_true));
fprintf(fp, " tnt_false: %ld\n", OFFSET(tnt_false));
+ fprintf(fp, " tnt_mod: %ld\n", OFFSET(tnt_mod));
fprintf(fp, " page_next: %ld\n", OFFSET(page_next));
fprintf(fp, " page_prev: %ld\n", OFFSET(page_prev));
--
2.7.4