From 3344ea3ad4b7c302c846a680dbaeedf96ed45c02 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 5 Jan 2003 04:07:53 -0800 Subject: [PATCH] MODULE_LICENSE and EXPORT_SYMBOL_GPL support This implements EXPORT_SYMBOL_GPL and MODULE_LICENSE properly (so restrictions are enforced). Also fixes "proprietory" spelling. --- include/linux/kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/kernel.h') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 9cb6277f5b86..e6b95f3bb173 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -105,7 +105,7 @@ extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in extern int tainted; extern const char *print_tainted(void); -#define TAINT_PROPRIETORY_MODULE (1<<0) +#define TAINT_PROPRIETARY_MODULE (1<<0) #define TAINT_FORCED_MODULE (1<<1) #define TAINT_UNSAFE_SMP (1<<2) #define TAINT_FORCED_RMMOD (1<<3) -- cgit v1.2.3 From 8e4f2cd334e33240605c353c7fa10e3826a920b3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 5 Jan 2003 16:53:06 -0800 Subject: [PATCH] Remove mod_bound macro and unify kernel_text_address(). Various archs (i386, m68k, s390, s390x, m68k, parisc, um, x86_64) implement kernel_text_address. Put this in kernel/extable.c, and the module iteration inside module.c. Other than cleanliness, this finally allows the module list and lock to be static to kernel/module.c (you didn't think I actually cared about those archs did you?) It also drops the module->init_size to zero when it's discarded, so bounds checking is simplified (and the /proc/modules size statistic will be more accurate, too). --- arch/i386/kernel/traps.c | 44 -------------------------------------------- arch/m68k/kernel/traps.c | 36 ------------------------------------ arch/parisc/kernel/traps.c | 25 ------------------------- arch/s390/kernel/traps.c | 44 -------------------------------------------- arch/s390x/kernel/traps.c | 44 -------------------------------------------- arch/um/kernel/sysrq.c | 43 ------------------------------------------- arch/x86_64/kernel/traps.c | 38 -------------------------------------- include/linux/kernel.h | 1 + include/linux/module.h | 17 +++++++++-------- kernel/extable.c | 10 ++++++++++ kernel/module.c | 44 +++++++++++++++++++++++--------------------- 11 files changed, 43 insertions(+), 303 deletions(-) (limited to 'include/linux/kernel.h') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 1e12d7b1b0d1..332ccea33b8b 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -87,50 +87,6 @@ asmlinkage void machine_check(void); static int kstack_depth_to_print = 24; - -/* - * If the address is either in the .text section of the - * kernel, or in the vmalloc'ed module regions, it *may* - * be the address of a calling routine - */ - -#ifdef CONFIG_MODULES - -/* FIXME: Accessed without a lock --RR */ -extern struct list_head modules; - -static inline int kernel_text_address(unsigned long addr) -{ - int retval = 0; - struct module *mod; - - if (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext) - return 1; - - list_for_each_entry(mod, &modules, list) { - /* mod_bound tests for addr being inside the vmalloc'ed - * module area. Of course it'd be better to test only - * for the .text subset... */ - if (mod_bound((void *)addr, 0, mod)) { - retval = 1; - break; - } - } - - return retval; -} - -#else - -static inline int kernel_text_address(unsigned long addr) -{ - return (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext); -} - -#endif - void show_trace(unsigned long * stack) { int i; diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index ad20bedba50c..65860c3865a5 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -821,42 +821,6 @@ asmlinkage void buserr_c(struct frame *fp) static int kstack_depth_to_print = 48; -extern char _stext, _etext; - -#ifdef CONFIG_MODULES - -/* FIXME: Accessed without a lock --RR */ -extern struct list_head modules; - -static inline int kernel_text_address(unsigned long addr) -{ - struct module *mod; - - if (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext) - return 1; - - list_for_each_entry(mod, &modules, list) { - /* mod_bound tests for addr being inside the vmalloc'ed - * module area. Of course it'd be better to test only - * for the .text subset... */ - if (mod_bound((void *)addr, 0, mod)) - return 1; - } - - return 0; -} - -#else // !CONFIG_MODULES - -static inline int kernel_text_address(unsigned long addr) -{ - return (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext); -} - -#endif // !CONFIG_MODULES - void show_trace(unsigned long *stack) { unsigned long *endstack; diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index f108dbc1614e..ed250fadcd89 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -123,31 +123,6 @@ void dump_stack(void) static int kstack_depth_to_print = 48; -extern struct module kernel_module; - -static inline int kernel_text_address(unsigned long addr) -{ -#ifdef CONFIG_MODULES - struct module *mod; -#endif - extern char _stext, _etext; - - if (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext) - return 1; - -#ifdef CONFIG_MODULES - for (mod = module_list; mod != &kernel_module; mod = mod->next) { - /* mod_bound tests for addr being inside the vmalloc'ed - * module area. Of course it'd be better to test only - * for the .text subset... */ - if (mod_bound(addr, 0, mod)) - return 1; - } -#endif - - return 0; -} void show_stack(unsigned long *sp) { diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 5eb5923e001b..8706fc762fd7 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -63,50 +63,6 @@ static ext_int_info_t ext_int_pfault; static int kstack_depth_to_print = 12; -/* - * If the address is either in the .text section of the - * kernel, or in the vmalloc'ed module regions, it *may* - * be the address of a calling routine - */ -extern char _stext, _etext; - -#ifdef CONFIG_MODULES - -/* FIXME: Accessed without a lock --RR */ -extern struct list_head modules; - -static inline int kernel_text_address(unsigned long addr) -{ - int retval = 0; - struct module *mod; - - if (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext) - return 1; - - list_for_each_entry(mod, &modules, list) { - /* mod_bound tests for addr being inside the vmalloc'ed - * module area. Of course it'd be better to test only - * for the .text subset... */ - if (mod_bound((void*)addr, 0, mod)) { - retval = 1; - break; - } - } - - return retval; -} - -#else - -static inline int kernel_text_address(unsigned long addr) -{ - return (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext); -} - -#endif - void show_trace(unsigned long * stack) { unsigned long backchain, low_addr, high_addr, ret_addr; diff --git a/arch/s390x/kernel/traps.c b/arch/s390x/kernel/traps.c index e67855f55ac4..1c5cd64b3ecd 100644 --- a/arch/s390x/kernel/traps.c +++ b/arch/s390x/kernel/traps.c @@ -65,50 +65,6 @@ static ext_int_info_t ext_int_pfault; static int kstack_depth_to_print = 20; -/* - * If the address is either in the .text section of the - * kernel, or in the vmalloc'ed module regions, it *may* - * be the address of a calling routine - */ -extern char _stext, _etext; - -#ifdef CONFIG_MODULES - -/* FIXME: Accessed without a lock --RR */ -extern struct list_head modules; - -static inline int kernel_text_address(unsigned long addr) -{ - int retval = 0; - struct module *mod; - - if (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext) - return 1; - - list_for_each_entry(mod, &modules, list) { - /* mod_bound tests for addr being inside the vmalloc'ed - * module area. Of course it'd be better to test only - * for the .text subset... */ - if (mod_bound((void*)addr, 0, mod)) { - retval = 1; - break; - } - } - - return retval; -} - -#else - -static inline int kernel_text_address(unsigned long addr) -{ - return (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext); -} - -#endif - void show_trace(unsigned long * stack) { unsigned long backchain, low_addr, high_addr, ret_addr; diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index 2bf29ad7ad27..4936445793b7 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c @@ -11,49 +11,6 @@ #include "sysrq.h" #include "user_util.h" - /* - * If the address is either in the .text section of the - * kernel, or in the vmalloc'ed module regions, it *may* - * be the address of a calling routine - */ - -#ifdef CONFIG_MODULES - -/* FIXME: Accessed without a lock --RR */ -extern struct list_head modules; - -static inline int kernel_text_address(unsigned long addr) -{ - int retval = 0; - struct module *mod; - - if (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext) - return 1; - - list_for_each_entry(mod, &modules, list) { - /* mod_bound tests for addr being inside the vmalloc'ed - * module area. Of course it'd be better to test only - * for the .text subset... */ - if (mod_bound((void *) addr, 0, mod)) { - retval = 1; - break; - } - } - - return retval; -} - -#else - -static inline int kernel_text_address(unsigned long addr) -{ - return (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext); -} - -#endif - void show_trace(unsigned long * stack) { int i; diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 20c4811bad6b..af118388f169 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -104,44 +104,6 @@ int printk_address(unsigned long address) } #endif - -#ifdef CONFIG_MODULES - -/* FIXME: Accessed without a lock --RR */ -extern struct list_head modules; - -static inline int kernel_text_address(unsigned long addr) -{ - int retval = 0; - struct module *mod; - - if (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext) - return 1; - - list_for_each_entry(mod, &modules, list) { - /* mod_bound tests for addr being inside the vmalloc'ed - * module area. Of course it'd be better to test only - * for the .text subset... */ - if (mod_bound((void *)addr, 0, mod)) { - retval = 1; - break; - } - } - - return retval; -} - -#else - -static inline int kernel_text_address(unsigned long addr) -{ - return (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext); -} - -#endif - static inline unsigned long *in_exception_stack(int cpu, unsigned long stack) { int k; diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e6b95f3bb173..7eedbb751856 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -84,6 +84,7 @@ extern unsigned long long memparse(char *ptr, char **retptr); extern void dev_probe_lock(void); extern void dev_probe_unlock(void); +extern int kernel_text_address(unsigned long addr); extern int session_of_pgrp(int pgrp); asmlinkage int printk(const char * fmt, ...) diff --git a/include/linux/module.h b/include/linux/module.h index 24fa571c4cc9..54214da9a651 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -234,6 +234,9 @@ static inline int module_is_live(struct module *mod) return mod->state != MODULE_STATE_GOING; } +/* Is this address in a module? */ +int module_text_address(unsigned long addr); + #ifdef CONFIG_MODULE_UNLOAD void __symbol_put(const char *symbol); @@ -324,6 +327,12 @@ search_module_extables(unsigned long addr) return NULL; } +/* Is this address in a module? */ +static int module_text_address(unsigned long addr) +{ + return 0; +} + /* Get/put a kernel symbol (calls should be symmetric) */ #define symbol_get(x) (&(x)) #define symbol_put(x) do { } while(0) @@ -426,14 +435,6 @@ extern int module_dummy_usage; #define GET_USE_COUNT(module) (module_dummy_usage) #define MOD_IN_USE 0 #define __MODULE_STRING(x) __stringify(x) -#define __mod_between(a_start, a_len, b_start, b_len) \ -(((a_start) >= (b_start) && (a_start) <= (b_start)+(b_len)) \ - || ((a_start)+(a_len) >= (b_start) \ - && (a_start)+(a_len) <= (b_start)+(b_len))) -#define mod_bound(p, n, m) \ -(((m)->module_init \ - && __mod_between((p),(n),(m)->module_init,(m)->init_size)) \ - || __mod_between((p),(n),(m)->module_core,(m)->core_size)) /* * The exception and symbol tables, and the lock diff --git a/kernel/extable.c b/kernel/extable.c index b980aa1d52d7..388995324d1c 100644 --- a/kernel/extable.c +++ b/kernel/extable.c @@ -19,6 +19,7 @@ extern const struct exception_table_entry __start___ex_table[]; extern const struct exception_table_entry __stop___ex_table[]; +extern char _stext[], _etext[]; /* Given an address, look for it in the exception tables. */ const struct exception_table_entry *search_exception_tables(unsigned long addr) @@ -30,3 +31,12 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr) e = search_module_extables(addr); return e; } + +int kernel_text_address(unsigned long addr) +{ + if (addr >= (unsigned long)_stext && + addr <= (unsigned long)_etext) + return 1; + + return module_text_address(addr); +} diff --git a/kernel/module.c b/kernel/module.c index 9189d3d3abf5..bd289a331692 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -54,9 +54,9 @@ /* Protects extables and symbols lists */ static spinlock_t modlist_lock = SPIN_LOCK_UNLOCKED; -/* List of modules, protected by module_mutex */ +/* List of modules, protected by module_mutex AND modlist_lock */ static DECLARE_MUTEX(module_mutex); -LIST_HEAD(modules); /* FIXME: Accessed w/o lock on oops by some archs */ +static LIST_HEAD(modules); static LIST_HEAD(symbols); static LIST_HEAD(extables); @@ -754,8 +754,8 @@ unsigned long find_symbol_internal(Elf_Shdr *sechdrs, static void free_module(struct module *mod) { /* Delete from various lists */ - list_del(&mod->list); spin_lock_irq(&modlist_lock); + list_del(&mod->list); list_del(&mod->symbols.list); list_del(&mod->gpl_symbols.list); list_del(&mod->extable.list); @@ -1290,8 +1290,8 @@ sys_init_module(void *umod, list_add(&mod->extable.list, &extables); list_add_tail(&mod->symbols.list, &symbols); list_add_tail(&mod->gpl_symbols.list, &symbols); - spin_unlock_irq(&modlist_lock); list_add(&mod->list, &modules); + spin_unlock_irq(&modlist_lock); /* Drop lock so they can recurse */ up(&module_mutex); @@ -1318,28 +1318,17 @@ sys_init_module(void *umod, mod->state = MODULE_STATE_LIVE; module_free(mod, mod->module_init); mod->module_init = NULL; + mod->init_size = 0; return 0; } -#ifdef CONFIG_KALLSYMS -static inline int inside_init(struct module *mod, unsigned long addr) -{ - if (mod->module_init - && (unsigned long)mod->module_init <= addr - && (unsigned long)mod->module_init + mod->init_size > addr) - return 1; - return 0; -} - -static inline int inside_core(struct module *mod, unsigned long addr) +static inline int within(unsigned long addr, void *start, unsigned long size) { - if ((unsigned long)mod->module_core <= addr - && (unsigned long)mod->module_core + mod->core_size > addr) - return 1; - return 0; + return ((void *)addr >= start && (void *)addr < start + size); } +#ifdef CONFIG_KALLSYMS static const char *get_ksymbol(struct module *mod, unsigned long addr, unsigned long *size, @@ -1349,7 +1338,7 @@ static const char *get_ksymbol(struct module *mod, unsigned long nextval; /* At worse, next value is at end of module */ - if (inside_core(mod, addr)) + if (within(addr, mod->module_init, mod->init_size)) nextval = (unsigned long)mod->module_core+mod->core_size; else nextval = (unsigned long)mod->module_init+mod->init_size; @@ -1387,7 +1376,8 @@ const char *module_address_lookup(unsigned long addr, struct module *mod; list_for_each_entry(mod, &modules, list) { - if (inside_core(mod, addr) || inside_init(mod, addr)) { + if (within(addr, mod->module_init, mod->init_size) + || within(addr, mod->module_core, mod->core_size)) { *modname = mod->name; return get_ksymbol(mod, addr, size, offset); } @@ -1471,6 +1461,18 @@ const struct exception_table_entry *search_module_extables(unsigned long addr) return e; } +/* Is this a valid kernel address? We don't grab the lock: we are oopsing. */ +int module_text_address(unsigned long addr) +{ + struct module *mod; + + list_for_each_entry(mod, &modules, list) + if (within(addr, mod->module_init, mod->init_size) + || within(addr, mod->module_core, mod->core_size)) + return 1; + return 0; +} + /* Provided by the linker */ extern const struct kernel_symbol __start___ksymtab[]; extern const struct kernel_symbol __stop___ksymtab[]; -- cgit v1.2.3