4590 lines · 117.2 KB · C
RawDownload
static bool check_exported_symbol(const struct symsearch *syms,				  struct module *owner,				  unsigned int symnum, void *data){	struct find_symbol_arg *fsa = data; 	if (!fsa->gplok) {		if (syms->license == GPL_ONLY)			return false;		if (syms->license == WILL_BE_GPL_ONLY && fsa->warn) {			pr_warn("Symbol %s is being used by a non-GPL module, "				"which will not be allowed in the future\n",				fsa->name);		}	} #ifdef CONFIG_UNUSED_SYMBOLS	if (syms->unused && fsa->warn) {		pr_warn("Symbol %s is marked as UNUSED, however this module is "			"using it.\n", fsa->name);		pr_warn("This symbol will go away in the future.\n");		pr_warn("Please evaluate if this is the right api to use and "			"if it really is, submit a report to the linux kernel "			"mailing list together with submitting your code for "			"inclusion.\n");	}#endif 	fsa->owner = owner;	fsa->crc = symversion(syms->crcs, symnum);	fsa->sym = &syms->start[symnum];	fsa->license = syms->license;	return true;} static unsigned long kernel_symbol_value(const struct kernel_symbol *sym){#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS	return (unsigned long)offset_to_ptr(&sym->value_offset);#else	return sym->value;#endif} static const char *kernel_symbol_name(const struct kernel_symbol *sym){#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS	return offset_to_ptr(&sym->name_offset);#else	return sym->name;#endif} static const char *kernel_symbol_namespace(const struct kernel_symbol *sym){#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS	if (!sym->namespace_offset)		return NULL;	return offset_to_ptr(&sym->namespace_offset);#else	return sym->namespace;#endif} static int cmp_name(const void *name, const void *sym){	return strcmp(name, kernel_symbol_name(sym));} static bool find_exported_symbol_in_section(const struct symsearch *syms,					    struct module *owner,					    void *data){	struct find_symbol_arg *fsa = data;	struct kernel_symbol *sym; 	sym = bsearch(fsa->name, syms->start, syms->stop - syms->start,			sizeof(struct kernel_symbol), cmp_name); 	if (sym != NULL && check_exported_symbol(syms, owner,						 sym - syms->start, data))		return true; 	return false;} /* Find an exported symbol and return it, along with, (optional) crc and * (optional) module which owns it.  Needs preempt disabled or module_mutex. */static const struct kernel_symbol *find_symbol(const char *name,					struct module **owner,					const s32 **crc,					enum mod_license *license,					bool gplok,					bool warn){	struct find_symbol_arg fsa; 	fsa.name = name;	fsa.gplok = gplok;	fsa.warn = warn; 	if (each_symbol_section(find_exported_symbol_in_section, &fsa)) {		if (owner)			*owner = fsa.owner;		if (crc)			*crc = fsa.crc;		if (license)			*license = fsa.license;		return fsa.sym;	} 	pr_debug("Failed to find symbol %s\n", name);	return NULL;} /* * Search for module by name: must hold module_mutex (or preempt disabled * for read-only access). */static struct module *find_module_all(const char *name, size_t len,				      bool even_unformed){	struct module *mod; 	module_assert_mutex_or_preempt(); 	list_for_each_entry_rcu(mod, &modules, list,				lockdep_is_held(&module_mutex)) {		if (!even_unformed && mod->state == MODULE_STATE_UNFORMED)			continue;		if (strlen(mod->name) == len && !memcmp(mod->name, name, len))			return mod;	}	return NULL;} struct module *find_module(const char *name){	module_assert_mutex();	return find_module_all(name, strlen(name), false);}EXPORT_SYMBOL_GPL(find_module); #ifdef CONFIG_SMP static inline void __percpu *mod_percpu(struct module *mod){	return mod->percpu;} static int percpu_modalloc(struct module *mod, struct load_info *info){	Elf_Shdr *pcpusec = &info->sechdrs[info->index.pcpu];	unsigned long align = pcpusec->sh_addralign; 	if (!pcpusec->sh_size)		return 0; 	if (align > PAGE_SIZE) {		pr_warn("%s: per-cpu alignment %li > %li\n",			mod->name, align, PAGE_SIZE);		align = PAGE_SIZE;	} 	mod->percpu = __alloc_reserved_percpu(pcpusec->sh_size, align);	if (!mod->percpu) {		pr_warn("%s: Could not allocate %lu bytes percpu data\n",			mod->name, (unsigned long)pcpusec->sh_size);		return -ENOMEM;	}	mod->percpu_size = pcpusec->sh_size;	return 0;} static void percpu_modfree(struct module *mod){	free_percpu(mod->percpu);} static unsigned int find_pcpusec(struct load_info *info){	return find_sec(info, ".data..percpu");} static void percpu_modcopy(struct module *mod,			   const void *from, unsigned long size){	int cpu; 	for_each_possible_cpu(cpu)		memcpy(per_cpu_ptr(mod->percpu, cpu), from, size);} bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr){	struct module *mod;	unsigned int cpu; 	preempt_disable(); 	list_for_each_entry_rcu(mod, &modules, list) {		if (mod->state == MODULE_STATE_UNFORMED)			continue;		if (!mod->percpu_size)			continue;		for_each_possible_cpu(cpu) {			void *start = per_cpu_ptr(mod->percpu, cpu);			void *va = (void *)addr; 			if (va >= start && va < start + mod->percpu_size) {				if (can_addr) {					*can_addr = (unsigned long) (va - start);					*can_addr += (unsigned long)						per_cpu_ptr(mod->percpu,							    get_boot_cpu_id());				}				preempt_enable();				return true;			}		}	} 	preempt_enable();	return false;} /** * is_module_percpu_address - test whether address is from module static percpu * @addr: address to test * * Test whether @addr belongs to module static percpu area. * * RETURNS: * %true if @addr is from module static percpu area */bool is_module_percpu_address(unsigned long addr){	return __is_module_percpu_address(addr, NULL);} #else /* ... !CONFIG_SMP */ static inline void __percpu *mod_percpu(struct module *mod){	return NULL;}static int percpu_modalloc(struct module *mod, struct load_info *info){	/* UP modules shouldn't have this section: ENOMEM isn't quite right */	if (info->sechdrs[info->index.pcpu].sh_size != 0)		return -ENOMEM;	return 0;}static inline void percpu_modfree(struct module *mod){}static unsigned int find_pcpusec(struct load_info *info){	return 0;}static inline void percpu_modcopy(struct module *mod,				  const void *from, unsigned long size){	/* pcpusec should be 0, and size of that section should be 0. */	BUG_ON(size != 0);}bool is_module_percpu_address(unsigned long addr){	return false;} bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr){	return false;} #endif /* CONFIG_SMP */ #define MODINFO_ATTR(field)	\static void setup_modinfo_##field(struct module *mod, const char *s)  \{                                                                     \	mod->field = kstrdup(s, GFP_KERNEL);                          \}                                                                     \static ssize_t show_modinfo_##field(struct module_attribute *mattr,   \			struct module_kobject *mk, char *buffer)      \{                                                                     \	return scnprintf(buffer, PAGE_SIZE, "%s\n", mk->mod->field);  \}                                                                     \static int modinfo_##field##_exists(struct module *mod)               \{                                                                     \	return mod->field != NULL;                                    \}                                                                     \static void free_modinfo_##field(struct module *mod)                  \{                                                                     \	kfree(mod->field);                                            \	mod->field = NULL;                                            \}                                                                     \static struct module_attribute modinfo_##field = {                    \	.attr = { .name = __stringify(field), .mode = 0444 },         \	.show = show_modinfo_##field,                                 \	.setup = setup_modinfo_##field,                               \	.test = modinfo_##field##_exists,                             \	.free = free_modinfo_##field,                                 \}; MODINFO_ATTR(version);MODINFO_ATTR(srcversion); static char last_unloaded_module[MODULE_NAME_LEN+1]; #ifdef CONFIG_MODULE_UNLOAD EXPORT_TRACEPOINT_SYMBOL(module_get); /* MODULE_REF_BASE is the base reference count by kmodule loader. */#define MODULE_REF_BASE	1 /* Init the unload section of the module. */static int module_unload_init(struct module *mod){	/*	 * Initialize reference counter to MODULE_REF_BASE.	 * refcnt == 0 means module is going.	 */	atomic_set(&mod->refcnt, MODULE_REF_BASE); 	INIT_LIST_HEAD(&mod->source_list);	INIT_LIST_HEAD(&mod->target_list); 	/* Hold reference count during initialization. */	atomic_inc(&mod->refcnt); 	return 0;} /* Does a already use b? */static int already_uses(struct module *a, struct module *b){	struct module_use *use; 	list_for_each_entry(use, &b->source_list, source_list) {		if (use->source == a) {			pr_debug("%s uses %s!\n", a->name, b->name);			return 1;		}	}	pr_debug("%s does not use %s!\n", a->name, b->name);	return 0;} /* * Module a uses b *  - we add 'a' as a "source", 'b' as a "target" of module use *  - the module_use is added to the list of 'b' sources (so *    'b' can walk the list to see who sourced them), and of 'a' *    targets (so 'a' can see what modules it targets). */static int add_module_usage(struct module *a, struct module *b){	struct module_use *use; 	pr_debug("Allocating new usage for %s.\n", a->name);	use = kmalloc(sizeof(*use), GFP_ATOMIC);	if (!use)		return -ENOMEM; 	use->source = a;	use->target = b;	list_add(&use->source_list, &b->source_list);	list_add(&use->target_list, &a->target_list);	return 0;} /* Module a uses b: caller needs module_mutex() */static int ref_module(struct module *a, struct module *b){	int err; 	if (b == NULL || already_uses(a, b))		return 0; 	/* If module isn't available, we fail. */	err = strong_try_module_get(b);	if (err)		return err; 	err = add_module_usage(a, b);	if (err) {		module_put(b);		return err;	}	return 0;} /* Clear the unload stuff of the module. */static void module_unload_free(struct module *mod){	struct module_use *use, *tmp; 	mutex_lock(&module_mutex);	list_for_each_entry_safe(use, tmp, &mod->target_list, target_list) {		struct module *i = use->target;		pr_debug("%s unusing %s\n", mod->name, i->name);		module_put(i);		list_del(&use->source_list);		list_del(&use->target_list);		kfree(use);	}	mutex_unlock(&module_mutex);} #ifdef CONFIG_MODULE_FORCE_UNLOADstatic inline int try_force_unload(unsigned int flags){	int ret = (flags & O_TRUNC);	if (ret)		add_taint(TAINT_FORCED_RMMOD, LOCKDEP_NOW_UNRELIABLE);	return ret;}#elsestatic inline int try_force_unload(unsigned int flags){	return 0;}#endif /* CONFIG_MODULE_FORCE_UNLOAD */ /* Try to release refcount of module, 0 means success. */static int try_release_module_ref(struct module *mod){	int ret; 	/* Try to decrement refcnt which we set at loading */	ret = atomic_sub_return(MODULE_REF_BASE, &mod->refcnt);	BUG_ON(ret < 0);	if (ret)		/* Someone can put this right now, recover with checking */		ret = atomic_add_unless(&mod->refcnt, MODULE_REF_BASE, 0); 	return ret;} static int try_stop_module(struct module *mod, int flags, int *forced){	/* If it's not unused, quit unless we're forcing. */	if (try_release_module_ref(mod) != 0) {		*forced = try_force_unload(flags);		if (!(*forced))			return -EWOULDBLOCK;	} 	/* Mark it as dying. */	mod->state = MODULE_STATE_GOING; 	return 0;} /** * module_refcount - return the refcount or -1 if unloading * * @mod:	the module we're checking * * Returns: *	-1 if the module is in the process of unloading *	otherwise the number of references in the kernel to the module */int module_refcount(struct module *mod){	return atomic_read(&mod->refcnt) - MODULE_REF_BASE;}EXPORT_SYMBOL(module_refcount); /* This exists whether we can unload or not */static void free_module(struct module *mod); SYSCALL_DEFINE2(delete_module, const char __user *, name_user,		unsigned int, flags){	struct module *mod;	char name[MODULE_NAME_LEN];	int ret, forced = 0; 	if (!capable(CAP_SYS_MODULE) || modules_disabled)		return -EPERM; 	if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)		return -EFAULT;	name[MODULE_NAME_LEN-1] = '\0'; 	audit_log_kern_module(name); 	if (mutex_lock_interruptible(&module_mutex) != 0)		return -EINTR; 	mod = find_module(name);	if (!mod) {		ret = -ENOENT;		goto out;	} 	if (!list_empty(&mod->source_list)) {

Lines 501–1000 of 4590. Previous lines