Blame SOURCES/github_a89ec821_vmcoreinfo_plugin.patch

608733
commit a89ec821cb5dbb106cb58e8740f84c7e382c0140
608733
Author: Dave Anderson <anderson@redhat.com>
608733
Date:   Fri Feb 8 11:12:23 2019 -0500
608733
608733
    For live system analysis where there is no vmcoreinfo ELF note
608733
    attached to /proc/kcore, or for dumpfile analysis where there is no
608733
    vmcoreinfo ELF note attached to the dumpfile, this patch sets the
608733
    internal pc->read_vmcoreinfo() function to a new plugin function
608733
    that reads the data directly from the live kernel or dumpfile.
608733
    Because the function is set much later during initialization than
608733
    if the ELF note is attached to /proc/kcore or the dumpfile, it may
608733
    not be available during very early session initialization.
608733
    (anderson@redhat.com)
608733
608733
diff --git a/defs.h b/defs.h
608733
index 05f2d17..5841b1f 100644
608733
--- a/defs.h
608733
+++ b/defs.h
608733
@@ -4872,6 +4872,7 @@ int clean_exit(int);
608733
 int untrusted_file(FILE *, char *);
608733
 char *readmem_function_name(void);
608733
 char *writemem_function_name(void);
608733
+char *no_vmcoreinfo(const char *);
608733
 
608733
 /*
608733
  *  cmdline.c
608733
diff --git a/kernel.c b/kernel.c
608733
index e512da5..9f5ba89 100644
608733
--- a/kernel.c
608733
+++ b/kernel.c
608733
@@ -93,6 +93,8 @@ static void source_tree_init(void);
608733
 static ulong dump_audit_skb_queue(ulong);
608733
 static ulong __dump_audit(char *);
608733
 static void dump_audit(void);
608733
+static char *vmcoreinfo_read_string(const char *);
608733
+static void check_vmcoreinfo(void);
608733
 
608733
 
608733
 /*
608733
@@ -127,6 +129,8 @@ kernel_init()
608733
 	kt->end = highest_bss_symbol();
608733
 	if ((sp1 = kernel_symbol_search("_end")) && (sp1->value > kt->end)) 
608733
 		kt->end = sp1->value;
608733
+
608733
+	check_vmcoreinfo();
608733
 	
608733
 	/*
608733
 	 *  For the traditional (non-pv_ops) Xen architecture, default to writable 
608733
@@ -11117,3 +11121,84 @@ dump_audit(void)
608733
 	if (!qlen)
608733
 		error(INFO, "kernel audit log is empty\n");
608733
 }
608733
+
608733
+/*
608733
+ * Reads a string value from the VMCOREINFO data stored in (live) memory.
608733
+ *
608733
+ * Returns a string (that has to be freed by the caller) that contains the
608733
+ * value for key or NULL if the key has not been found.
608733
+ */
608733
+static char *
608733
+vmcoreinfo_read_string(const char *key)
608733
+{
608733
+	char *buf, *value_string, *p1, *p2;
608733
+	size_t value_length;
608733
+	size_t vmcoreinfo_size;
608733
+	ulong vmcoreinfo_data;
608733
+	char keybuf[BUFSIZE];
608733
+
608733
+	buf = value_string = NULL;
608733
+
608733
+	switch (get_symbol_type("vmcoreinfo_data", NULL, NULL))
608733
+	{
608733
+	case TYPE_CODE_PTR:
608733
+		get_symbol_data("vmcoreinfo_data", sizeof(vmcoreinfo_data), &vmcoreinfo_data);
608733
+		break;
608733
+	case TYPE_CODE_ARRAY:
608733
+		vmcoreinfo_data = symbol_value("vmcoreinfo_data");
608733
+		break;
608733
+	default:
608733
+		return NULL;
608733
+	}
608733
+
608733
+	get_symbol_data("vmcoreinfo_size", sizeof(vmcoreinfo_size), &vmcoreinfo_size);
608733
+
608733
+	sprintf(keybuf, "%s=", key);
608733
+
608733
+	if ((buf = malloc(vmcoreinfo_size+1)) == NULL) {
608733
+		error(INFO, "cannot malloc vmcoreinfo buffer\n");
608733
+		goto err;
608733
+	}
608733
+
608733
+	if (!readmem(vmcoreinfo_data, KVADDR, buf, vmcoreinfo_size,
608733
+            "vmcoreinfo_data", RETURN_ON_ERROR|QUIET)) {
608733
+		error(INFO, "cannot read vmcoreinfo_data\n");
608733
+		goto err;
608733
+	}
608733
+
608733
+	buf[vmcoreinfo_size] = '\n';
608733
+
608733
+	if ((p1 = strstr(buf, keybuf))) {
608733
+		p2 = p1 + strlen(keybuf);
608733
+		p1 = strstr(p2, "\n");
608733
+		value_length = p1-p2;
608733
+		value_string = calloc(value_length+1, sizeof(char));
608733
+		strncpy(value_string, p2, value_length);
608733
+		value_string[value_length] = NULLCHAR;
608733
+	}
608733
+err:
608733
+	if (buf)
608733
+		free(buf);
608733
+
608733
+	return value_string;
608733
+}
608733
+
608733
+static void
608733
+check_vmcoreinfo(void)
608733
+{
608733
+	if (!kernel_symbol_exists("vmcoreinfo_data") ||
608733
+	    !kernel_symbol_exists("vmcoreinfo_size"))
608733
+		return;
608733
+
608733
+	if (pc->read_vmcoreinfo == no_vmcoreinfo) {
608733
+		switch (get_symbol_type("vmcoreinfo_data", NULL, NULL))
608733
+		{
608733
+		case TYPE_CODE_PTR:
608733
+			pc->read_vmcoreinfo = vmcoreinfo_read_string;
608733
+			break;
608733
+		case TYPE_CODE_ARRAY:
608733
+			pc->read_vmcoreinfo = vmcoreinfo_read_string;
608733
+			break;
608733
+		}
608733
+	}
608733
+}
608733
diff --git a/main.c b/main.c
608733
index 7248810..cd282cd 100644
608733
--- a/main.c
608733
+++ b/main.c
608733
@@ -1,8 +1,8 @@
608733
 /* main.c - core analysis suite
608733
  *
608733
  * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
608733
- * Copyright (C) 2002-2018 David Anderson
608733
- * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved.
608733
+ * Copyright (C) 2002-2019 David Anderson
608733
+ * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
608733
  *
608733
  * This program is free software; you can redistribute it and/or modify
608733
  * it under the terms of the GNU General Public License as published by
608733
@@ -29,7 +29,6 @@ static void check_xen_hyper(void);
608733
 static void show_untrusted_files(void);
608733
 static void get_osrelease(char *);
608733
 static void get_log(char *);
608733
-static char *no_vmcoreinfo(const char *);
608733
 
608733
 static struct option long_options[] = {
608733
         {"memory_module", required_argument, 0, 0},
608733
@@ -1950,7 +1949,7 @@ get_log(char *dumpfile)
608733
 }
608733
 
608733
 
608733
-static char *
608733
+char *
608733
 no_vmcoreinfo(const char *unused)
608733
 {
608733
 	return NULL;
608733
diff --git a/netdump.c b/netdump.c
608733
index d0179e0..5aeea6f 100644
608733
--- a/netdump.c
608733
+++ b/netdump.c
608733
@@ -1,7 +1,7 @@
608733
 /* netdump.c 
608733
  *
608733
- * Copyright (C) 2002-2018 David Anderson
608733
- * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved.
608733
+ * Copyright (C) 2002-2019 David Anderson
608733
+ * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
608733
  *
608733
  * This program is free software; you can redistribute it and/or modify
608733
  * it under the terms of the GNU General Public License as published by
608733
@@ -1786,11 +1786,13 @@ vmcoreinfo_read_string(const char *key)
608733
 		if (STREQ(key, "NUMBER(kimage_voffset)") && nd->arch_data) {
608733
 			value = calloc(VADDR_PRLEN+1, sizeof(char));
608733
 			sprintf(value, "%lx", nd->arch_data);
608733
+			pc->read_vmcoreinfo = no_vmcoreinfo;
608733
 			return value;
608733
 		}
608733
 		if (STREQ(key, "relocate") && nd->arch_data) {
608733
 			value = calloc(VADDR_PRLEN+1, sizeof(char));
608733
 			sprintf(value, "%lx", nd->arch_data);
608733
+			pc->read_vmcoreinfo = no_vmcoreinfo;
608733
 			return value;
608733
 		}
608733
 	}