Thread (13 messages) 13 messages, 4 authors, 2022-02-11

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 struct
load_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
  endif
diff --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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help