3539 lines · 89.7 KB · C
RawDownload
#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