All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 00/14] module: core code clean up
@ 2022-02-28 23:43 Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 01/14] module: Move all into module/ Aaron Tomlin
                   ` (14 more replies)
  0 siblings, 15 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

Hi Luis,

As per your suggestion [1], this is an attempt to refactor and split
optional code out of core module support code into separate components.
This version is based on Linus' commit 7993e65fdd0f ("Merge tag
'mtd/fixes-for-5.17-rc5' of
git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux").

Petr,

I decided to use preempt_disable() instead to remain consistent with the
rest of the file. Unfortunately, I did not make time to boot test etc.

Changes since v8 [2]

 - Resolved the reported lockdep warnings in kernel/module/kallsyms.c
   (Petr Mladek)

Changes since v7 [3]

 - Removed redundant ifdef CONFIG_MODULES and endif pairing from
   kernel/module/Makefile

Changes since v6 [4]

 - Moved KCOV_INSTRUMENT_module.o out of kernel/Makefile into
   kernel/module/Makefile (Christophe Leroy)
 - Moved kernel/module/signature.c back into kernel/
   (Christophe Leroy)
 - Fixed Oops in add_kallsyms() due to an invalid pointer assignment
   (Christophe Leroy)

Changes since v5 [5]:

 - Updated MAINTAINERS to include the entire kernel/module/ directory
   (Christophe Leroy)
 - Reintroduce commit a97ac8cb24a3 ("module: fix signature check failures
   when using in-kernel decompression") (Michal Suchánek)
 - Refactored code to address some (i.e.
   --ignore=MULTIPLE_ASSIGNMENTS,ASSIGN_IN_IF was used) style violations
   e.g. "Alignment should match open parenthesis", reported by
   scripts/checkpatch.pl --strict (Christophe Leroy)
 - Used PAGE_ALIGN() and PAGE_ALIGNED() instead (Christophe Leroy)
 - Removed sig_enforce from include/linux/module.h as it is only
   used in kernel/module/signing.c (Christophe Leroy)
 - Added static keyword for anything not used outside a source file
   (Christophe Leroy)
 - Moved mod_sysfs_teardown() to kernel/module/sysfs.c (Christophe Leroy)
 - Removed kdb_modules from kernel/debug/kdb/kdb_private.h
   (Christophe Leroy)

Changes since v4 [6]:

 - Moved is_livepatch_module() and set_livepatch_module() to
   kernel/module/livepatch.c
 - Addressed minor compiler warning concerning
   kernel/module/internal.h (0-day)
 - Resolved style violations reported by scripts/checkpatch.pl
 - Dropped patch 5 [7] so external patch [8] can be applied at
   a later date post merge into module-next (Christophe Leroy)

Changes since v3 [9]:

 - Refactored both is_livepatch_module() and set_livepatch_module(),
   respectively, to use IS_ENABLED(CONFIG_LIVEPATCH) (Joe Perches)
 - Addressed various compiler warnings e.g., no previous prototype (0-day)

Changes since v2 [10]:

 - Moved module decompress support to a separate file
 - Made check_modinfo_livepatch() generic (Petr Mladek)
 - Removed filename from each newly created file (Luis Chamberlain)
 - Addressed some (i.e. --ignore=ASSIGN_IN_IF,AVOID_BUG was used)
   minor scripts/checkpatch.pl concerns e.g., use strscpy over
   strlcpy and missing a blank line after declarations (Allen)

Changes since v1 [11]:

  - Moved module version support code into a new file

[1]: https://lore.kernel.org/lkml/YbEZ4HgSYQEPuRmS@bombadil.infradead.org/
[2]: https://lore.kernel.org/all/20220222141303.1392190-2-atomlin@redhat.com/
[3]: https://lore.kernel.org/lkml/20220222130911.1348513-1-atomlin@redhat.com/
[4]: https://lore.kernel.org/lkml/20220218212511.887059-1-atomlin@redhat.com/
[5]: https://lore.kernel.org/lkml/20220209170358.3266629-1-atomlin@redhat.com/
[6]: https://lore.kernel.org/lkml/20220130213214.1042497-1-atomlin@redhat.com/
[7]: https://lore.kernel.org/lkml/20220130213214.1042497-6-atomlin@redhat.com/
[8]: https://lore.kernel.org/lkml/203348805c9ac9851d8939d15cb9802ef047b5e2.1643919758.git.christophe.leroy@csgroup.eu/
[9]: https://lore.kernel.org/lkml/20220128203934.600247-1-atomlin@redhat.com/
[10]: https://lore.kernel.org/lkml/20220106234319.2067842-1-atomlin@redhat.com/
[11]: https://lore.kernel.org/lkml/20211228213041.1356334-1-atomlin@redhat.com/


Aaron Tomlin (14):
  module: Move all into module/
  module: Simple refactor in preparation for split
  module: Make internal.h and decompress.c more compliant
  module: Move livepatch support to a separate file
  module: Move latched RB-tree support to a separate file
  module: Move strict rwx support to a separate file
  module: Move extra signature support out of core code
  module: Move kmemleak support to a separate file
  module: Move kallsyms support into a separate file
  module: kallsyms: Fix suspicious rcu usage
  module: Move procfs support into a separate file
  module: Move sysfs support into a separate file
  module: Move kdb_modules list out of core code
  module: Move version support into a separate file

 MAINTAINERS                                   |    2 +-
 include/linux/module.h                        |    9 +-
 kernel/Makefile                               |    5 +-
 kernel/debug/kdb/kdb_main.c                   |    5 +
 kernel/debug/kdb/kdb_private.h                |    4 -
 kernel/module-internal.h                      |   50 -
 kernel/module/Makefile                        |   20 +
 kernel/module/debug_kmemleak.c                |   30 +
 .../decompress.c}                             |    5 +-
 kernel/module/internal.h                      |  275 +++
 kernel/module/kallsyms.c                      |  512 +++++
 kernel/module/livepatch.c                     |   74 +
 kernel/{module.c => module/main.c}            | 1856 +----------------
 kernel/module/procfs.c                        |  142 ++
 kernel/module/signing.c                       |  122 ++
 kernel/module/strict_rwx.c                    |   85 +
 kernel/module/sysfs.c                         |  436 ++++
 kernel/module/tree_lookup.c                   |  109 +
 kernel/module/version.c                       |  109 +
 kernel/module_signing.c                       |   45 -
 20 files changed, 2013 insertions(+), 1882 deletions(-)
 delete mode 100644 kernel/module-internal.h
 create mode 100644 kernel/module/Makefile
 create mode 100644 kernel/module/debug_kmemleak.c
 rename kernel/{module_decompress.c => module/decompress.c} (99%)
 create mode 100644 kernel/module/internal.h
 create mode 100644 kernel/module/kallsyms.c
 create mode 100644 kernel/module/livepatch.c
 rename kernel/{module.c => module/main.c} (64%)
 create mode 100644 kernel/module/procfs.c
 create mode 100644 kernel/module/signing.c
 create mode 100644 kernel/module/strict_rwx.c
 create mode 100644 kernel/module/sysfs.c
 create mode 100644 kernel/module/tree_lookup.c
 create mode 100644 kernel/module/version.c
 delete mode 100644 kernel/module_signing.c


base-commit: 7993e65fdd0fe07beb9f36f998f9bbef2c0ee391
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v9 01/14] module: Move all into module/
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 02/14] module: Simple refactor in preparation for split Aaron Tomlin
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional changes.

This patch moves all module related code into a separate directory,
modifies each file name and creates a new Makefile. Note: this effort
is in preparation to refactor core module code.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 MAINTAINERS                                         |  2 +-
 kernel/Makefile                                     |  5 +----
 kernel/module/Makefile                              | 12 ++++++++++++
 kernel/{module_decompress.c => module/decompress.c} |  2 +-
 kernel/{module-internal.h => module/internal.h}     |  0
 kernel/{module.c => module/main.c}                  |  2 +-
 kernel/{module_signing.c => module/signing.c}       |  2 +-
 7 files changed, 17 insertions(+), 8 deletions(-)
 create mode 100644 kernel/module/Makefile
 rename kernel/{module_decompress.c => module/decompress.c} (99%)
 rename kernel/{module-internal.h => module/internal.h} (100%)
 rename kernel/{module.c => module/main.c} (99%)
 rename kernel/{module_signing.c => module/signing.c} (97%)

diff --git a/MAINTAINERS b/MAINTAINERS
index bd86ed9fbc79..463bdb829db4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13012,7 +13012,7 @@ L:	linux-kernel@vger.kernel.org
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git modules-next
 F:	include/linux/module.h
-F:	kernel/module.c
+F:	kernel/module/
 
 MONOLITHIC POWER SYSTEM PMIC DRIVER
 M:	Saravanan Sekar <sravanhome@gmail.com>
diff --git a/kernel/Makefile b/kernel/Makefile
index 56f4ee97f328..717075b65deb 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -29,7 +29,6 @@ KCOV_INSTRUMENT_softirq.o := n
 KCSAN_SANITIZE_softirq.o = n
 # These are called from save_stack_trace() on slub debug path,
 # and produce insane amounts of uninteresting coverage.
-KCOV_INSTRUMENT_module.o := n
 KCOV_INSTRUMENT_extable.o := n
 KCOV_INSTRUMENT_stacktrace.o := n
 # Don't self-instrument.
@@ -53,6 +52,7 @@ obj-y += rcu/
 obj-y += livepatch/
 obj-y += dma/
 obj-y += entry/
+obj-$(CONFIG_MODULES) += module/
 
 obj-$(CONFIG_KCMP) += kcmp.o
 obj-$(CONFIG_FREEZER) += freezer.o
@@ -66,9 +66,6 @@ ifneq ($(CONFIG_SMP),y)
 obj-y += up.o
 endif
 obj-$(CONFIG_UID16) += uid16.o
-obj-$(CONFIG_MODULES) += module.o
-obj-$(CONFIG_MODULE_DECOMPRESS) += module_decompress.o
-obj-$(CONFIG_MODULE_SIG) += module_signing.o
 obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
diff --git a/kernel/module/Makefile b/kernel/module/Makefile
new file mode 100644
index 000000000000..cdd5c61b8c7f
--- /dev/null
+++ b/kernel/module/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for linux kernel module support
+#
+
+# These are called from save_stack_trace() on slub debug path,
+# and produce insane amounts of uninteresting coverage.
+KCOV_INSTRUMENT_module.o := n
+
+obj-y += main.o
+obj-$(CONFIG_MODULE_DECOMPRESS) += decompress.o
+obj-$(CONFIG_MODULE_SIG) += signing.o
diff --git a/kernel/module_decompress.c b/kernel/module/decompress.c
similarity index 99%
rename from kernel/module_decompress.c
rename to kernel/module/decompress.c
index ffef98a20320..d14d6443225a 100644
--- a/kernel/module_decompress.c
+++ b/kernel/module/decompress.c
@@ -12,7 +12,7 @@
 #include <linux/sysfs.h>
 #include <linux/vmalloc.h>
 
-#include "module-internal.h"
+#include "internal.h"
 
 static int module_extend_max_pages(struct load_info *info, unsigned int extent)
 {
diff --git a/kernel/module-internal.h b/kernel/module/internal.h
similarity index 100%
rename from kernel/module-internal.h
rename to kernel/module/internal.h
diff --git a/kernel/module.c b/kernel/module/main.c
similarity index 99%
rename from kernel/module.c
rename to kernel/module/main.c
index 46a5c2ed1928..34a2b0cf3c3e 100644
--- a/kernel/module.c
+++ b/kernel/module/main.c
@@ -58,7 +58,7 @@
 #include <linux/dynamic_debug.h>
 #include <linux/audit.h>
 #include <uapi/linux/module.h>
-#include "module-internal.h"
+#include "internal.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/module.h>
diff --git a/kernel/module_signing.c b/kernel/module/signing.c
similarity index 97%
rename from kernel/module_signing.c
rename to kernel/module/signing.c
index 8723ae70ea1f..8aeb6d2ee94b 100644
--- a/kernel/module_signing.c
+++ b/kernel/module/signing.c
@@ -12,7 +12,7 @@
 #include <linux/string.h>
 #include <linux/verification.h>
 #include <crypto/public_key.h>
-#include "module-internal.h"
+#include "internal.h"
 
 /*
  * Verify the signature on a module.
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 02/14] module: Simple refactor in preparation for split
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 01/14] module: Move all into module/ Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 03/14] module: Make internal.h and decompress.c more compliant Aaron Tomlin
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch makes it possible to move non-essential code
out of core module code.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/internal.h | 21 +++++++++++++++++++++
 kernel/module/main.c     | 22 ++--------------------
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index 8c381c99062f..ea8c4c02614c 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -7,6 +7,27 @@
 
 #include <linux/elf.h>
 #include <asm/module.h>
+#include <linux/mutex.h>
+
+#ifndef ARCH_SHF_SMALL
+#define ARCH_SHF_SMALL 0
+#endif
+
+/* If this is set, the section belongs in the init part of the module */
+#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG - 1))
+/* Maximum number of characters written by module_flags() */
+#define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4)
+
+extern struct mutex module_mutex;
+extern struct list_head modules;
+
+/* Provided by the linker */
+extern const struct kernel_symbol __start___ksymtab[];
+extern const struct kernel_symbol __stop___ksymtab[];
+extern const struct kernel_symbol __start___ksymtab_gpl[];
+extern const struct kernel_symbol __stop___ksymtab_gpl[];
+extern const s32 __start___kcrctab[];
+extern const s32 __start___kcrctab_gpl[];
 
 struct load_info {
 	const char *name;
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 34a2b0cf3c3e..5f5e21f972dd 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -63,10 +63,6 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/module.h>
 
-#ifndef ARCH_SHF_SMALL
-#define ARCH_SHF_SMALL 0
-#endif
-
 /*
  * Modules' sections will be aligned on page boundaries
  * to ensure complete separation of code and data, but
@@ -78,9 +74,6 @@
 # define debug_align(X) (X)
 #endif
 
-/* If this is set, the section belongs in the init part of the module */
-#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
-
 /*
  * Mutex protects:
  * 1) List of modules (also safely readable with preempt_disable),
@@ -88,8 +81,8 @@
  * 3) module_addr_min/module_addr_max.
  * (delete and add uses RCU list operations).
  */
-static DEFINE_MUTEX(module_mutex);
-static LIST_HEAD(modules);
+DEFINE_MUTEX(module_mutex);
+LIST_HEAD(modules);
 
 /* Work queue for freeing init sections in success case */
 static void do_free_init(struct work_struct *w);
@@ -408,14 +401,6 @@ static __maybe_unused void *any_section_objs(const struct load_info *info,
 	return (void *)info->sechdrs[sec].sh_addr;
 }
 
-/* Provided by the linker */
-extern const struct kernel_symbol __start___ksymtab[];
-extern const struct kernel_symbol __stop___ksymtab[];
-extern const struct kernel_symbol __start___ksymtab_gpl[];
-extern const struct kernel_symbol __stop___ksymtab_gpl[];
-extern const s32 __start___kcrctab[];
-extern const s32 __start___kcrctab_gpl[];
-
 #ifndef CONFIG_MODVERSIONS
 #define symversion(base, idx) NULL
 #else
@@ -4542,9 +4527,6 @@ static void cfi_cleanup(struct module *mod)
 #endif
 }
 
-/* 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)
 {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 03/14] module: Make internal.h and decompress.c more compliant
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 01/14] module: Move all into module/ Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 02/14] module: Simple refactor in preparation for split Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 04/14] module: Move livepatch support to a separate file Aaron Tomlin
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

This patch will address the following warning and style violations
generated by ./scripts/checkpatch.pl in strict mode:

  WARNING: Use #include <linux/module.h> instead of <asm/module.h>
  #10: FILE: kernel/module/internal.h:10:
  +#include <asm/module.h>

  CHECK: spaces preferred around that '-' (ctx:VxV)
  #18: FILE: kernel/module/internal.h:18:
  +#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))

  CHECK: Please use a blank line after function/struct/union/enum declarations
  #69: FILE: kernel/module/internal.h:69:
  +}
  +static inline void module_decompress_cleanup(struct load_info *info)
						   ^
  CHECK: extern prototypes should be avoided in .h files
  #84: FILE: kernel/module/internal.h:84:
  +extern int mod_verify_sig(const void *mod, struct load_info *info);

  WARNING: Missing a blank line after declarations
  #116: FILE: kernel/module/decompress.c:116:
  +               struct page *page = module_get_next_page(info);
  +               if (!page) {

  WARNING: Missing a blank line after declarations
  #174: FILE: kernel/module/decompress.c:174:
  +               struct page *page = module_get_next_page(info);
  +               if (!page) {

  CHECK: Please use a blank line after function/struct/union/enum declarations
  #258: FILE: kernel/module/decompress.c:258:
  +}
  +static struct kobj_attribute module_compression_attr = __ATTR_RO(compression);

Note: Fortunately, the multiple-include optimisation found in
include/linux/module.h will prevent duplication/or inclusion more than
once.

Fixes: f314dfea16a ("modsign: log module name in the event of an error")
Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/decompress.c | 3 +++
 kernel/module/internal.h   | 6 ++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/kernel/module/decompress.c b/kernel/module/decompress.c
index d14d6443225a..2fc7081dd7c1 100644
--- a/kernel/module/decompress.c
+++ b/kernel/module/decompress.c
@@ -113,6 +113,7 @@ static ssize_t module_gzip_decompress(struct load_info *info,
 
 	do {
 		struct page *page = module_get_next_page(info);
+
 		if (!page) {
 			retval = -ENOMEM;
 			goto out_inflate_end;
@@ -171,6 +172,7 @@ static ssize_t module_xz_decompress(struct load_info *info,
 
 	do {
 		struct page *page = module_get_next_page(info);
+
 		if (!page) {
 			retval = -ENOMEM;
 			goto out;
@@ -256,6 +258,7 @@ static ssize_t compression_show(struct kobject *kobj,
 {
 	return sysfs_emit(buf, "%s\n", __stringify(MODULE_COMPRESSION));
 }
+
 static struct kobj_attribute module_compression_attr = __ATTR_RO(compression);
 
 static int __init module_decompress_sysfs_init(void)
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index ea8c4c02614c..e0775e66bcf7 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -6,7 +6,8 @@
  */
 
 #include <linux/elf.h>
-#include <asm/module.h>
+#include <linux/compiler.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 
 #ifndef ARCH_SHF_SMALL
@@ -54,7 +55,7 @@ struct load_info {
 	} index;
 };
 
-extern int mod_verify_sig(const void *mod, struct load_info *info);
+int mod_verify_sig(const void *mod, struct load_info *info);
 
 #ifdef CONFIG_MODULE_DECOMPRESS
 int module_decompress(struct load_info *info, const void *buf, size_t size);
@@ -65,6 +66,7 @@ static inline int module_decompress(struct load_info *info,
 {
 	return -EOPNOTSUPP;
 }
+
 static inline void module_decompress_cleanup(struct load_info *info)
 {
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 04/14] module: Move livepatch support to a separate file
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (2 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 03/14] module: Make internal.h and decompress.c more compliant Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 05/14] module: Move latched RB-tree " Aaron Tomlin
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch migrates livepatch support (i.e. used during module
add/or load and remove/or deletion) from core module code into
kernel/module/livepatch.c. At the moment it contains code to
persist Elf information about a given livepatch module, only.

Reviewed-by: Petr Mladek <pmladek@suse.com>
Tested-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 include/linux/module.h    |   9 ++--
 kernel/module/Makefile    |   1 +
 kernel/module/internal.h  |  22 ++++++++
 kernel/module/livepatch.c |  74 +++++++++++++++++++++++++++
 kernel/module/main.c      | 102 ++++----------------------------------
 5 files changed, 110 insertions(+), 98 deletions(-)
 create mode 100644 kernel/module/livepatch.c

diff --git a/include/linux/module.h b/include/linux/module.h
index 1e135fd5c076..7ec9715de7dc 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -663,17 +663,14 @@ static inline bool module_requested_async_probing(struct module *module)
 	return module && module->async_probe_requested;
 }
 
-#ifdef CONFIG_LIVEPATCH
 static inline bool is_livepatch_module(struct module *mod)
 {
+#ifdef CONFIG_LIVEPATCH
 	return mod->klp;
-}
-#else /* !CONFIG_LIVEPATCH */
-static inline bool is_livepatch_module(struct module *mod)
-{
+#else
 	return false;
+#endif
 }
-#endif /* CONFIG_LIVEPATCH */
 
 bool is_module_sig_enforced(void);
 void set_module_sig_enforced(void);
diff --git a/kernel/module/Makefile b/kernel/module/Makefile
index cdd5c61b8c7f..ed3aacb04f17 100644
--- a/kernel/module/Makefile
+++ b/kernel/module/Makefile
@@ -10,3 +10,4 @@ KCOV_INSTRUMENT_module.o := n
 obj-y += main.o
 obj-$(CONFIG_MODULE_DECOMPRESS) += decompress.o
 obj-$(CONFIG_MODULE_SIG) += signing.o
+obj-$(CONFIG_LIVEPATCH) += livepatch.o
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index e0775e66bcf7..ad7a444253ed 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -57,6 +57,28 @@ struct load_info {
 
 int mod_verify_sig(const void *mod, struct load_info *info);
 
+#ifdef CONFIG_LIVEPATCH
+int copy_module_elf(struct module *mod, struct load_info *info);
+void free_module_elf(struct module *mod);
+#else /* !CONFIG_LIVEPATCH */
+static inline int copy_module_elf(struct module *mod, struct load_info *info)
+{
+	return 0;
+}
+
+static inline void free_module_elf(struct module *mod) { }
+#endif /* CONFIG_LIVEPATCH */
+
+static inline bool set_livepatch_module(struct module *mod)
+{
+#ifdef CONFIG_LIVEPATCH
+	mod->klp = true;
+	return true;
+#else
+	return false;
+#endif
+}
+
 #ifdef CONFIG_MODULE_DECOMPRESS
 int module_decompress(struct load_info *info, const void *buf, size_t size);
 void module_decompress_cleanup(struct load_info *info);
diff --git a/kernel/module/livepatch.c b/kernel/module/livepatch.c
new file mode 100644
index 000000000000..486d4ff92719
--- /dev/null
+++ b/kernel/module/livepatch.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Module livepatch support
+ *
+ * Copyright (C) 2016 Jessica Yu <jeyu@redhat.com>
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+/*
+ * Persist Elf information about a module. Copy the Elf header,
+ * section header table, section string table, and symtab section
+ * index from info to mod->klp_info.
+ */
+int copy_module_elf(struct module *mod, struct load_info *info)
+{
+	unsigned int size, symndx;
+	int ret;
+
+	size = sizeof(*mod->klp_info);
+	mod->klp_info = kmalloc(size, GFP_KERNEL);
+	if (!mod->klp_info)
+		return -ENOMEM;
+
+	/* Elf header */
+	size = sizeof(mod->klp_info->hdr);
+	memcpy(&mod->klp_info->hdr, info->hdr, size);
+
+	/* Elf section header table */
+	size = sizeof(*info->sechdrs) * info->hdr->e_shnum;
+	mod->klp_info->sechdrs = kmemdup(info->sechdrs, size, GFP_KERNEL);
+	if (!mod->klp_info->sechdrs) {
+		ret = -ENOMEM;
+		goto free_info;
+	}
+
+	/* Elf section name string table */
+	size = info->sechdrs[info->hdr->e_shstrndx].sh_size;
+	mod->klp_info->secstrings = kmemdup(info->secstrings, size, GFP_KERNEL);
+	if (!mod->klp_info->secstrings) {
+		ret = -ENOMEM;
+		goto free_sechdrs;
+	}
+
+	/* Elf symbol section index */
+	symndx = info->index.sym;
+	mod->klp_info->symndx = symndx;
+
+	/*
+	 * For livepatch modules, core_kallsyms.symtab is a complete
+	 * copy of the original symbol table. Adjust sh_addr to point
+	 * to core_kallsyms.symtab since the copy of the symtab in module
+	 * init memory is freed at the end of do_init_module().
+	 */
+	mod->klp_info->sechdrs[symndx].sh_addr = (unsigned long)mod->core_kallsyms.symtab;
+
+	return 0;
+
+free_sechdrs:
+	kfree(mod->klp_info->sechdrs);
+free_info:
+	kfree(mod->klp_info);
+	return ret;
+}
+
+void free_module_elf(struct module *mod)
+{
+	kfree(mod->klp_info->sechdrs);
+	kfree(mod->klp_info->secstrings);
+	kfree(mod->klp_info);
+}
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 5f5e21f972dd..3596ebf3a6c3 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2043,81 +2043,6 @@ static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
 }
 #endif /*  CONFIG_STRICT_MODULE_RWX */
 
-#ifdef CONFIG_LIVEPATCH
-/*
- * Persist Elf information about a module. Copy the Elf header,
- * section header table, section string table, and symtab section
- * index from info to mod->klp_info.
- */
-static int copy_module_elf(struct module *mod, struct load_info *info)
-{
-	unsigned int size, symndx;
-	int ret;
-
-	size = sizeof(*mod->klp_info);
-	mod->klp_info = kmalloc(size, GFP_KERNEL);
-	if (mod->klp_info == NULL)
-		return -ENOMEM;
-
-	/* Elf header */
-	size = sizeof(mod->klp_info->hdr);
-	memcpy(&mod->klp_info->hdr, info->hdr, size);
-
-	/* Elf section header table */
-	size = sizeof(*info->sechdrs) * info->hdr->e_shnum;
-	mod->klp_info->sechdrs = kmemdup(info->sechdrs, size, GFP_KERNEL);
-	if (mod->klp_info->sechdrs == NULL) {
-		ret = -ENOMEM;
-		goto free_info;
-	}
-
-	/* Elf section name string table */
-	size = info->sechdrs[info->hdr->e_shstrndx].sh_size;
-	mod->klp_info->secstrings = kmemdup(info->secstrings, size, GFP_KERNEL);
-	if (mod->klp_info->secstrings == NULL) {
-		ret = -ENOMEM;
-		goto free_sechdrs;
-	}
-
-	/* Elf symbol section index */
-	symndx = info->index.sym;
-	mod->klp_info->symndx = symndx;
-
-	/*
-	 * For livepatch modules, core_kallsyms.symtab is a complete
-	 * copy of the original symbol table. Adjust sh_addr to point
-	 * to core_kallsyms.symtab since the copy of the symtab in module
-	 * init memory is freed at the end of do_init_module().
-	 */
-	mod->klp_info->sechdrs[symndx].sh_addr = \
-		(unsigned long) mod->core_kallsyms.symtab;
-
-	return 0;
-
-free_sechdrs:
-	kfree(mod->klp_info->sechdrs);
-free_info:
-	kfree(mod->klp_info);
-	return ret;
-}
-
-static void free_module_elf(struct module *mod)
-{
-	kfree(mod->klp_info->sechdrs);
-	kfree(mod->klp_info->secstrings);
-	kfree(mod->klp_info);
-}
-#else /* !CONFIG_LIVEPATCH */
-static int copy_module_elf(struct module *mod, struct load_info *info)
-{
-	return 0;
-}
-
-static void free_module_elf(struct module *mod)
-{
-}
-#endif /* CONFIG_LIVEPATCH */
-
 void __weak module_memfree(void *module_region)
 {
 	/*
@@ -3092,30 +3017,23 @@ static int copy_chunked_from_user(void *dst, const void __user *usrc, unsigned l
 	return 0;
 }
 
-#ifdef CONFIG_LIVEPATCH
 static int check_modinfo_livepatch(struct module *mod, struct load_info *info)
 {
-	if (get_modinfo(info, "livepatch")) {
-		mod->klp = true;
+	if (!get_modinfo(info, "livepatch"))
+		/* Nothing more to do */
+		return 0;
+
+	if (set_livepatch_module(mod)) {
 		add_taint_module(mod, TAINT_LIVEPATCH, LOCKDEP_STILL_OK);
 		pr_notice_once("%s: tainting kernel with TAINT_LIVEPATCH\n",
-			       mod->name);
-	}
-
-	return 0;
-}
-#else /* !CONFIG_LIVEPATCH */
-static int check_modinfo_livepatch(struct module *mod, struct load_info *info)
-{
-	if (get_modinfo(info, "livepatch")) {
-		pr_err("%s: module is marked as livepatch module, but livepatch support is disabled",
-		       mod->name);
-		return -ENOEXEC;
+				mod->name);
+		return 0;
 	}
 
-	return 0;
+	pr_err("%s: module is marked as livepatch module, but livepatch support is disabled",
+	       mod->name);
+	return -ENOEXEC;
 }
-#endif /* CONFIG_LIVEPATCH */
 
 static void check_modinfo_retpoline(struct module *mod, struct load_info *info)
 {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 05/14] module: Move latched RB-tree support to a separate file
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (3 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 04/14] module: Move livepatch support to a separate file Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 06/14] module: Move strict rwx " Aaron Tomlin
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch migrates module latched RB-tree support
(e.g. see __module_address()) from core module code
into kernel/module/tree_lookup.c.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/Makefile      |   1 +
 kernel/module/internal.h    |  33 +++++++++
 kernel/module/main.c        | 130 ++----------------------------------
 kernel/module/tree_lookup.c | 109 ++++++++++++++++++++++++++++++
 4 files changed, 147 insertions(+), 126 deletions(-)
 create mode 100644 kernel/module/tree_lookup.c

diff --git a/kernel/module/Makefile b/kernel/module/Makefile
index ed3aacb04f17..88774e386276 100644
--- a/kernel/module/Makefile
+++ b/kernel/module/Makefile
@@ -11,3 +11,4 @@ obj-y += main.o
 obj-$(CONFIG_MODULE_DECOMPRESS) += decompress.o
 obj-$(CONFIG_MODULE_SIG) += signing.o
 obj-$(CONFIG_LIVEPATCH) += livepatch.o
+obj-$(CONFIG_MODULES_TREE_LOOKUP) += tree_lookup.o
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index ad7a444253ed..f1682e3677be 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -9,6 +9,7 @@
 #include <linux/compiler.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/rculist.h>
 
 #ifndef ARCH_SHF_SMALL
 #define ARCH_SHF_SMALL 0
@@ -93,3 +94,35 @@ static inline void module_decompress_cleanup(struct load_info *info)
 {
 }
 #endif
+
+#ifdef CONFIG_MODULES_TREE_LOOKUP
+struct mod_tree_root {
+	struct latch_tree_root root;
+	unsigned long addr_min;
+	unsigned long addr_max;
+};
+
+extern struct mod_tree_root mod_tree;
+
+void mod_tree_insert(struct module *mod);
+void mod_tree_remove_init(struct module *mod);
+void mod_tree_remove(struct module *mod);
+struct module *mod_find(unsigned long addr);
+#else /* !CONFIG_MODULES_TREE_LOOKUP */
+
+static inline void mod_tree_insert(struct module *mod) { }
+static inline void mod_tree_remove_init(struct module *mod) { }
+static inline void mod_tree_remove(struct module *mod) { }
+static inline struct module *mod_find(unsigned long addr)
+{
+	struct module *mod;
+
+	list_for_each_entry_rcu(mod, &modules, list,
+				lockdep_is_held(&module_mutex)) {
+		if (within_module(addr, mod))
+			return mod;
+	}
+
+	return NULL;
+}
+#endif /* CONFIG_MODULES_TREE_LOOKUP */
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 3596ebf3a6c3..76b53880ad91 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -90,138 +90,16 @@ static DECLARE_WORK(init_free_wq, do_free_init);
 static LLIST_HEAD(init_free_list);
 
 #ifdef CONFIG_MODULES_TREE_LOOKUP
-
-/*
- * Use a latched RB-tree for __module_address(); this allows us to use
- * RCU-sched lookups of the address from any context.
- *
- * This is conditional on PERF_EVENTS || TRACING because those can really hit
- * __module_address() hard by doing a lot of stack unwinding; potentially from
- * NMI context.
- */
-
-static __always_inline unsigned long __mod_tree_val(struct latch_tree_node *n)
-{
-	struct module_layout *layout = container_of(n, struct module_layout, mtn.node);
-
-	return (unsigned long)layout->base;
-}
-
-static __always_inline unsigned long __mod_tree_size(struct latch_tree_node *n)
-{
-	struct module_layout *layout = container_of(n, struct module_layout, mtn.node);
-
-	return (unsigned long)layout->size;
-}
-
-static __always_inline bool
-mod_tree_less(struct latch_tree_node *a, struct latch_tree_node *b)
-{
-	return __mod_tree_val(a) < __mod_tree_val(b);
-}
-
-static __always_inline int
-mod_tree_comp(void *key, struct latch_tree_node *n)
-{
-	unsigned long val = (unsigned long)key;
-	unsigned long start, end;
-
-	start = __mod_tree_val(n);
-	if (val < start)
-		return -1;
-
-	end = start + __mod_tree_size(n);
-	if (val >= end)
-		return 1;
-
-	return 0;
-}
-
-static const struct latch_tree_ops mod_tree_ops = {
-	.less = mod_tree_less,
-	.comp = mod_tree_comp,
-};
-
-static struct mod_tree_root {
-	struct latch_tree_root root;
-	unsigned long addr_min;
-	unsigned long addr_max;
-} mod_tree __cacheline_aligned = {
+struct mod_tree_root mod_tree __cacheline_aligned = {
 	.addr_min = -1UL,
 };
 
 #define module_addr_min mod_tree.addr_min
 #define module_addr_max mod_tree.addr_max
 
-static noinline void __mod_tree_insert(struct mod_tree_node *node)
-{
-	latch_tree_insert(&node->node, &mod_tree.root, &mod_tree_ops);
-}
-
-static void __mod_tree_remove(struct mod_tree_node *node)
-{
-	latch_tree_erase(&node->node, &mod_tree.root, &mod_tree_ops);
-}
-
-/*
- * These modifications: insert, remove_init and remove; are serialized by the
- * module_mutex.
- */
-static void mod_tree_insert(struct module *mod)
-{
-	mod->core_layout.mtn.mod = mod;
-	mod->init_layout.mtn.mod = mod;
-
-	__mod_tree_insert(&mod->core_layout.mtn);
-	if (mod->init_layout.size)
-		__mod_tree_insert(&mod->init_layout.mtn);
-}
-
-static void mod_tree_remove_init(struct module *mod)
-{
-	if (mod->init_layout.size)
-		__mod_tree_remove(&mod->init_layout.mtn);
-}
-
-static void mod_tree_remove(struct module *mod)
-{
-	__mod_tree_remove(&mod->core_layout.mtn);
-	mod_tree_remove_init(mod);
-}
-
-static struct module *mod_find(unsigned long addr)
-{
-	struct latch_tree_node *ltn;
-
-	ltn = latch_tree_find((void *)addr, &mod_tree.root, &mod_tree_ops);
-	if (!ltn)
-		return NULL;
-
-	return container_of(ltn, struct mod_tree_node, node)->mod;
-}
-
-#else /* MODULES_TREE_LOOKUP */
-
-static unsigned long module_addr_min = -1UL, module_addr_max = 0;
-
-static void mod_tree_insert(struct module *mod) { }
-static void mod_tree_remove_init(struct module *mod) { }
-static void mod_tree_remove(struct module *mod) { }
-
-static struct module *mod_find(unsigned long addr)
-{
-	struct module *mod;
-
-	list_for_each_entry_rcu(mod, &modules, list,
-				lockdep_is_held(&module_mutex)) {
-		if (within_module(addr, mod))
-			return mod;
-	}
-
-	return NULL;
-}
-
-#endif /* MODULES_TREE_LOOKUP */
+#else /* !CONFIG_MODULES_TREE_LOOKUP */
+static unsigned long module_addr_min = -1UL, module_addr_max;
+#endif /* CONFIG_MODULES_TREE_LOOKUP */
 
 /*
  * Bounds of module text, for speeding up __module_address.
diff --git a/kernel/module/tree_lookup.c b/kernel/module/tree_lookup.c
new file mode 100644
index 000000000000..0bc4ec3b22ce
--- /dev/null
+++ b/kernel/module/tree_lookup.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Modules tree lookup
+ *
+ * Copyright (C) 2015 Peter Zijlstra
+ * Copyright (C) 2015 Rusty Russell
+ */
+
+#include <linux/module.h>
+#include <linux/rbtree_latch.h>
+#include "internal.h"
+
+/*
+ * Use a latched RB-tree for __module_address(); this allows us to use
+ * RCU-sched lookups of the address from any context.
+ *
+ * This is conditional on PERF_EVENTS || TRACING because those can really hit
+ * __module_address() hard by doing a lot of stack unwinding; potentially from
+ * NMI context.
+ */
+
+static __always_inline unsigned long __mod_tree_val(struct latch_tree_node *n)
+{
+	struct module_layout *layout = container_of(n, struct module_layout, mtn.node);
+
+	return (unsigned long)layout->base;
+}
+
+static __always_inline unsigned long __mod_tree_size(struct latch_tree_node *n)
+{
+	struct module_layout *layout = container_of(n, struct module_layout, mtn.node);
+
+	return (unsigned long)layout->size;
+}
+
+static __always_inline bool
+mod_tree_less(struct latch_tree_node *a, struct latch_tree_node *b)
+{
+	return __mod_tree_val(a) < __mod_tree_val(b);
+}
+
+static __always_inline int
+mod_tree_comp(void *key, struct latch_tree_node *n)
+{
+	unsigned long val = (unsigned long)key;
+	unsigned long start, end;
+
+	start = __mod_tree_val(n);
+	if (val < start)
+		return -1;
+
+	end = start + __mod_tree_size(n);
+	if (val >= end)
+		return 1;
+
+	return 0;
+}
+
+static const struct latch_tree_ops mod_tree_ops = {
+	.less = mod_tree_less,
+	.comp = mod_tree_comp,
+};
+
+static noinline void __mod_tree_insert(struct mod_tree_node *node)
+{
+	latch_tree_insert(&node->node, &mod_tree.root, &mod_tree_ops);
+}
+
+static void __mod_tree_remove(struct mod_tree_node *node)
+{
+	latch_tree_erase(&node->node, &mod_tree.root, &mod_tree_ops);
+}
+
+/*
+ * These modifications: insert, remove_init and remove; are serialized by the
+ * module_mutex.
+ */
+void mod_tree_insert(struct module *mod)
+{
+	mod->core_layout.mtn.mod = mod;
+	mod->init_layout.mtn.mod = mod;
+
+	__mod_tree_insert(&mod->core_layout.mtn);
+	if (mod->init_layout.size)
+		__mod_tree_insert(&mod->init_layout.mtn);
+}
+
+void mod_tree_remove_init(struct module *mod)
+{
+	if (mod->init_layout.size)
+		__mod_tree_remove(&mod->init_layout.mtn);
+}
+
+void mod_tree_remove(struct module *mod)
+{
+	__mod_tree_remove(&mod->core_layout.mtn);
+	mod_tree_remove_init(mod);
+}
+
+struct module *mod_find(unsigned long addr)
+{
+	struct latch_tree_node *ltn;
+
+	ltn = latch_tree_find((void *)addr, &mod_tree.root, &mod_tree_ops);
+	if (!ltn)
+		return NULL;
+
+	return container_of(ltn, struct mod_tree_node, node)->mod;
+}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 06/14] module: Move strict rwx support to a separate file
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (4 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 05/14] module: Move latched RB-tree " Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 07/14] module: Move extra signature support out of core code Aaron Tomlin
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch migrates code that makes module text
and rodata memory read-only and non-text memory
non-executable from core module code into
kernel/module/strict_rwx.c.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/Makefile     |  1 +
 kernel/module/internal.h   | 32 ++++++++++++
 kernel/module/main.c       | 99 +-------------------------------------
 kernel/module/strict_rwx.c | 85 ++++++++++++++++++++++++++++++++
 4 files changed, 120 insertions(+), 97 deletions(-)
 create mode 100644 kernel/module/strict_rwx.c

diff --git a/kernel/module/Makefile b/kernel/module/Makefile
index 88774e386276..d313c8472cb3 100644
--- a/kernel/module/Makefile
+++ b/kernel/module/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_MODULE_DECOMPRESS) += decompress.o
 obj-$(CONFIG_MODULE_SIG) += signing.o
 obj-$(CONFIG_LIVEPATCH) += livepatch.o
 obj-$(CONFIG_MODULES_TREE_LOOKUP) += tree_lookup.o
+obj-$(CONFIG_STRICT_MODULE_RWX) += strict_rwx.o
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index f1682e3677be..a6895bb5598a 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -20,6 +20,17 @@
 /* Maximum number of characters written by module_flags() */
 #define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4)
 
+/*
+ * Modules' sections will be aligned on page boundaries
+ * to ensure complete separation of code and data, but
+ * only when CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
+ */
+#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX
+# define debug_align(X) PAGE_ALIGN(X)
+#else
+# define debug_align(X) (X)
+#endif
+
 extern struct mutex module_mutex;
 extern struct list_head modules;
 
@@ -126,3 +137,24 @@ static inline struct module *mod_find(unsigned long addr)
 	return NULL;
 }
 #endif /* CONFIG_MODULES_TREE_LOOKUP */
+
+#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX
+void frob_text(const struct module_layout *layout, int (*set_memory)(unsigned long start,
+								     int num_pages));
+#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */
+
+#ifdef CONFIG_STRICT_MODULE_RWX
+void module_enable_ro(const struct module *mod, bool after_init);
+void module_enable_nx(const struct module *mod);
+int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+				char *secstrings, struct module *mod);
+
+#else /* !CONFIG_STRICT_MODULE_RWX */
+static inline void module_enable_nx(const struct module *mod) { }
+static inline void module_enable_ro(const struct module *mod, bool after_init) {}
+static inline int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+				       char *secstrings, struct module *mod)
+{
+	return 0;
+}
+#endif /* CONFIG_STRICT_MODULE_RWX */
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 76b53880ad91..5cd63f14b1ef 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -63,17 +63,6 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/module.h>
 
-/*
- * Modules' sections will be aligned on page boundaries
- * to ensure complete separation of code and data, but
- * only when CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
- */
-#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX
-# define debug_align(X) ALIGN(X, PAGE_SIZE)
-#else
-# define debug_align(X) (X)
-#endif
-
 /*
  * Mutex protects:
  * 1) List of modules (also safely readable with preempt_disable),
@@ -1819,8 +1808,8 @@ static void mod_sysfs_teardown(struct module *mod)
  * whether we are strict.
  */
 #ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX
-static void frob_text(const struct module_layout *layout,
-		      int (*set_memory)(unsigned long start, int num_pages))
+void frob_text(const struct module_layout *layout,
+	       int (*set_memory)(unsigned long start, int num_pages))
 {
 	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
 	BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));
@@ -1837,90 +1826,6 @@ static void module_enable_x(const struct module *mod)
 static void module_enable_x(const struct module *mod) { }
 #endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */
 
-#ifdef CONFIG_STRICT_MODULE_RWX
-static void frob_rodata(const struct module_layout *layout,
-			int (*set_memory)(unsigned long start, int num_pages))
-{
-	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
-	BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));
-	BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));
-	set_memory((unsigned long)layout->base + layout->text_size,
-		   (layout->ro_size - layout->text_size) >> PAGE_SHIFT);
-}
-
-static void frob_ro_after_init(const struct module_layout *layout,
-				int (*set_memory)(unsigned long start, int num_pages))
-{
-	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
-	BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));
-	BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1));
-	set_memory((unsigned long)layout->base + layout->ro_size,
-		   (layout->ro_after_init_size - layout->ro_size) >> PAGE_SHIFT);
-}
-
-static void frob_writable_data(const struct module_layout *layout,
-			       int (*set_memory)(unsigned long start, int num_pages))
-{
-	BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
-	BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1));
-	BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1));
-	set_memory((unsigned long)layout->base + layout->ro_after_init_size,
-		   (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT);
-}
-
-static void module_enable_ro(const struct module *mod, bool after_init)
-{
-	if (!rodata_enabled)
-		return;
-
-	set_vm_flush_reset_perms(mod->core_layout.base);
-	set_vm_flush_reset_perms(mod->init_layout.base);
-	frob_text(&mod->core_layout, set_memory_ro);
-
-	frob_rodata(&mod->core_layout, set_memory_ro);
-	frob_text(&mod->init_layout, set_memory_ro);
-	frob_rodata(&mod->init_layout, set_memory_ro);
-
-	if (after_init)
-		frob_ro_after_init(&mod->core_layout, set_memory_ro);
-}
-
-static void module_enable_nx(const struct module *mod)
-{
-	frob_rodata(&mod->core_layout, set_memory_nx);
-	frob_ro_after_init(&mod->core_layout, set_memory_nx);
-	frob_writable_data(&mod->core_layout, set_memory_nx);
-	frob_rodata(&mod->init_layout, set_memory_nx);
-	frob_writable_data(&mod->init_layout, set_memory_nx);
-}
-
-static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
-				       char *secstrings, struct module *mod)
-{
-	const unsigned long shf_wx = SHF_WRITE|SHF_EXECINSTR;
-	int i;
-
-	for (i = 0; i < hdr->e_shnum; i++) {
-		if ((sechdrs[i].sh_flags & shf_wx) == shf_wx) {
-			pr_err("%s: section %s (index %d) has invalid WRITE|EXEC flags\n",
-				mod->name, secstrings + sechdrs[i].sh_name, i);
-			return -ENOEXEC;
-		}
-	}
-
-	return 0;
-}
-
-#else /* !CONFIG_STRICT_MODULE_RWX */
-static void module_enable_nx(const struct module *mod) { }
-static void module_enable_ro(const struct module *mod, bool after_init) {}
-static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
-				       char *secstrings, struct module *mod)
-{
-	return 0;
-}
-#endif /*  CONFIG_STRICT_MODULE_RWX */
-
 void __weak module_memfree(void *module_region)
 {
 	/*
diff --git a/kernel/module/strict_rwx.c b/kernel/module/strict_rwx.c
new file mode 100644
index 000000000000..7949dfd449c2
--- /dev/null
+++ b/kernel/module/strict_rwx.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Module strict rwx
+ *
+ * Copyright (C) 2015 Rusty Russell
+ */
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/set_memory.h>
+#include "internal.h"
+
+static void frob_rodata(const struct module_layout *layout,
+		 int (*set_memory)(unsigned long start, int num_pages))
+{
+	BUG_ON(!PAGE_ALIGNED(layout->base));
+	BUG_ON(!PAGE_ALIGNED(layout->text_size));
+	BUG_ON(!PAGE_ALIGNED(layout->ro_size));
+	set_memory((unsigned long)layout->base + layout->text_size,
+		   (layout->ro_size - layout->text_size) >> PAGE_SHIFT);
+}
+
+static void frob_ro_after_init(const struct module_layout *layout,
+			int (*set_memory)(unsigned long start, int num_pages))
+{
+	BUG_ON(!PAGE_ALIGNED(layout->base));
+	BUG_ON(!PAGE_ALIGNED(layout->ro_size));
+	BUG_ON(!PAGE_ALIGNED(layout->ro_after_init_size));
+	set_memory((unsigned long)layout->base + layout->ro_size,
+		   (layout->ro_after_init_size - layout->ro_size) >> PAGE_SHIFT);
+}
+
+static void frob_writable_data(const struct module_layout *layout,
+			int (*set_memory)(unsigned long start, int num_pages))
+{
+	BUG_ON(!PAGE_ALIGNED(layout->base));
+	BUG_ON(!PAGE_ALIGNED(layout->ro_after_init_size));
+	BUG_ON(!PAGE_ALIGNED(layout->size));
+	set_memory((unsigned long)layout->base + layout->ro_after_init_size,
+		   (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT);
+}
+
+void module_enable_ro(const struct module *mod, bool after_init)
+{
+	if (!rodata_enabled)
+		return;
+
+	set_vm_flush_reset_perms(mod->core_layout.base);
+	set_vm_flush_reset_perms(mod->init_layout.base);
+	frob_text(&mod->core_layout, set_memory_ro);
+
+	frob_rodata(&mod->core_layout, set_memory_ro);
+	frob_text(&mod->init_layout, set_memory_ro);
+	frob_rodata(&mod->init_layout, set_memory_ro);
+
+	if (after_init)
+		frob_ro_after_init(&mod->core_layout, set_memory_ro);
+}
+
+void module_enable_nx(const struct module *mod)
+{
+	frob_rodata(&mod->core_layout, set_memory_nx);
+	frob_ro_after_init(&mod->core_layout, set_memory_nx);
+	frob_writable_data(&mod->core_layout, set_memory_nx);
+	frob_rodata(&mod->init_layout, set_memory_nx);
+	frob_writable_data(&mod->init_layout, set_memory_nx);
+}
+
+int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+				char *secstrings, struct module *mod)
+{
+	const unsigned long shf_wx = SHF_WRITE | SHF_EXECINSTR;
+	int i;
+
+	for (i = 0; i < hdr->e_shnum; i++) {
+		if ((sechdrs[i].sh_flags & shf_wx) == shf_wx) {
+			pr_err("%s: section %s (index %d) has invalid WRITE|EXEC flags\n",
+			       mod->name, secstrings + sechdrs[i].sh_name, i);
+			return -ENOEXEC;
+		}
+	}
+
+	return 0;
+}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 07/14] module: Move extra signature support out of core code
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (5 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 06/14] module: Move strict rwx " Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-03-02  8:08   ` Christophe Leroy
  2022-02-28 23:43 ` [PATCH v9 08/14] module: Move kmemleak support to a separate file Aaron Tomlin
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch migrates additional module signature check
code from core module code into kernel/module/signing.c.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/internal.h |  9 +++++
 kernel/module/main.c     | 87 ----------------------------------------
 kernel/module/signing.c  | 77 +++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+), 87 deletions(-)

diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index a6895bb5598a..d6f646a5da41 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -158,3 +158,12 @@ static inline int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
 	return 0;
 }
 #endif /* CONFIG_STRICT_MODULE_RWX */
+
+#ifdef CONFIG_MODULE_SIG
+int module_sig_check(struct load_info *info, int flags);
+#else /* !CONFIG_MODULE_SIG */
+static inline int module_sig_check(struct load_info *info, int flags)
+{
+	return 0;
+}
+#endif /* !CONFIG_MODULE_SIG */
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 5cd63f14b1ef..c63e10c61694 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -23,7 +23,6 @@
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
 #include <linux/proc_fs.h>
-#include <linux/security.h>
 #include <linux/seq_file.h>
 #include <linux/syscalls.h>
 #include <linux/fcntl.h>
@@ -127,28 +126,6 @@ static void module_assert_mutex_or_preempt(void)
 #endif
 }
 
-#ifdef CONFIG_MODULE_SIG
-static bool sig_enforce = IS_ENABLED(CONFIG_MODULE_SIG_FORCE);
-module_param(sig_enforce, bool_enable_only, 0644);
-
-void set_module_sig_enforced(void)
-{
-	sig_enforce = true;
-}
-#else
-#define sig_enforce false
-#endif
-
-/*
- * Export sig_enforce kernel cmdline parameter to allow other subsystems rely
- * on that instead of directly to CONFIG_MODULE_SIG_FORCE config.
- */
-bool is_module_sig_enforced(void)
-{
-	return sig_enforce;
-}
-EXPORT_SYMBOL(is_module_sig_enforced);
-
 /* Block module loading/unloading? */
 int modules_disabled = 0;
 core_param(nomodule, modules_disabled, bint, 0);
@@ -2569,70 +2546,6 @@ static inline void kmemleak_load_module(const struct module *mod,
 }
 #endif
 
-#ifdef CONFIG_MODULE_SIG
-static int module_sig_check(struct load_info *info, int flags)
-{
-	int err = -ENODATA;
-	const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
-	const char *reason;
-	const void *mod = info->hdr;
-	bool mangled_module = flags & (MODULE_INIT_IGNORE_MODVERSIONS |
-				       MODULE_INIT_IGNORE_VERMAGIC);
-	/*
-	 * Do not allow mangled modules as a module with version information
-	 * removed is no longer the module that was signed.
-	 */
-	if (!mangled_module &&
-	    info->len > markerlen &&
-	    memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
-		/* We truncate the module to discard the signature */
-		info->len -= markerlen;
-		err = mod_verify_sig(mod, info);
-		if (!err) {
-			info->sig_ok = true;
-			return 0;
-		}
-	}
-
-	/*
-	 * We don't permit modules to be loaded into the trusted kernels
-	 * without a valid signature on them, but if we're not enforcing,
-	 * certain errors are non-fatal.
-	 */
-	switch (err) {
-	case -ENODATA:
-		reason = "unsigned module";
-		break;
-	case -ENOPKG:
-		reason = "module with unsupported crypto";
-		break;
-	case -ENOKEY:
-		reason = "module with unavailable key";
-		break;
-
-	default:
-		/*
-		 * All other errors are fatal, including lack of memory,
-		 * unparseable signatures, and signature check failures --
-		 * even if signatures aren't required.
-		 */
-		return err;
-	}
-
-	if (is_module_sig_enforced()) {
-		pr_notice("Loading of %s is rejected\n", reason);
-		return -EKEYREJECTED;
-	}
-
-	return security_locked_down(LOCKDOWN_MODULE_SIGNATURE);
-}
-#else /* !CONFIG_MODULE_SIG */
-static int module_sig_check(struct load_info *info, int flags)
-{
-	return 0;
-}
-#endif /* !CONFIG_MODULE_SIG */
-
 static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr)
 {
 #if defined(CONFIG_64BIT)
diff --git a/kernel/module/signing.c b/kernel/module/signing.c
index 8aeb6d2ee94b..85c8999dfecf 100644
--- a/kernel/module/signing.c
+++ b/kernel/module/signing.c
@@ -11,9 +11,29 @@
 #include <linux/module_signature.h>
 #include <linux/string.h>
 #include <linux/verification.h>
+#include <linux/security.h>
 #include <crypto/public_key.h>
+#include <uapi/linux/module.h>
 #include "internal.h"
 
+static bool sig_enforce = IS_ENABLED(CONFIG_MODULE_SIG_FORCE);
+module_param(sig_enforce, bool_enable_only, 0644);
+
+/*
+ * Export sig_enforce kernel cmdline parameter to allow other subsystems rely
+ * on that instead of directly to CONFIG_MODULE_SIG_FORCE config.
+ */
+bool is_module_sig_enforced(void)
+{
+	return sig_enforce;
+}
+EXPORT_SYMBOL(is_module_sig_enforced);
+
+void set_module_sig_enforced(void)
+{
+	sig_enforce = true;
+}
+
 /*
  * Verify the signature on a module.
  */
@@ -43,3 +63,60 @@ int mod_verify_sig(const void *mod, struct load_info *info)
 				      VERIFYING_MODULE_SIGNATURE,
 				      NULL, NULL);
 }
+
+int module_sig_check(struct load_info *info, int flags)
+{
+	int err = -ENODATA;
+	const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
+	const char *reason;
+	const void *mod = info->hdr;
+	bool mangled_module = flags & (MODULE_INIT_IGNORE_MODVERSIONS |
+				       MODULE_INIT_IGNORE_VERMAGIC);
+	/*
+	 * Do not allow mangled modules as a module with version information
+	 * removed is no longer the module that was signed.
+	 */
+	if (!mangled_module &&
+	    info->len > markerlen &&
+	    memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) {
+		/* We truncate the module to discard the signature */
+		info->len -= markerlen;
+		err = mod_verify_sig(mod, info);
+		if (!err) {
+			info->sig_ok = true;
+			return 0;
+		}
+	}
+
+	/*
+	 * We don't permit modules to be loaded into the trusted kernels
+	 * without a valid signature on them, but if we're not enforcing,
+	 * certain errors are non-fatal.
+	 */
+	switch (err) {
+	case -ENODATA:
+		reason = "unsigned module";
+		break;
+	case -ENOPKG:
+		reason = "module with unsupported crypto";
+		break;
+	case -ENOKEY:
+		reason = "module with unavailable key";
+		break;
+
+	default:
+		/*
+		 * All other errors are fatal, including lack of memory,
+		 * unparseable signatures, and signature check failures --
+		 * even if signatures aren't required.
+		 */
+		return err;
+	}
+
+	if (is_module_sig_enforced()) {
+		pr_notice("Loading of %s is rejected\n", reason);
+		return -EKEYREJECTED;
+	}
+
+	return security_locked_down(LOCKDOWN_MODULE_SIGNATURE);
+}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 08/14] module: Move kmemleak support to a separate file
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (6 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 07/14] module: Move extra signature support out of core code Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 09/14] module: Move kallsyms support into " Aaron Tomlin
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch migrates kmemleak code out of core module
code into kernel/module/debug_kmemleak.c

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/Makefile         |  1 +
 kernel/module/debug_kmemleak.c | 30 ++++++++++++++++++++++++++++++
 kernel/module/internal.h       |  7 +++++++
 kernel/module/main.c           | 27 ---------------------------
 4 files changed, 38 insertions(+), 27 deletions(-)
 create mode 100644 kernel/module/debug_kmemleak.c

diff --git a/kernel/module/Makefile b/kernel/module/Makefile
index d313c8472cb3..12388627725c 100644
--- a/kernel/module/Makefile
+++ b/kernel/module/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_MODULE_SIG) += signing.o
 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
diff --git a/kernel/module/debug_kmemleak.c b/kernel/module/debug_kmemleak.c
new file mode 100644
index 000000000000..12a569d361e8
--- /dev/null
+++ b/kernel/module/debug_kmemleak.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Module kmemleak support
+ *
+ * Copyright (C) 2009 Catalin Marinas
+ */
+
+#include <linux/module.h>
+#include <linux/kmemleak.h>
+#include "internal.h"
+
+void kmemleak_load_module(const struct module *mod,
+			  const struct load_info *info)
+{
+	unsigned int i;
+
+	/* only scan the sections containing data */
+	kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL);
+
+	for (i = 1; i < info->hdr->e_shnum; i++) {
+		/* Scan all writable sections that's not executable */
+		if (!(info->sechdrs[i].sh_flags & SHF_ALLOC) ||
+		    !(info->sechdrs[i].sh_flags & SHF_WRITE) ||
+		    (info->sechdrs[i].sh_flags & SHF_EXECINSTR))
+			continue;
+
+		kmemleak_scan_area((void *)info->sechdrs[i].sh_addr,
+				   info->sechdrs[i].sh_size, GFP_KERNEL);
+	}
+}
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index d6f646a5da41..b0c360839f63 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -167,3 +167,10 @@ static inline int module_sig_check(struct load_info *info, int flags)
 	return 0;
 }
 #endif /* !CONFIG_MODULE_SIG */
+
+#ifdef CONFIG_DEBUG_KMEMLEAK
+void kmemleak_load_module(const struct module *mod, const struct load_info *info);
+#else /* !CONFIG_DEBUG_KMEMLEAK */
+static inline void kmemleak_load_module(const struct module *mod,
+					const struct load_info *info) { }
+#endif /* CONFIG_DEBUG_KMEMLEAK */
diff --git a/kernel/module/main.c b/kernel/module/main.c
index c63e10c61694..7dd283959c5c 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2519,33 +2519,6 @@ bool __weak module_exit_section(const char *name)
 	return strstarts(name, ".exit");
 }
 
-#ifdef CONFIG_DEBUG_KMEMLEAK
-static void kmemleak_load_module(const struct module *mod,
-				 const struct load_info *info)
-{
-	unsigned int i;
-
-	/* only scan the sections containing data */
-	kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL);
-
-	for (i = 1; i < info->hdr->e_shnum; i++) {
-		/* Scan all writable sections that's not executable */
-		if (!(info->sechdrs[i].sh_flags & SHF_ALLOC) ||
-		    !(info->sechdrs[i].sh_flags & SHF_WRITE) ||
-		    (info->sechdrs[i].sh_flags & SHF_EXECINSTR))
-			continue;
-
-		kmemleak_scan_area((void *)info->sechdrs[i].sh_addr,
-				   info->sechdrs[i].sh_size, GFP_KERNEL);
-	}
-}
-#else
-static inline void kmemleak_load_module(const struct module *mod,
-					const struct load_info *info)
-{
-}
-#endif
-
 static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr)
 {
 #if defined(CONFIG_64BIT)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 09/14] module: Move kallsyms support into a separate file
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (7 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 08/14] module: Move kmemleak support to a separate file Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 10/14] module: kallsyms: Fix suspicious rcu usage Aaron Tomlin
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch migrates kallsyms code out of core module
code kernel/module/kallsyms.c

Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/Makefile   |   1 +
 kernel/module/internal.h |  29 +++
 kernel/module/kallsyms.c | 502 ++++++++++++++++++++++++++++++++++++
 kernel/module/main.c     | 531 +--------------------------------------
 4 files changed, 538 insertions(+), 525 deletions(-)
 create mode 100644 kernel/module/kallsyms.c

diff --git a/kernel/module/Makefile b/kernel/module/Makefile
index 12388627725c..9901bed3ab5b 100644
--- a/kernel/module/Makefile
+++ b/kernel/module/Makefile
@@ -14,3 +14,4 @@ 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
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index b0c360839f63..44ca05b9eb8f 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -68,6 +68,19 @@ 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);
+int cmp_name(const void *name, const void *sym);
+long module_get_offset(struct module *mod, unsigned int *size, Elf_Shdr *sechdr,
+		       unsigned int section);
+
+static inline unsigned long kernel_symbol_value(const struct kernel_symbol *sym)
+{
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+	return (unsigned long)offset_to_ptr(&sym->value_offset);
+#else
+	return sym->value;
+#endif
+}
 
 #ifdef CONFIG_LIVEPATCH
 int copy_module_elf(struct module *mod, struct load_info *info);
@@ -174,3 +187,19 @@ void kmemleak_load_module(const struct module *mod, const struct load_info *info
 static inline void kmemleak_load_module(const struct module *mod,
 					const struct load_info *info) { }
 #endif /* CONFIG_DEBUG_KMEMLEAK */
+
+#ifdef CONFIG_KALLSYMS
+void init_build_id(struct module *mod, const struct load_info *info);
+void layout_symtab(struct module *mod, struct load_info *info);
+void add_kallsyms(struct module *mod, const struct load_info *info);
+unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name);
+
+static inline bool sect_empty(const Elf_Shdr *sect)
+{
+	return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0;
+}
+#else /* !CONFIG_KALLSYMS */
+static inline void init_build_id(struct module *mod, const struct load_info *info) { }
+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) { }
+#endif /* CONFIG_KALLSYMS */
diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c
new file mode 100644
index 000000000000..1b0780e20aab
--- /dev/null
+++ b/kernel/module/kallsyms.c
@@ -0,0 +1,502 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Module kallsyms support
+ *
+ * Copyright (C) 2010 Rusty Russell
+ */
+
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/buildid.h>
+#include <linux/bsearch.h>
+#include "internal.h"
+
+/* Lookup exported symbol in given range of kernel_symbols */
+static const struct kernel_symbol *lookup_exported_symbol(const char *name,
+							  const struct kernel_symbol *start,
+							  const struct kernel_symbol *stop)
+{
+	return bsearch(name, start, stop - start,
+			sizeof(struct kernel_symbol), cmp_name);
+}
+
+static int is_exported(const char *name, unsigned long value,
+		       const struct module *mod)
+{
+	const struct kernel_symbol *ks;
+
+	if (!mod)
+		ks = lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab);
+	else
+		ks = lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms);
+
+	return ks && kernel_symbol_value(ks) == value;
+}
+
+/* As per nm */
+static char elf_type(const Elf_Sym *sym, const struct load_info *info)
+{
+	const Elf_Shdr *sechdrs = info->sechdrs;
+
+	if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
+		if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
+			return 'v';
+		else
+			return 'w';
+	}
+	if (sym->st_shndx == SHN_UNDEF)
+		return 'U';
+	if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu)
+		return 'a';
+	if (sym->st_shndx >= SHN_LORESERVE)
+		return '?';
+	if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
+		return 't';
+	if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC &&
+	    sechdrs[sym->st_shndx].sh_type != SHT_NOBITS) {
+		if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE))
+			return 'r';
+		else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
+			return 'g';
+		else
+			return 'd';
+	}
+	if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
+		if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
+			return 's';
+		else
+			return 'b';
+	}
+	if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name,
+		      ".debug")) {
+		return 'n';
+	}
+	return '?';
+}
+
+static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
+			   unsigned int shnum, unsigned int pcpundx)
+{
+	const Elf_Shdr *sec;
+
+	if (src->st_shndx == SHN_UNDEF ||
+	    src->st_shndx >= shnum ||
+	    !src->st_name)
+		return false;
+
+#ifdef CONFIG_KALLSYMS_ALL
+	if (src->st_shndx == pcpundx)
+		return true;
+#endif
+
+	sec = sechdrs + src->st_shndx;
+	if (!(sec->sh_flags & SHF_ALLOC)
+#ifndef CONFIG_KALLSYMS_ALL
+	    || !(sec->sh_flags & SHF_EXECINSTR)
+#endif
+	    || (sec->sh_entsize & INIT_OFFSET_MASK))
+		return false;
+
+	return true;
+}
+
+/*
+ * We only allocate and copy the strings needed by the parts of symtab
+ * we keep.  This is simple, but has the effect of making multiple
+ * copies of duplicates.  We could be more sophisticated, see
+ * linux-kernel thread starting with
+ * <73defb5e4bca04a6431392cc341112b1@localhost>.
+ */
+void layout_symtab(struct module *mod, struct load_info *info)
+{
+	Elf_Shdr *symsect = info->sechdrs + info->index.sym;
+	Elf_Shdr *strsect = info->sechdrs + info->index.str;
+	const Elf_Sym *src;
+	unsigned int i, nsrc, ndst, strtab_size = 0;
+
+	/* Put symbol section at end of init part of module. */
+	symsect->sh_flags |= SHF_ALLOC;
+	symsect->sh_entsize = module_get_offset(mod, &mod->init_layout.size, symsect,
+						info->index.sym) | INIT_OFFSET_MASK;
+	pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
+
+	src = (void *)info->hdr + symsect->sh_offset;
+	nsrc = symsect->sh_size / sizeof(*src);
+
+	/* Compute total space required for the core symbols' strtab. */
+	for (ndst = i = 0; i < nsrc; i++) {
+		if (i == 0 || is_livepatch_module(mod) ||
+		    is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
+				   info->index.pcpu)) {
+			strtab_size += strlen(&info->strtab[src[i].st_name]) + 1;
+			ndst++;
+		}
+	}
+
+	/* Append room for core symbols at end of core part. */
+	info->symoffs = ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1);
+	info->stroffs = mod->core_layout.size = info->symoffs + ndst * sizeof(Elf_Sym);
+	mod->core_layout.size += strtab_size;
+	info->core_typeoffs = mod->core_layout.size;
+	mod->core_layout.size += ndst * sizeof(char);
+	mod->core_layout.size = debug_align(mod->core_layout.size);
+
+	/* Put string table section at end of init part of module. */
+	strsect->sh_flags |= SHF_ALLOC;
+	strsect->sh_entsize = module_get_offset(mod, &mod->init_layout.size, strsect,
+						info->index.str) | INIT_OFFSET_MASK;
+	pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
+
+	/* We'll tack temporary mod_kallsyms on the end. */
+	mod->init_layout.size = ALIGN(mod->init_layout.size,
+				      __alignof__(struct mod_kallsyms));
+	info->mod_kallsyms_init_off = mod->init_layout.size;
+	mod->init_layout.size += sizeof(struct mod_kallsyms);
+	info->init_typeoffs = mod->init_layout.size;
+	mod->init_layout.size += nsrc * sizeof(char);
+	mod->init_layout.size = debug_align(mod->init_layout.size);
+}
+
+/*
+ * We use the full symtab and strtab which layout_symtab arranged to
+ * be appended to the init section.  Later we switch to the cut-down
+ * core-only ones.
+ */
+void add_kallsyms(struct module *mod, const struct load_info *info)
+{
+	unsigned int i, ndst;
+	const Elf_Sym *src;
+	Elf_Sym *dst;
+	char *s;
+	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;
+
+	/* The following is safe since this pointer cannot change */
+	mod->kallsyms->symtab = (void *)symsec->sh_addr;
+	mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
+	/* Make sure we get permanent strtab: don't use info->strtab. */
+	mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
+	mod->kallsyms->typetab = mod->init_layout.base + info->init_typeoffs;
+
+	/*
+	 * Now populate the cut down core kallsyms for after init
+	 * and set types up while we still have access to sections.
+	 */
+	mod->core_kallsyms.symtab = dst = mod->core_layout.base + info->symoffs;
+	mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs;
+	mod->core_kallsyms.typetab = mod->core_layout.base + info->core_typeoffs;
+	src = mod->kallsyms->symtab;
+	for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
+		mod->kallsyms->typetab[i] = elf_type(src + i, info);
+		if (i == 0 || is_livepatch_module(mod) ||
+		    is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
+				   info->index.pcpu)) {
+			mod->core_kallsyms.typetab[ndst] =
+			    mod->kallsyms->typetab[i];
+			dst[ndst] = src[i];
+			dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
+			s += strscpy(s, &mod->kallsyms->strtab[src[i].st_name],
+				     KSYM_NAME_LEN) + 1;
+		}
+	}
+	mod->core_kallsyms.num_symtab = ndst;
+}
+
+#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
+void init_build_id(struct module *mod, const struct load_info *info)
+{
+	const Elf_Shdr *sechdr;
+	unsigned int i;
+
+	for (i = 0; i < info->hdr->e_shnum; i++) {
+		sechdr = &info->sechdrs[i];
+		if (!sect_empty(sechdr) && sechdr->sh_type == SHT_NOTE &&
+		    !build_id_parse_buf((void *)sechdr->sh_addr, mod->build_id,
+					sechdr->sh_size))
+			break;
+	}
+}
+#else
+void init_build_id(struct module *mod, const struct load_info *info)
+{
+}
+#endif
+
+/*
+ * This ignores the intensely annoying "mapping symbols" found
+ * in ARM ELF files: $a, $t and $d.
+ */
+static inline int is_arm_mapping_symbol(const char *str)
+{
+	if (str[0] == '.' && str[1] == 'L')
+		return true;
+	return str[0] == '$' && strchr("axtd", str[1]) &&
+	       (str[2] == '\0' || str[2] == '.');
+}
+
+static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum)
+{
+	return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
+}
+
+/*
+ * Given a module and address, find the corresponding symbol and return its name
+ * while providing its size and offset if needed.
+ */
+static const char *find_kallsyms_symbol(struct module *mod,
+					unsigned long addr,
+					unsigned long *size,
+					unsigned long *offset)
+{
+	unsigned int i, best = 0;
+	unsigned long nextval, bestval;
+	struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
+
+	/* At worse, next value is at end of module */
+	if (within_module_init(addr, mod))
+		nextval = (unsigned long)mod->init_layout.base + mod->init_layout.text_size;
+	else
+		nextval = (unsigned long)mod->core_layout.base + mod->core_layout.text_size;
+
+	bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
+
+	/*
+	 * Scan for closest preceding symbol, and next symbol. (ELF
+	 * starts real symbols at 1).
+	 */
+	for (i = 1; i < kallsyms->num_symtab; i++) {
+		const Elf_Sym *sym = &kallsyms->symtab[i];
+		unsigned long thisval = kallsyms_symbol_value(sym);
+
+		if (sym->st_shndx == SHN_UNDEF)
+			continue;
+
+		/*
+		 * We ignore unnamed symbols: they're uninformative
+		 * and inserted at a whim.
+		 */
+		if (*kallsyms_symbol_name(kallsyms, i) == '\0' ||
+		    is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i)))
+			continue;
+
+		if (thisval <= addr && thisval > bestval) {
+			best = i;
+			bestval = thisval;
+		}
+		if (thisval > addr && thisval < nextval)
+			nextval = thisval;
+	}
+
+	if (!best)
+		return NULL;
+
+	if (size)
+		*size = nextval - bestval;
+	if (offset)
+		*offset = addr - bestval;
+
+	return kallsyms_symbol_name(kallsyms, best);
+}
+
+void * __weak dereference_module_function_descriptor(struct module *mod,
+						     void *ptr)
+{
+	return ptr;
+}
+
+/*
+ * For kallsyms to ask for address resolution.  NULL means not found.  Careful
+ * not to lock to avoid deadlock on oopses, simply disable preemption.
+ */
+const char *module_address_lookup(unsigned long addr,
+				  unsigned long *size,
+			    unsigned long *offset,
+			    char **modname,
+			    const unsigned char **modbuildid,
+			    char *namebuf)
+{
+	const char *ret = NULL;
+	struct module *mod;
+
+	preempt_disable();
+	mod = __module_address(addr);
+	if (mod) {
+		if (modname)
+			*modname = mod->name;
+		if (modbuildid) {
+#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
+			*modbuildid = mod->build_id;
+#else
+			*modbuildid = NULL;
+#endif
+		}
+
+		ret = find_kallsyms_symbol(mod, addr, size, offset);
+	}
+	/* Make a copy in here where it's safe */
+	if (ret) {
+		strncpy(namebuf, ret, KSYM_NAME_LEN - 1);
+		ret = namebuf;
+	}
+	preempt_enable();
+
+	return ret;
+}
+
+int lookup_module_symbol_name(unsigned long addr, char *symname)
+{
+	struct module *mod;
+
+	preempt_disable();
+	list_for_each_entry_rcu(mod, &modules, list) {
+		if (mod->state == MODULE_STATE_UNFORMED)
+			continue;
+		if (within_module(addr, mod)) {
+			const char *sym;
+
+			sym = find_kallsyms_symbol(mod, addr, NULL, NULL);
+			if (!sym)
+				goto out;
+
+			strscpy(symname, sym, KSYM_NAME_LEN);
+			preempt_enable();
+			return 0;
+		}
+	}
+out:
+	preempt_enable();
+	return -ERANGE;
+}
+
+int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
+			       unsigned long *offset, char *modname, char *name)
+{
+	struct module *mod;
+
+	preempt_disable();
+	list_for_each_entry_rcu(mod, &modules, list) {
+		if (mod->state == MODULE_STATE_UNFORMED)
+			continue;
+		if (within_module(addr, mod)) {
+			const char *sym;
+
+			sym = find_kallsyms_symbol(mod, addr, size, offset);
+			if (!sym)
+				goto out;
+			if (modname)
+				strscpy(modname, mod->name, MODULE_NAME_LEN);
+			if (name)
+				strscpy(name, sym, KSYM_NAME_LEN);
+			preempt_enable();
+			return 0;
+		}
+	}
+out:
+	preempt_enable();
+	return -ERANGE;
+}
+
+int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
+		       char *name, char *module_name, int *exported)
+{
+	struct module *mod;
+
+	preempt_disable();
+	list_for_each_entry_rcu(mod, &modules, list) {
+		struct mod_kallsyms *kallsyms;
+
+		if (mod->state == MODULE_STATE_UNFORMED)
+			continue;
+		kallsyms = rcu_dereference_sched(mod->kallsyms);
+		if (symnum < kallsyms->num_symtab) {
+			const Elf_Sym *sym = &kallsyms->symtab[symnum];
+
+			*value = kallsyms_symbol_value(sym);
+			*type = kallsyms->typetab[symnum];
+			strscpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN);
+			strscpy(module_name, mod->name, MODULE_NAME_LEN);
+			*exported = is_exported(name, *value, mod);
+			preempt_enable();
+			return 0;
+		}
+		symnum -= kallsyms->num_symtab;
+	}
+	preempt_enable();
+	return -ERANGE;
+}
+
+/* Given a module and name of symbol, find and return the symbol's value */
+unsigned long find_kallsyms_symbol_value(struct module *mod, const char *name)
+{
+	unsigned int i;
+	struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
+
+	for (i = 0; i < kallsyms->num_symtab; i++) {
+		const Elf_Sym *sym = &kallsyms->symtab[i];
+
+		if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) == 0 &&
+		    sym->st_shndx != SHN_UNDEF)
+			return kallsyms_symbol_value(sym);
+	}
+	return 0;
+}
+
+/* Look for this name: can be of form module:name. */
+unsigned long module_kallsyms_lookup_name(const char *name)
+{
+	struct module *mod;
+	char *colon;
+	unsigned long ret = 0;
+
+	/* Don't lock: we're in enough trouble already. */
+	preempt_disable();
+	if ((colon = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) {
+		if ((mod = find_module_all(name, colon - name, false)) != NULL)
+			ret = find_kallsyms_symbol_value(mod, colon + 1);
+	} else {
+		list_for_each_entry_rcu(mod, &modules, list) {
+			if (mod->state == MODULE_STATE_UNFORMED)
+				continue;
+			if ((ret = find_kallsyms_symbol_value(mod, name)) != 0)
+				break;
+		}
+	}
+	preempt_enable();
+	return ret;
+}
+
+#ifdef CONFIG_LIVEPATCH
+int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+					     struct module *, unsigned long),
+				   void *data)
+{
+	struct module *mod;
+	unsigned int i;
+	int ret = 0;
+
+	mutex_lock(&module_mutex);
+	list_for_each_entry(mod, &modules, list) {
+		/* We hold module_mutex: no need for rcu_dereference_sched */
+		struct mod_kallsyms *kallsyms = mod->kallsyms;
+
+		if (mod->state == MODULE_STATE_UNFORMED)
+			continue;
+		for (i = 0; i < kallsyms->num_symtab; i++) {
+			const Elf_Sym *sym = &kallsyms->symtab[i];
+
+			if (sym->st_shndx == SHN_UNDEF)
+				continue;
+
+			ret = fn(data, kallsyms_symbol_name(kallsyms, i),
+				 mod, kallsyms_symbol_value(sym));
+			if (ret != 0)
+				goto out;
+		}
+	}
+out:
+	mutex_unlock(&module_mutex);
+	return ret;
+}
+#endif /* CONFIG_LIVEPATCH */
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 7dd283959c5c..952079987ea4 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -288,15 +288,6 @@ static bool check_exported_symbol(const struct symsearch *syms,
 	return true;
 }
 
-static unsigned long kernel_symbol_value(const struct kernel_symbol *sym)
-{
-#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
-	return (unsigned long)offset_to_ptr(&sym->value_offset);
-#else
-	return sym->value;
-#endif
-}
-
 static const char *kernel_symbol_name(const struct kernel_symbol *sym)
 {
 #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
@@ -317,7 +308,7 @@ static const char *kernel_symbol_namespace(const struct kernel_symbol *sym)
 #endif
 }
 
-static int cmp_name(const void *name, const void *sym)
+int cmp_name(const void *name, const void *sym)
 {
 	return strcmp(name, kernel_symbol_name(sym));
 }
@@ -387,8 +378,8 @@ static bool find_symbol(struct find_symbol_arg *fsa)
  * Search for module by name: must hold module_mutex (or preempt disabled
  * for read-only access).
  */
-static struct module *find_module_all(const char *name, size_t len,
-				      bool even_unformed)
+struct module *find_module_all(const char *name, size_t len,
+			       bool even_unformed)
 {
 	struct module *mod;
 
@@ -1294,13 +1285,6 @@ resolve_symbol_wait(struct module *mod,
 	return ksym;
 }
 
-#ifdef CONFIG_KALLSYMS
-static inline bool sect_empty(const Elf_Shdr *sect)
-{
-	return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0;
-}
-#endif
-
 /*
  * /sys/module/foo/sections stuff
  * J. Corbet <corbet@lwn.net>
@@ -2065,7 +2049,7 @@ unsigned int __weak arch_mod_section_prepend(struct module *mod,
 }
 
 /* Update size with this section: return offset. */
-static long get_offset(struct module *mod, unsigned int *size,
+long module_get_offset(struct module *mod, unsigned int *size,
 		       Elf_Shdr *sechdr, unsigned int section)
 {
 	long ret;
@@ -2121,7 +2105,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
 			    || s->sh_entsize != ~0UL
 			    || module_init_layout_section(sname))
 				continue;
-			s->sh_entsize = get_offset(mod, &mod->core_layout.size, s, i);
+			s->sh_entsize = module_get_offset(mod, &mod->core_layout.size, s, i);
 			pr_debug("\t%s\n", sname);
 		}
 		switch (m) {
@@ -2154,7 +2138,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
 			    || s->sh_entsize != ~0UL
 			    || !module_init_layout_section(sname))
 				continue;
-			s->sh_entsize = (get_offset(mod, &mod->init_layout.size, s, i)
+			s->sh_entsize = (module_get_offset(mod, &mod->init_layout.size, s, i)
 					 | INIT_OFFSET_MASK);
 			pr_debug("\t%s\n", sname);
 		}
@@ -2267,228 +2251,6 @@ static void free_modinfo(struct module *mod)
 	}
 }
 
-#ifdef CONFIG_KALLSYMS
-
-/* Lookup exported symbol in given range of kernel_symbols */
-static const struct kernel_symbol *lookup_exported_symbol(const char *name,
-							  const struct kernel_symbol *start,
-							  const struct kernel_symbol *stop)
-{
-	return bsearch(name, start, stop - start,
-			sizeof(struct kernel_symbol), cmp_name);
-}
-
-static int is_exported(const char *name, unsigned long value,
-		       const struct module *mod)
-{
-	const struct kernel_symbol *ks;
-	if (!mod)
-		ks = lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab);
-	else
-		ks = lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms);
-
-	return ks != NULL && kernel_symbol_value(ks) == value;
-}
-
-/* As per nm */
-static char elf_type(const Elf_Sym *sym, const struct load_info *info)
-{
-	const Elf_Shdr *sechdrs = info->sechdrs;
-
-	if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
-		if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
-			return 'v';
-		else
-			return 'w';
-	}
-	if (sym->st_shndx == SHN_UNDEF)
-		return 'U';
-	if (sym->st_shndx == SHN_ABS || sym->st_shndx == info->index.pcpu)
-		return 'a';
-	if (sym->st_shndx >= SHN_LORESERVE)
-		return '?';
-	if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
-		return 't';
-	if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC
-	    && sechdrs[sym->st_shndx].sh_type != SHT_NOBITS) {
-		if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE))
-			return 'r';
-		else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
-			return 'g';
-		else
-			return 'd';
-	}
-	if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
-		if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
-			return 's';
-		else
-			return 'b';
-	}
-	if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name,
-		      ".debug")) {
-		return 'n';
-	}
-	return '?';
-}
-
-static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
-			unsigned int shnum, unsigned int pcpundx)
-{
-	const Elf_Shdr *sec;
-
-	if (src->st_shndx == SHN_UNDEF
-	    || src->st_shndx >= shnum
-	    || !src->st_name)
-		return false;
-
-#ifdef CONFIG_KALLSYMS_ALL
-	if (src->st_shndx == pcpundx)
-		return true;
-#endif
-
-	sec = sechdrs + src->st_shndx;
-	if (!(sec->sh_flags & SHF_ALLOC)
-#ifndef CONFIG_KALLSYMS_ALL
-	    || !(sec->sh_flags & SHF_EXECINSTR)
-#endif
-	    || (sec->sh_entsize & INIT_OFFSET_MASK))
-		return false;
-
-	return true;
-}
-
-/*
- * We only allocate and copy the strings needed by the parts of symtab
- * we keep.  This is simple, but has the effect of making multiple
- * copies of duplicates.  We could be more sophisticated, see
- * linux-kernel thread starting with
- * <73defb5e4bca04a6431392cc341112b1@localhost>.
- */
-static void layout_symtab(struct module *mod, struct load_info *info)
-{
-	Elf_Shdr *symsect = info->sechdrs + info->index.sym;
-	Elf_Shdr *strsect = info->sechdrs + info->index.str;
-	const Elf_Sym *src;
-	unsigned int i, nsrc, ndst, strtab_size = 0;
-
-	/* Put symbol section at end of init part of module. */
-	symsect->sh_flags |= SHF_ALLOC;
-	symsect->sh_entsize = get_offset(mod, &mod->init_layout.size, symsect,
-					 info->index.sym) | INIT_OFFSET_MASK;
-	pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
-
-	src = (void *)info->hdr + symsect->sh_offset;
-	nsrc = symsect->sh_size / sizeof(*src);
-
-	/* Compute total space required for the core symbols' strtab. */
-	for (ndst = i = 0; i < nsrc; i++) {
-		if (i == 0 || is_livepatch_module(mod) ||
-		    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
-				   info->index.pcpu)) {
-			strtab_size += strlen(&info->strtab[src[i].st_name])+1;
-			ndst++;
-		}
-	}
-
-	/* Append room for core symbols at end of core part. */
-	info->symoffs = ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1);
-	info->stroffs = mod->core_layout.size = info->symoffs + ndst * sizeof(Elf_Sym);
-	mod->core_layout.size += strtab_size;
-	info->core_typeoffs = mod->core_layout.size;
-	mod->core_layout.size += ndst * sizeof(char);
-	mod->core_layout.size = debug_align(mod->core_layout.size);
-
-	/* Put string table section at end of init part of module. */
-	strsect->sh_flags |= SHF_ALLOC;
-	strsect->sh_entsize = get_offset(mod, &mod->init_layout.size, strsect,
-					 info->index.str) | INIT_OFFSET_MASK;
-	pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
-
-	/* We'll tack temporary mod_kallsyms on the end. */
-	mod->init_layout.size = ALIGN(mod->init_layout.size,
-				      __alignof__(struct mod_kallsyms));
-	info->mod_kallsyms_init_off = mod->init_layout.size;
-	mod->init_layout.size += sizeof(struct mod_kallsyms);
-	info->init_typeoffs = mod->init_layout.size;
-	mod->init_layout.size += nsrc * sizeof(char);
-	mod->init_layout.size = debug_align(mod->init_layout.size);
-}
-
-/*
- * We use the full symtab and strtab which layout_symtab arranged to
- * be appended to the init section.  Later we switch to the cut-down
- * core-only ones.
- */
-static void add_kallsyms(struct module *mod, const struct load_info *info)
-{
-	unsigned int i, ndst;
-	const Elf_Sym *src;
-	Elf_Sym *dst;
-	char *s;
-	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->symtab = (void *)symsec->sh_addr;
-	mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
-	/* Make sure we get permanent strtab: don't use info->strtab. */
-	mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
-	mod->kallsyms->typetab = mod->init_layout.base + info->init_typeoffs;
-
-	/*
-	 * Now populate the cut down core kallsyms for after init
-	 * and set types up while we still have access to sections.
-	 */
-	mod->core_kallsyms.symtab = dst = mod->core_layout.base + info->symoffs;
-	mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs;
-	mod->core_kallsyms.typetab = mod->core_layout.base + info->core_typeoffs;
-	src = mod->kallsyms->symtab;
-	for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
-		mod->kallsyms->typetab[i] = elf_type(src + i, info);
-		if (i == 0 || is_livepatch_module(mod) ||
-		    is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
-				   info->index.pcpu)) {
-			mod->core_kallsyms.typetab[ndst] =
-			    mod->kallsyms->typetab[i];
-			dst[ndst] = src[i];
-			dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
-			s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
-				     KSYM_NAME_LEN) + 1;
-		}
-	}
-	mod->core_kallsyms.num_symtab = ndst;
-}
-#else
-static inline void layout_symtab(struct module *mod, struct load_info *info)
-{
-}
-
-static void add_kallsyms(struct module *mod, const struct load_info *info)
-{
-}
-#endif /* CONFIG_KALLSYMS */
-
-#if IS_ENABLED(CONFIG_KALLSYMS) && IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
-static void init_build_id(struct module *mod, const struct load_info *info)
-{
-	const Elf_Shdr *sechdr;
-	unsigned int i;
-
-	for (i = 0; i < info->hdr->e_shnum; i++) {
-		sechdr = &info->sechdrs[i];
-		if (!sect_empty(sechdr) && sechdr->sh_type == SHT_NOTE &&
-		    !build_id_parse_buf((void *)sechdr->sh_addr, mod->build_id,
-					sechdr->sh_size))
-			break;
-	}
-}
-#else
-static void init_build_id(struct module *mod, const struct load_info *info)
-{
-}
-#endif
-
 static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug, unsigned int num)
 {
 	if (!debug)
@@ -3799,287 +3561,6 @@ static inline int within(unsigned long addr, void *start, unsigned long size)
 	return ((void *)addr >= start && (void *)addr < start + size);
 }
 
-#ifdef CONFIG_KALLSYMS
-/*
- * This ignores the intensely annoying "mapping symbols" found
- * in ARM ELF files: $a, $t and $d.
- */
-static inline int is_arm_mapping_symbol(const char *str)
-{
-	if (str[0] == '.' && str[1] == 'L')
-		return true;
-	return str[0] == '$' && strchr("axtd", str[1])
-	       && (str[2] == '\0' || str[2] == '.');
-}
-
-static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum)
-{
-	return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
-}
-
-/*
- * Given a module and address, find the corresponding symbol and return its name
- * while providing its size and offset if needed.
- */
-static const char *find_kallsyms_symbol(struct module *mod,
-					unsigned long addr,
-					unsigned long *size,
-					unsigned long *offset)
-{
-	unsigned int i, best = 0;
-	unsigned long nextval, bestval;
-	struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
-
-	/* At worse, next value is at end of module */
-	if (within_module_init(addr, mod))
-		nextval = (unsigned long)mod->init_layout.base+mod->init_layout.text_size;
-	else
-		nextval = (unsigned long)mod->core_layout.base+mod->core_layout.text_size;
-
-	bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
-
-	/*
-	 * Scan for closest preceding symbol, and next symbol. (ELF
-	 * starts real symbols at 1).
-	 */
-	for (i = 1; i < kallsyms->num_symtab; i++) {
-		const Elf_Sym *sym = &kallsyms->symtab[i];
-		unsigned long thisval = kallsyms_symbol_value(sym);
-
-		if (sym->st_shndx == SHN_UNDEF)
-			continue;
-
-		/*
-		 * We ignore unnamed symbols: they're uninformative
-		 * and inserted at a whim.
-		 */
-		if (*kallsyms_symbol_name(kallsyms, i) == '\0'
-		    || is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i)))
-			continue;
-
-		if (thisval <= addr && thisval > bestval) {
-			best = i;
-			bestval = thisval;
-		}
-		if (thisval > addr && thisval < nextval)
-			nextval = thisval;
-	}
-
-	if (!best)
-		return NULL;
-
-	if (size)
-		*size = nextval - bestval;
-	if (offset)
-		*offset = addr - bestval;
-
-	return kallsyms_symbol_name(kallsyms, best);
-}
-
-void * __weak dereference_module_function_descriptor(struct module *mod,
-						     void *ptr)
-{
-	return ptr;
-}
-
-/*
- * For kallsyms to ask for address resolution.  NULL means not found.  Careful
- * not to lock to avoid deadlock on oopses, simply disable preemption.
- */
-const char *module_address_lookup(unsigned long addr,
-			    unsigned long *size,
-			    unsigned long *offset,
-			    char **modname,
-			    const unsigned char **modbuildid,
-			    char *namebuf)
-{
-	const char *ret = NULL;
-	struct module *mod;
-
-	preempt_disable();
-	mod = __module_address(addr);
-	if (mod) {
-		if (modname)
-			*modname = mod->name;
-		if (modbuildid) {
-#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
-			*modbuildid = mod->build_id;
-#else
-			*modbuildid = NULL;
-#endif
-		}
-
-		ret = find_kallsyms_symbol(mod, addr, size, offset);
-	}
-	/* Make a copy in here where it's safe */
-	if (ret) {
-		strncpy(namebuf, ret, KSYM_NAME_LEN - 1);
-		ret = namebuf;
-	}
-	preempt_enable();
-
-	return ret;
-}
-
-int lookup_module_symbol_name(unsigned long addr, char *symname)
-{
-	struct module *mod;
-
-	preempt_disable();
-	list_for_each_entry_rcu(mod, &modules, list) {
-		if (mod->state == MODULE_STATE_UNFORMED)
-			continue;
-		if (within_module(addr, mod)) {
-			const char *sym;
-
-			sym = find_kallsyms_symbol(mod, addr, NULL, NULL);
-			if (!sym)
-				goto out;
-
-			strlcpy(symname, sym, KSYM_NAME_LEN);
-			preempt_enable();
-			return 0;
-		}
-	}
-out:
-	preempt_enable();
-	return -ERANGE;
-}
-
-int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
-			unsigned long *offset, char *modname, char *name)
-{
-	struct module *mod;
-
-	preempt_disable();
-	list_for_each_entry_rcu(mod, &modules, list) {
-		if (mod->state == MODULE_STATE_UNFORMED)
-			continue;
-		if (within_module(addr, mod)) {
-			const char *sym;
-
-			sym = find_kallsyms_symbol(mod, addr, size, offset);
-			if (!sym)
-				goto out;
-			if (modname)
-				strlcpy(modname, mod->name, MODULE_NAME_LEN);
-			if (name)
-				strlcpy(name, sym, KSYM_NAME_LEN);
-			preempt_enable();
-			return 0;
-		}
-	}
-out:
-	preempt_enable();
-	return -ERANGE;
-}
-
-int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
-			char *name, char *module_name, int *exported)
-{
-	struct module *mod;
-
-	preempt_disable();
-	list_for_each_entry_rcu(mod, &modules, list) {
-		struct mod_kallsyms *kallsyms;
-
-		if (mod->state == MODULE_STATE_UNFORMED)
-			continue;
-		kallsyms = rcu_dereference_sched(mod->kallsyms);
-		if (symnum < kallsyms->num_symtab) {
-			const Elf_Sym *sym = &kallsyms->symtab[symnum];
-
-			*value = kallsyms_symbol_value(sym);
-			*type = kallsyms->typetab[symnum];
-			strlcpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN);
-			strlcpy(module_name, mod->name, MODULE_NAME_LEN);
-			*exported = is_exported(name, *value, mod);
-			preempt_enable();
-			return 0;
-		}
-		symnum -= kallsyms->num_symtab;
-	}
-	preempt_enable();
-	return -ERANGE;
-}
-
-/* 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)
-{
-	unsigned int i;
-	struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
-
-	for (i = 0; i < kallsyms->num_symtab; i++) {
-		const Elf_Sym *sym = &kallsyms->symtab[i];
-
-		if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) == 0 &&
-		    sym->st_shndx != SHN_UNDEF)
-			return kallsyms_symbol_value(sym);
-	}
-	return 0;
-}
-
-/* Look for this name: can be of form module:name. */
-unsigned long module_kallsyms_lookup_name(const char *name)
-{
-	struct module *mod;
-	char *colon;
-	unsigned long ret = 0;
-
-	/* Don't lock: we're in enough trouble already. */
-	preempt_disable();
-	if ((colon = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) {
-		if ((mod = find_module_all(name, colon - name, false)) != NULL)
-			ret = find_kallsyms_symbol_value(mod, colon+1);
-	} else {
-		list_for_each_entry_rcu(mod, &modules, list) {
-			if (mod->state == MODULE_STATE_UNFORMED)
-				continue;
-			if ((ret = find_kallsyms_symbol_value(mod, name)) != 0)
-				break;
-		}
-	}
-	preempt_enable();
-	return ret;
-}
-
-#ifdef CONFIG_LIVEPATCH
-int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
-					     struct module *, unsigned long),
-				   void *data)
-{
-	struct module *mod;
-	unsigned int i;
-	int ret = 0;
-
-	mutex_lock(&module_mutex);
-	list_for_each_entry(mod, &modules, list) {
-		/* We hold module_mutex: no need for rcu_dereference_sched */
-		struct mod_kallsyms *kallsyms = mod->kallsyms;
-
-		if (mod->state == MODULE_STATE_UNFORMED)
-			continue;
-		for (i = 0; i < kallsyms->num_symtab; i++) {
-			const Elf_Sym *sym = &kallsyms->symtab[i];
-
-			if (sym->st_shndx == SHN_UNDEF)
-				continue;
-
-			ret = fn(data, kallsyms_symbol_name(kallsyms, i),
-				 mod, kallsyms_symbol_value(sym));
-			if (ret != 0)
-				goto out;
-
-			cond_resched();
-		}
-	}
-out:
-	mutex_unlock(&module_mutex);
-	return ret;
-}
-#endif /* CONFIG_LIVEPATCH */
-#endif /* CONFIG_KALLSYMS */
-
 static void cfi_init(struct module *mod)
 {
 #ifdef CONFIG_CFI_CLANG
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 10/14] module: kallsyms: Fix suspicious rcu usage
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (8 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 09/14] module: Move kallsyms support into " Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-03-01 16:52   ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 11/14] module: Move procfs support into a separate file Aaron Tomlin
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

The purpose of this patch is to address the various Sparse warnings
due to the incorrect dereference/or access of an __rcu pointer.

Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/kallsyms.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c
index 1b0780e20aab..a3da0686a2a6 100644
--- a/kernel/module/kallsyms.c
+++ b/kernel/module/kallsyms.c
@@ -171,14 +171,17 @@ 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 = (void __rcu *)mod->init_layout.base +
+		info->mod_kallsyms_init_off;
 
+	preempt_disable();
 	/* The following is safe since this pointer cannot change */
-	mod->kallsyms->symtab = (void *)symsec->sh_addr;
-	mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
+	rcu_dereference_sched(mod->kallsyms)->symtab = (void *)symsec->sh_addr;
+	rcu_dereference_sched(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
 	/* Make sure we get permanent strtab: don't use info->strtab. */
-	mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
-	mod->kallsyms->typetab = mod->init_layout.base + info->init_typeoffs;
+	rcu_dereference_sched(mod->kallsyms)->strtab =
+		(void *)info->sechdrs[info->index.str].sh_addr;
+	rcu_dereference_sched(mod->kallsyms)->typetab = mod->init_layout.base + info->init_typeoffs;
 
 	/*
 	 * Now populate the cut down core kallsyms for after init
@@ -187,20 +190,22 @@ void add_kallsyms(struct module *mod, const struct load_info *info)
 	mod->core_kallsyms.symtab = dst = mod->core_layout.base + info->symoffs;
 	mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs;
 	mod->core_kallsyms.typetab = mod->core_layout.base + info->core_typeoffs;
-	src = mod->kallsyms->symtab;
-	for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
-		mod->kallsyms->typetab[i] = elf_type(src + i, info);
+	src = rcu_dereference_sched(mod->kallsyms)->symtab;
+	for (ndst = i = 0; i < rcu_dereference_sched(mod->kallsyms)->num_symtab; i++) {
+		rcu_dereference_sched(mod->kallsyms)->typetab[i] = elf_type(src + i, info);
 		if (i == 0 || is_livepatch_module(mod) ||
 		    is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
 				   info->index.pcpu)) {
 			mod->core_kallsyms.typetab[ndst] =
-			    mod->kallsyms->typetab[i];
+			    rcu_dereference_sched(mod->kallsyms)->typetab[i];
 			dst[ndst] = src[i];
 			dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
-			s += strscpy(s, &mod->kallsyms->strtab[src[i].st_name],
+			s += strscpy(s,
+				     &rcu_dereference_sched(mod->kallsyms)->strtab[src[i].st_name],
 				     KSYM_NAME_LEN) + 1;
 		}
 	}
+	preempt_enable();
 	mod->core_kallsyms.num_symtab = ndst;
 }
 
@@ -478,11 +483,16 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
 
 	mutex_lock(&module_mutex);
 	list_for_each_entry(mod, &modules, list) {
-		/* We hold module_mutex: no need for rcu_dereference_sched */
-		struct mod_kallsyms *kallsyms = mod->kallsyms;
+		struct mod_kallsyms *kallsyms;
 
 		if (mod->state == MODULE_STATE_UNFORMED)
 			continue;
+
+		/* Use rcu_dereference_sched() to remain compliant with the sparse tool */
+		preempt_disable();
+		kallsyms = rcu_dereference_sched(mod->kallsyms);
+		preempt_enable();
+
 		for (i = 0; i < kallsyms->num_symtab; i++) {
 			const Elf_Sym *sym = &kallsyms->symtab[i];
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 11/14] module: Move procfs support into a separate file
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (9 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 10/14] module: kallsyms: Fix suspicious rcu usage Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 12/14] module: Move sysfs " Aaron Tomlin
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch migrates code that allows one to generate a
list of loaded/or linked modules via /proc when procfs
support is enabled into kernel/module/procfs.c.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/Makefile   |   1 +
 kernel/module/internal.h |   1 +
 kernel/module/main.c     | 131 +-----------------------------------
 kernel/module/procfs.c   | 142 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 145 insertions(+), 130 deletions(-)
 create mode 100644 kernel/module/procfs.c

diff --git a/kernel/module/Makefile b/kernel/module/Makefile
index 9901bed3ab5b..94296c98a67f 100644
--- a/kernel/module/Makefile
+++ b/kernel/module/Makefile
@@ -15,3 +15,4 @@ 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
+obj-$(CONFIG_PROC_FS) += procfs.o
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index 44ca05b9eb8f..6af40c2d145f 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -72,6 +72,7 @@ struct module *find_module_all(const char *name, size_t len, bool even_unformed)
 int cmp_name(const void *name, const void *sym);
 long module_get_offset(struct module *mod, unsigned int *size, Elf_Shdr *sechdr,
 		       unsigned int section);
+char *module_flags(struct module *mod, char *buf);
 
 static inline unsigned long kernel_symbol_value(const struct kernel_symbol *sym)
 {
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 952079987ea4..44b6fd1acc44 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -22,7 +22,6 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
-#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/syscalls.h>
 #include <linux/fcntl.h>
@@ -805,31 +804,6 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
 	return ret;
 }
 
-static inline void print_unload_info(struct seq_file *m, struct module *mod)
-{
-	struct module_use *use;
-	int printed_something = 0;
-
-	seq_printf(m, " %i ", module_refcount(mod));
-
-	/*
-	 * Always include a trailing , so userspace can differentiate
-	 * between this and the old multi-field proc format.
-	 */
-	list_for_each_entry(use, &mod->source_list, source_list) {
-		printed_something = 1;
-		seq_printf(m, "%s,", use->source->name);
-	}
-
-	if (mod->init != NULL && mod->exit == NULL) {
-		printed_something = 1;
-		seq_puts(m, "[permanent],");
-	}
-
-	if (!printed_something)
-		seq_puts(m, "-");
-}
-
 void __symbol_put(const char *symbol)
 {
 	struct find_symbol_arg fsa = {
@@ -919,12 +893,6 @@ void module_put(struct module *module)
 EXPORT_SYMBOL(module_put);
 
 #else /* !CONFIG_MODULE_UNLOAD */
-static inline void print_unload_info(struct seq_file *m, struct module *mod)
-{
-	/* We don't know the usage count, or what modules are using. */
-	seq_puts(m, " - -");
-}
-
 static inline void module_unload_free(struct module *mod)
 {
 }
@@ -3596,7 +3564,7 @@ static void cfi_cleanup(struct module *mod)
 }
 
 /* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */
-static char *module_flags(struct module *mod, char *buf)
+char *module_flags(struct module *mod, char *buf)
 {
 	int bx = 0;
 
@@ -3619,103 +3587,6 @@ static char *module_flags(struct module *mod, char *buf)
 	return buf;
 }
 
-#ifdef CONFIG_PROC_FS
-/* Called by the /proc file system to return a list of modules. */
-static void *m_start(struct seq_file *m, loff_t *pos)
-{
-	mutex_lock(&module_mutex);
-	return seq_list_start(&modules, *pos);
-}
-
-static void *m_next(struct seq_file *m, void *p, loff_t *pos)
-{
-	return seq_list_next(p, &modules, pos);
-}
-
-static void m_stop(struct seq_file *m, void *p)
-{
-	mutex_unlock(&module_mutex);
-}
-
-static int m_show(struct seq_file *m, void *p)
-{
-	struct module *mod = list_entry(p, struct module, list);
-	char buf[MODULE_FLAGS_BUF_SIZE];
-	void *value;
-
-	/* We always ignore unformed modules. */
-	if (mod->state == MODULE_STATE_UNFORMED)
-		return 0;
-
-	seq_printf(m, "%s %u",
-		   mod->name, mod->init_layout.size + mod->core_layout.size);
-	print_unload_info(m, mod);
-
-	/* Informative for users. */
-	seq_printf(m, " %s",
-		   mod->state == MODULE_STATE_GOING ? "Unloading" :
-		   mod->state == MODULE_STATE_COMING ? "Loading" :
-		   "Live");
-	/* Used by oprofile and other similar tools. */
-	value = m->private ? NULL : mod->core_layout.base;
-	seq_printf(m, " 0x%px", value);
-
-	/* Taints info */
-	if (mod->taints)
-		seq_printf(m, " %s", module_flags(mod, buf));
-
-	seq_puts(m, "\n");
-	return 0;
-}
-
-/*
- * Format: modulename size refcount deps address
- *
- * Where refcount is a number or -, and deps is a comma-separated list
- * of depends or -.
- */
-static const struct seq_operations modules_op = {
-	.start	= m_start,
-	.next	= m_next,
-	.stop	= m_stop,
-	.show	= m_show
-};
-
-/*
- * This also sets the "private" pointer to non-NULL if the
- * kernel pointers should be hidden (so you can just test
- * "m->private" to see if you should keep the values private).
- *
- * We use the same logic as for /proc/kallsyms.
- */
-static int modules_open(struct inode *inode, struct file *file)
-{
-	int err = seq_open(file, &modules_op);
-
-	if (!err) {
-		struct seq_file *m = file->private_data;
-		m->private = kallsyms_show_value(file->f_cred) ? NULL : (void *)8ul;
-	}
-
-	return err;
-}
-
-static const struct proc_ops modules_proc_ops = {
-	.proc_flags	= PROC_ENTRY_PERMANENT,
-	.proc_open	= modules_open,
-	.proc_read	= seq_read,
-	.proc_lseek	= seq_lseek,
-	.proc_release	= seq_release,
-};
-
-static int __init proc_modules_init(void)
-{
-	proc_create("modules", 0, NULL, &modules_proc_ops);
-	return 0;
-}
-module_init(proc_modules_init);
-#endif
-
 /* Given an address, look for it in the module exception tables. */
 const struct exception_table_entry *search_module_extables(unsigned long addr)
 {
diff --git a/kernel/module/procfs.c b/kernel/module/procfs.c
new file mode 100644
index 000000000000..2717e130788e
--- /dev/null
+++ b/kernel/module/procfs.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Module proc support
+ *
+ * Copyright (C) 2008 Alexey Dobriyan
+ */
+
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/mutex.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include "internal.h"
+
+#ifdef CONFIG_MODULE_UNLOAD
+static inline void print_unload_info(struct seq_file *m, struct module *mod)
+{
+	struct module_use *use;
+	int printed_something = 0;
+
+	seq_printf(m, " %i ", module_refcount(mod));
+
+	/*
+	 * Always include a trailing , so userspace can differentiate
+	 * between this and the old multi-field proc format.
+	 */
+	list_for_each_entry(use, &mod->source_list, source_list) {
+		printed_something = 1;
+		seq_printf(m, "%s,", use->source->name);
+	}
+
+	if (mod->init && !mod->exit) {
+		printed_something = 1;
+		seq_puts(m, "[permanent],");
+	}
+
+	if (!printed_something)
+		seq_puts(m, "-");
+}
+#else /* !CONFIG_MODULE_UNLOAD */
+static inline void print_unload_info(struct seq_file *m, struct module *mod)
+{
+	/* We don't know the usage count, or what modules are using. */
+	seq_puts(m, " - -");
+}
+#endif /* CONFIG_MODULE_UNLOAD */
+
+/* Called by the /proc file system to return a list of modules. */
+static void *m_start(struct seq_file *m, loff_t *pos)
+{
+	mutex_lock(&module_mutex);
+	return seq_list_start(&modules, *pos);
+}
+
+static void *m_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	return seq_list_next(p, &modules, pos);
+}
+
+static void m_stop(struct seq_file *m, void *p)
+{
+	mutex_unlock(&module_mutex);
+}
+
+static int m_show(struct seq_file *m, void *p)
+{
+	struct module *mod = list_entry(p, struct module, list);
+	char buf[MODULE_FLAGS_BUF_SIZE];
+	void *value;
+
+	/* We always ignore unformed modules. */
+	if (mod->state == MODULE_STATE_UNFORMED)
+		return 0;
+
+	seq_printf(m, "%s %u",
+		   mod->name, mod->init_layout.size + mod->core_layout.size);
+	print_unload_info(m, mod);
+
+	/* Informative for users. */
+	seq_printf(m, " %s",
+		   mod->state == MODULE_STATE_GOING ? "Unloading" :
+		   mod->state == MODULE_STATE_COMING ? "Loading" :
+		   "Live");
+	/* Used by oprofile and other similar tools. */
+	value = m->private ? NULL : mod->core_layout.base;
+	seq_printf(m, " 0x%px", value);
+
+	/* Taints info */
+	if (mod->taints)
+		seq_printf(m, " %s", module_flags(mod, buf));
+
+	seq_puts(m, "\n");
+	return 0;
+}
+
+/*
+ * Format: modulename size refcount deps address
+ *
+ * Where refcount is a number or -, and deps is a comma-separated list
+ * of depends or -.
+ */
+static const struct seq_operations modules_op = {
+	.start	= m_start,
+	.next	= m_next,
+	.stop	= m_stop,
+	.show	= m_show
+};
+
+/*
+ * This also sets the "private" pointer to non-NULL if the
+ * kernel pointers should be hidden (so you can just test
+ * "m->private" to see if you should keep the values private).
+ *
+ * We use the same logic as for /proc/kallsyms.
+ */
+static int modules_open(struct inode *inode, struct file *file)
+{
+	int err = seq_open(file, &modules_op);
+
+	if (!err) {
+		struct seq_file *m = file->private_data;
+
+		m->private = kallsyms_show_value(file->f_cred) ? NULL : (void *)8ul;
+	}
+
+	return err;
+}
+
+static const struct proc_ops modules_proc_ops = {
+	.proc_flags	= PROC_ENTRY_PERMANENT,
+	.proc_open	= modules_open,
+	.proc_read	= seq_read,
+	.proc_lseek	= seq_lseek,
+	.proc_release	= seq_release,
+};
+
+static int __init proc_modules_init(void)
+{
+	proc_create("modules", 0, NULL, &modules_proc_ops);
+	return 0;
+}
+module_init(proc_modules_init);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 12/14] module: Move sysfs support into a separate file
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (10 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 11/14] module: Move procfs support into a separate file Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-02-28 23:43 ` [PATCH v9 13/14] module: Move kdb_modules list out of core code Aaron Tomlin
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch migrates module sysfs support out of core code into
kernel/module/sysfs.c. In addition simple code refactoring to
make this possible.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/Makefile   |   1 +
 kernel/module/internal.h |  21 ++
 kernel/module/main.c     | 469 +--------------------------------------
 kernel/module/sysfs.c    | 436 ++++++++++++++++++++++++++++++++++++
 4 files changed, 461 insertions(+), 466 deletions(-)
 create mode 100644 kernel/module/sysfs.c

diff --git a/kernel/module/Makefile b/kernel/module/Makefile
index 94296c98a67f..cf8dcdc6b55f 100644
--- a/kernel/module/Makefile
+++ b/kernel/module/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_STRICT_MODULE_RWX) += strict_rwx.o
 obj-$(CONFIG_DEBUG_KMEMLEAK) += debug_kmemleak.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_PROC_FS) += procfs.o
+obj-$(CONFIG_SYSFS) += sysfs.o
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index 6af40c2d145f..62d749ef695e 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -34,6 +34,9 @@
 extern struct mutex module_mutex;
 extern struct list_head modules;
 
+extern struct module_attribute *modinfo_attrs[];
+extern size_t modinfo_attrs_count;
+
 /* Provided by the linker */
 extern const struct kernel_symbol __start___ksymtab[];
 extern const struct kernel_symbol __stop___ksymtab[];
@@ -204,3 +207,21 @@ static inline void init_build_id(struct module *mod, const struct load_info *inf
 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) { }
 #endif /* CONFIG_KALLSYMS */
+
+#ifdef CONFIG_SYSFS
+int mod_sysfs_setup(struct module *mod, const struct load_info *info,
+		    struct kernel_param *kparam, unsigned int num_params);
+void mod_sysfs_teardown(struct module *mod);
+void init_param_lock(struct module *mod);
+#else /* !CONFIG_SYSFS */
+static inline int mod_sysfs_setup(struct module *mod,
+			   	  const struct load_info *info,
+			   	  struct kernel_param *kparam,
+			   	  unsigned int num_params)
+{
+	return 0;
+}
+
+static inline void mod_sysfs_teardown(struct module *mod) { }
+static inline void init_param_lock(struct module *mod) { }
+#endif /* CONFIG_SYSFS */
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 44b6fd1acc44..b8a59b5c3e3a 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -14,9 +14,7 @@
 #include <linux/init.h>
 #include <linux/kallsyms.h>
 #include <linux/buildid.h>
-#include <linux/file.h>
 #include <linux/fs.h>
-#include <linux/sysfs.h>
 #include <linux/kernel.h>
 #include <linux/kernel_read_file.h>
 #include <linux/slab.h>
@@ -989,7 +987,7 @@ static ssize_t show_taint(struct module_attribute *mattr,
 static struct module_attribute modinfo_taint =
 	__ATTR(taint, 0444, show_taint, NULL);
 
-static struct module_attribute *modinfo_attrs[] = {
+struct module_attribute *modinfo_attrs[] = {
 	&module_uevent,
 	&modinfo_version,
 	&modinfo_srcversion,
@@ -1003,6 +1001,8 @@ static struct module_attribute *modinfo_attrs[] = {
 	NULL,
 };
 
+size_t modinfo_attrs_count = ARRAY_SIZE(modinfo_attrs);
+
 static const char vermagic[] = VERMAGIC_STRING;
 
 static int try_to_force_load(struct module *mod, const char *reason)
@@ -1253,469 +1253,6 @@ resolve_symbol_wait(struct module *mod,
 	return ksym;
 }
 
-/*
- * /sys/module/foo/sections stuff
- * J. Corbet <corbet@lwn.net>
- */
-#ifdef CONFIG_SYSFS
-
-#ifdef CONFIG_KALLSYMS
-struct module_sect_attr {
-	struct bin_attribute battr;
-	unsigned long address;
-};
-
-struct module_sect_attrs {
-	struct attribute_group grp;
-	unsigned int nsections;
-	struct module_sect_attr attrs[];
-};
-
-#define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4))
-static ssize_t module_sect_read(struct file *file, struct kobject *kobj,
-				struct bin_attribute *battr,
-				char *buf, loff_t pos, size_t count)
-{
-	struct module_sect_attr *sattr =
-		container_of(battr, struct module_sect_attr, battr);
-	char bounce[MODULE_SECT_READ_SIZE + 1];
-	size_t wrote;
-
-	if (pos != 0)
-		return -EINVAL;
-
-	/*
-	 * Since we're a binary read handler, we must account for the
-	 * trailing NUL byte that sprintf will write: if "buf" is
-	 * too small to hold the NUL, or the NUL is exactly the last
-	 * byte, the read will look like it got truncated by one byte.
-	 * Since there is no way to ask sprintf nicely to not write
-	 * the NUL, we have to use a bounce buffer.
-	 */
-	wrote = scnprintf(bounce, sizeof(bounce), "0x%px\n",
-			 kallsyms_show_value(file->f_cred)
-				? (void *)sattr->address : NULL);
-	count = min(count, wrote);
-	memcpy(buf, bounce, count);
-
-	return count;
-}
-
-static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
-{
-	unsigned int section;
-
-	for (section = 0; section < sect_attrs->nsections; section++)
-		kfree(sect_attrs->attrs[section].battr.attr.name);
-	kfree(sect_attrs);
-}
-
-static void add_sect_attrs(struct module *mod, const struct load_info *info)
-{
-	unsigned int nloaded = 0, i, size[2];
-	struct module_sect_attrs *sect_attrs;
-	struct module_sect_attr *sattr;
-	struct bin_attribute **gattr;
-
-	/* Count loaded sections and allocate structures */
-	for (i = 0; i < info->hdr->e_shnum; i++)
-		if (!sect_empty(&info->sechdrs[i]))
-			nloaded++;
-	size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
-			sizeof(sect_attrs->grp.bin_attrs[0]));
-	size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
-	sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
-	if (sect_attrs == NULL)
-		return;
-
-	/* Setup section attributes. */
-	sect_attrs->grp.name = "sections";
-	sect_attrs->grp.bin_attrs = (void *)sect_attrs + size[0];
-
-	sect_attrs->nsections = 0;
-	sattr = &sect_attrs->attrs[0];
-	gattr = &sect_attrs->grp.bin_attrs[0];
-	for (i = 0; i < info->hdr->e_shnum; i++) {
-		Elf_Shdr *sec = &info->sechdrs[i];
-		if (sect_empty(sec))
-			continue;
-		sysfs_bin_attr_init(&sattr->battr);
-		sattr->address = sec->sh_addr;
-		sattr->battr.attr.name =
-			kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
-		if (sattr->battr.attr.name == NULL)
-			goto out;
-		sect_attrs->nsections++;
-		sattr->battr.read = module_sect_read;
-		sattr->battr.size = MODULE_SECT_READ_SIZE;
-		sattr->battr.attr.mode = 0400;
-		*(gattr++) = &(sattr++)->battr;
-	}
-	*gattr = NULL;
-
-	if (sysfs_create_group(&mod->mkobj.kobj, &sect_attrs->grp))
-		goto out;
-
-	mod->sect_attrs = sect_attrs;
-	return;
-  out:
-	free_sect_attrs(sect_attrs);
-}
-
-static void remove_sect_attrs(struct module *mod)
-{
-	if (mod->sect_attrs) {
-		sysfs_remove_group(&mod->mkobj.kobj,
-				   &mod->sect_attrs->grp);
-		/*
-		 * We are positive that no one is using any sect attrs
-		 * at this point.  Deallocate immediately.
-		 */
-		free_sect_attrs(mod->sect_attrs);
-		mod->sect_attrs = NULL;
-	}
-}
-
-/*
- * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections.
- */
-
-struct module_notes_attrs {
-	struct kobject *dir;
-	unsigned int notes;
-	struct bin_attribute attrs[];
-};
-
-static ssize_t module_notes_read(struct file *filp, struct kobject *kobj,
-				 struct bin_attribute *bin_attr,
-				 char *buf, loff_t pos, size_t count)
-{
-	/*
-	 * The caller checked the pos and count against our size.
-	 */
-	memcpy(buf, bin_attr->private + pos, count);
-	return count;
-}
-
-static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
-			     unsigned int i)
-{
-	if (notes_attrs->dir) {
-		while (i-- > 0)
-			sysfs_remove_bin_file(notes_attrs->dir,
-					      &notes_attrs->attrs[i]);
-		kobject_put(notes_attrs->dir);
-	}
-	kfree(notes_attrs);
-}
-
-static void add_notes_attrs(struct module *mod, const struct load_info *info)
-{
-	unsigned int notes, loaded, i;
-	struct module_notes_attrs *notes_attrs;
-	struct bin_attribute *nattr;
-
-	/* failed to create section attributes, so can't create notes */
-	if (!mod->sect_attrs)
-		return;
-
-	/* Count notes sections and allocate structures.  */
-	notes = 0;
-	for (i = 0; i < info->hdr->e_shnum; i++)
-		if (!sect_empty(&info->sechdrs[i]) &&
-		    (info->sechdrs[i].sh_type == SHT_NOTE))
-			++notes;
-
-	if (notes == 0)
-		return;
-
-	notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes),
-			      GFP_KERNEL);
-	if (notes_attrs == NULL)
-		return;
-
-	notes_attrs->notes = notes;
-	nattr = &notes_attrs->attrs[0];
-	for (loaded = i = 0; i < info->hdr->e_shnum; ++i) {
-		if (sect_empty(&info->sechdrs[i]))
-			continue;
-		if (info->sechdrs[i].sh_type == SHT_NOTE) {
-			sysfs_bin_attr_init(nattr);
-			nattr->attr.name = mod->sect_attrs->attrs[loaded].battr.attr.name;
-			nattr->attr.mode = S_IRUGO;
-			nattr->size = info->sechdrs[i].sh_size;
-			nattr->private = (void *) info->sechdrs[i].sh_addr;
-			nattr->read = module_notes_read;
-			++nattr;
-		}
-		++loaded;
-	}
-
-	notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj);
-	if (!notes_attrs->dir)
-		goto out;
-
-	for (i = 0; i < notes; ++i)
-		if (sysfs_create_bin_file(notes_attrs->dir,
-					  &notes_attrs->attrs[i]))
-			goto out;
-
-	mod->notes_attrs = notes_attrs;
-	return;
-
-  out:
-	free_notes_attrs(notes_attrs, i);
-}
-
-static void remove_notes_attrs(struct module *mod)
-{
-	if (mod->notes_attrs)
-		free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes);
-}
-
-#else
-
-static inline void add_sect_attrs(struct module *mod,
-				  const struct load_info *info)
-{
-}
-
-static inline void remove_sect_attrs(struct module *mod)
-{
-}
-
-static inline void add_notes_attrs(struct module *mod,
-				   const struct load_info *info)
-{
-}
-
-static inline void remove_notes_attrs(struct module *mod)
-{
-}
-#endif /* CONFIG_KALLSYMS */
-
-static void del_usage_links(struct module *mod)
-{
-#ifdef CONFIG_MODULE_UNLOAD
-	struct module_use *use;
-
-	mutex_lock(&module_mutex);
-	list_for_each_entry(use, &mod->target_list, target_list)
-		sysfs_remove_link(use->target->holders_dir, mod->name);
-	mutex_unlock(&module_mutex);
-#endif
-}
-
-static int add_usage_links(struct module *mod)
-{
-	int ret = 0;
-#ifdef CONFIG_MODULE_UNLOAD
-	struct module_use *use;
-
-	mutex_lock(&module_mutex);
-	list_for_each_entry(use, &mod->target_list, target_list) {
-		ret = sysfs_create_link(use->target->holders_dir,
-					&mod->mkobj.kobj, mod->name);
-		if (ret)
-			break;
-	}
-	mutex_unlock(&module_mutex);
-	if (ret)
-		del_usage_links(mod);
-#endif
-	return ret;
-}
-
-static void module_remove_modinfo_attrs(struct module *mod, int end);
-
-static int module_add_modinfo_attrs(struct module *mod)
-{
-	struct module_attribute *attr;
-	struct module_attribute *temp_attr;
-	int error = 0;
-	int i;
-
-	mod->modinfo_attrs = kzalloc((sizeof(struct module_attribute) *
-					(ARRAY_SIZE(modinfo_attrs) + 1)),
-					GFP_KERNEL);
-	if (!mod->modinfo_attrs)
-		return -ENOMEM;
-
-	temp_attr = mod->modinfo_attrs;
-	for (i = 0; (attr = modinfo_attrs[i]); i++) {
-		if (!attr->test || attr->test(mod)) {
-			memcpy(temp_attr, attr, sizeof(*temp_attr));
-			sysfs_attr_init(&temp_attr->attr);
-			error = sysfs_create_file(&mod->mkobj.kobj,
-					&temp_attr->attr);
-			if (error)
-				goto error_out;
-			++temp_attr;
-		}
-	}
-
-	return 0;
-
-error_out:
-	if (i > 0)
-		module_remove_modinfo_attrs(mod, --i);
-	else
-		kfree(mod->modinfo_attrs);
-	return error;
-}
-
-static void module_remove_modinfo_attrs(struct module *mod, int end)
-{
-	struct module_attribute *attr;
-	int i;
-
-	for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) {
-		if (end >= 0 && i > end)
-			break;
-		/* pick a field to test for end of list */
-		if (!attr->attr.name)
-			break;
-		sysfs_remove_file(&mod->mkobj.kobj, &attr->attr);
-		if (attr->free)
-			attr->free(mod);
-	}
-	kfree(mod->modinfo_attrs);
-}
-
-static void mod_kobject_put(struct module *mod)
-{
-	DECLARE_COMPLETION_ONSTACK(c);
-	mod->mkobj.kobj_completion = &c;
-	kobject_put(&mod->mkobj.kobj);
-	wait_for_completion(&c);
-}
-
-static int mod_sysfs_init(struct module *mod)
-{
-	int err;
-	struct kobject *kobj;
-
-	if (!module_sysfs_initialized) {
-		pr_err("%s: module sysfs not initialized\n", mod->name);
-		err = -EINVAL;
-		goto out;
-	}
-
-	kobj = kset_find_obj(module_kset, mod->name);
-	if (kobj) {
-		pr_err("%s: module is already loaded\n", mod->name);
-		kobject_put(kobj);
-		err = -EINVAL;
-		goto out;
-	}
-
-	mod->mkobj.mod = mod;
-
-	memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
-	mod->mkobj.kobj.kset = module_kset;
-	err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL,
-				   "%s", mod->name);
-	if (err)
-		mod_kobject_put(mod);
-
-out:
-	return err;
-}
-
-static int mod_sysfs_setup(struct module *mod,
-			   const struct load_info *info,
-			   struct kernel_param *kparam,
-			   unsigned int num_params)
-{
-	int err;
-
-	err = mod_sysfs_init(mod);
-	if (err)
-		goto out;
-
-	mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj);
-	if (!mod->holders_dir) {
-		err = -ENOMEM;
-		goto out_unreg;
-	}
-
-	err = module_param_sysfs_setup(mod, kparam, num_params);
-	if (err)
-		goto out_unreg_holders;
-
-	err = module_add_modinfo_attrs(mod);
-	if (err)
-		goto out_unreg_param;
-
-	err = add_usage_links(mod);
-	if (err)
-		goto out_unreg_modinfo_attrs;
-
-	add_sect_attrs(mod, info);
-	add_notes_attrs(mod, info);
-
-	return 0;
-
-out_unreg_modinfo_attrs:
-	module_remove_modinfo_attrs(mod, -1);
-out_unreg_param:
-	module_param_sysfs_remove(mod);
-out_unreg_holders:
-	kobject_put(mod->holders_dir);
-out_unreg:
-	mod_kobject_put(mod);
-out:
-	return err;
-}
-
-static void mod_sysfs_fini(struct module *mod)
-{
-	remove_notes_attrs(mod);
-	remove_sect_attrs(mod);
-	mod_kobject_put(mod);
-}
-
-static void init_param_lock(struct module *mod)
-{
-	mutex_init(&mod->param_lock);
-}
-#else /* !CONFIG_SYSFS */
-
-static int mod_sysfs_setup(struct module *mod,
-			   const struct load_info *info,
-			   struct kernel_param *kparam,
-			   unsigned int num_params)
-{
-	return 0;
-}
-
-static void mod_sysfs_fini(struct module *mod)
-{
-}
-
-static void module_remove_modinfo_attrs(struct module *mod, int end)
-{
-}
-
-static void del_usage_links(struct module *mod)
-{
-}
-
-static void init_param_lock(struct module *mod)
-{
-}
-#endif /* CONFIG_SYSFS */
-
-static void mod_sysfs_teardown(struct module *mod)
-{
-	del_usage_links(mod);
-	module_remove_modinfo_attrs(mod, -1);
-	module_param_sysfs_remove(mod);
-	kobject_put(mod->mkobj.drivers_dir);
-	kobject_put(mod->holders_dir);
-	mod_sysfs_fini(mod);
-}
-
 /*
  * LKM RO/NX protection: protect module's text/ro-data
  * from modification and any data from execution.
diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c
new file mode 100644
index 000000000000..ce68f821dcd1
--- /dev/null
+++ b/kernel/module/sysfs.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Module sysfs support
+ *
+ * Copyright (C) 2008 Rusty Russell
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/kallsyms.h>
+#include <linux/mutex.h>
+#include "internal.h"
+
+/*
+ * /sys/module/foo/sections stuff
+ * J. Corbet <corbet@lwn.net>
+ */
+#ifdef CONFIG_KALLSYMS
+struct module_sect_attr {
+	struct bin_attribute battr;
+	unsigned long address;
+};
+
+struct module_sect_attrs {
+	struct attribute_group grp;
+	unsigned int nsections;
+	struct module_sect_attr attrs[];
+};
+
+#define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4))
+static ssize_t module_sect_read(struct file *file, struct kobject *kobj,
+				struct bin_attribute *battr,
+				char *buf, loff_t pos, size_t count)
+{
+	struct module_sect_attr *sattr =
+		container_of(battr, struct module_sect_attr, battr);
+	char bounce[MODULE_SECT_READ_SIZE + 1];
+	size_t wrote;
+
+	if (pos != 0)
+		return -EINVAL;
+
+	/*
+	 * Since we're a binary read handler, we must account for the
+	 * trailing NUL byte that sprintf will write: if "buf" is
+	 * too small to hold the NUL, or the NUL is exactly the last
+	 * byte, the read will look like it got truncated by one byte.
+	 * Since there is no way to ask sprintf nicely to not write
+	 * the NUL, we have to use a bounce buffer.
+	 */
+	wrote = scnprintf(bounce, sizeof(bounce), "0x%px\n",
+			  kallsyms_show_value(file->f_cred)
+				? (void *)sattr->address : NULL);
+	count = min(count, wrote);
+	memcpy(buf, bounce, count);
+
+	return count;
+}
+
+static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
+{
+	unsigned int section;
+
+	for (section = 0; section < sect_attrs->nsections; section++)
+		kfree(sect_attrs->attrs[section].battr.attr.name);
+	kfree(sect_attrs);
+}
+
+static void add_sect_attrs(struct module *mod, const struct load_info *info)
+{
+	unsigned int nloaded = 0, i, size[2];
+	struct module_sect_attrs *sect_attrs;
+	struct module_sect_attr *sattr;
+	struct bin_attribute **gattr;
+
+	/* Count loaded sections and allocate structures */
+	for (i = 0; i < info->hdr->e_shnum; i++)
+		if (!sect_empty(&info->sechdrs[i]))
+			nloaded++;
+	size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
+			sizeof(sect_attrs->grp.bin_attrs[0]));
+	size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
+	sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
+	if (!sect_attrs)
+		return;
+
+	/* Setup section attributes. */
+	sect_attrs->grp.name = "sections";
+	sect_attrs->grp.bin_attrs = (void *)sect_attrs + size[0];
+
+	sect_attrs->nsections = 0;
+	sattr = &sect_attrs->attrs[0];
+	gattr = &sect_attrs->grp.bin_attrs[0];
+	for (i = 0; i < info->hdr->e_shnum; i++) {
+		Elf_Shdr *sec = &info->sechdrs[i];
+
+		if (sect_empty(sec))
+			continue;
+		sysfs_bin_attr_init(&sattr->battr);
+		sattr->address = sec->sh_addr;
+		sattr->battr.attr.name =
+			kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
+		if (!sattr->battr.attr.name)
+			goto out;
+		sect_attrs->nsections++;
+		sattr->battr.read = module_sect_read;
+		sattr->battr.size = MODULE_SECT_READ_SIZE;
+		sattr->battr.attr.mode = 0400;
+		*(gattr++) = &(sattr++)->battr;
+	}
+	*gattr = NULL;
+
+	if (sysfs_create_group(&mod->mkobj.kobj, &sect_attrs->grp))
+		goto out;
+
+	mod->sect_attrs = sect_attrs;
+	return;
+out:
+	free_sect_attrs(sect_attrs);
+}
+
+static void remove_sect_attrs(struct module *mod)
+{
+	if (mod->sect_attrs) {
+		sysfs_remove_group(&mod->mkobj.kobj,
+				   &mod->sect_attrs->grp);
+		/*
+		 * We are positive that no one is using any sect attrs
+		 * at this point.  Deallocate immediately.
+		 */
+		free_sect_attrs(mod->sect_attrs);
+		mod->sect_attrs = NULL;
+	}
+}
+
+/*
+ * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections.
+ */
+
+struct module_notes_attrs {
+	struct kobject *dir;
+	unsigned int notes;
+	struct bin_attribute attrs[];
+};
+
+static ssize_t module_notes_read(struct file *filp, struct kobject *kobj,
+				 struct bin_attribute *bin_attr,
+				 char *buf, loff_t pos, size_t count)
+{
+	/*
+	 * The caller checked the pos and count against our size.
+	 */
+	memcpy(buf, bin_attr->private + pos, count);
+	return count;
+}
+
+static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
+			     unsigned int i)
+{
+	if (notes_attrs->dir) {
+		while (i-- > 0)
+			sysfs_remove_bin_file(notes_attrs->dir,
+					      &notes_attrs->attrs[i]);
+		kobject_put(notes_attrs->dir);
+	}
+	kfree(notes_attrs);
+}
+
+static void add_notes_attrs(struct module *mod, const struct load_info *info)
+{
+	unsigned int notes, loaded, i;
+	struct module_notes_attrs *notes_attrs;
+	struct bin_attribute *nattr;
+
+	/* failed to create section attributes, so can't create notes */
+	if (!mod->sect_attrs)
+		return;
+
+	/* Count notes sections and allocate structures.  */
+	notes = 0;
+	for (i = 0; i < info->hdr->e_shnum; i++)
+		if (!sect_empty(&info->sechdrs[i]) &&
+		    info->sechdrs[i].sh_type == SHT_NOTE)
+			++notes;
+
+	if (notes == 0)
+		return;
+
+	notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes),
+			      GFP_KERNEL);
+	if (!notes_attrs)
+		return;
+
+	notes_attrs->notes = notes;
+	nattr = &notes_attrs->attrs[0];
+	for (loaded = i = 0; i < info->hdr->e_shnum; ++i) {
+		if (sect_empty(&info->sechdrs[i]))
+			continue;
+		if (info->sechdrs[i].sh_type == SHT_NOTE) {
+			sysfs_bin_attr_init(nattr);
+			nattr->attr.name = mod->sect_attrs->attrs[loaded].battr.attr.name;
+			nattr->attr.mode = 0444;
+			nattr->size = info->sechdrs[i].sh_size;
+			nattr->private = (void *)info->sechdrs[i].sh_addr;
+			nattr->read = module_notes_read;
+			++nattr;
+		}
+		++loaded;
+	}
+
+	notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj);
+	if (!notes_attrs->dir)
+		goto out;
+
+	for (i = 0; i < notes; ++i)
+		if (sysfs_create_bin_file(notes_attrs->dir,
+					  &notes_attrs->attrs[i]))
+			goto out;
+
+	mod->notes_attrs = notes_attrs;
+	return;
+
+out:
+	free_notes_attrs(notes_attrs, i);
+}
+
+static void remove_notes_attrs(struct module *mod)
+{
+	if (mod->notes_attrs)
+		free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes);
+}
+
+#else /* !CONFIG_KALLSYMS */
+static inline void add_sect_attrs(struct module *mod, const struct load_info *info) { }
+static inline void remove_sect_attrs(struct module *mod) { }
+static inline void add_notes_attrs(struct module *mod, const struct load_info *info) { }
+static inline void remove_notes_attrs(struct module *mod) { }
+#endif /* CONFIG_KALLSYMS */
+
+static void del_usage_links(struct module *mod)
+{
+#ifdef CONFIG_MODULE_UNLOAD
+	struct module_use *use;
+
+	mutex_lock(&module_mutex);
+	list_for_each_entry(use, &mod->target_list, target_list)
+		sysfs_remove_link(use->target->holders_dir, mod->name);
+	mutex_unlock(&module_mutex);
+#endif
+}
+
+static int add_usage_links(struct module *mod)
+{
+	int ret = 0;
+#ifdef CONFIG_MODULE_UNLOAD
+	struct module_use *use;
+
+	mutex_lock(&module_mutex);
+	list_for_each_entry(use, &mod->target_list, target_list) {
+		ret = sysfs_create_link(use->target->holders_dir,
+					&mod->mkobj.kobj, mod->name);
+		if (ret)
+			break;
+	}
+	mutex_unlock(&module_mutex);
+	if (ret)
+		del_usage_links(mod);
+#endif
+	return ret;
+}
+
+static void module_remove_modinfo_attrs(struct module *mod, int end)
+{
+	struct module_attribute *attr;
+	int i;
+
+	for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) {
+		if (end >= 0 && i > end)
+			break;
+		/* pick a field to test for end of list */
+		if (!attr->attr.name)
+			break;
+		sysfs_remove_file(&mod->mkobj.kobj, &attr->attr);
+		if (attr->free)
+			attr->free(mod);
+	}
+	kfree(mod->modinfo_attrs);
+}
+
+static int module_add_modinfo_attrs(struct module *mod)
+{
+	struct module_attribute *attr;
+	struct module_attribute *temp_attr;
+	int error = 0;
+	int i;
+
+	mod->modinfo_attrs = kzalloc((sizeof(struct module_attribute) *
+					(modinfo_attrs_count + 1)),
+					GFP_KERNEL);
+	if (!mod->modinfo_attrs)
+		return -ENOMEM;
+
+	temp_attr = mod->modinfo_attrs;
+	for (i = 0; (attr = modinfo_attrs[i]); i++) {
+		if (!attr->test || attr->test(mod)) {
+			memcpy(temp_attr, attr, sizeof(*temp_attr));
+			sysfs_attr_init(&temp_attr->attr);
+			error = sysfs_create_file(&mod->mkobj.kobj,
+						  &temp_attr->attr);
+			if (error)
+				goto error_out;
+			++temp_attr;
+		}
+	}
+
+	return 0;
+
+error_out:
+	if (i > 0)
+		module_remove_modinfo_attrs(mod, --i);
+	else
+		kfree(mod->modinfo_attrs);
+	return error;
+}
+
+static void mod_kobject_put(struct module *mod)
+{
+	DECLARE_COMPLETION_ONSTACK(c);
+
+	mod->mkobj.kobj_completion = &c;
+	kobject_put(&mod->mkobj.kobj);
+	wait_for_completion(&c);
+}
+
+static int mod_sysfs_init(struct module *mod)
+{
+	int err;
+	struct kobject *kobj;
+
+	if (!module_sysfs_initialized) {
+		pr_err("%s: module sysfs not initialized\n", mod->name);
+		err = -EINVAL;
+		goto out;
+	}
+
+	kobj = kset_find_obj(module_kset, mod->name);
+	if (kobj) {
+		pr_err("%s: module is already loaded\n", mod->name);
+		kobject_put(kobj);
+		err = -EINVAL;
+		goto out;
+	}
+
+	mod->mkobj.mod = mod;
+
+	memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
+	mod->mkobj.kobj.kset = module_kset;
+	err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL,
+				   "%s", mod->name);
+	if (err)
+		mod_kobject_put(mod);
+
+out:
+	return err;
+}
+
+int mod_sysfs_setup(struct module *mod,
+		    const struct load_info *info,
+			   struct kernel_param *kparam,
+			   unsigned int num_params)
+{
+	int err;
+
+	err = mod_sysfs_init(mod);
+	if (err)
+		goto out;
+
+	mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj);
+	if (!mod->holders_dir) {
+		err = -ENOMEM;
+		goto out_unreg;
+	}
+
+	err = module_param_sysfs_setup(mod, kparam, num_params);
+	if (err)
+		goto out_unreg_holders;
+
+	err = module_add_modinfo_attrs(mod);
+	if (err)
+		goto out_unreg_param;
+
+	err = add_usage_links(mod);
+	if (err)
+		goto out_unreg_modinfo_attrs;
+
+	add_sect_attrs(mod, info);
+	add_notes_attrs(mod, info);
+
+	return 0;
+
+out_unreg_modinfo_attrs:
+	module_remove_modinfo_attrs(mod, -1);
+out_unreg_param:
+	module_param_sysfs_remove(mod);
+out_unreg_holders:
+	kobject_put(mod->holders_dir);
+out_unreg:
+	mod_kobject_put(mod);
+out:
+	return err;
+}
+
+static void mod_sysfs_fini(struct module *mod)
+{
+	remove_notes_attrs(mod);
+	remove_sect_attrs(mod);
+	mod_kobject_put(mod);
+}
+
+void mod_sysfs_teardown(struct module *mod)
+{
+	del_usage_links(mod);
+	module_remove_modinfo_attrs(mod, -1);
+	module_param_sysfs_remove(mod);
+	kobject_put(mod->mkobj.drivers_dir);
+	kobject_put(mod->holders_dir);
+	mod_sysfs_fini(mod);
+}
+
+void init_param_lock(struct module *mod)
+{
+	mutex_init(&mod->param_lock);
+}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (11 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 12/14] module: Move sysfs " Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-03-02 16:19   ` Daniel Thompson
  2022-02-28 23:43 ` [PATCH v9 14/14] module: Move version support into a separate file Aaron Tomlin
  2022-03-01  0:21 ` [PATCH v9 00/14] module: core code clean up Luis Chamberlain
  14 siblings, 1 reply; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch migrates kdb_modules list to core kdb code
since the list of added/or loaded modules is no longer
private.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/debug/kdb/kdb_main.c    | 5 +++++
 kernel/debug/kdb/kdb_private.h | 4 ----
 kernel/module/main.c           | 4 ----
 3 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 0852a537dad4..5369bf45c5d4 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -59,6 +59,11 @@ EXPORT_SYMBOL(kdb_grepping_flag);
 int kdb_grep_leading;
 int kdb_grep_trailing;
 
+#ifdef CONFIG_MODULES
+extern struct list_head modules;
+static struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
+#endif /* CONFIG_MODULES */
+
 /*
  * Kernel debugger state flags
  */
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h
index 0d2f9feea0a4..1f8c519a5f81 100644
--- a/kernel/debug/kdb/kdb_private.h
+++ b/kernel/debug/kdb/kdb_private.h
@@ -226,10 +226,6 @@ extern void kdb_kbd_cleanup_state(void);
 #define kdb_kbd_cleanup_state()
 #endif /* ! CONFIG_KDB_KEYBOARD */
 
-#ifdef CONFIG_MODULES
-extern struct list_head *kdb_modules;
-#endif /* CONFIG_MODULES */
-
 extern char kdb_prompt_str[];
 
 #define	KDB_WORD_SIZE	((int)sizeof(unsigned long))
diff --git a/kernel/module/main.c b/kernel/module/main.c
index b8a59b5c3e3a..bcc4f7a82649 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -108,10 +108,6 @@ static void mod_update_bounds(struct module *mod)
 		__mod_update_bounds(mod->init_layout.base, mod->init_layout.size);
 }
 
-#ifdef CONFIG_KGDB_KDB
-struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
-#endif /* CONFIG_KGDB_KDB */
-
 static void module_assert_mutex_or_preempt(void)
 {
 #ifdef CONFIG_LOCKDEP
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PATCH v9 14/14] module: Move version support into a separate file
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (12 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 13/14] module: Move kdb_modules list out of core code Aaron Tomlin
@ 2022-02-28 23:43 ` Aaron Tomlin
  2022-03-01  0:21 ` [PATCH v9 00/14] module: core code clean up Luis Chamberlain
  14 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-02-28 23:43 UTC (permalink / raw)
  To: mcgrof, christophe.leroy, pmladek
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson

No functional change.

This patch migrates module version support out of core code into
kernel/module/version.c. In addition simple code refactoring to
make this possible.

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
---
 kernel/module/Makefile   |   1 +
 kernel/module/internal.h |  48 ++++++++++++
 kernel/module/main.c     | 156 ++-------------------------------------
 kernel/module/version.c  | 109 +++++++++++++++++++++++++++
 4 files changed, 166 insertions(+), 148 deletions(-)
 create mode 100644 kernel/module/version.c

diff --git a/kernel/module/Makefile b/kernel/module/Makefile
index cf8dcdc6b55f..a46e6361017f 100644
--- a/kernel/module/Makefile
+++ b/kernel/module/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_DEBUG_KMEMLEAK) += debug_kmemleak.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_PROC_FS) += procfs.o
 obj-$(CONFIG_SYSFS) += sysfs.o
+obj-$(CONFIG_MODVERSIONS) += version.o
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index 62d749ef695e..3fc139d5074b 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -70,7 +70,27 @@ struct load_info {
 	} index;
 };
 
+enum mod_license {
+	NOT_GPL_ONLY,
+	GPL_ONLY,
+};
+
+struct find_symbol_arg {
+	/* Input */
+	const char *name;
+	bool gplok;
+	bool warn;
+
+	/* Output */
+	struct module *owner;
+	const s32 *crc;
+	const struct kernel_symbol *sym;
+	enum mod_license license;
+};
+
 int mod_verify_sig(const void *mod, struct load_info *info);
+int try_to_force_load(struct module *mod, const char *reason);
+bool find_symbol(struct find_symbol_arg *fsa);
 struct module *find_module_all(const char *name, size_t len, bool even_unformed);
 int cmp_name(const void *name, const void *sym);
 long module_get_offset(struct module *mod, unsigned int *size, Elf_Shdr *sechdr,
@@ -225,3 +245,31 @@ static inline int mod_sysfs_setup(struct module *mod,
 static inline void mod_sysfs_teardown(struct module *mod) { }
 static inline void init_param_lock(struct module *mod) { }
 #endif /* CONFIG_SYSFS */
+
+#ifdef CONFIG_MODVERSIONS
+int check_version(const struct load_info *info,
+		  const char *symname, struct module *mod, const s32 *crc);
+void module_layout(struct module *mod, struct modversion_info *ver, struct kernel_param *kp,
+		   struct kernel_symbol *ks, struct tracepoint * const *tp);
+int check_modstruct_version(const struct load_info *info, struct module *mod);
+int same_magic(const char *amagic, const char *bmagic, bool has_crcs);
+#else /* !CONFIG_MODVERSIONS */
+static inline int check_version(const struct load_info *info,
+				const char *symname,
+				struct module *mod,
+				const s32 *crc)
+{
+	return 1;
+}
+
+static inline int check_modstruct_version(const struct load_info *info,
+					  struct module *mod)
+{
+	return 1;
+}
+
+static inline int same_magic(const char *amagic, const char *bmagic, bool has_crcs)
+{
+	return strcmp(amagic, bmagic) == 0;
+}
+#endif /* CONFIG_MODVERSIONS */
diff --git a/kernel/module/main.c b/kernel/module/main.c
index bcc4f7a82649..0749afdc34b5 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -86,6 +86,12 @@ struct mod_tree_root mod_tree __cacheline_aligned = {
 static unsigned long module_addr_min = -1UL, module_addr_max;
 #endif /* CONFIG_MODULES_TREE_LOOKUP */
 
+struct symsearch {
+	const struct kernel_symbol *start, *stop;
+	const s32 *crcs;
+	enum mod_license license;
+};
+
 /*
  * Bounds of module text, for speeding up __module_address.
  * Protected by module_mutex.
@@ -244,28 +250,6 @@ static __maybe_unused void *any_section_objs(const struct load_info *info,
 #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
 #endif
 
-struct symsearch {
-	const struct kernel_symbol *start, *stop;
-	const s32 *crcs;
-	enum mod_license {
-		NOT_GPL_ONLY,
-		GPL_ONLY,
-	} license;
-};
-
-struct find_symbol_arg {
-	/* Input */
-	const char *name;
-	bool gplok;
-	bool warn;
-
-	/* Output */
-	struct module *owner;
-	const s32 *crc;
-	const struct kernel_symbol *sym;
-	enum mod_license license;
-};
-
 static bool check_exported_symbol(const struct symsearch *syms,
 				  struct module *owner,
 				  unsigned int symnum, void *data)
@@ -327,7 +311,7 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
  * Find an exported symbol and return it, along with, (optional) crc and
  * (optional) module which owns it.  Needs preempt disabled or module_mutex.
  */
-static bool find_symbol(struct find_symbol_arg *fsa)
+bool find_symbol(struct find_symbol_arg *fsa)
 {
 	static const struct symsearch arr[] = {
 		{ __start___ksymtab, __stop___ksymtab, __start___kcrctab,
@@ -1001,7 +985,7 @@ size_t modinfo_attrs_count = ARRAY_SIZE(modinfo_attrs);
 
 static const char vermagic[] = VERMAGIC_STRING;
 
-static int try_to_force_load(struct module *mod, const char *reason)
+int try_to_force_load(struct module *mod, const char *reason)
 {
 #ifdef CONFIG_MODULE_FORCE_LOAD
 	if (!test_taint(TAINT_FORCED_MODULE))
@@ -1013,115 +997,6 @@ static int try_to_force_load(struct module *mod, const char *reason)
 #endif
 }
 
-#ifdef CONFIG_MODVERSIONS
-
-static u32 resolve_rel_crc(const s32 *crc)
-{
-	return *(u32 *)((void *)crc + *crc);
-}
-
-static int check_version(const struct load_info *info,
-			 const char *symname,
-			 struct module *mod,
-			 const s32 *crc)
-{
-	Elf_Shdr *sechdrs = info->sechdrs;
-	unsigned int versindex = info->index.vers;
-	unsigned int i, num_versions;
-	struct modversion_info *versions;
-
-	/* Exporting module didn't supply crcs?  OK, we're already tainted. */
-	if (!crc)
-		return 1;
-
-	/* No versions at all?  modprobe --force does this. */
-	if (versindex == 0)
-		return try_to_force_load(mod, symname) == 0;
-
-	versions = (void *) sechdrs[versindex].sh_addr;
-	num_versions = sechdrs[versindex].sh_size
-		/ sizeof(struct modversion_info);
-
-	for (i = 0; i < num_versions; i++) {
-		u32 crcval;
-
-		if (strcmp(versions[i].name, symname) != 0)
-			continue;
-
-		if (IS_ENABLED(CONFIG_MODULE_REL_CRCS))
-			crcval = resolve_rel_crc(crc);
-		else
-			crcval = *crc;
-		if (versions[i].crc == crcval)
-			return 1;
-		pr_debug("Found checksum %X vs module %lX\n",
-			 crcval, versions[i].crc);
-		goto bad_version;
-	}
-
-	/* Broken toolchain. Warn once, then let it go.. */
-	pr_warn_once("%s: no symbol version for %s\n", info->name, symname);
-	return 1;
-
-bad_version:
-	pr_warn("%s: disagrees about version of symbol %s\n",
-	       info->name, symname);
-	return 0;
-}
-
-static inline int check_modstruct_version(const struct load_info *info,
-					  struct module *mod)
-{
-	struct find_symbol_arg fsa = {
-		.name	= "module_layout",
-		.gplok	= true,
-	};
-
-	/*
-	 * Since this should be found in kernel (which can't be removed), no
-	 * locking is necessary -- use preempt_disable() to placate lockdep.
-	 */
-	preempt_disable();
-	if (!find_symbol(&fsa)) {
-		preempt_enable();
-		BUG();
-	}
-	preempt_enable();
-	return check_version(info, "module_layout", mod, fsa.crc);
-}
-
-/* First part is kernel version, which we ignore if module has crcs. */
-static inline int same_magic(const char *amagic, const char *bmagic,
-			     bool has_crcs)
-{
-	if (has_crcs) {
-		amagic += strcspn(amagic, " ");
-		bmagic += strcspn(bmagic, " ");
-	}
-	return strcmp(amagic, bmagic) == 0;
-}
-#else
-static inline int check_version(const struct load_info *info,
-				const char *symname,
-				struct module *mod,
-				const s32 *crc)
-{
-	return 1;
-}
-
-static inline int check_modstruct_version(const struct load_info *info,
-					  struct module *mod)
-{
-	return 1;
-}
-
-static inline int same_magic(const char *amagic, const char *bmagic,
-			     bool has_crcs)
-{
-	return strcmp(amagic, bmagic) == 0;
-}
-#endif /* CONFIG_MODVERSIONS */
-
 static char *get_modinfo(const struct load_info *info, const char *tag);
 static char *get_next_modinfo(const struct load_info *info, const char *tag,
 			      char *prev);
@@ -3247,18 +3122,3 @@ void print_modules(void)
 		pr_cont(" [last unloaded: %s]", last_unloaded_module);
 	pr_cont("\n");
 }
-
-#ifdef CONFIG_MODVERSIONS
-/*
- * Generate the signature for all relevant module structures here.
- * If these change, we don't want to try to parse the module.
- */
-void module_layout(struct module *mod,
-		   struct modversion_info *ver,
-		   struct kernel_param *kp,
-		   struct kernel_symbol *ks,
-		   struct tracepoint * const *tp)
-{
-}
-EXPORT_SYMBOL(module_layout);
-#endif
diff --git a/kernel/module/version.c b/kernel/module/version.c
new file mode 100644
index 000000000000..adaedce1dc97
--- /dev/null
+++ b/kernel/module/version.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Module version support
+ *
+ * Copyright (C) 2008 Rusty Russell
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/printk.h>
+#include "internal.h"
+
+static u32 resolve_rel_crc(const s32 *crc)
+{
+	return *(u32 *)((void *)crc + *crc);
+}
+
+int check_version(const struct load_info *info,
+		  const char *symname,
+			 struct module *mod,
+			 const s32 *crc)
+{
+	Elf_Shdr *sechdrs = info->sechdrs;
+	unsigned int versindex = info->index.vers;
+	unsigned int i, num_versions;
+	struct modversion_info *versions;
+
+	/* Exporting module didn't supply crcs?  OK, we're already tainted. */
+	if (!crc)
+		return 1;
+
+	/* No versions at all?  modprobe --force does this. */
+	if (versindex == 0)
+		return try_to_force_load(mod, symname) == 0;
+
+	versions = (void *)sechdrs[versindex].sh_addr;
+	num_versions = sechdrs[versindex].sh_size
+		/ sizeof(struct modversion_info);
+
+	for (i = 0; i < num_versions; i++) {
+		u32 crcval;
+
+		if (strcmp(versions[i].name, symname) != 0)
+			continue;
+
+		if (IS_ENABLED(CONFIG_MODULE_REL_CRCS))
+			crcval = resolve_rel_crc(crc);
+		else
+			crcval = *crc;
+		if (versions[i].crc == crcval)
+			return 1;
+		pr_debug("Found checksum %X vs module %lX\n",
+			 crcval, versions[i].crc);
+		goto bad_version;
+	}
+
+	/* Broken toolchain. Warn once, then let it go.. */
+	pr_warn_once("%s: no symbol version for %s\n", info->name, symname);
+	return 1;
+
+bad_version:
+	pr_warn("%s: disagrees about version of symbol %s\n", info->name, symname);
+	return 0;
+}
+
+int check_modstruct_version(const struct load_info *info,
+			    struct module *mod)
+{
+	struct find_symbol_arg fsa = {
+		.name	= "module_layout",
+		.gplok	= true,
+	};
+
+	/*
+	 * Since this should be found in kernel (which can't be removed), no
+	 * locking is necessary -- use preempt_disable() to placate lockdep.
+	 */
+	preempt_disable();
+	if (!find_symbol(&fsa)) {
+		preempt_enable();
+		BUG();
+	}
+	preempt_enable();
+	return check_version(info, "module_layout", mod, fsa.crc);
+}
+
+/* First part is kernel version, which we ignore if module has crcs. */
+int same_magic(const char *amagic, const char *bmagic,
+	       bool has_crcs)
+{
+	if (has_crcs) {
+		amagic += strcspn(amagic, " ");
+		bmagic += strcspn(bmagic, " ");
+	}
+	return strcmp(amagic, bmagic) == 0;
+}
+
+/*
+ * Generate the signature for all relevant module structures here.
+ * If these change, we don't want to try to parse the module.
+ */
+void module_layout(struct module *mod,
+		   struct modversion_info *ver,
+		   struct kernel_param *kp,
+		   struct kernel_symbol *ks,
+		   struct tracepoint * const *tp)
+{
+}
+EXPORT_SYMBOL(module_layout);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 00/14] module: core code clean up
  2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
                   ` (13 preceding siblings ...)
  2022-02-28 23:43 ` [PATCH v9 14/14] module: Move version support into a separate file Aaron Tomlin
@ 2022-03-01  0:21 ` Luis Chamberlain
  2022-03-01  7:07   ` Christophe Leroy
  2022-03-01  7:44   ` Christophe Leroy
  14 siblings, 2 replies; 48+ messages in thread
From: Luis Chamberlain @ 2022-03-01  0:21 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: christophe.leroy, pmladek, cl, mbenes, akpm, jeyu, linux-kernel,
	linux-modules, void, atomlin, allen.lkml, joe, msuchanek,
	oleksandr, jason.wessel, daniel.thompson

On Mon, Feb 28, 2022 at 11:43:08PM +0000, Aaron Tomlin wrote:
> Hi Luis,
> 
> As per your suggestion [1], this is an attempt to refactor and split
> optional code out of core module support code into separate components.
> This version is based on Linus' commit 7993e65fdd0f ("Merge tag
> 'mtd/fixes-for-5.17-rc5' of
> git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux").
> 
> Petr,
> 
> I decided to use preempt_disable() instead to remain consistent with the
> rest of the file. Unfortunately, I did not make time to boot test etc.

Aaron, thanks so much for doing this!

Since no boot tests are performed yet, I just pushed this to modules-testing
for now, after we get some boot test results I'll push to modules-next.

We should run kmod tests as well.

  Luis

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 00/14] module: core code clean up
  2022-03-01  0:21 ` [PATCH v9 00/14] module: core code clean up Luis Chamberlain
@ 2022-03-01  7:07   ` Christophe Leroy
  2022-03-01 16:00     ` Luis Chamberlain
  2022-03-01  7:44   ` Christophe Leroy
  1 sibling, 1 reply; 48+ messages in thread
From: Christophe Leroy @ 2022-03-01  7:07 UTC (permalink / raw)
  To: Luis Chamberlain, Aaron Tomlin
  Cc: pmladek, cl, mbenes, akpm, jeyu, linux-kernel, linux-modules,
	void, atomlin, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel, daniel.thompson

Hi Luis,

Le 01/03/2022 à 01:21, Luis Chamberlain a écrit :
> On Mon, Feb 28, 2022 at 11:43:08PM +0000, Aaron Tomlin wrote:
>> Hi Luis,
>>
>> As per your suggestion [1], this is an attempt to refactor and split
>> optional code out of core module support code into separate components.
>> This version is based on Linus' commit 7993e65fdd0f ("Merge tag
>> 'mtd/fixes-for-5.17-rc5' of
>> git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux").
>>
>> Petr,
>>
>> I decided to use preempt_disable() instead to remain consistent with the
>> rest of the file. Unfortunately, I did not make time to boot test etc.
> 
> Aaron, thanks so much for doing this!
> 
> Since no boot tests are performed yet, I just pushed this to modules-testing
> for now, after we get some boot test results I'll push to modules-next.
> 
> We should run kmod tests as well.
> 


My Kconfig patch and my two series still cleanly apply on v9. I don't 
need to rebase/resend them.


boot test is OK for me with Aaron's v9.


Christophe

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 00/14] module: core code clean up
  2022-03-01  0:21 ` [PATCH v9 00/14] module: core code clean up Luis Chamberlain
  2022-03-01  7:07   ` Christophe Leroy
@ 2022-03-01  7:44   ` Christophe Leroy
  2022-03-01 16:01     ` Luis Chamberlain
  1 sibling, 1 reply; 48+ messages in thread
From: Christophe Leroy @ 2022-03-01  7:44 UTC (permalink / raw)
  To: Luis Chamberlain
  Cc: pmladek, cl, mbenes, akpm, jeyu, linux-kernel, linux-modules,
	void, atomlin, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel, daniel.thompson, Aaron Tomlin



Le 01/03/2022 à 01:21, Luis Chamberlain a écrit :
> 
> We should run kmod tests as well.
> 

I tried to build kmod tests, but I get a crazy result:


$ ./configure --host=ppc-linux --prefix=/usr/local

$ make

$ cd testsuite

$ make

$ file test-list
test-list: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 
(SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 
3.2.0, with debug_info, not stripped

$ file module-playground/mod-loop-a.ko
module-playground/mod-loop-a.ko: ELF 64-bit LSB relocatable, x86-64, 
version 1 (SYSV), 
BuildID[sha1]=d46956a4fd36d8d3467806c31831c81217a573f5, with debug_info, 
not stripped



How do I get it to crossbuild proper PowerPC module ?

Thanks
Christophe

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 00/14] module: core code clean up
  2022-03-01  7:07   ` Christophe Leroy
@ 2022-03-01 16:00     ` Luis Chamberlain
  0 siblings, 0 replies; 48+ messages in thread
From: Luis Chamberlain @ 2022-03-01 16:00 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Aaron Tomlin, pmladek, cl, mbenes, akpm, jeyu, linux-kernel,
	linux-modules, void, atomlin, allen.lkml, joe, msuchanek,
	oleksandr, jason.wessel, daniel.thompson

On Tue, Mar 01, 2022 at 07:07:30AM +0000, Christophe Leroy wrote:
> Hi Luis,
> 
> Le 01/03/2022 à 01:21, Luis Chamberlain a écrit :
> > On Mon, Feb 28, 2022 at 11:43:08PM +0000, Aaron Tomlin wrote:
> >> Hi Luis,
> >>
> >> As per your suggestion [1], this is an attempt to refactor and split
> >> optional code out of core module support code into separate components.
> >> This version is based on Linus' commit 7993e65fdd0f ("Merge tag
> >> 'mtd/fixes-for-5.17-rc5' of
> >> git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux").
> >>
> >> Petr,
> >>
> >> I decided to use preempt_disable() instead to remain consistent with the
> >> rest of the file. Unfortunately, I did not make time to boot test etc.
> > 
> > Aaron, thanks so much for doing this!
> > 
> > Since no boot tests are performed yet, I just pushed this to modules-testing
> > for now, after we get some boot test results I'll push to modules-next.
> > 
> > We should run kmod tests as well.
> > 
> 
> 
> My Kconfig patch and my two series still cleanly apply on v9. I don't 
> need to rebase/resend them.
> 
> 
> boot test is OK for me with Aaron's v9.

Great thanks yes, I intend on applying them as soon as I get some test
confirmations on modules-testing. It's all about testing now.

  Luis

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 00/14] module: core code clean up
  2022-03-01  7:44   ` Christophe Leroy
@ 2022-03-01 16:01     ` Luis Chamberlain
  2022-03-01 17:15       ` Lucas De Marchi
  0 siblings, 1 reply; 48+ messages in thread
From: Luis Chamberlain @ 2022-03-01 16:01 UTC (permalink / raw)
  To: Christophe Leroy, Lucas De Marchi, Lucas De Marchi
  Cc: pmladek, cl, mbenes, akpm, jeyu, linux-kernel, linux-modules,
	void, atomlin, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel, daniel.thompson, Aaron Tomlin

On Tue, Mar 01, 2022 at 07:44:26AM +0000, Christophe Leroy wrote:
> 
> 
> Le 01/03/2022 à 01:21, Luis Chamberlain a écrit :
> > 
> > We should run kmod tests as well.
> > 
> 
> I tried to build kmod tests, but I get a crazy result:
> 
> 
> $ ./configure --host=ppc-linux --prefix=/usr/local
> 
> $ make
> 
> $ cd testsuite
> 
> $ make
> 
> $ file test-list
> test-list: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 
> (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 
> 3.2.0, with debug_info, not stripped
> 
> $ file module-playground/mod-loop-a.ko
> module-playground/mod-loop-a.ko: ELF 64-bit LSB relocatable, x86-64, 
> version 1 (SYSV), 
> BuildID[sha1]=d46956a4fd36d8d3467806c31831c81217a573f5, with debug_info, 
> not stripped
> 
> 
> 
> How do I get it to crossbuild proper PowerPC module ?

Lucas?

  Luis

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 10/14] module: kallsyms: Fix suspicious rcu usage
  2022-02-28 23:43 ` [PATCH v9 10/14] module: kallsyms: Fix suspicious rcu usage Aaron Tomlin
@ 2022-03-01 16:52   ` Aaron Tomlin
  2022-03-02 17:02     ` Aaron Tomlin
  0 siblings, 1 reply; 48+ messages in thread
From: Aaron Tomlin @ 2022-03-01 16:52 UTC (permalink / raw)
  To: pmladek
  Cc: mcgrof, christophe.leroy, cl, mbenes, akpm, jeyu, linux-kernel,
	linux-modules, void, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel, daniel.thompson

On Mon 2022-02-28 23:43 +0000, Aaron Tomlin wrote:
> No functional change.
> 
> The purpose of this patch is to address the various Sparse warnings
> due to the incorrect dereference/or access of an __rcu pointer.
> 
> Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
> ---
>  kernel/module/kallsyms.c | 34 ++++++++++++++++++++++------------
>  1 file changed, 22 insertions(+), 12 deletions(-)

Petr,

Any concerns?

Unfortunately, I didn't make enough time to test.


Kind regards,

-- 
Aaron Tomlin

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 00/14] module: core code clean up
  2022-03-01 16:01     ` Luis Chamberlain
@ 2022-03-01 17:15       ` Lucas De Marchi
  2022-03-01 17:43         ` Christophe Leroy
  0 siblings, 1 reply; 48+ messages in thread
From: Lucas De Marchi @ 2022-03-01 17:15 UTC (permalink / raw)
  To: Luis Chamberlain
  Cc: Christophe Leroy, Lucas De Marchi, pmladek, cl, mbenes, akpm,
	jeyu, linux-kernel, linux-modules, void, atomlin, allen.lkml,
	joe, msuchanek, oleksandr, jason.wessel, daniel.thompson,
	Aaron Tomlin

On Tue, Mar 01, 2022 at 08:01:23AM -0800, Luis Chamberlain wrote:
>On Tue, Mar 01, 2022 at 07:44:26AM +0000, Christophe Leroy wrote:
>>
>>
>> Le 01/03/2022 à 01:21, Luis Chamberlain a écrit :
>> >
>> > We should run kmod tests as well.
>> >
>>
>> I tried to build kmod tests, but I get a crazy result:
>>
>>
>> $ ./configure --host=ppc-linux --prefix=/usr/local
>>
>> $ make
>>
>> $ cd testsuite
>>
>> $ make
>>
>> $ file test-list
>> test-list: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1
>> (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux
>> 3.2.0, with debug_info, not stripped
>>
>> $ file module-playground/mod-loop-a.ko
>> module-playground/mod-loop-a.ko: ELF 64-bit LSB relocatable, x86-64,
>> version 1 (SYSV),
>> BuildID[sha1]=d46956a4fd36d8d3467806c31831c81217a573f5, with debug_info,
>> not stripped
>>
>>
>>
>> How do I get it to crossbuild proper PowerPC module ?

do I understand correctly that you want to crossbuild kmod + kernel
modules to do your test? why?

If you really need it, then beware we just chainload the kernel build
for the out-of-tree modules when compiling the test modules. Something
like this should work:

	make V=1 KDIR=$HOME/p/gfx-internal/linux-arm64/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- check

But running the cross built binaries is probably not what you want?

Another thing is that unless you are patching kmod binaries or libkmod,
the testsuite won't test much. kmod's testsuite don't test anything on
the kernel side... the kernel part is mocked by the testsuite itself.
Adding proper integration with the kernel part is possible, but not
something ready.

Lucas De Marchi

>
>Lucas?
>
>  Luis

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 00/14] module: core code clean up
  2022-03-01 17:15       ` Lucas De Marchi
@ 2022-03-01 17:43         ` Christophe Leroy
  0 siblings, 0 replies; 48+ messages in thread
From: Christophe Leroy @ 2022-03-01 17:43 UTC (permalink / raw)
  To: Lucas De Marchi, Luis Chamberlain
  Cc: Lucas De Marchi, pmladek, cl, mbenes, akpm, jeyu, linux-kernel,
	linux-modules, void, atomlin, allen.lkml, joe, msuchanek,
	oleksandr, jason.wessel, daniel.thompson, Aaron Tomlin



Le 01/03/2022 à 18:15, Lucas De Marchi a écrit :
> On Tue, Mar 01, 2022 at 08:01:23AM -0800, Luis Chamberlain wrote:
>> On Tue, Mar 01, 2022 at 07:44:26AM +0000, Christophe Leroy wrote:
>>>
>>>
>>> Le 01/03/2022 à 01:21, Luis Chamberlain a écrit :
>>> >
>>> > We should run kmod tests as well.
>>> >
>>>
>>> I tried to build kmod tests, but I get a crazy result:
>>>
>>>
>>> $ ./configure --host=ppc-linux --prefix=/usr/local
>>>
>>> $ make
>>>
>>> $ cd testsuite
>>>
>>> $ make
>>>
>>> $ file test-list
>>> test-list: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1
>>> (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux
>>> 3.2.0, with debug_info, not stripped
>>>
>>> $ file module-playground/mod-loop-a.ko
>>> module-playground/mod-loop-a.ko: ELF 64-bit LSB relocatable, x86-64,
>>> version 1 (SYSV),
>>> BuildID[sha1]=d46956a4fd36d8d3467806c31831c81217a573f5, with debug_info,
>>> not stripped
>>>
>>>
>>>
>>> How do I get it to crossbuild proper PowerPC module ?
> 
> do I understand correctly that you want to crossbuild kmod + kernel
> modules to do your test? why?


Yes, I want to build the tests on my PC and run them on a powerpc board.

> 
> If you really need it, then beware we just chainload the kernel build
> for the out-of-tree modules when compiling the test modules. Something
> like this should work:
> 
>      make V=1 KDIR=$HOME/p/gfx-internal/linux-arm64/ ARCH=arm64 
> CROSS_COMPILE=aarch64-linux-gnu- check
> 
> But running the cross built binaries is probably not what you want?

I want to run them on the board.

> 
> Another thing is that unless you are patching kmod binaries or libkmod,
> the testsuite won't test much. kmod's testsuite don't test anything on
> the kernel side... the kernel part is mocked by the testsuite itself.
> Adding proper integration with the kernel part is possible, but not
> something ready.

Ah, I see.

I made non trivial modification on kernel modules handling (see series 
at 
https://patchwork.kernel.org/project/linux-modules/cover/cover.1645607143.git.christophe.leroy@csgroup.eu/) 
and Luis suggested to run kmod test suite to perform regression testing.

Christophe

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 07/14] module: Move extra signature support out of core code
  2022-02-28 23:43 ` [PATCH v9 07/14] module: Move extra signature support out of core code Aaron Tomlin
@ 2022-03-02  8:08   ` Christophe Leroy
  2022-03-02 13:33     ` Aaron Tomlin
  2022-03-05 20:37     ` Aaron Tomlin
  0 siblings, 2 replies; 48+ messages in thread
From: Christophe Leroy @ 2022-03-02  8:08 UTC (permalink / raw)
  To: Aaron Tomlin, mcgrof
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson, pmladek



Le 01/03/2022 à 00:43, Aaron Tomlin a écrit :
> No functional change.
> 
> This patch migrates additional module signature check
> code from core module code into kernel/module/signing.c.
> 
> Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
> ---
>   kernel/module/internal.h |  9 +++++
>   kernel/module/main.c     | 87 ----------------------------------------
>   kernel/module/signing.c  | 77 +++++++++++++++++++++++++++++++++++
>   3 files changed, 86 insertions(+), 87 deletions(-)
> 

> diff --git a/kernel/module/signing.c b/kernel/module/signing.c
> index 8aeb6d2ee94b..85c8999dfecf 100644
> --- a/kernel/module/signing.c
> +++ b/kernel/module/signing.c
> @@ -11,9 +11,29 @@
>   #include <linux/module_signature.h>
>   #include <linux/string.h>
>   #include <linux/verification.h>
> +#include <linux/security.h>
>   #include <crypto/public_key.h>
> +#include <uapi/linux/module.h>
>   #include "internal.h"
>   
> +static bool sig_enforce = IS_ENABLED(CONFIG_MODULE_SIG_FORCE);
> +module_param(sig_enforce, bool_enable_only, 0644);
> +
> +/*
> + * Export sig_enforce kernel cmdline parameter to allow other subsystems rely
> + * on that instead of directly to CONFIG_MODULE_SIG_FORCE config.
> + */
> +bool is_module_sig_enforced(void)
> +{
> +	return sig_enforce;
> +}
> +EXPORT_SYMBOL(is_module_sig_enforced);

As reported by the test robot, that's not enough.

When it was in main.c, is_module_sig_enforced() was build as soon as 
CONFIG_MODULES was set.

Now it is only built when CONFIG_MODULE_SIG is selected, so you have to 
modify include/linux/modules.h and have the stub 
is_module_sig_enforced() when CONFIG_MODULE_SIG is not selected and not 
only when CONFIG_MODULES is not selected.


> +
> +void set_module_sig_enforced(void)
> +{
> +	sig_enforce = true;
> +}
> +
>   /*
>    * Verify the signature on a module.
>    */

Christophe

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 07/14] module: Move extra signature support out of core code
  2022-03-02  8:08   ` Christophe Leroy
@ 2022-03-02 13:33     ` Aaron Tomlin
  2022-03-02 13:41       ` Christophe Leroy
  2022-03-05 20:37     ` Aaron Tomlin
  1 sibling, 1 reply; 48+ messages in thread
From: Aaron Tomlin @ 2022-03-02 13:33 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: mcgrof, cl, mbenes, akpm, jeyu, linux-kernel, linux-modules,
	void, atomlin, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel, daniel.thompson, pmladek

On Wed 2022-03-02 08:08 +0000, Christophe Leroy wrote:
> > +bool is_module_sig_enforced(void)
> > +{
> > +	return sig_enforce;
> > +}
> > +EXPORT_SYMBOL(is_module_sig_enforced);
> 
> As reported by the test robot, that's not enough.

Hi Christophe,

Thanks for testing this.

> When it was in main.c, is_module_sig_enforced() was build as soon as 
> CONFIG_MODULES was set.
> Now it is only built when CONFIG_MODULE_SIG is selected,

Agreed.

> so you have to modify include/linux/modules.h and have the stub
> is_module_sig_enforced() when CONFIG_MODULE_SIG is not selected and not
> only when CONFIG_MODULES is not selected.

Sure: when Kconfig CONFIG_MODULE_SIG is not selected.

Luis,

I can see that the latest series is in mcgrof/modules-testing.
Should I address the above as a separate patch with "Fixes:" or
provide a whole new series, with the fix within the same patch?
In my opinion, another iteration would be cleaner.


Kind regards,

-- 
Aaron Tomlin


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 07/14] module: Move extra signature support out of core code
  2022-03-02 13:33     ` Aaron Tomlin
@ 2022-03-02 13:41       ` Christophe Leroy
  0 siblings, 0 replies; 48+ messages in thread
From: Christophe Leroy @ 2022-03-02 13:41 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: mcgrof, cl, mbenes, akpm, jeyu, linux-kernel, linux-modules,
	void, atomlin, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel, daniel.thompson, pmladek



Le 02/03/2022 à 14:33, Aaron Tomlin a écrit :
> On Wed 2022-03-02 08:08 +0000, Christophe Leroy wrote:
>>> +bool is_module_sig_enforced(void)
>>> +{
>>> +	return sig_enforce;
>>> +}
>>> +EXPORT_SYMBOL(is_module_sig_enforced);
>>
>> As reported by the test robot, that's not enough.
> 
> Hi Christophe,
> 
> Thanks for testing this.
> 
>> When it was in main.c, is_module_sig_enforced() was build as soon as
>> CONFIG_MODULES was set.
>> Now it is only built when CONFIG_MODULE_SIG is selected,
> 
> Agreed.
> 
>> so you have to modify include/linux/modules.h and have the stub
>> is_module_sig_enforced() when CONFIG_MODULE_SIG is not selected and not
>> only when CONFIG_MODULES is not selected.
> 
> Sure: when Kconfig CONFIG_MODULE_SIG is not selected.
> 
> Luis,
> 
> I can see that the latest series is in mcgrof/modules-testing.
> Should I address the above as a separate patch with "Fixes:" or
> provide a whole new series, with the fix within the same patch?
> In my opinion, another iteration would be cleaner.
> 
> 

On the powerpc list, usually for this kind of stuff, if the fixup 
doesn't impact the other commits of the series, we provide an 
incremental fixup and Michael squashes it in the faulty commit while 
rebasing.

That way you get the advantage of a new iteration without the disadvantages.

Up to Luis to tell what he prefers.

Christophe

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-02-28 23:43 ` [PATCH v9 13/14] module: Move kdb_modules list out of core code Aaron Tomlin
@ 2022-03-02 16:19   ` Daniel Thompson
  2022-03-02 16:26     ` Daniel Thompson
  2022-03-02 20:31     ` Aaron Tomlin
  0 siblings, 2 replies; 48+ messages in thread
From: Daniel Thompson @ 2022-03-02 16:19 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: mcgrof, christophe.leroy, pmladek, cl, mbenes, akpm, jeyu,
	linux-kernel, linux-modules, void, atomlin, allen.lkml, joe,
	msuchanek, oleksandr, jason.wessel

On Mon, Feb 28, 2022 at 11:43:21PM +0000, Aaron Tomlin wrote:
> No functional change.
> 
> This patch migrates kdb_modules list to core kdb code
> since the list of added/or loaded modules is no longer
> private.
> 
> Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
> ---
>  kernel/debug/kdb/kdb_main.c    | 5 +++++
>  kernel/debug/kdb/kdb_private.h | 4 ----
>  kernel/module/main.c           | 4 ----
>  3 files changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
> index 0852a537dad4..5369bf45c5d4 100644
> --- a/kernel/debug/kdb/kdb_main.c
> +++ b/kernel/debug/kdb/kdb_main.c
> @@ -59,6 +59,11 @@ EXPORT_SYMBOL(kdb_grepping_flag);
>  int kdb_grep_leading;
>  int kdb_grep_trailing;
>  
> +#ifdef CONFIG_MODULES
> +extern struct list_head modules;
> +static struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */

If modules is no longer static then why do we kdb_modules at all?
kdb_modules is used exactly once and it can now simply be replaced
with &modules.


Daniel.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-02 16:19   ` Daniel Thompson
@ 2022-03-02 16:26     ` Daniel Thompson
  2022-03-02 20:31     ` Aaron Tomlin
  1 sibling, 0 replies; 48+ messages in thread
From: Daniel Thompson @ 2022-03-02 16:26 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: mcgrof, christophe.leroy, pmladek, cl, mbenes, akpm, jeyu,
	linux-kernel, linux-modules, void, atomlin, allen.lkml, joe,
	msuchanek, oleksandr, jason.wessel

On Wed, Mar 02, 2022 at 04:19:17PM +0000, Daniel Thompson wrote:
> On Mon, Feb 28, 2022 at 11:43:21PM +0000, Aaron Tomlin wrote:
> > No functional change.
> > 
> > This patch migrates kdb_modules list to core kdb code
> > since the list of added/or loaded modules is no longer
> > private.
> > 
> > Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> > Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
> > ---
> >  kernel/debug/kdb/kdb_main.c    | 5 +++++
> >  kernel/debug/kdb/kdb_private.h | 4 ----
> >  kernel/module/main.c           | 4 ----
> >  3 files changed, 5 insertions(+), 8 deletions(-)
> > 
> > diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
> > index 0852a537dad4..5369bf45c5d4 100644
> > --- a/kernel/debug/kdb/kdb_main.c
> > +++ b/kernel/debug/kdb/kdb_main.c
> > @@ -59,6 +59,11 @@ EXPORT_SYMBOL(kdb_grepping_flag);
> >  int kdb_grep_leading;
> >  int kdb_grep_trailing;
> >  
> > +#ifdef CONFIG_MODULES
> > +extern struct list_head modules;

Actually thinking a bit harder and trying
`git grep '#include .*[.][.]' kernel/` (which finds some prior art) I
wonder if we even want the extern or whether
`#include "../../module/internal.h"` would be more robust.


Daniel.


> > +static struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
> 
> If modules is no longer static then why do we kdb_modules at all?
> kdb_modules is used exactly once and it can now simply be replaced
> with &modules.
> 
> 
> Daniel.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 10/14] module: kallsyms: Fix suspicious rcu usage
  2022-03-01 16:52   ` Aaron Tomlin
@ 2022-03-02 17:02     ` Aaron Tomlin
  2022-03-02 22:24       ` Luis Chamberlain
  0 siblings, 1 reply; 48+ messages in thread
From: Aaron Tomlin @ 2022-03-02 17:02 UTC (permalink / raw)
  To: pmladek
  Cc: mcgrof, christophe.leroy, cl, mbenes, akpm, jeyu, linux-kernel,
	linux-modules, void, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel, daniel.thompson, atomlin

On Tue 2022-03-01 16:52 +0000, Aaron Tomlin wrote:
> Petr,
> 
> Any concerns?
> 
> Unfortunately, I didn't make enough time to test.

Petr,

$ sudo ./test-livepatch.sh
[sudo] password for atomlin:
TEST: basic function patching ... ok
TEST: multiple livepatches ... ok
TEST: atomic replace livepatch ... ok

 - dmesg output excerpt

[  209.354909] ===== TEST: basic function patching =====
[  209.435376] % modprobe test_klp_livepatch
[  209.467226] test_klp_livepatch: tainting kernel with TAINT_LIVEPATCH
[  209.539749] livepatch: enabling patch 'test_klp_livepatch'
[  209.539785] livepatch: 'test_klp_livepatch': initializing patching transition
[  209.543671] livepatch: 'test_klp_livepatch': starting patching transition
[  210.716486] livepatch: 'test_klp_livepatch': completing patching transition
[  210.717405] livepatch: 'test_klp_livepatch': patching complete
[  210.766777] % echo 0 > /sys/kernel/livepatch/test_klp_livepatch/enabled
[  210.767446] livepatch: 'test_klp_livepatch': initializing unpatching transition
[  210.767548] livepatch: 'test_klp_livepatch': starting unpatching transition
[  211.739802] livepatch: 'test_klp_livepatch': completing unpatching transition
[  211.778846] livepatch: 'test_klp_livepatch': unpatching complete
[  211.862102] % rmmod test_klp_livepatch


Kind regards,

-- 
Aaron Tomlin


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-02 16:19   ` Daniel Thompson
  2022-03-02 16:26     ` Daniel Thompson
@ 2022-03-02 20:31     ` Aaron Tomlin
  2022-03-02 20:56       ` Christophe Leroy
  2022-03-03 12:55       ` Daniel Thompson
  1 sibling, 2 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-03-02 20:31 UTC (permalink / raw)
  To: Daniel Thompson
  Cc: mcgrof, christophe.leroy, pmladek, cl, mbenes, akpm, jeyu,
	linux-kernel, linux-modules, void, atomlin, allen.lkml, joe,
	msuchanek, oleksandr, jason.wessel

On Wed 2022-03-02 16:19 +0000, Daniel Thompson wrote:
> On Mon, Feb 28, 2022 at 11:43:21PM +0000, Aaron Tomlin wrote:
> > No functional change.
> > 
> > This patch migrates kdb_modules list to core kdb code
> > since the list of added/or loaded modules is no longer
> > private.
> > 
> > Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> > Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
> > ---
> >  kernel/debug/kdb/kdb_main.c    | 5 +++++
> >  kernel/debug/kdb/kdb_private.h | 4 ----
> >  kernel/module/main.c           | 4 ----
> >  3 files changed, 5 insertions(+), 8 deletions(-)
> > 
> > diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
> > index 0852a537dad4..5369bf45c5d4 100644
> > --- a/kernel/debug/kdb/kdb_main.c
> > +++ b/kernel/debug/kdb/kdb_main.c
> > @@ -59,6 +59,11 @@ EXPORT_SYMBOL(kdb_grepping_flag);
> >  int kdb_grep_leading;
> >  int kdb_grep_trailing;
> >  
> > +#ifdef CONFIG_MODULES
> > +extern struct list_head modules;
> > +static struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */

Hi Daniel,

> If modules is no longer static then why do we kdb_modules at all?
> kdb_modules is used exactly once and it can now simply be replaced
> with &modules.

In my opinion, I would prefer to avoid an explicit include of "internal.h"
in kernel/module. By definition it should be reserved for internal use to
kernel/module only. Please keep to the above logic.

Christophe, Luis,

Thoughts?


Kind regards,

-- 
Aaron Tomlin


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-02 20:31     ` Aaron Tomlin
@ 2022-03-02 20:56       ` Christophe Leroy
  2022-03-02 22:46         ` Luis Chamberlain
  2022-03-03 13:37         ` Christoph Hellwig
  2022-03-03 12:55       ` Daniel Thompson
  1 sibling, 2 replies; 48+ messages in thread
From: Christophe Leroy @ 2022-03-02 20:56 UTC (permalink / raw)
  To: Aaron Tomlin, Daniel Thompson
  Cc: mcgrof, pmladek, cl, mbenes, akpm, jeyu, linux-kernel,
	linux-modules, void, atomlin, allen.lkml, joe, msuchanek,
	oleksandr, jason.wessel



Le 02/03/2022 à 21:31, Aaron Tomlin a écrit :
> On Wed 2022-03-02 16:19 +0000, Daniel Thompson wrote:
>> On Mon, Feb 28, 2022 at 11:43:21PM +0000, Aaron Tomlin wrote:
>>> No functional change.
>>>
>>> This patch migrates kdb_modules list to core kdb code
>>> since the list of added/or loaded modules is no longer
>>> private.
>>>
>>> Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>>> Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
>>> ---
>>>   kernel/debug/kdb/kdb_main.c    | 5 +++++
>>>   kernel/debug/kdb/kdb_private.h | 4 ----
>>>   kernel/module/main.c           | 4 ----
>>>   3 files changed, 5 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
>>> index 0852a537dad4..5369bf45c5d4 100644
>>> --- a/kernel/debug/kdb/kdb_main.c
>>> +++ b/kernel/debug/kdb/kdb_main.c
>>> @@ -59,6 +59,11 @@ EXPORT_SYMBOL(kdb_grepping_flag);
>>>   int kdb_grep_leading;
>>>   int kdb_grep_trailing;
>>>   
>>> +#ifdef CONFIG_MODULES
>>> +extern struct list_head modules;
>>> +static struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
> 
> Hi Daniel,
> 
>> If modules is no longer static then why do we kdb_modules at all?
>> kdb_modules is used exactly once and it can now simply be replaced
>> with &modules.
> 
> In my opinion, I would prefer to avoid an explicit include of "internal.h"
> in kernel/module. By definition it should be reserved for internal use to
> kernel/module only. Please keep to the above logic.
> 
> Christophe, Luis,
> 
> Thoughts?
> 

Do we really want to hide the 'struct list_head modules' from external 
world ?

Otherwise we could declare it in include/linux/module.h ?

Christophe

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 10/14] module: kallsyms: Fix suspicious rcu usage
  2022-03-02 17:02     ` Aaron Tomlin
@ 2022-03-02 22:24       ` Luis Chamberlain
  0 siblings, 0 replies; 48+ messages in thread
From: Luis Chamberlain @ 2022-03-02 22:24 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: pmladek, christophe.leroy, cl, mbenes, akpm, jeyu, linux-kernel,
	linux-modules, void, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel, daniel.thompson, atomlin

On Wed, Mar 02, 2022 at 05:02:02PM +0000, Aaron Tomlin wrote:
> On Tue 2022-03-01 16:52 +0000, Aaron Tomlin wrote:
> > Petr,
> > 
> > Any concerns?
> > 
> > Unfortunately, I didn't make enough time to test.
> 
> Petr,
> 
> $ sudo ./test-livepatch.sh
> [sudo] password for atomlin:
> TEST: basic function patching ... ok
> TEST: multiple livepatches ... ok
> TEST: atomic replace livepatch ... ok
> 
>  - dmesg output excerpt

Since you're going to send a v10 can you also add the livepatch
to MAINTAINERS? :) Likewise if you see other files which can use
help in maintenance review, let's go for that.

We're in no rush for the merge window as we'll be skiping the
next merge window. So all this just needs to be thought well
and tested well.

  Luis

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-02 20:56       ` Christophe Leroy
@ 2022-03-02 22:46         ` Luis Chamberlain
  2022-03-03 10:44           ` Aaron Tomlin
  2022-03-03 13:37         ` Christoph Hellwig
  1 sibling, 1 reply; 48+ messages in thread
From: Luis Chamberlain @ 2022-03-02 22:46 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Aaron Tomlin, Daniel Thompson, pmladek, cl, mbenes, akpm, jeyu,
	linux-kernel, linux-modules, void, atomlin, allen.lkml, joe,
	msuchanek, oleksandr, jason.wessel

On Wed, Mar 02, 2022 at 08:56:23PM +0000, Christophe Leroy wrote:
> 
> 
> Le 02/03/2022 à 21:31, Aaron Tomlin a écrit :
> > On Wed 2022-03-02 16:19 +0000, Daniel Thompson wrote:
> >> On Mon, Feb 28, 2022 at 11:43:21PM +0000, Aaron Tomlin wrote:
> >>> No functional change.
> >>>
> >>> This patch migrates kdb_modules list to core kdb code
> >>> since the list of added/or loaded modules is no longer
> >>> private.
> >>>
> >>> Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> >>> Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
> >>> ---
> >>>   kernel/debug/kdb/kdb_main.c    | 5 +++++
> >>>   kernel/debug/kdb/kdb_private.h | 4 ----
> >>>   kernel/module/main.c           | 4 ----
> >>>   3 files changed, 5 insertions(+), 8 deletions(-)
> >>>
> >>> diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
> >>> index 0852a537dad4..5369bf45c5d4 100644
> >>> --- a/kernel/debug/kdb/kdb_main.c
> >>> +++ b/kernel/debug/kdb/kdb_main.c
> >>> @@ -59,6 +59,11 @@ EXPORT_SYMBOL(kdb_grepping_flag);
> >>>   int kdb_grep_leading;
> >>>   int kdb_grep_trailing;
> >>>   
> >>> +#ifdef CONFIG_MODULES
> >>> +extern struct list_head modules;
> >>> +static struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
> > 
> > Hi Daniel,
> > 
> >> If modules is no longer static then why do we kdb_modules at all?
> >> kdb_modules is used exactly once and it can now simply be replaced
> >> with &modules.
> > 
> > In my opinion, I would prefer to avoid an explicit include of "internal.h"
> > in kernel/module. By definition it should be reserved for internal use to
> > kernel/module only. Please keep to the above logic.
> > 
> > Christophe, Luis,
> > 
> > Thoughts?
> > 
> 
> Do we really want to hide the 'struct list_head modules' from external 
> world ?

> Otherwise we could declare it in include/linux/module.h ?

Since we are doing this to help with the cleaning this crap up
the natural thing to do is have the code be a helper which only
built-in code can use, so writing a helper starting with
list_for_each_entry() which prints the modules out. I'm
surprised we have no other users of this. There is nothing
kdb specific about the functionality in that code. So it should
just be moved.

Exposing just the list_head was a bad idea to begin with. So
let's do away with that. This can be a preamble change to the
series.

  Luis

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-02 22:46         ` Luis Chamberlain
@ 2022-03-03 10:44           ` Aaron Tomlin
  2022-03-03 14:57             ` Luis Chamberlain
  0 siblings, 1 reply; 48+ messages in thread
From: Aaron Tomlin @ 2022-03-03 10:44 UTC (permalink / raw)
  To: Luis Chamberlain
  Cc: Christophe Leroy, Daniel Thompson, pmladek, cl, mbenes, akpm,
	jeyu, linux-kernel, linux-modules, void, atomlin, allen.lkml,
	joe, msuchanek, oleksandr, jason.wessel

On Wed 2022-03-02 14:46 -0800, Luis Chamberlain wrote:
> Since we are doing this to help with the cleaning this crap up
> the natural thing to do is have the code be a helper which only
> built-in code can use, so writing a helper starting with
> list_for_each_entry() which prints the modules out. I'm
> surprised we have no other users of this. There is nothing
> kdb specific about the functionality in that code. So it should
> just be moved.

Hi Luis,

Good point, albeit is it really worth it since the only external
user is kernel/debug/kdb/ code?


Kind regards,

-- 
Aaron Tomlin


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-02 20:31     ` Aaron Tomlin
  2022-03-02 20:56       ` Christophe Leroy
@ 2022-03-03 12:55       ` Daniel Thompson
  1 sibling, 0 replies; 48+ messages in thread
From: Daniel Thompson @ 2022-03-03 12:55 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: mcgrof, christophe.leroy, pmladek, cl, mbenes, akpm, jeyu,
	linux-kernel, linux-modules, void, atomlin, allen.lkml, joe,
	msuchanek, oleksandr, jason.wessel

On Wed, Mar 02, 2022 at 08:31:53PM +0000, Aaron Tomlin wrote:
> On Wed 2022-03-02 16:19 +0000, Daniel Thompson wrote:
> > On Mon, Feb 28, 2022 at 11:43:21PM +0000, Aaron Tomlin wrote:
> > > No functional change.
> > > 
> > > This patch migrates kdb_modules list to core kdb code
> > > since the list of added/or loaded modules is no longer
> > > private.
> > > 
> > > Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> > > Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
> > > ---
> > >  kernel/debug/kdb/kdb_main.c    | 5 +++++
> > >  kernel/debug/kdb/kdb_private.h | 4 ----
> > >  kernel/module/main.c           | 4 ----
> > >  3 files changed, 5 insertions(+), 8 deletions(-)
> > > 
> > > diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
> > > index 0852a537dad4..5369bf45c5d4 100644
> > > --- a/kernel/debug/kdb/kdb_main.c
> > > +++ b/kernel/debug/kdb/kdb_main.c
> > > @@ -59,6 +59,11 @@ EXPORT_SYMBOL(kdb_grepping_flag);
> > >  int kdb_grep_leading;
> > >  int kdb_grep_trailing;
> > >  
> > > +#ifdef CONFIG_MODULES
> > > +extern struct list_head modules;
> > > +static struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
> 
> Hi Daniel,
> 
> > If modules is no longer static then why do we kdb_modules at all?
> > kdb_modules is used exactly once and it can now simply be replaced
> > with &modules.
> 
> In my opinion, I would prefer to avoid an explicit include of "internal.h"
> in kernel/module. By definition it should be reserved for internal use to
> kernel/module only. Please keep to the above logic.

Are you sure you are replying the right e-mail here? The quoted text
doesn't propose what you are replying to (although my other e-mail did).

To be clear there are two bits of feedback here and I don't think
"please keep to the above logic" is a sufficient answer.

If I remove the proposal on how to fix the second issue get get:

1. Remove kdb_modules because it is pointless (kdb_main.c can just use
   &modules directly lower down the file).
2. Having an extern in a kdb C file that duplicatively declares
   something from an alien header file is gross ;-) .


Daniel.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-02 20:56       ` Christophe Leroy
  2022-03-02 22:46         ` Luis Chamberlain
@ 2022-03-03 13:37         ` Christoph Hellwig
  2022-03-03 14:59           ` Daniel Thompson
  2022-03-04 11:12           ` Aaron Tomlin
  1 sibling, 2 replies; 48+ messages in thread
From: Christoph Hellwig @ 2022-03-03 13:37 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Aaron Tomlin, Daniel Thompson, mcgrof, pmladek, cl, mbenes, akpm,
	jeyu, linux-kernel, linux-modules, void, atomlin, allen.lkml,
	joe, msuchanek, oleksandr, jason.wessel

On Wed, Mar 02, 2022 at 08:56:23PM +0000, Christophe Leroy wrote:
> Do we really want to hide the 'struct list_head modules' from external 
> world ?
> 
> Otherwise we could declare it in include/linux/module.h ?

I'd just move the trivial code that uses it from kernel/kdb/ to
kernel/module/ as it is tied to module internals and just uses the
KDB interfaces exposed to other parts of the kernel.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-03 10:44           ` Aaron Tomlin
@ 2022-03-03 14:57             ` Luis Chamberlain
  0 siblings, 0 replies; 48+ messages in thread
From: Luis Chamberlain @ 2022-03-03 14:57 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: Christophe Leroy, Daniel Thompson, pmladek, cl, mbenes, akpm,
	jeyu, linux-kernel, linux-modules, void, atomlin, allen.lkml,
	joe, msuchanek, oleksandr, jason.wessel

On Thu, Mar 03, 2022 at 10:44:04AM +0000, Aaron Tomlin wrote:
> On Wed 2022-03-02 14:46 -0800, Luis Chamberlain wrote:
> > Since we are doing this to help with the cleaning this crap up
> > the natural thing to do is have the code be a helper which only
> > built-in code can use, so writing a helper starting with
> > list_for_each_entry() which prints the modules out. I'm
> > surprised we have no other users of this. There is nothing
> > kdb specific about the functionality in that code. So it should
> > just be moved.
> 
> Hi Luis,
> 
> Good point, albeit is it really worth it since the only external
> user is kernel/debug/kdb/ code?

Yes, no need to be exposing that list out anywhere else. And if the list
is needed better to have a helper for the users.

  Luis

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-03 13:37         ` Christoph Hellwig
@ 2022-03-03 14:59           ` Daniel Thompson
  2022-03-03 17:54             ` Christoph Hellwig
  2022-03-04 11:12           ` Aaron Tomlin
  1 sibling, 1 reply; 48+ messages in thread
From: Daniel Thompson @ 2022-03-03 14:59 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Christophe Leroy, Aaron Tomlin, mcgrof, pmladek, cl, mbenes,
	akpm, jeyu, linux-kernel, linux-modules, void, atomlin,
	allen.lkml, joe, msuchanek, oleksandr, jason.wessel

On Thu, Mar 03, 2022 at 05:37:29AM -0800, Christoph Hellwig wrote:
> On Wed, Mar 02, 2022 at 08:56:23PM +0000, Christophe Leroy wrote:
> > Do we really want to hide the 'struct list_head modules' from external 
> > world ?
> > 
> > Otherwise we could declare it in include/linux/module.h ?
> 
> I'd just move the trivial code that uses it from kernel/kdb/ to
> kernel/module/ as it is tied to module internals and just uses the
> KDB interfaces exposed to other parts of the kernel.

One of the best ways that we can common up code might be to dust
off some code I wrote a while back to display seq_files from
kdb.

The basic idea worked well enough but it often needs special
start/stop operatings to ensure the start meeds kdb's rather
odd locking restrictions. If there is a willingness for
something like the below to be included in the module code then we
could replace kdb_lsmod() with something that reused the code to
 format /proc/modules.


Daniel.


diff --git a/kernel/module.c b/kernel/module.c
index 84a9141a5e159..ab43ee23cdba0 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -4664,7 +4664,33 @@ static int __init proc_modules_init(void)
        return 0;
 }
 module_init(proc_modules_init);
-#endif
+
+#ifdef CONFIG_KGDB_KDB
+static void *kdb_m_start(struct seq_file *m, loff_t *pos)
+{
+       static LIST_HEAD(empty);
+       struct list_head *modlist = &modules;
+
+       if (mutex_is_locked(&module_mutex)) {
+               pr_info("Cannot display module list because it is
locked\n");
+               modlist = empty;
+       }
+
+       return seq_list_start(modlist, *pos);
+}
+
+const struct seq_operations kdb_modules_seqops = {
+       .start  = kdb_m_start,
+       .next   = m_next,
+       .show   = m_show
+};
+#endif /* CONFIG_KGDB_KDB */
+
+/*
+ * TODO: Need to decide if it OK to disable kdb lsmod if
+ * !CONFIG_PROC_FS... but it probably is!
+ */
+#endif /* CONFIG_PROC_FS */
 
 /* Given an address, look for it in the module exception tables. */
 const struct exception_table_entry *search_module_extables(unsigned
long addr)

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-03 14:59           ` Daniel Thompson
@ 2022-03-03 17:54             ` Christoph Hellwig
  2022-03-03 18:16               ` Christophe Leroy
  2022-03-03 19:21               ` Luis Chamberlain
  0 siblings, 2 replies; 48+ messages in thread
From: Christoph Hellwig @ 2022-03-03 17:54 UTC (permalink / raw)
  To: Daniel Thompson
  Cc: Christoph Hellwig, Christophe Leroy, Aaron Tomlin, mcgrof,
	pmladek, cl, mbenes, akpm, jeyu, linux-kernel, linux-modules,
	void, atomlin, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel

On Thu, Mar 03, 2022 at 02:59:49PM +0000, Daniel Thompson wrote:
> 
> One of the best ways that we can common up code might be to dust
> off some code I wrote a while back to display seq_files from
> kdb.
> 
> The basic idea worked well enough but it often needs special
> start/stop operatings to ensure the start meeds kdb's rather
> odd locking restrictions. If there is a willingness for
> something like the below to be included in the module code then we
> could replace kdb_lsmod() with something that reused the code to
>  format /proc/modules.

Displaying seq_files sounds nice to have, but in the short term I'm
just thinking of something like this:

diff --git a/include/linux/kdb.h b/include/linux/kdb.h
index ea0f5e580fac2..07dfb6a20a1c4 100644
--- a/include/linux/kdb.h
+++ b/include/linux/kdb.h
@@ -222,5 +222,6 @@ enum {
 
 extern int kdbgetintenv(const char *, int *);
 extern int kdb_set(int, const char **);
+int kdb_lsmod(int argc, const char **argv);
 
 #endif	/* !_KDB_H */
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 0852a537dad4c..292a407118a4f 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -2004,54 +2004,6 @@ static int kdb_ef(int argc, const char **argv)
 	return 0;
 }
 
-#if defined(CONFIG_MODULES)
-/*
- * kdb_lsmod - This function implements the 'lsmod' command.  Lists
- *	currently loaded kernel modules.
- *	Mostly taken from userland lsmod.
- */
-static int kdb_lsmod(int argc, const char **argv)
-{
-	struct module *mod;
-
-	if (argc != 0)
-		return KDB_ARGCOUNT;
-
-	kdb_printf("Module                  Size  modstruct     Used by\n");
-	list_for_each_entry(mod, kdb_modules, list) {
-		if (mod->state == MODULE_STATE_UNFORMED)
-			continue;
-
-		kdb_printf("%-20s%8u  0x%px ", mod->name,
-			   mod->core_layout.size, (void *)mod);
-#ifdef CONFIG_MODULE_UNLOAD
-		kdb_printf("%4d ", module_refcount(mod));
-#endif
-		if (mod->state == MODULE_STATE_GOING)
-			kdb_printf(" (Unloading)");
-		else if (mod->state == MODULE_STATE_COMING)
-			kdb_printf(" (Loading)");
-		else
-			kdb_printf(" (Live)");
-		kdb_printf(" 0x%px", mod->core_layout.base);
-
-#ifdef CONFIG_MODULE_UNLOAD
-		{
-			struct module_use *use;
-			kdb_printf(" [ ");
-			list_for_each_entry(use, &mod->source_list,
-					    source_list)
-				kdb_printf("%s ", use->target->name);
-			kdb_printf("]\n");
-		}
-#endif
-	}
-
-	return 0;
-}
-
-#endif	/* CONFIG_MODULES */
-
 /*
  * kdb_env - This function implements the 'env' command.  Display the
  *	current environment variables.
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h
index 0d2f9feea0a46..1f8c519a5f81c 100644
--- a/kernel/debug/kdb/kdb_private.h
+++ b/kernel/debug/kdb/kdb_private.h
@@ -226,10 +226,6 @@ extern void kdb_kbd_cleanup_state(void);
 #define kdb_kbd_cleanup_state()
 #endif /* ! CONFIG_KDB_KEYBOARD */
 
-#ifdef CONFIG_MODULES
-extern struct list_head *kdb_modules;
-#endif /* CONFIG_MODULES */
-
 extern char kdb_prompt_str[];
 
 #define	KDB_WORD_SIZE	((int)sizeof(unsigned long))
diff --git a/kernel/module.c b/kernel/module.c
index 6cea788fd965c..754ec20aab4f1 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -57,6 +57,7 @@
 #include <linux/bsearch.h>
 #include <linux/dynamic_debug.h>
 #include <linux/audit.h>
+#include <linux/kdb.h>
 #include <uapi/linux/module.h>
 #include "module-internal.h"
 
@@ -252,10 +253,6 @@ static void mod_update_bounds(struct module *mod)
 		__mod_update_bounds(mod->init_layout.base, mod->init_layout.size);
 }
 
-#ifdef CONFIG_KGDB_KDB
-struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
-#endif /* CONFIG_KGDB_KDB */
-
 static void module_assert_mutex_or_preempt(void)
 {
 #ifdef CONFIG_LOCKDEP
@@ -4808,3 +4805,45 @@ void module_layout(struct module *mod,
 }
 EXPORT_SYMBOL(module_layout);
 #endif
+
+#ifdef CONFIG_KGDB_KDB
+int kdb_lsmod(int argc, const char **argv)
+{
+	struct module *mod;
+
+	if (argc != 0)
+		return KDB_ARGCOUNT;
+
+	kdb_printf("Module                  Size  modstruct     Used by\n");
+	list_for_each_entry(mod, &modules, list) {
+		if (mod->state == MODULE_STATE_UNFORMED)
+			continue;
+
+		kdb_printf("%-20s%8u  0x%px ", mod->name,
+			   mod->core_layout.size, (void *)mod);
+#ifdef CONFIG_MODULE_UNLOAD
+		kdb_printf("%4d ", module_refcount(mod));
+#endif
+		if (mod->state == MODULE_STATE_GOING)
+			kdb_printf(" (Unloading)");
+		else if (mod->state == MODULE_STATE_COMING)
+			kdb_printf(" (Loading)");
+		else
+			kdb_printf(" (Live)");
+		kdb_printf(" 0x%px", mod->core_layout.base);
+
+#ifdef CONFIG_MODULE_UNLOAD
+		{
+			struct module_use *use;
+			kdb_printf(" [ ");
+			list_for_each_entry(use, &mod->source_list,
+					    source_list)
+				kdb_printf("%s ", use->target->name);
+			kdb_printf("]\n");
+		}
+#endif
+	}
+
+	return 0;
+}
+#endif	/* CONFIG_KGDB_KDB */

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-03 17:54             ` Christoph Hellwig
@ 2022-03-03 18:16               ` Christophe Leroy
  2022-03-03 19:00                 ` Christoph Hellwig
  2022-03-03 19:21               ` Luis Chamberlain
  1 sibling, 1 reply; 48+ messages in thread
From: Christophe Leroy @ 2022-03-03 18:16 UTC (permalink / raw)
  To: Christoph Hellwig, Daniel Thompson
  Cc: Aaron Tomlin, mcgrof, pmladek, cl, mbenes, akpm, jeyu,
	linux-kernel, linux-modules, void, atomlin, allen.lkml, joe,
	msuchanek, oleksandr, jason.wessel



Le 03/03/2022 à 18:54, Christoph Hellwig a écrit :
> On Thu, Mar 03, 2022 at 02:59:49PM +0000, Daniel Thompson wrote:
>>
>> One of the best ways that we can common up code might be to dust
>> off some code I wrote a while back to display seq_files from
>> kdb.
>>
>> The basic idea worked well enough but it often needs special
>> start/stop operatings to ensure the start meeds kdb's rather
>> odd locking restrictions. If there is a willingness for
>> something like the below to be included in the module code then we
>> could replace kdb_lsmod() with something that reused the code to
>>   format /proc/modules.
> 
> Displaying seq_files sounds nice to have, but in the short term I'm
> just thinking of something like this:

Well .... The idea at the first place was to get rid of the #ifdef 
CONFIG_KGDB_KDB in modules.

Here you propose it the other way round. Why not, in that case that 
would mean a dedicated file in kernel/module/ as part of the series 
https://patchwork.kernel.org/project/linux-modules/list/?series=618917&state=*

Christophe

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-03 18:16               ` Christophe Leroy
@ 2022-03-03 19:00                 ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2022-03-03 19:00 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Christoph Hellwig, Daniel Thompson, Aaron Tomlin, mcgrof,
	pmladek, cl, mbenes, akpm, jeyu, linux-kernel, linux-modules,
	void, atomlin, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel

On Thu, Mar 03, 2022 at 06:16:58PM +0000, Christophe Leroy wrote:
> Well .... The idea at the first place was to get rid of the #ifdef 
> CONFIG_KGDB_KDB in modules.
> 
> Here you propose it the other way round. Why not, in that case that 
> would mean a dedicated file in kernel/module/ as part of the series 
> https://patchwork.kernel.org/project/linux-modules/list/?series=618917&state=*

With the series you can of course move it to a new kernel/module/kdb.c.
But I don't have a tree with the series applied at hand and just want
to show how kdb_lsmod can live outside of kernel/debug easily.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-03 17:54             ` Christoph Hellwig
  2022-03-03 18:16               ` Christophe Leroy
@ 2022-03-03 19:21               ` Luis Chamberlain
  1 sibling, 0 replies; 48+ messages in thread
From: Luis Chamberlain @ 2022-03-03 19:21 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Daniel Thompson, Christophe Leroy, Aaron Tomlin, pmladek, cl,
	mbenes, akpm, jeyu, linux-kernel, linux-modules, void, atomlin,
	allen.lkml, joe, msuchanek, oleksandr, jason.wessel

On Thu, Mar 03, 2022 at 09:54:14AM -0800, Christoph Hellwig wrote:
> On Thu, Mar 03, 2022 at 02:59:49PM +0000, Daniel Thompson wrote:
> > 
> > One of the best ways that we can common up code might be to dust
> > off some code I wrote a while back to display seq_files from
> > kdb.
> > 
> > The basic idea worked well enough but it often needs special
> > start/stop operatings to ensure the start meeds kdb's rather
> > odd locking restrictions. If there is a willingness for
> > something like the below to be included in the module code then we
> > could replace kdb_lsmod() with something that reused the code to
> >  format /proc/modules.
> 
> Displaying seq_files sounds nice to have, but in the short term I'm
> just thinking of something like this:
> 
> diff --git a/include/linux/kdb.h b/include/linux/kdb.h
> index ea0f5e580fac2..07dfb6a20a1c4 100644
> --- a/include/linux/kdb.h
> +++ b/include/linux/kdb.h
> @@ -222,5 +222,6 @@ enum {
>  
>  extern int kdbgetintenv(const char *, int *);
>  extern int kdb_set(int, const char **);
> +int kdb_lsmod(int argc, const char **argv);

Yes exactly.

>  #endif	/* !_KDB_H */
> diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
> index 0852a537dad4c..292a407118a4f 100644
> --- a/kernel/debug/kdb/kdb_main.c
> +++ b/kernel/debug/kdb/kdb_main.c
> @@ -2004,54 +2004,6 @@ static int kdb_ef(int argc, const char **argv)
>  	return 0;
>  }
>  
> -#if defined(CONFIG_MODULES)
> -/*
> - * kdb_lsmod - This function implements the 'lsmod' command.  Lists
> - *	currently loaded kernel modules.
> - *	Mostly taken from userland lsmod.
> - */
> -static int kdb_lsmod(int argc, const char **argv)
> -{
> -	struct module *mod;
> -
> -	if (argc != 0)
> -		return KDB_ARGCOUNT;
> -
> -	kdb_printf("Module                  Size  modstruct     Used by\n");
> -	list_for_each_entry(mod, kdb_modules, list) {
> -		if (mod->state == MODULE_STATE_UNFORMED)
> -			continue;
> -
> -		kdb_printf("%-20s%8u  0x%px ", mod->name,
> -			   mod->core_layout.size, (void *)mod);
> -#ifdef CONFIG_MODULE_UNLOAD
> -		kdb_printf("%4d ", module_refcount(mod));
> -#endif
> -		if (mod->state == MODULE_STATE_GOING)
> -			kdb_printf(" (Unloading)");
> -		else if (mod->state == MODULE_STATE_COMING)
> -			kdb_printf(" (Loading)");
> -		else
> -			kdb_printf(" (Live)");
> -		kdb_printf(" 0x%px", mod->core_layout.base);
> -
> -#ifdef CONFIG_MODULE_UNLOAD
> -		{
> -			struct module_use *use;
> -			kdb_printf(" [ ");
> -			list_for_each_entry(use, &mod->source_list,
> -					    source_list)
> -				kdb_printf("%s ", use->target->name);
> -			kdb_printf("]\n");
> -		}
> -#endif
> -	}
> -
> -	return 0;
> -}
> -
> -#endif	/* CONFIG_MODULES */
> -
>  /*
>   * kdb_env - This function implements the 'env' command.  Display the
>   *	current environment variables.
> diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h
> index 0d2f9feea0a46..1f8c519a5f81c 100644
> --- a/kernel/debug/kdb/kdb_private.h
> +++ b/kernel/debug/kdb/kdb_private.h
> @@ -226,10 +226,6 @@ extern void kdb_kbd_cleanup_state(void);
>  #define kdb_kbd_cleanup_state()
>  #endif /* ! CONFIG_KDB_KEYBOARD */
>  
> -#ifdef CONFIG_MODULES
> -extern struct list_head *kdb_modules;
> -#endif /* CONFIG_MODULES */
> -
>  extern char kdb_prompt_str[];
>  
>  #define	KDB_WORD_SIZE	((int)sizeof(unsigned long))
> diff --git a/kernel/module.c b/kernel/module.c
> index 6cea788fd965c..754ec20aab4f1 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -57,6 +57,7 @@
>  #include <linux/bsearch.h>
>  #include <linux/dynamic_debug.h>
>  #include <linux/audit.h>
> +#include <linux/kdb.h>
>  #include <uapi/linux/module.h>
>  #include "module-internal.h"
>  
> @@ -252,10 +253,6 @@ static void mod_update_bounds(struct module *mod)
>  		__mod_update_bounds(mod->init_layout.base, mod->init_layout.size);
>  }
>  
> -#ifdef CONFIG_KGDB_KDB
> -struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
> -#endif /* CONFIG_KGDB_KDB */
> -
>  static void module_assert_mutex_or_preempt(void)
>  {
>  #ifdef CONFIG_LOCKDEP
> @@ -4808,3 +4805,45 @@ void module_layout(struct module *mod,
>  }
>  EXPORT_SYMBOL(module_layout);
>  #endif
> +
> +#ifdef CONFIG_KGDB_KDB

Yes! And then when we move all this crap to its own files on
kernel/module/Makefile:

obj-$(CONFIG_KGDB_KDB) += kdb.o

> +int kdb_lsmod(int argc, const char **argv)
> +{
> +	struct module *mod;
> +
> +	if (argc != 0)
> +		return KDB_ARGCOUNT;
> +
> +	kdb_printf("Module                  Size  modstruct     Used by\n");

Indeed, we need to do it this way because kdb_printf() which emits
messages directly to I/O drivers, bypassing the kernel log. Perhaps this
info should be added to the top of kernel/module/kdb.c

> +	list_for_each_entry(mod, &modules, list) {
> +		if (mod->state == MODULE_STATE_UNFORMED)
> +			continue;
> +
> +		kdb_printf("%-20s%8u  0x%px ", mod->name,
> +			   mod->core_layout.size, (void *)mod);
> +#ifdef CONFIG_MODULE_UNLOAD
> +		kdb_printf("%4d ", module_refcount(mod));
> +#endif

Yes and later this can be if IS_ENABLED(CONFIG_MODULE_UNLOAD)

> +		if (mod->state == MODULE_STATE_GOING)
> +			kdb_printf(" (Unloading)");
> +		else if (mod->state == MODULE_STATE_COMING)
> +			kdb_printf(" (Loading)");
> +		else
> +			kdb_printf(" (Live)");
> +		kdb_printf(" 0x%px", mod->core_layout.base);
> +
> +#ifdef CONFIG_MODULE_UNLOAD

and if IS_ENABLED(CONFIG_MODULE_UNLOAD) later

> +		{
> +			struct module_use *use;
> +			kdb_printf(" [ ");
> +			list_for_each_entry(use, &mod->source_list,
> +					    source_list)
> +				kdb_printf("%s ", use->target->name);
> +			kdb_printf("]\n");
> +		}
> +#endif
> +	}
> +
> +	return 0;
> +}
> +#endif	/* CONFIG_KGDB_KDB */

  Luis

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-03 13:37         ` Christoph Hellwig
  2022-03-03 14:59           ` Daniel Thompson
@ 2022-03-04 11:12           ` Aaron Tomlin
  2022-03-04 11:54             ` Daniel Thompson
  1 sibling, 1 reply; 48+ messages in thread
From: Aaron Tomlin @ 2022-03-04 11:12 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Christophe Leroy, Daniel Thompson, mcgrof, pmladek, cl, mbenes,
	akpm, jeyu, linux-kernel, linux-modules, void, atomlin,
	allen.lkml, joe, msuchanek, oleksandr, jason.wessel

On Thu 2022-03-03 05:37 -0800, Christoph Hellwig wrote:
> On Wed, Mar 02, 2022 at 08:56:23PM +0000, Christophe Leroy wrote:
> > Do we really want to hide the 'struct list_head modules' from external 
> > world ?
> > 
> > Otherwise we could declare it in include/linux/module.h ?
> I'd just move the trivial code that uses it from kernel/kdb/ to
> kernel/module/ as it is tied to module internals and just uses the
> KDB interfaces exposed to other parts of the kernel.

Hi Christoph,

This is a great idea. I'll do this instead.


Kind regards,

-- 
Aaron Tomlin


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-04 11:12           ` Aaron Tomlin
@ 2022-03-04 11:54             ` Daniel Thompson
  2022-03-04 11:59               ` Aaron Tomlin
  0 siblings, 1 reply; 48+ messages in thread
From: Daniel Thompson @ 2022-03-04 11:54 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: Christoph Hellwig, Christophe Leroy, mcgrof, pmladek, cl, mbenes,
	akpm, jeyu, linux-kernel, linux-modules, void, atomlin,
	allen.lkml, joe, msuchanek, oleksandr, jason.wessel

On Fri, Mar 04, 2022 at 11:12:07AM +0000, Aaron Tomlin wrote:
> On Thu 2022-03-03 05:37 -0800, Christoph Hellwig wrote:
> > On Wed, Mar 02, 2022 at 08:56:23PM +0000, Christophe Leroy wrote:
> > > Do we really want to hide the 'struct list_head modules' from external 
> > > world ?
> > > 
> > > Otherwise we could declare it in include/linux/module.h ?
> > I'd just move the trivial code that uses it from kernel/kdb/ to
> > kernel/module/ as it is tied to module internals and just uses the
> > KDB interfaces exposed to other parts of the kernel.
> 
> Hi Christoph,
> 
> This is a great idea. I'll do this instead.

Adding this as a new file is fine for me.

There were proposed changes to this function this kernel cycle
(CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC) which I Acked already.
However it looks like all involved with that are already particpating
in this thread so I assume an merge issues with that are already in
hand.

Aaron: Are you OK to add the new kdb file to the "KGDB / KDB
/debug_core" file list in MAINTAINERS? Mostly I'd expect to just
Ack changes and move on... but I'd like to be in the loop.


Daniel.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 13/14] module: Move kdb_modules list out of core code
  2022-03-04 11:54             ` Daniel Thompson
@ 2022-03-04 11:59               ` Aaron Tomlin
  0 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-03-04 11:59 UTC (permalink / raw)
  To: Daniel Thompson
  Cc: Christoph Hellwig, Christophe Leroy, mcgrof, pmladek, cl, mbenes,
	akpm, jeyu, linux-kernel, linux-modules, void, atomlin,
	allen.lkml, joe, msuchanek, oleksandr, jason.wessel

On Fri 2022-03-04 11:54 +0000, Daniel Thompson wrote:
> Aaron: Are you OK to add the new kdb file to the "KGDB / KDB
> /debug_core" file list in MAINTAINERS? Mostly I'd expect to just
> Ack changes and move on... but I'd like to be in the loop.

Hi Daniel,

Sure - no problem.


Kind regards,

-- 
Aaron Tomlin


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 07/14] module: Move extra signature support out of core code
  2022-03-02  8:08   ` Christophe Leroy
  2022-03-02 13:33     ` Aaron Tomlin
@ 2022-03-05 20:37     ` Aaron Tomlin
  2022-03-06 17:46       ` Christophe Leroy
  1 sibling, 1 reply; 48+ messages in thread
From: Aaron Tomlin @ 2022-03-05 20:37 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: mcgrof, cl, mbenes, akpm, jeyu, linux-kernel, linux-modules,
	void, atomlin, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel, daniel.thompson, pmladek

On Wed 2022-03-02 08:08 +0000, Christophe Leroy wrote:
> When it was in main.c, is_module_sig_enforced() was build as soon as 
> CONFIG_MODULES was set.
> 
> Now it is only built when CONFIG_MODULE_SIG is selected, so you have to 
> modify include/linux/modules.h and have the stub 
> is_module_sig_enforced() when CONFIG_MODULE_SIG is not selected and not 
> only when CONFIG_MODULES is not selected.

Hi Christophe,

Looking at this again, perhaps I'm missing something. If I understand
correctly, Kconfig CONFIG_MODULE_SIG cannot be selected without
CONFIG_MODULES; also CONFIG_MODULE_SIG depends on CONFIG_MODULES, no?
So, what is present is enough right i.e. the stub when CONFIG_MODULES is
not enabled?


Kind regards,

-- 
Aaron Tomlin


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 07/14] module: Move extra signature support out of core code
  2022-03-05 20:37     ` Aaron Tomlin
@ 2022-03-06 17:46       ` Christophe Leroy
  2022-03-07  9:38         ` Aaron Tomlin
  0 siblings, 1 reply; 48+ messages in thread
From: Christophe Leroy @ 2022-03-06 17:46 UTC (permalink / raw)
  To: Aaron Tomlin
  Cc: mcgrof, cl, mbenes, akpm, jeyu, linux-kernel, linux-modules,
	void, atomlin, allen.lkml, joe, msuchanek, oleksandr,
	jason.wessel, daniel.thompson, pmladek



Le 05/03/2022 à 21:37, Aaron Tomlin a écrit :
> On Wed 2022-03-02 08:08 +0000, Christophe Leroy wrote:
>> When it was in main.c, is_module_sig_enforced() was build as soon as
>> CONFIG_MODULES was set.
>>
>> Now it is only built when CONFIG_MODULE_SIG is selected, so you have to
>> modify include/linux/modules.h and have the stub
>> is_module_sig_enforced() when CONFIG_MODULE_SIG is not selected and not
>> only when CONFIG_MODULES is not selected.
> 
> Hi Christophe,
> 
> Looking at this again, perhaps I'm missing something. If I understand
> correctly, Kconfig CONFIG_MODULE_SIG cannot be selected without
> CONFIG_MODULES; also CONFIG_MODULE_SIG depends on CONFIG_MODULES, no?
> So, what is present is enough right i.e. the stub when CONFIG_MODULES is
> not enabled?
> 

There are three possibilities:
1/ CONFIG_MODULES=n, CONFIG_MODULE_SIG=n
2/ CONFIG_MODULES=y, CONFIG_MODULE_SIG=n
3/ CONFIG_MODULES=y, CONFIG_MODULE_SIG=y

Case 1/, is_module_sig_enforced() is a static inline stub in 
linux/modules.h returning always false

Case 3/, is_module_sig_enforced() is in kernel/module/signing.c

Case 2/, is_module_sig_enforced() is nowhere.

In linux/modules.h, you have:

#ifdef CONFIG_MODULES
....
a lot of stuff
...
bool is_module_sig_enforced(void);
void set_module_sig_enforced(void);

#else
....
a lot of stuff
...
static inline bool is_module_sig_enforced(void)
{
	return false;
}

static inline void set_module_sig_enforced(void)
{
}
...
some more stuff
#endif



You must take is_module_sig_enforced() out of that #ifdef CONFIG_MODULES 
/ #else / #endif and add after the #endif /* CONFIG_MODULES */:

#ifdef CONFIG_MODULE_SIG
bool is_module_sig_enforced(void);
#else
static inline bool is_module_sig_enforced(void)
{
	return false;
}
#endif

Christophe

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v9 07/14] module: Move extra signature support out of core code
  2022-03-06 17:46       ` Christophe Leroy
@ 2022-03-07  9:38         ` Aaron Tomlin
  0 siblings, 0 replies; 48+ messages in thread
From: Aaron Tomlin @ 2022-03-07  9:38 UTC (permalink / raw)
  To: christophe.leroy, mcgrof
  Cc: cl, mbenes, akpm, jeyu, linux-kernel, linux-modules, void,
	atomlin, allen.lkml, joe, msuchanek, oleksandr, jason.wessel,
	daniel.thompson, pmladek

On Sun 2022-03-06 17:46 +0000, Christophe Leroy wrote:
> 2/ CONFIG_MODULES=y, CONFIG_MODULE_SIG=n

Christophe,

I see, I did not notice that the above is even possible.

> Case 2/, is_module_sig_enforced() is nowhere.

Understood.


Luis,

I'll send a v10 later today.


Kind regards,

-- 
Aaron Tomlin


^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2022-03-07  9:42 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-28 23:43 [PATCH v9 00/14] module: core code clean up Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 01/14] module: Move all into module/ Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 02/14] module: Simple refactor in preparation for split Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 03/14] module: Make internal.h and decompress.c more compliant Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 04/14] module: Move livepatch support to a separate file Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 05/14] module: Move latched RB-tree " Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 06/14] module: Move strict rwx " Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 07/14] module: Move extra signature support out of core code Aaron Tomlin
2022-03-02  8:08   ` Christophe Leroy
2022-03-02 13:33     ` Aaron Tomlin
2022-03-02 13:41       ` Christophe Leroy
2022-03-05 20:37     ` Aaron Tomlin
2022-03-06 17:46       ` Christophe Leroy
2022-03-07  9:38         ` Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 08/14] module: Move kmemleak support to a separate file Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 09/14] module: Move kallsyms support into " Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 10/14] module: kallsyms: Fix suspicious rcu usage Aaron Tomlin
2022-03-01 16:52   ` Aaron Tomlin
2022-03-02 17:02     ` Aaron Tomlin
2022-03-02 22:24       ` Luis Chamberlain
2022-02-28 23:43 ` [PATCH v9 11/14] module: Move procfs support into a separate file Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 12/14] module: Move sysfs " Aaron Tomlin
2022-02-28 23:43 ` [PATCH v9 13/14] module: Move kdb_modules list out of core code Aaron Tomlin
2022-03-02 16:19   ` Daniel Thompson
2022-03-02 16:26     ` Daniel Thompson
2022-03-02 20:31     ` Aaron Tomlin
2022-03-02 20:56       ` Christophe Leroy
2022-03-02 22:46         ` Luis Chamberlain
2022-03-03 10:44           ` Aaron Tomlin
2022-03-03 14:57             ` Luis Chamberlain
2022-03-03 13:37         ` Christoph Hellwig
2022-03-03 14:59           ` Daniel Thompson
2022-03-03 17:54             ` Christoph Hellwig
2022-03-03 18:16               ` Christophe Leroy
2022-03-03 19:00                 ` Christoph Hellwig
2022-03-03 19:21               ` Luis Chamberlain
2022-03-04 11:12           ` Aaron Tomlin
2022-03-04 11:54             ` Daniel Thompson
2022-03-04 11:59               ` Aaron Tomlin
2022-03-03 12:55       ` Daniel Thompson
2022-02-28 23:43 ` [PATCH v9 14/14] module: Move version support into a separate file Aaron Tomlin
2022-03-01  0:21 ` [PATCH v9 00/14] module: core code clean up Luis Chamberlain
2022-03-01  7:07   ` Christophe Leroy
2022-03-01 16:00     ` Luis Chamberlain
2022-03-01  7:44   ` Christophe Leroy
2022-03-01 16:01     ` Luis Chamberlain
2022-03-01 17:15       ` Lucas De Marchi
2022-03-01 17:43         ` Christophe Leroy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.