This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re-send [PATCH] : Validating address in runtime
- From: Wenji Huang <wenji dot huang at oracle dot com>
- To: systemtap at sources dot redhat dot com
- Date: Mon, 23 Jun 2008 10:54:08 +0800
- Subject: 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) {