diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2008-01-29 17:13:22 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2008-01-29 17:13:23 +1100 |
commit | 6dd06c9fbe025f542bce4cdb91790c0f91962722 (patch) | |
tree | 5c946eb93f30c64fd435bdd6d1064880ef21557a /kernel/module.c | |
parent | bb9d3d56e792d2619cc0903df4ac01d86ac1261d (diff) | |
download | lwn-6dd06c9fbe025f542bce4cdb91790c0f91962722.tar.gz lwn-6dd06c9fbe025f542bce4cdb91790c0f91962722.zip |
module: make module_address_lookup safe
module_address_lookup releases preemption then returns a pointer into
the module space. The only user (kallsyms) copies the result, so just
do that under the preempt disable.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/kernel/module.c b/kernel/module.c index 12067ff34d01..e814cd7da634 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2230,14 +2230,13 @@ static const char *get_ksymbol(struct module *mod, return mod->strtab + mod->symtab[best].st_name; } -/* For kallsyms to ask for address resolution. NULL means not found. - We don't lock, as this is used for oops resolution and races are a - lesser concern. */ -/* FIXME: Risky: returns a pointer into a module w/o lock */ -const char *module_address_lookup(unsigned long addr, - unsigned long *size, - unsigned long *offset, - char **modname) +/* For kallsyms to ask for address resolution. NULL means not found. Careful + * not to lock to avoid deadlock on oopses, simply disable preemption. */ +char *module_address_lookup(unsigned long addr, + unsigned long *size, + unsigned long *offset, + char **modname, + char *namebuf) { struct module *mod; const char *ret = NULL; @@ -2252,8 +2251,13 @@ const char *module_address_lookup(unsigned long addr, break; } } + /* Make a copy in here where it's safe */ + if (ret) { + strncpy(namebuf, ret, KSYM_NAME_LEN - 1); + ret = namebuf; + } preempt_enable(); - return ret; + return (char *)ret; } int lookup_module_symbol_name(unsigned long addr, char *symname) |