Commit 4d98ead1 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'modules-for-v4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux

Pull modules updates from Jessica Yu:
 "Summary of modules changes for the 4.10 merge window:

   - The rodata= cmdline parameter has been extended to additionally
     apply to module mappings

   - Fix a hard to hit race between module loader error/clean up
     handling and ftrace registration

   - Some code cleanups, notably panic.c and modules code use a unified
     taint_flags table now. This is much cleaner than duplicating the
     taint flag code in modules.c"

* tag 'modules-for-v4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux:
  module: fix DEBUG_SET_MODULE_RONX typo
  module: extend 'rodata=off' boot cmdline parameter to module mappings
  module: Fix a comment above strong_try_module_get()
  module: When modifying a module's text ignore modules which are going away too
  module: Ensure a module's state is set accordingly during module coming cleanup code
  module: remove trailing whitespace
  taint/module: Clean up global and module taint flags handling
  modpost: free allocated memory
parents a57cb1c1 4d217a5a
...@@ -126,6 +126,9 @@ void prepare_namespace(void); ...@@ -126,6 +126,9 @@ void prepare_namespace(void);
void __init load_default_modules(void); void __init load_default_modules(void);
int __init init_rootfs(void); int __init init_rootfs(void);
#if defined(CONFIG_DEBUG_RODATA) || defined(CONFIG_DEBUG_SET_MODULE_RONX)
extern bool rodata_enabled;
#endif
#ifdef CONFIG_DEBUG_RODATA #ifdef CONFIG_DEBUG_RODATA
void mark_rodata_ro(void); void mark_rodata_ro(void);
#endif #endif
......
...@@ -511,6 +511,15 @@ extern enum system_states { ...@@ -511,6 +511,15 @@ extern enum system_states {
#define TAINT_UNSIGNED_MODULE 13 #define TAINT_UNSIGNED_MODULE 13
#define TAINT_SOFTLOCKUP 14 #define TAINT_SOFTLOCKUP 14
#define TAINT_LIVEPATCH 15 #define TAINT_LIVEPATCH 15
#define TAINT_FLAGS_COUNT 16
struct taint_flag {
char true; /* character printed when tainted */
char false; /* character printed when not tainted */
bool module; /* also show as a per-module taint flag */
};
extern const struct taint_flag taint_flags[TAINT_FLAGS_COUNT];
extern const char hex_asc[]; extern const char hex_asc[];
#define hex_asc_lo(x) hex_asc[((x) & 0x0f)] #define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
......
...@@ -399,7 +399,7 @@ struct module { ...@@ -399,7 +399,7 @@ struct module {
/* Arch-specific module values */ /* Arch-specific module values */
struct mod_arch_specific arch; struct mod_arch_specific arch;
unsigned int taints; /* same bits as kernel:tainted */ unsigned long taints; /* same bits as kernel:taint_flags */
#ifdef CONFIG_GENERIC_BUG #ifdef CONFIG_GENERIC_BUG
/* Support for BUG */ /* Support for BUG */
...@@ -412,7 +412,7 @@ struct module { ...@@ -412,7 +412,7 @@ struct module {
/* Protected by RCU and/or module_mutex: use rcu_dereference() */ /* Protected by RCU and/or module_mutex: use rcu_dereference() */
struct mod_kallsyms *kallsyms; struct mod_kallsyms *kallsyms;
struct mod_kallsyms core_kallsyms; struct mod_kallsyms core_kallsyms;
/* Section attributes */ /* Section attributes */
struct module_sect_attrs *sect_attrs; struct module_sect_attrs *sect_attrs;
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
#include <linux/integrity.h> #include <linux/integrity.h>
#include <linux/proc_ns.h> #include <linux/proc_ns.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/cache.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/bugs.h> #include <asm/bugs.h>
...@@ -925,14 +926,16 @@ static int try_to_run_init_process(const char *init_filename) ...@@ -925,14 +926,16 @@ static int try_to_run_init_process(const char *init_filename)
static noinline void __init kernel_init_freeable(void); static noinline void __init kernel_init_freeable(void);
#ifdef CONFIG_DEBUG_RODATA #if defined(CONFIG_DEBUG_RODATA) || defined(CONFIG_DEBUG_SET_MODULE_RONX)
static bool rodata_enabled = true; bool rodata_enabled __ro_after_init = true;
static int __init set_debug_rodata(char *str) static int __init set_debug_rodata(char *str)
{ {
return strtobool(str, &rodata_enabled); return strtobool(str, &rodata_enabled);
} }
__setup("rodata=", set_debug_rodata); __setup("rodata=", set_debug_rodata);
#endif
#ifdef CONFIG_DEBUG_RODATA
static void mark_readonly(void) static void mark_readonly(void)
{ {
if (rodata_enabled) if (rodata_enabled)
......
...@@ -313,8 +313,11 @@ struct load_info { ...@@ -313,8 +313,11 @@ struct load_info {
} index; } index;
}; };
/* We require a truly strong try_module_get(): 0 means failure due to /*
ongoing or failed initialization etc. */ * We require a truly strong try_module_get(): 0 means success.
* Otherwise an error is returned due to ongoing or failed
* initialization etc.
*/
static inline int strong_try_module_get(struct module *mod) static inline int strong_try_module_get(struct module *mod)
{ {
BUG_ON(mod && mod->state == MODULE_STATE_UNFORMED); BUG_ON(mod && mod->state == MODULE_STATE_UNFORMED);
...@@ -330,7 +333,7 @@ static inline void add_taint_module(struct module *mod, unsigned flag, ...@@ -330,7 +333,7 @@ static inline void add_taint_module(struct module *mod, unsigned flag,
enum lockdep_ok lockdep_ok) enum lockdep_ok lockdep_ok)
{ {
add_taint(flag, lockdep_ok); add_taint(flag, lockdep_ok);
mod->taints |= (1U << flag); set_bit(flag, &mod->taints);
} }
/* /*
...@@ -1138,24 +1141,13 @@ static inline int module_unload_init(struct module *mod) ...@@ -1138,24 +1141,13 @@ static inline int module_unload_init(struct module *mod)
static size_t module_flags_taint(struct module *mod, char *buf) static size_t module_flags_taint(struct module *mod, char *buf)
{ {
size_t l = 0; 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].true;
}
if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
buf[l++] = 'P';
if (mod->taints & (1 << TAINT_OOT_MODULE))
buf[l++] = 'O';
if (mod->taints & (1 << TAINT_FORCED_MODULE))
buf[l++] = 'F';
if (mod->taints & (1 << TAINT_CRAP))
buf[l++] = 'C';
if (mod->taints & (1 << TAINT_UNSIGNED_MODULE))
buf[l++] = 'E';
if (mod->taints & (1 << TAINT_LIVEPATCH))
buf[l++] = 'K';
/*
* TAINT_FORCED_RMMOD: could be added.
* TAINT_CPU_OUT_OF_SPEC, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
* apply to modules.
*/
return l; return l;
} }
...@@ -1911,6 +1903,9 @@ static void frob_writable_data(const struct module_layout *layout, ...@@ -1911,6 +1903,9 @@ static void frob_writable_data(const struct module_layout *layout,
/* livepatching wants to disable read-only so it can frob module. */ /* livepatching wants to disable read-only so it can frob module. */
void module_disable_ro(const struct module *mod) void module_disable_ro(const struct module *mod)
{ {
if (!rodata_enabled)
return;
frob_text(&mod->core_layout, set_memory_rw); frob_text(&mod->core_layout, set_memory_rw);
frob_rodata(&mod->core_layout, set_memory_rw); frob_rodata(&mod->core_layout, set_memory_rw);
frob_ro_after_init(&mod->core_layout, set_memory_rw); frob_ro_after_init(&mod->core_layout, set_memory_rw);
...@@ -1920,6 +1915,9 @@ void module_disable_ro(const struct module *mod) ...@@ -1920,6 +1915,9 @@ void module_disable_ro(const struct module *mod)
void module_enable_ro(const struct module *mod, bool after_init) void module_enable_ro(const struct module *mod, bool after_init)
{ {
if (!rodata_enabled)
return;
frob_text(&mod->core_layout, set_memory_ro); frob_text(&mod->core_layout, set_memory_ro);
frob_rodata(&mod->core_layout, set_memory_ro); frob_rodata(&mod->core_layout, set_memory_ro);
frob_text(&mod->init_layout, set_memory_ro); frob_text(&mod->init_layout, set_memory_ro);
...@@ -1952,6 +1950,9 @@ void set_all_modules_text_rw(void) ...@@ -1952,6 +1950,9 @@ void set_all_modules_text_rw(void)
{ {
struct module *mod; struct module *mod;
if (!rodata_enabled)
return;
mutex_lock(&module_mutex); mutex_lock(&module_mutex);
list_for_each_entry_rcu(mod, &modules, list) { list_for_each_entry_rcu(mod, &modules, list) {
if (mod->state == MODULE_STATE_UNFORMED) if (mod->state == MODULE_STATE_UNFORMED)
...@@ -1968,9 +1969,18 @@ void set_all_modules_text_ro(void) ...@@ -1968,9 +1969,18 @@ void set_all_modules_text_ro(void)
{ {
struct module *mod; struct module *mod;
if (!rodata_enabled)
return;
mutex_lock(&module_mutex); mutex_lock(&module_mutex);
list_for_each_entry_rcu(mod, &modules, list) { list_for_each_entry_rcu(mod, &modules, list) {
if (mod->state == MODULE_STATE_UNFORMED) /*
* Ignore going modules since it's possible that ro
* protection has already been disabled, otherwise we'll
* run into protection faults at module deallocation.
*/
if (mod->state == MODULE_STATE_UNFORMED ||
mod->state == MODULE_STATE_GOING)
continue; continue;
frob_text(&mod->core_layout, set_memory_ro); frob_text(&mod->core_layout, set_memory_ro);
...@@ -1981,10 +1991,12 @@ void set_all_modules_text_ro(void) ...@@ -1981,10 +1991,12 @@ void set_all_modules_text_ro(void)
static void disable_ro_nx(const struct module_layout *layout) static void disable_ro_nx(const struct module_layout *layout)
{ {
frob_text(layout, set_memory_rw); if (rodata_enabled) {
frob_rodata(layout, set_memory_rw); frob_text(layout, set_memory_rw);
frob_rodata(layout, set_memory_rw);
frob_ro_after_init(layout, set_memory_rw);
}
frob_rodata(layout, set_memory_x); frob_rodata(layout, set_memory_x);
frob_ro_after_init(layout, set_memory_rw);
frob_ro_after_init(layout, set_memory_x); frob_ro_after_init(layout, set_memory_x);
frob_writable_data(layout, set_memory_x); frob_writable_data(layout, set_memory_x);
} }
...@@ -3709,6 +3721,7 @@ static int load_module(struct load_info *info, const char __user *uargs, ...@@ -3709,6 +3721,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
sysfs_cleanup: sysfs_cleanup:
mod_sysfs_teardown(mod); mod_sysfs_teardown(mod);
coming_cleanup: coming_cleanup:
mod->state = MODULE_STATE_GOING;
blocking_notifier_call_chain(&module_notify_list, blocking_notifier_call_chain(&module_notify_list,
MODULE_STATE_GOING, mod); MODULE_STATE_GOING, mod);
klp_module_going(mod); klp_module_going(mod);
...@@ -4042,6 +4055,10 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, ...@@ -4042,6 +4055,10 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
} }
#endif /* CONFIG_KALLSYMS */ #endif /* CONFIG_KALLSYMS */
/* Maximum number of characters written by module_flags() */
#define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4)
/* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */
static char *module_flags(struct module *mod, char *buf) static char *module_flags(struct module *mod, char *buf)
{ {
int bx = 0; int bx = 0;
...@@ -4086,7 +4103,7 @@ static void m_stop(struct seq_file *m, void *p) ...@@ -4086,7 +4103,7 @@ static void m_stop(struct seq_file *m, void *p)
static int m_show(struct seq_file *m, void *p) static int m_show(struct seq_file *m, void *p)
{ {
struct module *mod = list_entry(p, struct module, list); struct module *mod = list_entry(p, struct module, list);
char buf[8]; char buf[MODULE_FLAGS_BUF_SIZE];
/* We always ignore unformed modules. */ /* We always ignore unformed modules. */
if (mod->state == MODULE_STATE_UNFORMED) if (mod->state == MODULE_STATE_UNFORMED)
...@@ -4257,7 +4274,7 @@ EXPORT_SYMBOL_GPL(__module_text_address); ...@@ -4257,7 +4274,7 @@ EXPORT_SYMBOL_GPL(__module_text_address);
void print_modules(void) void print_modules(void)
{ {
struct module *mod; struct module *mod;
char buf[8]; char buf[MODULE_FLAGS_BUF_SIZE];
printk(KERN_DEFAULT "Modules linked in:"); printk(KERN_DEFAULT "Modules linked in:");
/* Most callers should already have preempt disabled, but make sure */ /* Most callers should already have preempt disabled, but make sure */
......
...@@ -298,30 +298,27 @@ void panic(const char *fmt, ...) ...@@ -298,30 +298,27 @@ void panic(const char *fmt, ...)
EXPORT_SYMBOL(panic); EXPORT_SYMBOL(panic);
/*
struct tnt { * TAINT_FORCED_RMMOD could be a per-module flag but the module
u8 bit; * is being removed anyway.
char true; */
char false; const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
}; { 'P', 'G', true }, /* TAINT_PROPRIETARY_MODULE */
{ 'F', ' ', true }, /* TAINT_FORCED_MODULE */
static const struct tnt tnts[] = { { 'S', ' ', false }, /* TAINT_CPU_OUT_OF_SPEC */
{ TAINT_PROPRIETARY_MODULE, 'P', 'G' }, { 'R', ' ', false }, /* TAINT_FORCED_RMMOD */
{ TAINT_FORCED_MODULE, 'F', ' ' }, { 'M', ' ', false }, /* TAINT_MACHINE_CHECK */
{ TAINT_CPU_OUT_OF_SPEC, 'S', ' ' }, { 'B', ' ', false }, /* TAINT_BAD_PAGE */
{ TAINT_FORCED_RMMOD, 'R', ' ' }, { 'U', ' ', false }, /* TAINT_USER */
{ TAINT_MACHINE_CHECK, 'M', ' ' }, { 'D', ' ', false }, /* TAINT_DIE */
{ TAINT_BAD_PAGE, 'B', ' ' }, { 'A', ' ', false }, /* TAINT_OVERRIDDEN_ACPI_TABLE */
{ TAINT_USER, 'U', ' ' }, { 'W', ' ', false }, /* TAINT_WARN */
{ TAINT_DIE, 'D', ' ' }, { 'C', ' ', true }, /* TAINT_CRAP */
{ TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' }, { 'I', ' ', false }, /* TAINT_FIRMWARE_WORKAROUND */
{ TAINT_WARN, 'W', ' ' }, { 'O', ' ', true }, /* TAINT_OOT_MODULE */
{ TAINT_CRAP, 'C', ' ' }, { 'E', ' ', true }, /* TAINT_UNSIGNED_MODULE */
{ TAINT_FIRMWARE_WORKAROUND, 'I', ' ' }, { 'L', ' ', false }, /* TAINT_SOFTLOCKUP */
{ TAINT_OOT_MODULE, 'O', ' ' }, { 'K', ' ', true }, /* TAINT_LIVEPATCH */
{ TAINT_UNSIGNED_MODULE, 'E', ' ' },
{ TAINT_SOFTLOCKUP, 'L', ' ' },
{ TAINT_LIVEPATCH, 'K', ' ' },
}; };
/** /**
...@@ -348,16 +345,16 @@ static const struct tnt tnts[] = { ...@@ -348,16 +345,16 @@ static const struct tnt tnts[] = {
*/ */
const char *print_tainted(void) const char *print_tainted(void)
{ {
static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ")]; static char buf[TAINT_FLAGS_COUNT + sizeof("Tainted: ")];
if (tainted_mask) { if (tainted_mask) {
char *s; char *s;
int i; int i;
s = buf + sprintf(buf, "Tainted: "); s = buf + sprintf(buf, "Tainted: ");
for (i = 0; i < ARRAY_SIZE(tnts); i++) { for (i = 0; i < TAINT_FLAGS_COUNT; i++) {
const struct tnt *t = &tnts[i]; const struct taint_flag *t = &taint_flags[i];
*s++ = test_bit(t->bit, &tainted_mask) ? *s++ = test_bit(i, &tainted_mask) ?
t->true : t->false; t->true : t->false;
} }
*s = 0; *s = 0;
......
...@@ -2371,6 +2371,7 @@ static void write_dump(const char *fname) ...@@ -2371,6 +2371,7 @@ static void write_dump(const char *fname)
} }
} }
write_if_changed(&buf, fname); write_if_changed(&buf, fname);
free(buf.p);
} }
struct ext_sym_list { struct ext_sym_list {
...@@ -2496,6 +2497,7 @@ int main(int argc, char **argv) ...@@ -2496,6 +2497,7 @@ int main(int argc, char **argv)
"Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n"); "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
} }
} }
free(buf.p);
return err; return err;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment