module: Provide EXPORT_SYMBOL_GPL_FOR_MODULES() helper

[ Upstream commit 707f853d7fa3ce323a6875487890c213e34d81a0 ]

Helper macro to more easily limit the export of a symbol to a given
list of modules.

Eg:

  EXPORT_SYMBOL_GPL_FOR_MODULES(preempt_notifier_inc, "kvm");

will limit the use of said function to kvm.ko, any other module trying
to use this symbol will refure to load (and get modpost build
failures).

Requested-by: Masahiro Yamada <masahiroy@kernel.org>
Requested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Stable-dep-of: cbe4134ea4bc ("fs: export anon_inode_make_secure_inode() and fix secretmem LSM bypass")
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Peter Zijlstra
2025-05-02 16:12:09 +02:00
committed by Greg Kroah-Hartman
parent a6069306f4
commit adb29b437f
2 changed files with 32 additions and 2 deletions

View File

@@ -28,6 +28,9 @@ kernel. As of today, modules that make use of symbols exported into namespaces,
are required to import the namespace. Otherwise the kernel will, depending on are required to import the namespace. Otherwise the kernel will, depending on
its configuration, reject loading the module or warn about a missing import. its configuration, reject loading the module or warn about a missing import.
Additionally, it is possible to put symbols into a module namespace, strictly
limiting which modules are allowed to use these symbols.
2. How to define Symbol Namespaces 2. How to define Symbol Namespaces
================================== ==================================
@@ -84,6 +87,22 @@ unit as preprocessor statement. The above example would then read::
within the corresponding compilation unit before any EXPORT_SYMBOL macro is within the corresponding compilation unit before any EXPORT_SYMBOL macro is
used. used.
2.3 Using the EXPORT_SYMBOL_GPL_FOR_MODULES() macro
===================================================
Symbols exported using this macro are put into a module namespace. This
namespace cannot be imported.
The macro takes a comma separated list of module names, allowing only those
modules to access this symbol. Simple tail-globs are supported.
For example:
EXPORT_SYMBOL_GPL_FOR_MODULES(preempt_notifier_inc, "kvm,kvm-*")
will limit usage of this symbol to modules whoes name matches the given
patterns.
3. How to use Symbols exported in Namespaces 3. How to use Symbols exported in Namespaces
============================================ ============================================
@@ -155,3 +174,6 @@ in-tree modules::
You can also run nsdeps for external module builds. A typical usage is:: You can also run nsdeps for external module builds. A typical usage is::
$ make -C <path_to_kernel_src> M=$PWD nsdeps $ make -C <path_to_kernel_src> M=$PWD nsdeps
Note: it will happily generate an import statement for the module namespace;
which will not work and generates build and runtime failures.

View File

@@ -42,11 +42,17 @@ extern struct module __this_module;
.long sym .long sym
#endif #endif
#define ___EXPORT_SYMBOL(sym, license, ns) \ /*
* LLVM integrated assembler cam merge adjacent string literals (like
* C and GNU-as) passed to '.ascii', but not to '.asciz' and chokes on:
*
* .asciz "MODULE_" "kvm" ;
*/
#define ___EXPORT_SYMBOL(sym, license, ns...) \
.section ".export_symbol","a" ASM_NL \ .section ".export_symbol","a" ASM_NL \
__export_symbol_##sym: ASM_NL \ __export_symbol_##sym: ASM_NL \
.asciz license ASM_NL \ .asciz license ASM_NL \
.asciz ns ASM_NL \ .ascii ns "\0" ASM_NL \
__EXPORT_SYMBOL_REF(sym) ASM_NL \ __EXPORT_SYMBOL_REF(sym) ASM_NL \
.previous .previous
@@ -88,4 +94,6 @@ extern struct module __this_module;
#define EXPORT_SYMBOL_NS(sym, ns) __EXPORT_SYMBOL(sym, "", __stringify(ns)) #define EXPORT_SYMBOL_NS(sym, ns) __EXPORT_SYMBOL(sym, "", __stringify(ns))
#define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL(sym, "GPL", __stringify(ns)) #define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL(sym, "GPL", __stringify(ns))
#define EXPORT_SYMBOL_GPL_FOR_MODULES(sym, mods) __EXPORT_SYMBOL(sym, "GPL", "module:" mods)
#endif /* _LINUX_EXPORT_H */ #endif /* _LINUX_EXPORT_H */