[PATCH 1/2] module: Restrict module namespace access to in-tree modules

Vlastimil Babka posted 2 patches 3 months ago
[PATCH 1/2] module: Restrict module namespace access to in-tree modules
Posted by Vlastimil Babka 3 months ago
The module namespace support has been introduced to allow restricting
exports to specific modules only, and intended for in-tree modules such
as kvm. Make this intention explicit by disallowing out of tree modules
both for the module loader and modpost.

Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
---
 Documentation/core-api/symbol-namespaces.rst | 5 +++--
 kernel/module/main.c                         | 3 ++-
 scripts/mod/modpost.c                        | 6 +++++-
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/Documentation/core-api/symbol-namespaces.rst b/Documentation/core-api/symbol-namespaces.rst
index 32fc73dc5529e8844c2ce2580987155bcd13cd09..dc228ac738a5cdc49cc736c29170ca96df6a28dc 100644
--- a/Documentation/core-api/symbol-namespaces.rst
+++ b/Documentation/core-api/symbol-namespaces.rst
@@ -83,13 +83,14 @@ 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.
+modules to access this symbol. The access is restricted to in-tree modules.
+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
+will limit usage of this symbol to in-tree modules whoes name matches the given
 patterns.
 
 How to use Symbols exported in Namespaces
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 413ac6ea37021bc8ae260f624ca2745ed85333fc..ec7d8daa0347e3b65713396d6b6d14c2cb0270d3 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -1157,7 +1157,8 @@ static int verify_namespace_is_imported(const struct load_info *info,
 	namespace = kernel_symbol_namespace(sym);
 	if (namespace && namespace[0]) {
 
-		if (verify_module_namespace(namespace, mod->name))
+		if (get_modinfo(info, "intree") &&
+		    verify_module_namespace(namespace, mod->name))
 			return 0;
 
 		for_each_modinfo_entry(imported_namespace, info, "import_ns") {
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 5ca7c268294ebb65acb0ba52a671eddca9279c61..d78be9834ed75f4b6ddb9af02a300a9bcc9234cc 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1695,7 +1695,8 @@ void buf_write(struct buffer *buf, const char *s, int len)
  * @modname: module name
  *
  * If @namespace is prefixed with "module:" to indicate it is a module namespace
- * then test if @modname matches any of the comma separated patterns.
+ * then test if @modname matches any of the comma separated patterns. Access to
+ * module namespaces is restricted to in-tree modules only.
  *
  * The patterns only support tail-glob.
  */
@@ -1706,6 +1707,9 @@ static bool verify_module_namespace(const char *namespace, const char *modname)
 	const char *sep;
 	bool glob;
 
+	if (external_module)
+		return false;
+
 	if (!strstarts(namespace, prefix))
 		return false;
 

-- 
2.50.0
Re: [PATCH 1/2] module: Restrict module namespace access to in-tree modules
Posted by Nicolas Schier 3 months ago
On Tue, Jul 08, 2025 at 09:28:57AM +0200 Vlastimil Babka wrote:
> The module namespace support has been introduced to allow restricting
> exports to specific modules only, and intended for in-tree modules such
> as kvm. Make this intention explicit by disallowing out of tree modules
> both for the module loader and modpost.
> 
> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
> ---
>  Documentation/core-api/symbol-namespaces.rst | 5 +++--
>  kernel/module/main.c                         | 3 ++-
>  scripts/mod/modpost.c                        | 6 +++++-
>  3 files changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/core-api/symbol-namespaces.rst b/Documentation/core-api/symbol-namespaces.rst
> index 32fc73dc5529e8844c2ce2580987155bcd13cd09..dc228ac738a5cdc49cc736c29170ca96df6a28dc 100644
> --- a/Documentation/core-api/symbol-namespaces.rst
> +++ b/Documentation/core-api/symbol-namespaces.rst
> @@ -83,13 +83,14 @@ 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.
> +modules to access this symbol. The access is restricted to in-tree modules.
> +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
> +will limit usage of this symbol to in-tree modules whoes name matches the given

If you keep touching this line, might you fix the typo?

s/whoes/whose/

Kind regards,
Nicolas
Re: [PATCH 1/2] module: Restrict module namespace access to in-tree modules
Posted by Petr Pavlu 3 months ago
On 7/8/25 9:28 AM, Vlastimil Babka wrote:
> The module namespace support has been introduced to allow restricting
> exports to specific modules only, and intended for in-tree modules such
> as kvm. Make this intention explicit by disallowing out of tree modules
> both for the module loader and modpost.
> 
> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
> ---
> [...]
> diff --git a/kernel/module/main.c b/kernel/module/main.c
> index 413ac6ea37021bc8ae260f624ca2745ed85333fc..ec7d8daa0347e3b65713396d6b6d14c2cb0270d3 100644
> --- a/kernel/module/main.c
> +++ b/kernel/module/main.c
> @@ -1157,7 +1157,8 @@ static int verify_namespace_is_imported(const struct load_info *info,
>  	namespace = kernel_symbol_namespace(sym);
>  	if (namespace && namespace[0]) {
>  
> -		if (verify_module_namespace(namespace, mod->name))
> +		if (get_modinfo(info, "intree") &&
> +		    verify_module_namespace(namespace, mod->name))
>  			return 0;
>  
>  		for_each_modinfo_entry(imported_namespace, info, "import_ns") {

I'd rather avoid another walk of the modinfo data in
verify_namespace_is_imported(). I suggest checking whether mod->taints
has TAINT_OOT_MODULE set instead, which should provide the same
information. The symbol resolution already relies on the taint flags, so
this is consistent with the rest of the code.

-- 
Thanks,
Petr
Re: [PATCH 1/2] module: Restrict module namespace access to in-tree modules
Posted by Masahiro Yamada 3 months ago
On Tue, Jul 8, 2025 at 4:29 PM Vlastimil Babka <vbabka@suse.cz> wrote:
>
> The module namespace support has been introduced to allow restricting
> exports to specific modules only, and intended for in-tree modules such
> as kvm. Make this intention explicit by disallowing out of tree modules
> both for the module loader and modpost.
>
> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>



In my understanding, an external module with the same name
can override the internal one.

This change disallows such a use-case.



-- 
Best Regards
Masahiro Yamada
Re: [PATCH 1/2] module: Restrict module namespace access to in-tree modules
Posted by Vlastimil Babka 3 months ago
On 7/8/25 14:41, Masahiro Yamada wrote:
> On Tue, Jul 8, 2025 at 4:29 PM Vlastimil Babka <vbabka@suse.cz> wrote:
>>
>> The module namespace support has been introduced to allow restricting
>> exports to specific modules only, and intended for in-tree modules such
>> as kvm. Make this intention explicit by disallowing out of tree modules
>> both for the module loader and modpost.
>>
>> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
> 
> 
> 
> In my understanding, an external module with the same name
> can override the internal one.
> 
> This change disallows such a use-case.

Hmm I'm not familiar with this, but for such cases to be legitimate we can
assume the external module has to be derived from the internal one and not
something completely unrelated impersonating the internal one? So in that
case just patch 2 alone would be sufficient and not break any legitimate use
cases?
Re: [PATCH 1/2] module: Restrict module namespace access to in-tree modules
Posted by Masahiro Yamada 3 months ago
On Wed, Jul 9, 2025 at 12:08 AM Vlastimil Babka <vbabka@suse.cz> wrote:
>
> On 7/8/25 14:41, Masahiro Yamada wrote:
> > On Tue, Jul 8, 2025 at 4:29 PM Vlastimil Babka <vbabka@suse.cz> wrote:
> >>
> >> The module namespace support has been introduced to allow restricting
> >> exports to specific modules only, and intended for in-tree modules such
> >> as kvm. Make this intention explicit by disallowing out of tree modules
> >> both for the module loader and modpost.
> >>
> >> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
> >
> >
> >
> > In my understanding, an external module with the same name
> > can override the internal one.
> >
> > This change disallows such a use-case.
>
> Hmm I'm not familiar with this, but for such cases to be legitimate we can
> assume the external module has to be derived from the internal one and not
> something completely unrelated impersonating the internal one? So in that
> case just patch 2 alone would be sufficient and not break any legitimate use
> cases?
>

IIRC, nvdimm uses this feature for testing.


In-tree drivers:
  drivers/nvdimm/Makefile

Out-of-tree drivers:
  tools/testing/nvdimm/Makefile
  tools/testing/nvdimm/Kbuild




-- 
Best Regards
Masahiro Yamada
Re: [PATCH 1/2] module: Restrict module namespace access to in-tree modules
Posted by Shivank Garg 3 months ago

On 7/8/2025 12:58 PM, Vlastimil Babka wrote:
> The module namespace support has been introduced to allow restricting
> exports to specific modules only, and intended for in-tree modules such
> as kvm. Make this intention explicit by disallowing out of tree modules
> both for the module loader and modpost.
> 
> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
> ---
>  Documentation/core-api/symbol-namespaces.rst | 5 +++--
>  kernel/module/main.c                         | 3 ++-
>  scripts/mod/modpost.c                        | 6 +++++-
>  3 files changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/core-api/symbol-namespaces.rst b/Documentation/core-api/symbol-namespaces.rst
> index 32fc73dc5529e8844c2ce2580987155bcd13cd09..dc228ac738a5cdc49cc736c29170ca96df6a28dc 100644
> --- a/Documentation/core-api/symbol-namespaces.rst
> +++ b/Documentation/core-api/symbol-namespaces.rst
> @@ -83,13 +83,14 @@ 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.
> +modules to access this symbol. The access is restricted to in-tree modules.
> +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
> +will limit usage of this symbol to in-tree modules whoes name matches the given
>  patterns.
>  
>  How to use Symbols exported in Namespaces
> diff --git a/kernel/module/main.c b/kernel/module/main.c
> index 413ac6ea37021bc8ae260f624ca2745ed85333fc..ec7d8daa0347e3b65713396d6b6d14c2cb0270d3 100644
> --- a/kernel/module/main.c
> +++ b/kernel/module/main.c
> @@ -1157,7 +1157,8 @@ static int verify_namespace_is_imported(const struct load_info *info,
>  	namespace = kernel_symbol_namespace(sym);
>  	if (namespace && namespace[0]) {
>  
> -		if (verify_module_namespace(namespace, mod->name))
> +		if (get_modinfo(info, "intree") &&
> +		    verify_module_namespace(namespace, mod->name))
>  			return 0;
>  
>  		for_each_modinfo_entry(imported_namespace, info, "import_ns") {
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index 5ca7c268294ebb65acb0ba52a671eddca9279c61..d78be9834ed75f4b6ddb9af02a300a9bcc9234cc 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -1695,7 +1695,8 @@ void buf_write(struct buffer *buf, const char *s, int len)
>   * @modname: module name
>   *
>   * If @namespace is prefixed with "module:" to indicate it is a module namespace
> - * then test if @modname matches any of the comma separated patterns.
> + * then test if @modname matches any of the comma separated patterns. Access to
> + * module namespaces is restricted to in-tree modules only.
>   *
>   * The patterns only support tail-glob.
>   */
> @@ -1706,6 +1707,9 @@ static bool verify_module_namespace(const char *namespace, const char *modname)
>  	const char *sep;
>  	bool glob;
>  
> +	if (external_module)
> +		return false;
> +
>  	if (!strstarts(namespace, prefix))
>  		return false;
>  
> 

Reviewed-by: Shivank Garg <shivankg@amd.com>

Thanks,
Shivank