Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull module update from Rusty Russell: "The sweeping change is to make add_taint() explicitly indicate whether to disable lockdep, but it's a mechanical change." * tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: MODSIGN: Add option to not sign modules during modules_install MODSIGN: Add -s <signature> option to sign-file MODSIGN: Specify the hash algorithm on sign-file command line MODSIGN: Simplify Makefile with a Kconfig helper module: clean up load_module a little more. modpost: Ignore ARC specific non-alloc sections module: constify within_module_* taint: add explicit flag to show whether lock dep is still OK. module: printk message when module signature fail taints kernel.
This commit is contained in:
@@ -153,23 +153,7 @@ kernel/modsign_certificate.o: signing_key.x509 extra_certificates
|
||||
# fail and that the kernel may be used afterwards.
|
||||
#
|
||||
###############################################################################
|
||||
sign_key_with_hash :=
|
||||
ifeq ($(CONFIG_MODULE_SIG_SHA1),y)
|
||||
sign_key_with_hash := -sha1
|
||||
endif
|
||||
ifeq ($(CONFIG_MODULE_SIG_SHA224),y)
|
||||
sign_key_with_hash := -sha224
|
||||
endif
|
||||
ifeq ($(CONFIG_MODULE_SIG_SHA256),y)
|
||||
sign_key_with_hash := -sha256
|
||||
endif
|
||||
ifeq ($(CONFIG_MODULE_SIG_SHA384),y)
|
||||
sign_key_with_hash := -sha384
|
||||
endif
|
||||
ifeq ($(CONFIG_MODULE_SIG_SHA512),y)
|
||||
sign_key_with_hash := -sha512
|
||||
endif
|
||||
ifeq ($(sign_key_with_hash),)
|
||||
ifndef CONFIG_MODULE_SIG_HASH
|
||||
$(error Could not determine digest type to use from kernel config)
|
||||
endif
|
||||
|
||||
@@ -182,8 +166,8 @@ signing_key.priv signing_key.x509: x509.genkey
|
||||
@echo "### needs to be run as root, and uses a hardware random"
|
||||
@echo "### number generator if one is available."
|
||||
@echo "###"
|
||||
openssl req -new -nodes -utf8 $(sign_key_with_hash) -days 36500 -batch \
|
||||
-x509 -config x509.genkey \
|
||||
openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \
|
||||
-batch -x509 -config x509.genkey \
|
||||
-outform DER -out signing_key.x509 \
|
||||
-keyout signing_key.priv
|
||||
@echo "###"
|
||||
|
140
kernel/module.c
140
kernel/module.c
@@ -197,9 +197,10 @@ static inline int strong_try_module_get(struct module *mod)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static inline void add_taint_module(struct module *mod, unsigned flag)
|
||||
static inline void add_taint_module(struct module *mod, unsigned flag,
|
||||
enum lockdep_ok lockdep_ok)
|
||||
{
|
||||
add_taint(flag);
|
||||
add_taint(flag, lockdep_ok);
|
||||
mod->taints |= (1U << flag);
|
||||
}
|
||||
|
||||
@@ -727,7 +728,7 @@ static inline int try_force_unload(unsigned int flags)
|
||||
{
|
||||
int ret = (flags & O_TRUNC);
|
||||
if (ret)
|
||||
add_taint(TAINT_FORCED_RMMOD);
|
||||
add_taint(TAINT_FORCED_RMMOD, LOCKDEP_NOW_UNRELIABLE);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
@@ -1138,7 +1139,7 @@ static int try_to_force_load(struct module *mod, const char *reason)
|
||||
if (!test_taint(TAINT_FORCED_MODULE))
|
||||
printk(KERN_WARNING "%s: %s: kernel tainted.\n",
|
||||
mod->name, reason);
|
||||
add_taint_module(mod, TAINT_FORCED_MODULE);
|
||||
add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_NOW_UNRELIABLE);
|
||||
return 0;
|
||||
#else
|
||||
return -ENOEXEC;
|
||||
@@ -2147,7 +2148,8 @@ static void set_license(struct module *mod, const char *license)
|
||||
if (!test_taint(TAINT_PROPRIETARY_MODULE))
|
||||
printk(KERN_WARNING "%s: module license '%s' taints "
|
||||
"kernel.\n", mod->name, license);
|
||||
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
|
||||
add_taint_module(mod, TAINT_PROPRIETARY_MODULE,
|
||||
LOCKDEP_NOW_UNRELIABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2700,10 +2702,10 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
|
||||
}
|
||||
|
||||
if (!get_modinfo(info, "intree"))
|
||||
add_taint_module(mod, TAINT_OOT_MODULE);
|
||||
add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
|
||||
|
||||
if (get_modinfo(info, "staging")) {
|
||||
add_taint_module(mod, TAINT_CRAP);
|
||||
add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK);
|
||||
printk(KERN_WARNING "%s: module is from the staging directory,"
|
||||
" the quality is unknown, you have been warned.\n",
|
||||
mod->name);
|
||||
@@ -2869,15 +2871,17 @@ static int check_module_license_and_versions(struct module *mod)
|
||||
* using GPL-only symbols it needs.
|
||||
*/
|
||||
if (strcmp(mod->name, "ndiswrapper") == 0)
|
||||
add_taint(TAINT_PROPRIETARY_MODULE);
|
||||
add_taint(TAINT_PROPRIETARY_MODULE, LOCKDEP_NOW_UNRELIABLE);
|
||||
|
||||
/* driverloader was caught wrongly pretending to be under GPL */
|
||||
if (strcmp(mod->name, "driverloader") == 0)
|
||||
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
|
||||
add_taint_module(mod, TAINT_PROPRIETARY_MODULE,
|
||||
LOCKDEP_NOW_UNRELIABLE);
|
||||
|
||||
/* lve claims to be GPL but upstream won't provide source */
|
||||
if (strcmp(mod->name, "lve") == 0)
|
||||
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
|
||||
add_taint_module(mod, TAINT_PROPRIETARY_MODULE,
|
||||
LOCKDEP_NOW_UNRELIABLE);
|
||||
|
||||
#ifdef CONFIG_MODVERSIONS
|
||||
if ((mod->num_syms && !mod->crcs)
|
||||
@@ -3141,12 +3145,72 @@ static int may_init_module(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We try to place it in the list now to make sure it's unique before
|
||||
* we dedicate too many resources. In particular, temporary percpu
|
||||
* memory exhaustion.
|
||||
*/
|
||||
static int add_unformed_module(struct module *mod)
|
||||
{
|
||||
int err;
|
||||
struct module *old;
|
||||
|
||||
mod->state = MODULE_STATE_UNFORMED;
|
||||
|
||||
again:
|
||||
mutex_lock(&module_mutex);
|
||||
if ((old = find_module_all(mod->name, true)) != NULL) {
|
||||
if (old->state == MODULE_STATE_COMING
|
||||
|| old->state == MODULE_STATE_UNFORMED) {
|
||||
/* Wait in case it fails to load. */
|
||||
mutex_unlock(&module_mutex);
|
||||
err = wait_event_interruptible(module_wq,
|
||||
finished_loading(mod->name));
|
||||
if (err)
|
||||
goto out_unlocked;
|
||||
goto again;
|
||||
}
|
||||
err = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
list_add_rcu(&mod->list, &modules);
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
mutex_unlock(&module_mutex);
|
||||
out_unlocked:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int complete_formation(struct module *mod, struct load_info *info)
|
||||
{
|
||||
int err;
|
||||
|
||||
mutex_lock(&module_mutex);
|
||||
|
||||
/* Find duplicate symbols (must be called under lock). */
|
||||
err = verify_export_symbols(mod);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
/* This relies on module_mutex for list integrity. */
|
||||
module_bug_finalize(info->hdr, info->sechdrs, mod);
|
||||
|
||||
/* Mark state as coming so strong_try_module_get() ignores us,
|
||||
* but kallsyms etc. can see us. */
|
||||
mod->state = MODULE_STATE_COMING;
|
||||
|
||||
out:
|
||||
mutex_unlock(&module_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Allocate and load the module: note that size of section 0 is always
|
||||
zero, and we rely on this for optional sections. */
|
||||
static int load_module(struct load_info *info, const char __user *uargs,
|
||||
int flags)
|
||||
{
|
||||
struct module *mod, *old;
|
||||
struct module *mod;
|
||||
long err;
|
||||
|
||||
err = module_sig_check(info);
|
||||
@@ -3164,36 +3228,20 @@ static int load_module(struct load_info *info, const char __user *uargs,
|
||||
goto free_copy;
|
||||
}
|
||||
|
||||
/*
|
||||
* We try to place it in the list now to make sure it's unique
|
||||
* before we dedicate too many resources. In particular,
|
||||
* temporary percpu memory exhaustion.
|
||||
*/
|
||||
mod->state = MODULE_STATE_UNFORMED;
|
||||
again:
|
||||
mutex_lock(&module_mutex);
|
||||
if ((old = find_module_all(mod->name, true)) != NULL) {
|
||||
if (old->state == MODULE_STATE_COMING
|
||||
|| old->state == MODULE_STATE_UNFORMED) {
|
||||
/* Wait in case it fails to load. */
|
||||
mutex_unlock(&module_mutex);
|
||||
err = wait_event_interruptible(module_wq,
|
||||
finished_loading(mod->name));
|
||||
if (err)
|
||||
goto free_module;
|
||||
goto again;
|
||||
}
|
||||
err = -EEXIST;
|
||||
mutex_unlock(&module_mutex);
|
||||
/* Reserve our place in the list. */
|
||||
err = add_unformed_module(mod);
|
||||
if (err)
|
||||
goto free_module;
|
||||
}
|
||||
list_add_rcu(&mod->list, &modules);
|
||||
mutex_unlock(&module_mutex);
|
||||
|
||||
#ifdef CONFIG_MODULE_SIG
|
||||
mod->sig_ok = info->sig_ok;
|
||||
if (!mod->sig_ok)
|
||||
add_taint_module(mod, TAINT_FORCED_MODULE);
|
||||
if (!mod->sig_ok) {
|
||||
printk_once(KERN_NOTICE
|
||||
"%s: module verification failed: signature and/or"
|
||||
" required key missing - tainting kernel\n",
|
||||
mod->name);
|
||||
add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_STILL_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now module is in final location, initialize linked lists, etc. */
|
||||
@@ -3236,21 +3284,11 @@ again:
|
||||
|
||||
dynamic_debug_setup(info->debug, info->num_debug);
|
||||
|
||||
mutex_lock(&module_mutex);
|
||||
/* Find duplicate symbols (must be called under lock). */
|
||||
err = verify_export_symbols(mod);
|
||||
if (err < 0)
|
||||
/* Finally it's fully formed, ready to start executing. */
|
||||
err = complete_formation(mod, info);
|
||||
if (err)
|
||||
goto ddebug_cleanup;
|
||||
|
||||
/* This relies on module_mutex for list integrity. */
|
||||
module_bug_finalize(info->hdr, info->sechdrs, mod);
|
||||
|
||||
/* Mark state as coming so strong_try_module_get() ignores us,
|
||||
* but kallsyms etc. can see us. */
|
||||
mod->state = MODULE_STATE_COMING;
|
||||
|
||||
mutex_unlock(&module_mutex);
|
||||
|
||||
/* Module is ready to execute: parsing args may do that. */
|
||||
err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
|
||||
-32768, 32767, &ddebug_dyndbg_module_param_cb);
|
||||
@@ -3274,8 +3312,8 @@ again:
|
||||
/* module_bug_cleanup needs module_mutex protection */
|
||||
mutex_lock(&module_mutex);
|
||||
module_bug_cleanup(mod);
|
||||
ddebug_cleanup:
|
||||
mutex_unlock(&module_mutex);
|
||||
ddebug_cleanup:
|
||||
dynamic_debug_remove(info->debug);
|
||||
synchronize_sched();
|
||||
kfree(mod->args);
|
||||
|
@@ -259,26 +259,19 @@ unsigned long get_taint(void)
|
||||
return tainted_mask;
|
||||
}
|
||||
|
||||
void add_taint(unsigned flag)
|
||||
/**
|
||||
* add_taint: add a taint flag if not already set.
|
||||
* @flag: one of the TAINT_* constants.
|
||||
* @lockdep_ok: whether lock debugging is still OK.
|
||||
*
|
||||
* If something bad has gone wrong, you'll want @lockdebug_ok = false, but for
|
||||
* some notewortht-but-not-corrupting cases, it can be set to true.
|
||||
*/
|
||||
void add_taint(unsigned flag, enum lockdep_ok lockdep_ok)
|
||||
{
|
||||
/*
|
||||
* Can't trust the integrity of the kernel anymore.
|
||||
* We don't call directly debug_locks_off() because the issue
|
||||
* is not necessarily serious enough to set oops_in_progress to 1
|
||||
* Also we want to keep up lockdep for staging/out-of-tree
|
||||
* development and post-warning case.
|
||||
*/
|
||||
switch (flag) {
|
||||
case TAINT_CRAP:
|
||||
case TAINT_OOT_MODULE:
|
||||
case TAINT_WARN:
|
||||
case TAINT_FIRMWARE_WORKAROUND:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (__debug_locks_off())
|
||||
printk(KERN_WARNING "Disabling lock debugging due to kernel taint\n");
|
||||
}
|
||||
if (lockdep_ok == LOCKDEP_NOW_UNRELIABLE && __debug_locks_off())
|
||||
printk(KERN_WARNING
|
||||
"Disabling lock debugging due to kernel taint\n");
|
||||
|
||||
set_bit(flag, &tainted_mask);
|
||||
}
|
||||
@@ -421,7 +414,8 @@ static void warn_slowpath_common(const char *file, int line, void *caller,
|
||||
print_modules();
|
||||
dump_stack();
|
||||
print_oops_end_marker();
|
||||
add_taint(taint);
|
||||
/* Just a warning, don't kill lockdep. */
|
||||
add_taint(taint, LOCKDEP_STILL_OK);
|
||||
}
|
||||
|
||||
void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...)
|
||||
|
@@ -2796,7 +2796,7 @@ static noinline void __schedule_bug(struct task_struct *prev)
|
||||
if (irqs_disabled())
|
||||
print_irqtrace_events(prev);
|
||||
dump_stack();
|
||||
add_taint(TAINT_WARN);
|
||||
add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -2018,7 +2018,7 @@ static int proc_taint(struct ctl_table *table, int write,
|
||||
int i;
|
||||
for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
|
||||
if ((tmptaint >> i) & 1)
|
||||
add_taint(i);
|
||||
add_taint(i, LOCKDEP_STILL_OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
Verwijs in nieuw issue
Block a user