#ifdef CONFIG_CONSTRUCTORS unsigned long i; for (i = 0; i < mod->num_ctors; i++) mod->ctors[i]();#endif} /* This is where the real work happens */SYSCALL_DEFINE3(init_module, void __user *, umod, unsigned long, len, const char __user *, uargs){ struct module *mod; int ret = 0; /* Must have permission */ if (!capable(CAP_SYS_MODULE) || modules_disabled) return -EPERM; /* Do all the hard work */ mod = load_module(umod, len, uargs); if (IS_ERR(mod)) return PTR_ERR(mod); blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod); /* Set RO and NX regions for core */ set_section_ro_nx(mod->module_core, mod->core_text_size, mod->core_ro_size, mod->core_size); /* Set RO and NX regions for init */ set_section_ro_nx(mod->module_init, mod->init_text_size, mod->init_ro_size, mod->init_size); do_mod_ctors(mod); /* Start the module */ if (mod->init != NULL) ret = do_one_initcall(mod->init); if (ret < 0) { /* Init routine failed: abort. Try to protect us from buggy refcounters. */ mod->state = MODULE_STATE_GOING; synchronize_sched(); module_put(mod); blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod); free_module(mod); wake_up(&module_wq); return ret; } if (ret > 0) { printk(KERN_WARNING"%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n""%s: loading module anyway...\n", __func__, mod->name, ret, __func__); dump_stack(); } /* Now it's a first class citizen! Wake up anyone waiting for it. */ mod->state = MODULE_STATE_LIVE; wake_up(&module_wq); blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_LIVE, mod); /* We need to finish all async code before the module init sequence is done */ async_synchronize_full(); mutex_lock(&module_mutex); /* Drop initial reference. */ module_put(mod); trim_init_extable(mod);#ifdef CONFIG_KALLSYMS mod->num_symtab = mod->core_num_syms; mod->symtab = mod->core_symtab; mod->strtab = mod->core_strtab;#endif unset_module_init_ro_nx(mod); module_free(mod, mod->module_init); mod->module_init = NULL; mod->init_size = 0; mod->init_ro_size = 0; mod->init_text_size = 0; mutex_unlock(&module_mutex); return 0;} static inline int within(unsigned long addr, void *start, unsigned long size){ return ((void *)addr >= start && (void *)addr < start + size);} #ifdef CONFIG_KALLSYMS/* * This ignores the intensely annoying "mapping symbols" found * in ARM ELF files: $a, $t and $d. */static inline int is_arm_mapping_symbol(const char *str){ return str[0] == '$' && strchr("atd", str[1]) && (str[2] == '\0' || str[2] == '.');} static const char *get_ksymbol(struct module *mod, unsigned long addr, unsigned long *size, unsigned long *offset){ unsigned int i, best = 0; unsigned long nextval; /* At worse, next value is at end of module */ if (within_module_init(addr, mod)) nextval = (unsigned long)mod->module_init+mod->init_text_size; else nextval = (unsigned long)mod->module_core+mod->core_text_size; /* Scan for closest preceding symbol, and next symbol. (ELF starts real symbols at 1). */ for (i = 1; i < mod->num_symtab; i++) { if (mod->symtab[i].st_shndx == SHN_UNDEF) continue; /* We ignore unnamed symbols: they're uninformative * and inserted at a whim. */ if (mod->symtab[i].st_value <= addr && mod->symtab[i].st_value > mod->symtab[best].st_value && *(mod->strtab + mod->symtab[i].st_name) != '\0' && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name)) best = i; if (mod->symtab[i].st_value > addr && mod->symtab[i].st_value < nextval && *(mod->strtab + mod->symtab[i].st_name) != '\0' && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name)) nextval = mod->symtab[i].st_value; } if (!best) return NULL; if (size) *size = nextval - mod->symtab[best].st_value; if (offset) *offset = addr - mod->symtab[best].st_value; return mod->strtab + mod->symtab[best].st_name;} /* For kallsyms to ask for address resolution. NULL means not found. Careful * not to lock to avoid deadlock on oopses, simply disable preemption. */const char *module_address_lookup(unsigned long addr, unsigned long *size, unsigned long *offset, char **modname, char *namebuf){ struct module *mod; const char *ret = NULL; preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (within_module_init(addr, mod) || within_module_core(addr, mod)) { if (modname) *modname = mod->name; ret = get_ksymbol(mod, addr, size, offset); 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;} int lookup_module_symbol_name(unsigned long addr, char *symname){ struct module *mod; preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (within_module_init(addr, mod) || within_module_core(addr, mod)) { const char *sym; sym = get_ksymbol(mod, addr, NULL, NULL); if (!sym) goto out; strlcpy(symname, sym, KSYM_NAME_LEN); preempt_enable(); return 0; } }out: preempt_enable(); return -ERANGE;} int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name){ struct module *mod; preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (within_module_init(addr, mod) || within_module_core(addr, mod)) { const char *sym; sym = get_ksymbol(mod, addr, size, offset); if (!sym) goto out; if (modname) strlcpy(modname, mod->name, MODULE_NAME_LEN); if (name) strlcpy(name, sym, KSYM_NAME_LEN); preempt_enable(); return 0; } }out: preempt_enable(); return -ERANGE;} int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, char *name, char *module_name, int *exported){ struct module *mod; preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (symnum < mod->num_symtab) { *value = mod->symtab[symnum].st_value; *type = mod->symtab[symnum].st_info; strlcpy(name, mod->strtab + mod->symtab[symnum].st_name, KSYM_NAME_LEN); strlcpy(module_name, mod->name, MODULE_NAME_LEN); *exported = is_exported(name, *value, mod); preempt_enable(); return 0; } symnum -= mod->num_symtab; } preempt_enable(); return -ERANGE;} static unsigned long mod_find_symname(struct module *mod, const char *name){ unsigned int i; for (i = 0; i < mod->num_symtab; i++) if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0 && mod->symtab[i].st_info != 'U') return mod->symtab[i].st_value; return 0;} /* Look for this name: can be of form module:name. */unsigned long module_kallsyms_lookup_name(const char *name){ struct module *mod; char *colon; unsigned long ret = 0; /* Don't lock: we're in enough trouble already. */ preempt_disable(); if ((colon = strchr(name, ':')) != NULL) { *colon = '\0'; if ((mod = find_module(name)) != NULL) ret = mod_find_symname(mod, colon+1); *colon = ':'; } else { list_for_each_entry_rcu(mod, &modules, list) if ((ret = mod_find_symname(mod, name)) != 0) break; } preempt_enable(); return ret;} int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, unsigned long), void *data){ struct module *mod; unsigned int i; int ret; list_for_each_entry(mod, &modules, list) { for (i = 0; i < mod->num_symtab; i++) { ret = fn(data, mod->strtab + mod->symtab[i].st_name, mod, mod->symtab[i].st_value); if (ret != 0) return ret; } } return 0;}#endif /* CONFIG_KALLSYMS */ static char *module_flags(struct module *mod, char *buf){ int bx = 0; if (mod->taints || mod->state == MODULE_STATE_GOING || mod->state == MODULE_STATE_COMING) { buf[bx++] = '('; bx += module_flags_taint(mod, buf + bx); /* Show a - for module-is-being-unloaded */ if (mod->state == MODULE_STATE_GOING) buf[bx++] = '-'; /* Show a + for module-is-being-loaded */ if (mod->state == MODULE_STATE_COMING) buf[bx++] = '+'; buf[bx++] = ')'; } buf[bx] = '\0'; return buf;} #ifdef CONFIG_PROC_FS/* Called by the /proc file system to return a list of modules. */static void *m_start(struct seq_file *m, loff_t *pos){ mutex_lock(&module_mutex); return seq_list_start(&modules, *pos);} static void *m_next(struct seq_file *m, void *p, loff_t *pos){ return seq_list_next(p, &modules, pos);} static void m_stop(struct seq_file *m, void *p){ mutex_unlock(&module_mutex);} static int m_show(struct seq_file *m, void *p){ struct module *mod = list_entry(p, struct module, list); char buf[8]; seq_printf(m, "%s %u", mod->name, mod->init_size + mod->core_size); print_unload_info(m, mod); /* Informative for users. */ seq_printf(m, " %s", mod->state == MODULE_STATE_GOING ? "Unloading": mod->state == MODULE_STATE_COMING ? "Loading": "Live"); /* Used by oprofile and other similar tools. */ seq_printf(m, " 0x%pK", mod->module_core); /* Taints info */ if (mod->taints) seq_printf(m, " %s", module_flags(mod, buf)); seq_printf(m, "\n"); return 0;} /* Format: modulename size refcount deps address Where refcount is a number or -, and deps is a comma-separated list of depends or -.*/static const struct seq_operations modules_op = { .start = m_start, .next = m_next, .stop = m_stop, .show = m_show}; static int modules_open(struct inode *inode, struct file *file){ return seq_open(file, &modules_op);} static const struct file_operations proc_modules_operations = { .open = modules_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release,}; static int __init proc_modules_init(void){ proc_create("modules", 0, NULL, &proc_modules_operations); return 0;}module_init(proc_modules_init);#endif /* Given an address, look for it in the module exception tables. */const struct exception_table_entry *search_module_extables(unsigned long addr){ const struct exception_table_entry *e = NULL; struct module *mod; preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (mod->num_exentries == 0) continue; e = search_extable(mod->extable, mod->extable + mod->num_exentries - 1, addr); if (e) break; } preempt_enable(); /* Now, if we found one, we are running inside it now, hence we cannot unload the module, hence no refcnt needed. */ return e;} /* * is_module_address - is this address inside a module? * @addr: the address to check. * * See is_module_text_address() if you simply want to see if the address * is code (not data). */bool is_module_address(unsigned long addr){ bool ret; preempt_disable(); ret = __module_address(addr) != NULL; preempt_enable(); return ret;} /* * __module_address - get the module which contains an address. * @addr: the address. * * Must be called with preempt disabled or module mutex held so that * module doesn't get freed during this. */struct module *__module_address(unsigned long addr){ struct module *mod; if (addr < module_addr_min || addr > module_addr_max) return NULL; list_for_each_entry_rcu(mod, &modules, list) if (within_module_core(addr, mod) || within_module_init(addr, mod)) return mod; return NULL;}EXPORT_SYMBOL_GPL(__module_address); /* * is_module_text_address - is this address inside module code? * @addr: the address to check. * * See is_module_address() if you simply want to see if the address is * anywhere in a module. See kernel_text_address() for testing if an * address corresponds to kernel or module code. */bool is_module_text_address(unsigned long addr){ bool ret; preempt_disable(); ret = __module_text_address(addr) != NULL; preempt_enable(); return ret;} /* * __module_text_address - get the module whose code contains an address. * @addr: the address. * * Must be called with preempt disabled or module mutex held so that * module doesn't get freed during this. */struct module *__module_text_address(unsigned long addr){ struct module *mod = __module_address(addr);Lines 3001–3500 of 3539. Previous lines Load more
#ifdef CONFIG_CONSTRUCTORS unsigned long i; for (i = 0; i < mod->num_ctors; i++) mod->ctors[i](); #endif } /* This is where the real work happens */ SYSCALL_DEFINE3(init_module, void __user *, umod, unsigned long, len, const char __user *, uargs) { struct module *mod; int ret = 0; /* Must have permission */ if (!capable(CAP_SYS_MODULE) || modules_disabled) return -EPERM; /* Do all the hard work */ mod = load_module(umod, len, uargs); if (IS_ERR(mod)) return PTR_ERR(mod); blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod); /* Set RO and NX regions for core */ set_section_ro_nx(mod->module_core, mod->core_text_size, mod->core_ro_size, mod->core_size); /* Set RO and NX regions for init */ set_section_ro_nx(mod->module_init, mod->init_text_size, mod->init_ro_size, mod->init_size); do_mod_ctors(mod); /* Start the module */ if (mod->init != NULL) ret = do_one_initcall(mod->init); if (ret < 0) { /* Init routine failed: abort. Try to protect us from buggy refcounters. */ mod->state = MODULE_STATE_GOING; synchronize_sched(); module_put(mod); blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod); free_module(mod); wake_up(&module_wq); return ret; } if (ret > 0) { printk(KERN_WARNING "%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n" "%s: loading module anyway...\n", __func__, mod->name, ret, __func__); dump_stack(); } /* Now it's a first class citizen! Wake up anyone waiting for it. */ mod->state = MODULE_STATE_LIVE; wake_up(&module_wq); blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_LIVE, mod); /* We need to finish all async code before the module init sequence is done */ async_synchronize_full(); mutex_lock(&module_mutex); /* Drop initial reference. */ module_put(mod); trim_init_extable(mod); #ifdef CONFIG_KALLSYMS mod->num_symtab = mod->core_num_syms; mod->symtab = mod->core_symtab; mod->strtab = mod->core_strtab; #endif unset_module_init_ro_nx(mod); module_free(mod, mod->module_init); mod->module_init = NULL; mod->init_size = 0; mod->init_ro_size = 0; mod->init_text_size = 0; mutex_unlock(&module_mutex); return 0; } static inline int within(unsigned long addr, void *start, unsigned long size) { return ((void *)addr >= start && (void *)addr < start + size); } #ifdef CONFIG_KALLSYMS /* * This ignores the intensely annoying "mapping symbols" found * in ARM ELF files: $a, $t and $d. */ static inline int is_arm_mapping_symbol(const char *str) { return str[0] == '$' && strchr("atd", str[1]) && (str[2] == '\0' || str[2] == '.'); } static const char *get_ksymbol(struct module *mod, unsigned long addr, unsigned long *size, unsigned long *offset) { unsigned int i, best = 0; unsigned long nextval; /* At worse, next value is at end of module */ if (within_module_init(addr, mod)) nextval = (unsigned long)mod->module_init+mod->init_text_size; else nextval = (unsigned long)mod->module_core+mod->core_text_size; /* Scan for closest preceding symbol, and next symbol. (ELF starts real symbols at 1). */ for (i = 1; i < mod->num_symtab; i++) { if (mod->symtab[i].st_shndx == SHN_UNDEF) continue; /* We ignore unnamed symbols: they're uninformative * and inserted at a whim. */ if (mod->symtab[i].st_value <= addr && mod->symtab[i].st_value > mod->symtab[best].st_value && *(mod->strtab + mod->symtab[i].st_name) != '\0' && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name)) best = i; if (mod->symtab[i].st_value > addr && mod->symtab[i].st_value < nextval && *(mod->strtab + mod->symtab[i].st_name) != '\0' && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name)) nextval = mod->symtab[i].st_value; } if (!best) return NULL; if (size) *size = nextval - mod->symtab[best].st_value; if (offset) *offset = addr - mod->symtab[best].st_value; return mod->strtab + mod->symtab[best].st_name; } /* For kallsyms to ask for address resolution. NULL means not found. Careful * not to lock to avoid deadlock on oopses, simply disable preemption. */ const char *module_address_lookup(unsigned long addr, unsigned long *size, unsigned long *offset, char **modname, char *namebuf) { struct module *mod; const char *ret = NULL; preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (within_module_init(addr, mod) || within_module_core(addr, mod)) { if (modname) *modname = mod->name; ret = get_ksymbol(mod, addr, size, offset); 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; } int lookup_module_symbol_name(unsigned long addr, char *symname) { struct module *mod; preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (within_module_init(addr, mod) || within_module_core(addr, mod)) { const char *sym; sym = get_ksymbol(mod, addr, NULL, NULL); if (!sym) goto out; strlcpy(symname, sym, KSYM_NAME_LEN); preempt_enable(); return 0; } } out: preempt_enable(); return -ERANGE; } int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name) { struct module *mod; preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (within_module_init(addr, mod) || within_module_core(addr, mod)) { const char *sym; sym = get_ksymbol(mod, addr, size, offset); if (!sym) goto out; if (modname) strlcpy(modname, mod->name, MODULE_NAME_LEN); if (name) strlcpy(name, sym, KSYM_NAME_LEN); preempt_enable(); return 0; } } out: preempt_enable(); return -ERANGE; } int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, char *name, char *module_name, int *exported) { struct module *mod; preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (symnum < mod->num_symtab) { *value = mod->symtab[symnum].st_value; *type = mod->symtab[symnum].st_info; strlcpy(name, mod->strtab + mod->symtab[symnum].st_name, KSYM_NAME_LEN); strlcpy(module_name, mod->name, MODULE_NAME_LEN); *exported = is_exported(name, *value, mod); preempt_enable(); return 0; } symnum -= mod->num_symtab; } preempt_enable(); return -ERANGE; } static unsigned long mod_find_symname(struct module *mod, const char *name) { unsigned int i; for (i = 0; i < mod->num_symtab; i++) if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0 && mod->symtab[i].st_info != 'U') return mod->symtab[i].st_value; return 0; } /* Look for this name: can be of form module:name. */ unsigned long module_kallsyms_lookup_name(const char *name) { struct module *mod; char *colon; unsigned long ret = 0; /* Don't lock: we're in enough trouble already. */ preempt_disable(); if ((colon = strchr(name, ':')) != NULL) { *colon = '\0'; if ((mod = find_module(name)) != NULL) ret = mod_find_symname(mod, colon+1); *colon = ':'; } else { list_for_each_entry_rcu(mod, &modules, list) if ((ret = mod_find_symname(mod, name)) != 0) break; } preempt_enable(); return ret; } int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, unsigned long), void *data) { struct module *mod; unsigned int i; int ret; list_for_each_entry(mod, &modules, list) { for (i = 0; i < mod->num_symtab; i++) { ret = fn(data, mod->strtab + mod->symtab[i].st_name, mod, mod->symtab[i].st_value); if (ret != 0) return ret; } } return 0; } #endif /* CONFIG_KALLSYMS */ static char *module_flags(struct module *mod, char *buf) { int bx = 0; if (mod->taints || mod->state == MODULE_STATE_GOING || mod->state == MODULE_STATE_COMING) { buf[bx++] = '('; bx += module_flags_taint(mod, buf + bx); /* Show a - for module-is-being-unloaded */ if (mod->state == MODULE_STATE_GOING) buf[bx++] = '-'; /* Show a + for module-is-being-loaded */ if (mod->state == MODULE_STATE_COMING) buf[bx++] = '+'; buf[bx++] = ')'; } buf[bx] = '\0'; return buf; } #ifdef CONFIG_PROC_FS /* Called by the /proc file system to return a list of modules. */ static void *m_start(struct seq_file *m, loff_t *pos) { mutex_lock(&module_mutex); return seq_list_start(&modules, *pos); } static void *m_next(struct seq_file *m, void *p, loff_t *pos) { return seq_list_next(p, &modules, pos); } static void m_stop(struct seq_file *m, void *p) { mutex_unlock(&module_mutex); } static int m_show(struct seq_file *m, void *p) { struct module *mod = list_entry(p, struct module, list); char buf[8]; seq_printf(m, "%s %u", mod->name, mod->init_size + mod->core_size); print_unload_info(m, mod); /* Informative for users. */ seq_printf(m, " %s", mod->state == MODULE_STATE_GOING ? "Unloading": mod->state == MODULE_STATE_COMING ? "Loading": "Live"); /* Used by oprofile and other similar tools. */ seq_printf(m, " 0x%pK", mod->module_core); /* Taints info */ if (mod->taints) seq_printf(m, " %s", module_flags(mod, buf)); seq_printf(m, "\n"); return 0; } /* Format: modulename size refcount deps address Where refcount is a number or -, and deps is a comma-separated list of depends or -. */ static const struct seq_operations modules_op = { .start = m_start, .next = m_next, .stop = m_stop, .show = m_show }; static int modules_open(struct inode *inode, struct file *file) { return seq_open(file, &modules_op); } static const struct file_operations proc_modules_operations = { .open = modules_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, }; static int __init proc_modules_init(void) { proc_create("modules", 0, NULL, &proc_modules_operations); return 0; } module_init(proc_modules_init); #endif /* Given an address, look for it in the module exception tables. */ const struct exception_table_entry *search_module_extables(unsigned long addr) { const struct exception_table_entry *e = NULL; struct module *mod; preempt_disable(); list_for_each_entry_rcu(mod, &modules, list) { if (mod->num_exentries == 0) continue; e = search_extable(mod->extable, mod->extable + mod->num_exentries - 1, addr); if (e) break; } preempt_enable(); /* Now, if we found one, we are running inside it now, hence we cannot unload the module, hence no refcnt needed. */ return e; } /* * is_module_address - is this address inside a module? * @addr: the address to check. * * See is_module_text_address() if you simply want to see if the address * is code (not data). */ bool is_module_address(unsigned long addr) { bool ret; preempt_disable(); ret = __module_address(addr) != NULL; preempt_enable(); return ret; } /* * __module_address - get the module which contains an address. * @addr: the address. * * Must be called with preempt disabled or module mutex held so that * module doesn't get freed during this. */ struct module *__module_address(unsigned long addr) { struct module *mod; if (addr < module_addr_min || addr > module_addr_max) return NULL; list_for_each_entry_rcu(mod, &modules, list) if (within_module_core(addr, mod) || within_module_init(addr, mod)) return mod; return NULL; } EXPORT_SYMBOL_GPL(__module_address); /* * is_module_text_address - is this address inside module code? * @addr: the address to check. * * See is_module_address() if you simply want to see if the address is * anywhere in a module. See kernel_text_address() for testing if an * address corresponds to kernel or module code. */ bool is_module_text_address(unsigned long addr) { bool ret; preempt_disable(); ret = __module_text_address(addr) != NULL; preempt_enable(); return ret; } /* * __module_text_address - get the module whose code contains an address. * @addr: the address. * * Must be called with preempt disabled or module mutex held so that * module doesn't get freed during this. */ struct module *__module_text_address(unsigned long addr) { struct module *mod = __module_address(addr);