Fix race between rmmod and cat /proc/kallsyms
module_get_kallsym() leaks "struct module *" outside of module_mutex which is no-no, because module can dissapear right after mutex unlock. Copy all needed information from inside module_mutex into caller-supplied space. [bunk@stusta.de: is_exported() can now become static] Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru> Cc: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
ae84e32470
commit
ea07890a68
@@ -370,16 +370,14 @@ struct module *module_text_address(unsigned long addr);
|
||||
struct module *__module_text_address(unsigned long addr);
|
||||
int is_module_address(unsigned long addr);
|
||||
|
||||
/* Returns module and fills in value, defined and namebuf, or NULL if
|
||||
/* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
|
||||
symnum out of range. */
|
||||
struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
|
||||
char *type, char *name);
|
||||
int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
|
||||
char *name, char *module_name, int *exported);
|
||||
|
||||
/* Look for this name: can be of form module:name. */
|
||||
unsigned long module_kallsyms_lookup_name(const char *name);
|
||||
|
||||
int is_exported(const char *name, const struct module *mod);
|
||||
|
||||
extern void __module_put_and_exit(struct module *mod, long code)
|
||||
__attribute__((noreturn));
|
||||
#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
|
||||
@@ -527,11 +525,11 @@ static inline const char *module_address_lookup(unsigned long addr,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct module *module_get_kallsym(unsigned int symnum,
|
||||
unsigned long *value,
|
||||
char *type, char *name)
|
||||
static inline int module_get_kallsym(unsigned int symnum, unsigned long *value,
|
||||
char *type, char *name,
|
||||
char *module_name, int *exported)
|
||||
{
|
||||
return NULL;
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
static inline unsigned long module_kallsyms_lookup_name(const char *name)
|
||||
@@ -539,11 +537,6 @@ static inline unsigned long module_kallsyms_lookup_name(const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_exported(const char *name, const struct module *mod)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int register_module_notifier(struct notifier_block * nb)
|
||||
{
|
||||
/* no events will happen anyway, so this can always succeed */
|
||||
|
Reference in New Issue
Block a user