/* Other modules depend on us: get rid of them first. */ ret = -EWOULDBLOCK; goto out; } /* Doing init or already dying? */ if (mod->state != MODULE_STATE_LIVE) { /* FIXME: if (force), slam module count damn the torpedoes */ pr_debug("%s already dying\n", mod->name); ret = -EBUSY; goto out; } /* If it has an init func, it must have an exit func to unload */ if (mod->init && !mod->exit) { forced = try_force_unload(flags); if (!forced) { /* This module can't be removed */ ret = -EBUSY; goto out; } } /* Stop the machine so refcounts can't move and disable module. */ ret = try_stop_module(mod, flags, &forced); if (ret != 0) goto out; mutex_unlock(&module_mutex); /* Final destruction now no one is using it. */ if (mod->exit != NULL) mod->exit(); blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod); klp_module_going(mod); ftrace_release_mod(mod); async_synchronize_full(); /* Store the name of the last unloaded module for diagnostic purposes */ strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); free_module(mod); /* someone could wait for the module in add_unformed_module() */ wake_up_all(&module_wq); return 0;out: mutex_unlock(&module_mutex); return ret;} static inline void print_unload_info(struct seq_file *m, struct module *mod){ struct module_use *use; int printed_something = 0; seq_printf(m, " %i ", module_refcount(mod)); /* * Always include a trailing , so userspace can differentiate * between this and the old multi-field proc format. */ list_for_each_entry(use, &mod->source_list, source_list) { printed_something = 1; seq_printf(m, "%s,", use->source->name); } if (mod->init != NULL && mod->exit == NULL) { printed_something = 1; seq_puts(m, "[permanent],"); } if (!printed_something) seq_puts(m, "-");} void __symbol_put(const char *symbol){ struct module *owner; preempt_disable(); if (!find_symbol(symbol, &owner, NULL, NULL, true, false)) BUG(); module_put(owner); preempt_enable();}EXPORT_SYMBOL(__symbol_put); /* Note this assumes addr is a function, which it currently always is. */void symbol_put_addr(void *addr){ struct module *modaddr; unsigned long a = (unsigned long)dereference_function_descriptor(addr); if (core_kernel_text(a)) return; /* * Even though we hold a reference on the module; we still need to * disable preemption in order to safely traverse the data structure. */ preempt_disable(); modaddr = __module_text_address(a); BUG_ON(!modaddr); module_put(modaddr); preempt_enable();}EXPORT_SYMBOL_GPL(symbol_put_addr); static ssize_t show_refcnt(struct module_attribute *mattr, struct module_kobject *mk, char *buffer){ return sprintf(buffer, "%i\n", module_refcount(mk->mod));} static struct module_attribute modinfo_refcnt = __ATTR(refcnt, 0444, show_refcnt, NULL); void __module_get(struct module *module){ if (module) { preempt_disable(); atomic_inc(&module->refcnt); trace_module_get(module, _RET_IP_); preempt_enable(); }}EXPORT_SYMBOL(__module_get); bool try_module_get(struct module *module){ bool ret = true; if (module) { preempt_disable(); /* Note: here, we can fail to get a reference */ if (likely(module_is_live(module) && atomic_inc_not_zero(&module->refcnt) != 0)) trace_module_get(module, _RET_IP_); else ret = false; preempt_enable(); } return ret;}EXPORT_SYMBOL(try_module_get); void module_put(struct module *module){ int ret; if (module) { preempt_disable(); ret = atomic_dec_if_positive(&module->refcnt); WARN_ON(ret < 0); /* Failed to put refcount */ trace_module_put(module, _RET_IP_); preempt_enable(); }}EXPORT_SYMBOL(module_put); #else /* !CONFIG_MODULE_UNLOAD */static inline void print_unload_info(struct seq_file *m, struct module *mod){ /* We don't know the usage count, or what modules are using. */ seq_puts(m, " - -");} static inline void module_unload_free(struct module *mod){} static int ref_module(struct module *a, struct module *b){ return strong_try_module_get(b);} static inline int module_unload_init(struct module *mod){ return 0;}#endif /* CONFIG_MODULE_UNLOAD */ static size_t module_flags_taint(struct module *mod, char *buf){ size_t l = 0; int i; for (i = 0; i < TAINT_FLAGS_COUNT; i++) { if (taint_flags[i].module && test_bit(i, &mod->taints)) buf[l++] = taint_flags[i].c_true; } return l;} static ssize_t show_initstate(struct module_attribute *mattr, struct module_kobject *mk, char *buffer){ const char *state = "unknown"; switch (mk->mod->state) { case MODULE_STATE_LIVE: state = "live"; break; case MODULE_STATE_COMING: state = "coming"; break; case MODULE_STATE_GOING: state = "going"; break; default: BUG(); } return sprintf(buffer, "%s\n", state);} static struct module_attribute modinfo_initstate = __ATTR(initstate, 0444, show_initstate, NULL); static ssize_t store_uevent(struct module_attribute *mattr, struct module_kobject *mk, const char *buffer, size_t count){ int rc; rc = kobject_synth_uevent(&mk->kobj, buffer, count); return rc ? rc : count;} struct module_attribute module_uevent = __ATTR(uevent, 0200, NULL, store_uevent); static ssize_t show_coresize(struct module_attribute *mattr, struct module_kobject *mk, char *buffer){ return sprintf(buffer, "%u\n", mk->mod->core_layout.size);} static struct module_attribute modinfo_coresize = __ATTR(coresize, 0444, show_coresize, NULL); static ssize_t show_initsize(struct module_attribute *mattr, struct module_kobject *mk, char *buffer){ return sprintf(buffer, "%u\n", mk->mod->init_layout.size);} static struct module_attribute modinfo_initsize = __ATTR(initsize, 0444, show_initsize, NULL); static ssize_t show_taint(struct module_attribute *mattr, struct module_kobject *mk, char *buffer){ size_t l; l = module_flags_taint(mk->mod, buffer); buffer[l++] = '\n'; return l;} static struct module_attribute modinfo_taint = __ATTR(taint, 0444, show_taint, NULL); static struct module_attribute *modinfo_attrs[] = { &module_uevent, &modinfo_version, &modinfo_srcversion, &modinfo_initstate, &modinfo_coresize, &modinfo_initsize, &modinfo_taint,#ifdef CONFIG_MODULE_UNLOAD &modinfo_refcnt,#endif NULL,}; static const char vermagic[] = VERMAGIC_STRING; static int try_to_force_load(struct module *mod, const char *reason){#ifdef CONFIG_MODULE_FORCE_LOAD if (!test_taint(TAINT_FORCED_MODULE)) pr_warn("%s: %s: kernel tainted.\n", mod->name, reason); add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_NOW_UNRELIABLE); return 0;#else return -ENOEXEC;#endif} #ifdef CONFIG_MODVERSIONS static u32 resolve_rel_crc(const s32 *crc){ return *(u32 *)((void *)crc + *crc);} static int check_version(const struct load_info *info, const char *symname, struct module *mod, const s32 *crc){ Elf_Shdr *sechdrs = info->sechdrs; unsigned int versindex = info->index.vers; unsigned int i, num_versions; struct modversion_info *versions; /* Exporting module didn't supply crcs? OK, we're already tainted. */ if (!crc) return 1; /* No versions at all? modprobe --force does this. */ if (versindex == 0) return try_to_force_load(mod, symname) == 0; versions = (void *) sechdrs[versindex].sh_addr; num_versions = sechdrs[versindex].sh_size / sizeof(struct modversion_info); for (i = 0; i < num_versions; i++) { u32 crcval; if (strcmp(versions[i].name, symname) != 0) continue; if (IS_ENABLED(CONFIG_MODULE_REL_CRCS)) crcval = resolve_rel_crc(crc); else crcval = *crc; if (versions[i].crc == crcval) return 1; pr_debug("Found checksum %X vs module %lX\n", crcval, versions[i].crc); goto bad_version; } /* Broken toolchain. Warn once, then let it go.. */ pr_warn_once("%s: no symbol version for %s\n", info->name, symname); return 1; bad_version: pr_warn("%s: disagrees about version of symbol %s\n", info->name, symname); return 0;} static inline int check_modstruct_version(const struct load_info *info, struct module *mod){ const s32 *crc; /* * Since this should be found in kernel (which can't be removed), no * locking is necessary -- use preempt_disable() to placate lockdep. */ preempt_disable(); if (!find_symbol("module_layout", NULL, &crc, NULL, true, false)) { preempt_enable(); BUG(); } preempt_enable(); return check_version(info, "module_layout", mod, crc);} /* First part is kernel version, which we ignore if module has crcs. */static inline int same_magic(const char *amagic, const char *bmagic, bool has_crcs){ if (has_crcs) { amagic += strcspn(amagic, " "); bmagic += strcspn(bmagic, " "); } return strcmp(amagic, bmagic) == 0;}#elsestatic inline int check_version(const struct load_info *info, const char *symname, struct module *mod, const s32 *crc){ return 1;} static inline int check_modstruct_version(const struct load_info *info, struct module *mod){ return 1;} static inline int same_magic(const char *amagic, const char *bmagic, bool has_crcs){ return strcmp(amagic, bmagic) == 0;}#endif /* CONFIG_MODVERSIONS */ static char *get_modinfo(const struct load_info *info, const char *tag);static char *get_next_modinfo(const struct load_info *info, const char *tag, char *prev); static int verify_namespace_is_imported(const struct load_info *info, const struct kernel_symbol *sym, struct module *mod){ const char *namespace; char *imported_namespace; namespace = kernel_symbol_namespace(sym); if (namespace && namespace[0]) { imported_namespace = get_modinfo(info, "import_ns"); while (imported_namespace) { if (strcmp(namespace, imported_namespace) == 0) return 0; imported_namespace = get_next_modinfo( info, "import_ns", imported_namespace); }#ifdef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS pr_warn(#else pr_err(#endif "%s: module uses symbol (%s) from namespace %s, but does not import it.\n", mod->name, kernel_symbol_name(sym), namespace);#ifndef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS return -EINVAL;#endif } return 0;} static bool inherit_taint(struct module *mod, struct module *owner){ if (!owner || !test_bit(TAINT_PROPRIETARY_MODULE, &owner->taints)) return true; if (mod->using_gplonly_symbols) { pr_err("%s: module using GPL-only symbols uses symbols from proprietary module %s.\n", mod->name, owner->name); return false; } if (!test_bit(TAINT_PROPRIETARY_MODULE, &mod->taints)) { pr_warn("%s: module uses symbols from proprietary module %s, inheriting taint.\n", mod->name, owner->name); set_bit(TAINT_PROPRIETARY_MODULE, &mod->taints); } return true;} /* Resolve a symbol for this module. I.e. if we find one, record usage. */static const struct kernel_symbol *resolve_symbol(struct module *mod, const struct load_info *info, const char *name, char ownername[]){ struct module *owner; const struct kernel_symbol *sym; const s32 *crc; enum mod_license license; int err; /* * The module_mutex should not be a heavily contended lock; * if we get the occasional sleep here, we'll go an extra iteration * in the wait_event_interruptible(), which is harmless. */ sched_annotate_sleep(); mutex_lock(&module_mutex); sym = find_symbol(name, &owner, &crc, &license, !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); if (!sym) goto unlock; if (license == GPL_ONLY) mod->using_gplonly_symbols = true; if (!inherit_taint(mod, owner)) { sym = NULL; goto getname; } if (!check_version(info, name, mod, crc)) { sym = ERR_PTR(-EINVAL); goto getname; } err = verify_namespace_is_imported(info, sym, mod); if (err) { sym = ERR_PTR(err); goto getname; } err = ref_module(mod, owner); if (err) { sym = ERR_PTR(err); goto getname; }Lines 1001–1500 of 4590. Previous lines Load more
/* Other modules depend on us: get rid of them first. */ ret = -EWOULDBLOCK; goto out; } /* Doing init or already dying? */ if (mod->state != MODULE_STATE_LIVE) { /* FIXME: if (force), slam module count damn the torpedoes */ pr_debug("%s already dying\n", mod->name); ret = -EBUSY; goto out; } /* If it has an init func, it must have an exit func to unload */ if (mod->init && !mod->exit) { forced = try_force_unload(flags); if (!forced) { /* This module can't be removed */ ret = -EBUSY; goto out; } } /* Stop the machine so refcounts can't move and disable module. */ ret = try_stop_module(mod, flags, &forced); if (ret != 0) goto out; mutex_unlock(&module_mutex); /* Final destruction now no one is using it. */ if (mod->exit != NULL) mod->exit(); blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod); klp_module_going(mod); ftrace_release_mod(mod); async_synchronize_full(); /* Store the name of the last unloaded module for diagnostic purposes */ strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); free_module(mod); /* someone could wait for the module in add_unformed_module() */ wake_up_all(&module_wq); return 0; out: mutex_unlock(&module_mutex); return ret; } static inline void print_unload_info(struct seq_file *m, struct module *mod) { struct module_use *use; int printed_something = 0; seq_printf(m, " %i ", module_refcount(mod)); /* * Always include a trailing , so userspace can differentiate * between this and the old multi-field proc format. */ list_for_each_entry(use, &mod->source_list, source_list) { printed_something = 1; seq_printf(m, "%s,", use->source->name); } if (mod->init != NULL && mod->exit == NULL) { printed_something = 1; seq_puts(m, "[permanent],"); } if (!printed_something) seq_puts(m, "-"); } void __symbol_put(const char *symbol) { struct module *owner; preempt_disable(); if (!find_symbol(symbol, &owner, NULL, NULL, true, false)) BUG(); module_put(owner); preempt_enable(); } EXPORT_SYMBOL(__symbol_put); /* Note this assumes addr is a function, which it currently always is. */ void symbol_put_addr(void *addr) { struct module *modaddr; unsigned long a = (unsigned long)dereference_function_descriptor(addr); if (core_kernel_text(a)) return; /* * Even though we hold a reference on the module; we still need to * disable preemption in order to safely traverse the data structure. */ preempt_disable(); modaddr = __module_text_address(a); BUG_ON(!modaddr); module_put(modaddr); preempt_enable(); } EXPORT_SYMBOL_GPL(symbol_put_addr); static ssize_t show_refcnt(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { return sprintf(buffer, "%i\n", module_refcount(mk->mod)); } static struct module_attribute modinfo_refcnt = __ATTR(refcnt, 0444, show_refcnt, NULL); void __module_get(struct module *module) { if (module) { preempt_disable(); atomic_inc(&module->refcnt); trace_module_get(module, _RET_IP_); preempt_enable(); } } EXPORT_SYMBOL(__module_get); bool try_module_get(struct module *module) { bool ret = true; if (module) { preempt_disable(); /* Note: here, we can fail to get a reference */ if (likely(module_is_live(module) && atomic_inc_not_zero(&module->refcnt) != 0)) trace_module_get(module, _RET_IP_); else ret = false; preempt_enable(); } return ret; } EXPORT_SYMBOL(try_module_get); void module_put(struct module *module) { int ret; if (module) { preempt_disable(); ret = atomic_dec_if_positive(&module->refcnt); WARN_ON(ret < 0); /* Failed to put refcount */ trace_module_put(module, _RET_IP_); preempt_enable(); } } EXPORT_SYMBOL(module_put); #else /* !CONFIG_MODULE_UNLOAD */ static inline void print_unload_info(struct seq_file *m, struct module *mod) { /* We don't know the usage count, or what modules are using. */ seq_puts(m, " - -"); } static inline void module_unload_free(struct module *mod) { } static int ref_module(struct module *a, struct module *b) { return strong_try_module_get(b); } static inline int module_unload_init(struct module *mod) { return 0; } #endif /* CONFIG_MODULE_UNLOAD */ static size_t module_flags_taint(struct module *mod, char *buf) { size_t l = 0; int i; for (i = 0; i < TAINT_FLAGS_COUNT; i++) { if (taint_flags[i].module && test_bit(i, &mod->taints)) buf[l++] = taint_flags[i].c_true; } return l; } static ssize_t show_initstate(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { const char *state = "unknown"; switch (mk->mod->state) { case MODULE_STATE_LIVE: state = "live"; break; case MODULE_STATE_COMING: state = "coming"; break; case MODULE_STATE_GOING: state = "going"; break; default: BUG(); } return sprintf(buffer, "%s\n", state); } static struct module_attribute modinfo_initstate = __ATTR(initstate, 0444, show_initstate, NULL); static ssize_t store_uevent(struct module_attribute *mattr, struct module_kobject *mk, const char *buffer, size_t count) { int rc; rc = kobject_synth_uevent(&mk->kobj, buffer, count); return rc ? rc : count; } struct module_attribute module_uevent = __ATTR(uevent, 0200, NULL, store_uevent); static ssize_t show_coresize(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { return sprintf(buffer, "%u\n", mk->mod->core_layout.size); } static struct module_attribute modinfo_coresize = __ATTR(coresize, 0444, show_coresize, NULL); static ssize_t show_initsize(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { return sprintf(buffer, "%u\n", mk->mod->init_layout.size); } static struct module_attribute modinfo_initsize = __ATTR(initsize, 0444, show_initsize, NULL); static ssize_t show_taint(struct module_attribute *mattr, struct module_kobject *mk, char *buffer) { size_t l; l = module_flags_taint(mk->mod, buffer); buffer[l++] = '\n'; return l; } static struct module_attribute modinfo_taint = __ATTR(taint, 0444, show_taint, NULL); static struct module_attribute *modinfo_attrs[] = { &module_uevent, &modinfo_version, &modinfo_srcversion, &modinfo_initstate, &modinfo_coresize, &modinfo_initsize, &modinfo_taint, #ifdef CONFIG_MODULE_UNLOAD &modinfo_refcnt, #endif NULL, }; static const char vermagic[] = VERMAGIC_STRING; static int try_to_force_load(struct module *mod, const char *reason) { #ifdef CONFIG_MODULE_FORCE_LOAD if (!test_taint(TAINT_FORCED_MODULE)) pr_warn("%s: %s: kernel tainted.\n", mod->name, reason); add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_NOW_UNRELIABLE); return 0; #else return -ENOEXEC; #endif } #ifdef CONFIG_MODVERSIONS static u32 resolve_rel_crc(const s32 *crc) { return *(u32 *)((void *)crc + *crc); } static int check_version(const struct load_info *info, const char *symname, struct module *mod, const s32 *crc) { Elf_Shdr *sechdrs = info->sechdrs; unsigned int versindex = info->index.vers; unsigned int i, num_versions; struct modversion_info *versions; /* Exporting module didn't supply crcs? OK, we're already tainted. */ if (!crc) return 1; /* No versions at all? modprobe --force does this. */ if (versindex == 0) return try_to_force_load(mod, symname) == 0; versions = (void *) sechdrs[versindex].sh_addr; num_versions = sechdrs[versindex].sh_size / sizeof(struct modversion_info); for (i = 0; i < num_versions; i++) { u32 crcval; if (strcmp(versions[i].name, symname) != 0) continue; if (IS_ENABLED(CONFIG_MODULE_REL_CRCS)) crcval = resolve_rel_crc(crc); else crcval = *crc; if (versions[i].crc == crcval) return 1; pr_debug("Found checksum %X vs module %lX\n", crcval, versions[i].crc); goto bad_version; } /* Broken toolchain. Warn once, then let it go.. */ pr_warn_once("%s: no symbol version for %s\n", info->name, symname); return 1; bad_version: pr_warn("%s: disagrees about version of symbol %s\n", info->name, symname); return 0; } static inline int check_modstruct_version(const struct load_info *info, struct module *mod) { const s32 *crc; /* * Since this should be found in kernel (which can't be removed), no * locking is necessary -- use preempt_disable() to placate lockdep. */ preempt_disable(); if (!find_symbol("module_layout", NULL, &crc, NULL, true, false)) { preempt_enable(); BUG(); } preempt_enable(); return check_version(info, "module_layout", mod, crc); } /* First part is kernel version, which we ignore if module has crcs. */ static inline int same_magic(const char *amagic, const char *bmagic, bool has_crcs) { if (has_crcs) { amagic += strcspn(amagic, " "); bmagic += strcspn(bmagic, " "); } return strcmp(amagic, bmagic) == 0; } #else static inline int check_version(const struct load_info *info, const char *symname, struct module *mod, const s32 *crc) { return 1; } static inline int check_modstruct_version(const struct load_info *info, struct module *mod) { return 1; } static inline int same_magic(const char *amagic, const char *bmagic, bool has_crcs) { return strcmp(amagic, bmagic) == 0; } #endif /* CONFIG_MODVERSIONS */ static char *get_modinfo(const struct load_info *info, const char *tag); static char *get_next_modinfo(const struct load_info *info, const char *tag, char *prev); static int verify_namespace_is_imported(const struct load_info *info, const struct kernel_symbol *sym, struct module *mod) { const char *namespace; char *imported_namespace; namespace = kernel_symbol_namespace(sym); if (namespace && namespace[0]) { imported_namespace = get_modinfo(info, "import_ns"); while (imported_namespace) { if (strcmp(namespace, imported_namespace) == 0) return 0; imported_namespace = get_next_modinfo( info, "import_ns", imported_namespace); } #ifdef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS pr_warn( #else pr_err( #endif "%s: module uses symbol (%s) from namespace %s, but does not import it.\n", mod->name, kernel_symbol_name(sym), namespace); #ifndef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS return -EINVAL; #endif } return 0; } static bool inherit_taint(struct module *mod, struct module *owner) { if (!owner || !test_bit(TAINT_PROPRIETARY_MODULE, &owner->taints)) return true; if (mod->using_gplonly_symbols) { pr_err("%s: module using GPL-only symbols uses symbols from proprietary module %s.\n", mod->name, owner->name); return false; } if (!test_bit(TAINT_PROPRIETARY_MODULE, &mod->taints)) { pr_warn("%s: module uses symbols from proprietary module %s, inheriting taint.\n", mod->name, owner->name); set_bit(TAINT_PROPRIETARY_MODULE, &mod->taints); } return true; } /* Resolve a symbol for this module. I.e. if we find one, record usage. */ static const struct kernel_symbol *resolve_symbol(struct module *mod, const struct load_info *info, const char *name, char ownername[]) { struct module *owner; const struct kernel_symbol *sym; const s32 *crc; enum mod_license license; int err; /* * The module_mutex should not be a heavily contended lock; * if we get the occasional sleep here, we'll go an extra iteration * in the wait_event_interruptible(), which is harmless. */ sched_annotate_sleep(); mutex_lock(&module_mutex); sym = find_symbol(name, &owner, &crc, &license, !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); if (!sym) goto unlock; if (license == GPL_ONLY) mod->using_gplonly_symbols = true; if (!inherit_taint(mod, owner)) { sym = NULL; goto getname; } if (!check_version(info, name, mod, crc)) { sym = ERR_PTR(-EINVAL); goto getname; } err = verify_namespace_is_imported(info, sym, mod); if (err) { sym = ERR_PTR(err); goto getname; } err = ref_module(mod, owner); if (err) { sym = ERR_PTR(err); goto getname; }