This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re-send [PATCH] : Validating address in runtime


Hi,

Regarding PR6646, seems no good way to solve it. I just think maybe double checking the address in runtime to make things safer.

This patch adds validating address vs name mapping in runtime for several symbols which are used in initializing process. So kernel oops could be early avoided in case of incorrect vmlinux or wrong address.

Any comments are welcome.

Regards,
Wenji

diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c
index 4a3c4e1..9c9f340 100644
--- a/runtime/transport/symbols.c
+++ b/runtime/transport/symbols.c
@@ -176,6 +176,24 @@ static void _stp_free_modules(void)
 		_stp_del_module(_stp_modules[i]);
 }
 
+/* validate the addr in runtime kernel*/
+static int _stp_validate_addr(char *name, unsigned long addr)
+{
+
+        char addr_str[KSYM_SYMBOL_LEN];
+	size_t len;
+
+        sprint_symbol(addr_str, addr);
+        len = strlen(name);
+	if ( strlen(addr_str) < len+1
+             || strncmp(addr_str, name, len) 
+	     || addr_str[len]!='+') {
+          errk("Incorrect mapping 0x%lx vs %s.\n", addr, name);
+          return 1;
+        }
+        return 0;
+}
+
 static unsigned long _stp_kallsyms_lookup_name(const char *name);
 static void _stp_create_unwind_hdr(struct _stp_module *m);
 
@@ -205,11 +223,22 @@ static int _stp_init_kernel_symbols(void)
 	  _dbug("Lookup of _stext failed. Exiting.\n");
 	  return -1;
 	}
+
+	#ifdef __powerpc__
+	if (_stp_validate_addr(".__start", (unsigned long)_stp_modules[0]->text))
+	#else 
+	if (_stp_validate_addr("_stext", (unsigned long)_stp_modules[0]->text))
+	#endif
+	  return -1;
+
 	_stp_modules[0]->data = _stp_kallsyms_lookup_name("_etext");
 	if (_stp_modules[0]->data == 0) {
 	  _dbug("Lookup of _etext failed. Exiting.\n");
 	  return -1;
 	}
+	if (_stp_validate_addr("_etext", (unsigned long)_stp_modules[0]->data))
+	  return -1;
+
 	_stp_modules[0]->text_size = _stp_modules[0]->data - _stp_modules[0]->text;
 	_stp_modules_by_addr[0] = _stp_modules[0];
 	
@@ -609,12 +638,15 @@ static int _stp_init_modules(void)
 	void *res;
 	struct module *mod;
 	const struct seq_operations *modules_op = (const struct seq_operations *)_stp_kallsyms_lookup_name("modules_op");
-	
+
 	if (modules_op == NULL) {
 	  _dbug("Lookup of modules_op failed.\n");
 	  return -1;
 	}
 
+	if (_stp_validate_addr("modules_op", (unsigned long)modules_op))
+	  return -1;
+
 	/* Use the seq_file interface to safely get a list of installed modules */
 	res = modules_op->start(NULL, &pos);
 	while (res) {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]