aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 3202c9950073..c2e3e2e98801 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -81,7 +81,8 @@ int unregister_module_notifier(struct notifier_block * nb)
81} 81}
82EXPORT_SYMBOL(unregister_module_notifier); 82EXPORT_SYMBOL(unregister_module_notifier);
83 83
84/* We require a truly strong try_module_get() */ 84/* We require a truly strong try_module_get(): 0 means failure due to
85 ongoing or failed initialization etc. */
85static inline int strong_try_module_get(struct module *mod) 86static inline int strong_try_module_get(struct module *mod)
86{ 87{
87 if (mod && mod->state == MODULE_STATE_COMING) 88 if (mod && mod->state == MODULE_STATE_COMING)
@@ -952,7 +953,8 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
952 ret = __find_symbol(name, &owner, &crc, 953 ret = __find_symbol(name, &owner, &crc,
953 !(mod->taints & TAINT_PROPRIETARY_MODULE)); 954 !(mod->taints & TAINT_PROPRIETARY_MODULE));
954 if (ret) { 955 if (ret) {
955 /* use_module can fail due to OOM, or module unloading */ 956 /* use_module can fail due to OOM,
957 or module initialization or unloading */
956 if (!check_version(sechdrs, versindex, name, mod, crc) || 958 if (!check_version(sechdrs, versindex, name, mod, crc) ||
957 !use_module(mod, owner)) 959 !use_module(mod, owner))
958 ret = 0; 960 ret = 0;
@@ -1369,7 +1371,7 @@ dup:
1369 return ret; 1371 return ret;
1370} 1372}
1371 1373
1372/* Change all symbols so that sh_value encodes the pointer directly. */ 1374/* Change all symbols so that st_value encodes the pointer directly. */
1373static int simplify_symbols(Elf_Shdr *sechdrs, 1375static int simplify_symbols(Elf_Shdr *sechdrs,
1374 unsigned int symindex, 1376 unsigned int symindex,
1375 const char *strtab, 1377 const char *strtab,
@@ -2212,29 +2214,34 @@ static const char *get_ksymbol(struct module *mod,
2212/* For kallsyms to ask for address resolution. NULL means not found. 2214/* For kallsyms to ask for address resolution. NULL means not found.
2213 We don't lock, as this is used for oops resolution and races are a 2215 We don't lock, as this is used for oops resolution and races are a
2214 lesser concern. */ 2216 lesser concern. */
2217/* FIXME: Risky: returns a pointer into a module w/o lock */
2215const char *module_address_lookup(unsigned long addr, 2218const char *module_address_lookup(unsigned long addr,
2216 unsigned long *size, 2219 unsigned long *size,
2217 unsigned long *offset, 2220 unsigned long *offset,
2218 char **modname) 2221 char **modname)
2219{ 2222{
2220 struct module *mod; 2223 struct module *mod;
2224 const char *ret = NULL;
2221 2225
2226 preempt_disable();
2222 list_for_each_entry(mod, &modules, list) { 2227 list_for_each_entry(mod, &modules, list) {
2223 if (within(addr, mod->module_init, mod->init_size) 2228 if (within(addr, mod->module_init, mod->init_size)
2224 || within(addr, mod->module_core, mod->core_size)) { 2229 || within(addr, mod->module_core, mod->core_size)) {
2225 if (modname) 2230 if (modname)
2226 *modname = mod->name; 2231 *modname = mod->name;
2227 return get_ksymbol(mod, addr, size, offset); 2232 ret = get_ksymbol(mod, addr, size, offset);
2233 break;
2228 } 2234 }
2229 } 2235 }
2230 return NULL; 2236 preempt_enable();
2237 return ret;
2231} 2238}
2232 2239
2233int lookup_module_symbol_name(unsigned long addr, char *symname) 2240int lookup_module_symbol_name(unsigned long addr, char *symname)
2234{ 2241{
2235 struct module *mod; 2242 struct module *mod;
2236 2243
2237 mutex_lock(&module_mutex); 2244 preempt_disable();
2238 list_for_each_entry(mod, &modules, list) { 2245 list_for_each_entry(mod, &modules, list) {
2239 if (within(addr, mod->module_init, mod->init_size) || 2246 if (within(addr, mod->module_init, mod->init_size) ||
2240 within(addr, mod->module_core, mod->core_size)) { 2247 within(addr, mod->module_core, mod->core_size)) {
@@ -2244,12 +2251,12 @@ int lookup_module_symbol_name(unsigned long addr, char *symname)
2244 if (!sym) 2251 if (!sym)
2245 goto out; 2252 goto out;
2246 strlcpy(symname, sym, KSYM_NAME_LEN); 2253 strlcpy(symname, sym, KSYM_NAME_LEN);
2247 mutex_unlock(&module_mutex); 2254 preempt_enable();
2248 return 0; 2255 return 0;
2249 } 2256 }
2250 } 2257 }
2251out: 2258out:
2252 mutex_unlock(&module_mutex); 2259 preempt_enable();
2253 return -ERANGE; 2260 return -ERANGE;
2254} 2261}
2255 2262
@@ -2258,7 +2265,7 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
2258{ 2265{
2259 struct module *mod; 2266 struct module *mod;
2260 2267
2261 mutex_lock(&module_mutex); 2268 preempt_disable();
2262 list_for_each_entry(mod, &modules, list) { 2269 list_for_each_entry(mod, &modules, list) {
2263 if (within(addr, mod->module_init, mod->init_size) || 2270 if (within(addr, mod->module_init, mod->init_size) ||
2264 within(addr, mod->module_core, mod->core_size)) { 2271 within(addr, mod->module_core, mod->core_size)) {
@@ -2271,12 +2278,12 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
2271 strlcpy(modname, mod->name, MODULE_NAME_LEN); 2278 strlcpy(modname, mod->name, MODULE_NAME_LEN);
2272 if (name) 2279 if (name)
2273 strlcpy(name, sym, KSYM_NAME_LEN); 2280 strlcpy(name, sym, KSYM_NAME_LEN);
2274 mutex_unlock(&module_mutex); 2281 preempt_enable();
2275 return 0; 2282 return 0;
2276 } 2283 }
2277 } 2284 }
2278out: 2285out:
2279 mutex_unlock(&module_mutex); 2286 preempt_enable();
2280 return -ERANGE; 2287 return -ERANGE;
2281} 2288}
2282 2289
@@ -2285,7 +2292,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
2285{ 2292{
2286 struct module *mod; 2293 struct module *mod;
2287 2294
2288 mutex_lock(&module_mutex); 2295 preempt_disable();
2289 list_for_each_entry(mod, &modules, list) { 2296 list_for_each_entry(mod, &modules, list) {
2290 if (symnum < mod->num_symtab) { 2297 if (symnum < mod->num_symtab) {
2291 *value = mod->symtab[symnum].st_value; 2298 *value = mod->symtab[symnum].st_value;
@@ -2294,12 +2301,12 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
2294 KSYM_NAME_LEN); 2301 KSYM_NAME_LEN);
2295 strlcpy(module_name, mod->name, MODULE_NAME_LEN); 2302 strlcpy(module_name, mod->name, MODULE_NAME_LEN);
2296 *exported = is_exported(name, mod); 2303 *exported = is_exported(name, mod);
2297 mutex_unlock(&module_mutex); 2304 preempt_enable();
2298 return 0; 2305 return 0;
2299 } 2306 }
2300 symnum -= mod->num_symtab; 2307 symnum -= mod->num_symtab;
2301 } 2308 }
2302 mutex_unlock(&module_mutex); 2309 preempt_enable();
2303 return -ERANGE; 2310 return -ERANGE;
2304} 2311}
2305 2312
@@ -2322,6 +2329,7 @@ unsigned long module_kallsyms_lookup_name(const char *name)
2322 unsigned long ret = 0; 2329 unsigned long ret = 0;
2323 2330
2324 /* Don't lock: we're in enough trouble already. */ 2331 /* Don't lock: we're in enough trouble already. */
2332 preempt_disable();
2325 if ((colon = strchr(name, ':')) != NULL) { 2333 if ((colon = strchr(name, ':')) != NULL) {
2326 *colon = '\0'; 2334 *colon = '\0';
2327 if ((mod = find_module(name)) != NULL) 2335 if ((mod = find_module(name)) != NULL)
@@ -2332,6 +2340,7 @@ unsigned long module_kallsyms_lookup_name(const char *name)
2332 if ((ret = mod_find_symname(mod, name)) != 0) 2340 if ((ret = mod_find_symname(mod, name)) != 0)
2333 break; 2341 break;
2334 } 2342 }
2343 preempt_enable();
2335 return ret; 2344 return ret;
2336} 2345}
2337#endif /* CONFIG_KALLSYMS */ 2346#endif /* CONFIG_KALLSYMS */