Re: [PATCH v5 09/13] module: Move kallsyms support into a separate file
From: Aaron Tomlin <hidden>
Date: 2022-02-11 19:56:09
Also in:
live-patching, lkml
On Thu 2022-02-10 13:43 +0000, Christophe Leroy wrote:
Checkpatch reports: total: 3 errors, 1 warnings, 26 checks, 1103 lines checked
Christophe,
Sparse reports the following: CHECK kernel/module/kallsyms.c kernel/module/kallsyms.c:174:23: warning: incorrect type in assignment (different address spaces) kernel/module/kallsyms.c:174:23: expected struct mod_kallsyms [noderef] __rcu *kallsyms kernel/module/kallsyms.c:174:23: got void *
Thanks once again for your review and feedback! Indeed I can see the same via 'make C=2 kernel/module/'. Looking at struct 'module' declaration we see that field namely "kallsyms" has the __rcu marker. So, If I understand correctly, perhaps this can be resolved as follows, to be more explicit:
@@ -171,7 +171,7 @@ void add_kallsyms(struct module *mod, const structload_info *info)
Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
/* Set up to point into init section. */
- mod->kallsyms = mod->init_layout.base + info->mod_kallsyms_init_off;
+ mod->kallsyms = (struct mod_kallsyms __rcu
*)mod->init_layout.base + info->mod_kallsyms_init_off;
kernel/module/kallsyms.c:176:12: warning: dereference of noderef expression kernel/module/kallsyms.c:177:12: warning: dereference of noderef expression kernel/module/kallsyms.c:179:12: warning: dereference of noderef expression kernel/module/kallsyms.c:180:12: warning: dereference of noderef expression kernel/module/kallsyms.c:189:18: warning: dereference of noderef expression kernel/module/kallsyms.c:190:35: warning: dereference of noderef expression kernel/module/kallsyms.c:191:20: warning: dereference of noderef expression kernel/module/kallsyms.c:196:32: warning: dereference of noderef expression kernel/module/kallsyms.c:199:45: warning: dereference of noderef expression
I will use rcu_dereference*() for the above since the pointer should not be accessed directly.
quoted
diff --git a/kernel/module/Makefile b/kernel/module/Makefile index 62c9fc91d411..868b13c06920 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile@@ -12,4 +12,5 @@ obj-$(CONFIG_LIVEPATCH) += livepatch.o obj-$(CONFIG_MODULES_TREE_LOOKUP) += tree_lookup.o obj-$(CONFIG_STRICT_MODULE_RWX) += strict_rwx.o obj-$(CONFIG_DEBUG_KMEMLEAK) += debug_kmemleak.o +obj-$(CONFIG_KALLSYMS) += kallsyms.o endifdiff --git a/kernel/module/internal.h b/kernel/module/internal.h index 33d7befd0602..7973666452c3 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h@@ -69,6 +69,11 @@ struct load_info { }; int mod_verify_sig(const void *mod, struct load_info *info); +struct module *find_module_all(const char *name, size_t len, bool even_unformed); +unsigned long kernel_symbol_value(const struct kernel_symbol *sym);This function is small enought to be a 'static inline' in internal.h
Fair enough.
quoted
+int cmp_name(const void *name, const void *sym); +long get_offset(struct module *mod, unsigned int *size, Elf_Shdr *sechdr, + unsigned int section);Having a non static function called get_offset() seems dangerous. There are already several get_offset() functions in the kernel allthough they are all static. It takes a struct module as an argument so it could be called module_get_offset()
The rename is a good idea.
quoted
+bool sect_empty(const Elf_Shdr *sect);sect_empty() is small enough to remain a static inline.
Yes and moved to kernel/module/internal.h.
quoted
+const char *find_kallsyms_symbol(struct module *mod, unsigned long addr, + unsigned long *size, unsigned long *offset);This is not used outside kallsyms.c, no need to have it in internal.h
Agreed.
quoted
+#else /* !CONFIG_KALLSYMS */ +static inline void layout_symtab(struct module *mod, struct load_info *info) { } +static inline void add_kallsyms(struct module *mod, const struct load_info *info) { } +static inline char *find_kallsyms_symbol(struct module *mod, unsigned long addr, + unsigned long *size, unsigned long *offset)This is not used outside kallsyms.c, no need to have it when !CONFIG_KALLSYMS
Agreed.
quoted
+{ + return NULL; +} +#endif /* CONFIG_KALLSYMS */diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c new file mode 100644 index 000000000000..ed28f6310701 --- /dev/null +++ b/kernel/module/kallsyms.c@@ -0,0 +1,502 @@...quoted
+ +/* Given a module and name of symbol, find and return the symbol's value */ +static unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name)This function is called from main.c, it can't be static and must be defined in internal.h
Agreed. This was an unfortunate oversight.
quoted
-static unsigned long kernel_symbol_value(const struct kernel_symbol *sym) +unsigned long kernel_symbol_value(const struct kernel_symbol *sym)This function is small enought to become a 'static inline' in internal.h
Agreed.
quoted
+int cmp_name(const void *name, const void *sym)This function is small enought to become a 'static inline' in internal.h
Agreed. Kind regards, -- Aaron Tomlin