Live Patching
 help / color / mirror / Atom feed
* [PATCH] objtool/klp: Fix vmlinux klp relocations for EXPORT_SYMBOL_FOR_MODULES()
@ 2026-08-15  2:36 Josh Poimboeuf
  2026-08-15 17:08 ` Song Liu
  2026-08-17 16:21 ` Dylan Hatch
  0 siblings, 2 replies; 4+ messages in thread
From: Josh Poimboeuf @ 2026-08-15  2:36 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
	Song Liu, Miroslav Benes, Petr Mladek, Dylan Hatch

When a module function references a vmlinux symbol which is exported
with EXPORT_SYMBOL_FOR_MODULES(), a patch to that function needs to use
a klp reloc.

Currently, livepatch fails to load such a module:

  livepatch: invalid access to vmlinux symbol 'get_task_policy' from module-specific livepatch relocation section
  livepatch: failed to initialize patch 'livepatch_test' for module 'testmod' (-22)
  livepatch: patch 'livepatch_test' failed for module 'testmod', refusing to load module 'testmod'

klp diff puts all klp relocs in __klp_relocs.<patched object>, so
post-link names the section .klp.rela.<patched object>.<secname>, which the
kernel rejects for vmlinux symbols.

Commit 07f14d6af9d77 ("objtool/klp: Fix cross-module klp relocation
section naming") changed the meaning of objname in the klp rela section
name to be where the referenced symbol is referenced rather than where
it lives.  That premise only holds for symbols in a module: the relocs
get applied when the patched module gets patched, and the module
dependency guarantees the referenced module is loaded by then.

A vmlinux symbol needs the opposite.  It's always resolvable, and it has
to be applied when the patch module loads, before the module loader
initializes the patch module's special sections, which may reference it.
That's why livepatch rejects vmlinux symbols in module-specific
sections.

Use "vmlinux" as the section objname when the referenced symbol lives in
vmlinux.  This moves such klp relocs from .klp.rela.kvm..text to
.klp.rela.vmlinux..text.

Fixes: 07f14d6af9d77 ("objtool/klp: Fix cross-module klp relocation section naming")
Reported-by: Dylan Hatch <dylanbhatch@google.com>
Closes: https://lore.kernel.org/CADBMgpz7iWC0=t=_gE-tfvv0mTPq4kg0qQ2zgPH8DVPE6eQ9Kw@mail.gmail.com
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
 tools/objtool/include/objtool/klp.h |  5 +++--
 tools/objtool/klp-diff.c            | 35 ++++++++++++++++++-----------
 2 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/tools/objtool/include/objtool/klp.h b/tools/objtool/include/objtool/klp.h
index 646d8e1f12eff..c57775d78c71e 100644
--- a/tools/objtool/include/objtool/klp.h
+++ b/tools/objtool/include/objtool/klp.h
@@ -20,8 +20,9 @@
  * SHF_RELA_LIVEPATCH, nor does it support having two RELA sections for a
  * single PROGBITS section.
  *
- * "objname" is the name of the object being patched ("vmlinux" or a module
- * name).  post-link uses it to name the resulting
+ * "objname" is the object whose loading gates the relocation: "vmlinux" for
+ * references to vmlinux symbols, otherwise the name of the module being
+ * patched.  post-link uses it to name the resulting
  * .klp.rela.objname.section_name sections.
  */
 #define KLP_RELOCS_SEC	"__klp_relocs"
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index a66049e0726a6..16681a76f13d0 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1344,13 +1344,14 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
 			   struct section *sec, unsigned long offset,
 			   struct export *export)
 {
+	const char *sym_modname, *sym_orig_name, *sec_objname;
 	struct symbol *patched_sym = patched_reloc->sym;
 	s64 addend = reloc_addend(patched_reloc);
-	const char *sym_modname, *sym_orig_name;
-	static struct section *klp_relocs;
 	char tombstone_name[SYM_NAME_LEN];
 	struct symbol *sym, *klp_sym;
 	unsigned long klp_reloc_off;
+	struct section *klp_relocs;
+	char sec_name[SEC_NAME_LEN];
 	char sym_name[SYM_NAME_LEN];
 	struct klp_reloc klp_reloc;
 	unsigned long sympos;
@@ -1441,20 +1442,28 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
 	 * This intermediate step is necessary to prevent corruption by the
 	 * linker, which doesn't know how to properly handle two rela sections
 	 * applying to the same base section.
+	 *
+	 * The objname decides when the reloc gets applied.  A reference to a
+	 * vmlinux symbol goes in the vmlinux section so it gets applied when
+	 * the patch module loads.  Everything else goes in the patched
+	 * object's section, applied when the patched module is loaded.
 	 */
 
+	if (!strcmp(sym_modname, "vmlinux")) {
+		sec_objname = "vmlinux";
+	} else {
+		sec_objname = find_modname(e);
+		if (!sec_objname)
+			return -1;
+	}
+
+	/* section format: __klp_relocs.objname */
+	if (snprintf_check(sec_name, SEC_NAME_LEN,
+			   KLP_RELOCS_SEC ".%s", sec_objname))
+		return -1;
+
+	klp_relocs = find_section_by_name(e->out, sec_name);
 	if (!klp_relocs) {
-		const char *objname = find_modname(e);
-		char sec_name[SEC_NAME_LEN];
-
-		if (!objname)
-			return -1;
-
-		/* section format: __klp_relocs.objname */
-		if (snprintf_check(sec_name, SEC_NAME_LEN,
-				   KLP_RELOCS_SEC ".%s", objname))
-			return -1;
-
 		klp_relocs = elf_create_section(e->out, sec_name, 0,
 						0, SHT_PROGBITS, 8, SHF_ALLOC);
 		if (!klp_relocs)
-- 
2.55.0


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

* Re: [PATCH] objtool/klp: Fix vmlinux klp relocations for EXPORT_SYMBOL_FOR_MODULES()
  2026-08-15  2:36 [PATCH] objtool/klp: Fix vmlinux klp relocations for EXPORT_SYMBOL_FOR_MODULES() Josh Poimboeuf
@ 2026-08-15 17:08 ` Song Liu
  2026-08-17 16:21 ` Dylan Hatch
  1 sibling, 0 replies; 4+ messages in thread
From: Song Liu @ 2026-08-15 17:08 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
	Miroslav Benes, Petr Mladek, Dylan Hatch

On Fri, Aug 14, 2026 at 7:36 PM Josh Poimboeuf <jpoimboe@kernel.org> wrote:
>
> When a module function references a vmlinux symbol which is exported
> with EXPORT_SYMBOL_FOR_MODULES(), a patch to that function needs to use
> a klp reloc.
>
> Currently, livepatch fails to load such a module:
>
>   livepatch: invalid access to vmlinux symbol 'get_task_policy' from module-specific livepatch relocation section
>   livepatch: failed to initialize patch 'livepatch_test' for module 'testmod' (-22)
>   livepatch: patch 'livepatch_test' failed for module 'testmod', refusing to load module 'testmod'
>
> klp diff puts all klp relocs in __klp_relocs.<patched object>, so
> post-link names the section .klp.rela.<patched object>.<secname>, which the
> kernel rejects for vmlinux symbols.
>
> Commit 07f14d6af9d77 ("objtool/klp: Fix cross-module klp relocation
> section naming") changed the meaning of objname in the klp rela section
> name to be where the referenced symbol is referenced rather than where
> it lives.  That premise only holds for symbols in a module: the relocs
> get applied when the patched module gets patched, and the module
> dependency guarantees the referenced module is loaded by then.
>
> A vmlinux symbol needs the opposite.  It's always resolvable, and it has
> to be applied when the patch module loads, before the module loader
> initializes the patch module's special sections, which may reference it.
> That's why livepatch rejects vmlinux symbols in module-specific
> sections.
>
> Use "vmlinux" as the section objname when the referenced symbol lives in
> vmlinux.  This moves such klp relocs from .klp.rela.kvm..text to
> .klp.rela.vmlinux..text.
>
> Fixes: 07f14d6af9d77 ("objtool/klp: Fix cross-module klp relocation section naming")
> Reported-by: Dylan Hatch <dylanbhatch@google.com>
> Closes: https://lore.kernel.org/CADBMgpz7iWC0=t=_gE-tfvv0mTPq4kg0qQ2zgPH8DVPE6eQ9Kw@mail.gmail.com
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

Acked-by: Song Liu <song@kernel.org>

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

* Re: [PATCH] objtool/klp: Fix vmlinux klp relocations for EXPORT_SYMBOL_FOR_MODULES()
  2026-08-15  2:36 [PATCH] objtool/klp: Fix vmlinux klp relocations for EXPORT_SYMBOL_FOR_MODULES() Josh Poimboeuf
  2026-08-15 17:08 ` Song Liu
@ 2026-08-17 16:21 ` Dylan Hatch
  2026-08-17 16:53   ` Joe Lawrence
  1 sibling, 1 reply; 4+ messages in thread
From: Dylan Hatch @ 2026-08-17 16:21 UTC (permalink / raw)
  To: Josh Poimboeuf
  Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
	Song Liu, Miroslav Benes, Petr Mladek

On Fri, Aug 14, 2026 at 7:36 PM Josh Poimboeuf <jpoimboe@kernel.org> wrote:
>
> When a module function references a vmlinux symbol which is exported
> with EXPORT_SYMBOL_FOR_MODULES(), a patch to that function needs to use
> a klp reloc.
>
> Currently, livepatch fails to load such a module:
>
>   livepatch: invalid access to vmlinux symbol 'get_task_policy' from module-specific livepatch relocation section
>   livepatch: failed to initialize patch 'livepatch_test' for module 'testmod' (-22)
>   livepatch: patch 'livepatch_test' failed for module 'testmod', refusing to load module 'testmod'
>
> klp diff puts all klp relocs in __klp_relocs.<patched object>, so
> post-link names the section .klp.rela.<patched object>.<secname>, which the
> kernel rejects for vmlinux symbols.
>
> Commit 07f14d6af9d77 ("objtool/klp: Fix cross-module klp relocation
> section naming") changed the meaning of objname in the klp rela section
> name to be where the referenced symbol is referenced rather than where
> it lives.  That premise only holds for symbols in a module: the relocs
> get applied when the patched module gets patched, and the module
> dependency guarantees the referenced module is loaded by then.
>
> A vmlinux symbol needs the opposite.  It's always resolvable, and it has
> to be applied when the patch module loads, before the module loader
> initializes the patch module's special sections, which may reference it.
> That's why livepatch rejects vmlinux symbols in module-specific
> sections.
>
> Use "vmlinux" as the section objname when the referenced symbol lives in
> vmlinux.  This moves such klp relocs from .klp.rela.kvm..text to
> .klp.rela.vmlinux..text.
>
> Fixes: 07f14d6af9d77 ("objtool/klp: Fix cross-module klp relocation section naming")
> Reported-by: Dylan Hatch <dylanbhatch@google.com>
> Closes: https://lore.kernel.org/CADBMgpz7iWC0=t=_gE-tfvv0mTPq4kg0qQ2zgPH8DVPE6eQ9Kw@mail.gmail.com
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> ---
>  tools/objtool/include/objtool/klp.h |  5 +++--
>  tools/objtool/klp-diff.c            | 35 ++++++++++++++++++-----------
>  2 files changed, 25 insertions(+), 15 deletions(-)
>
> diff --git a/tools/objtool/include/objtool/klp.h b/tools/objtool/include/objtool/klp.h
> index 646d8e1f12eff..c57775d78c71e 100644
> --- a/tools/objtool/include/objtool/klp.h
> +++ b/tools/objtool/include/objtool/klp.h
> @@ -20,8 +20,9 @@
>   * SHF_RELA_LIVEPATCH, nor does it support having two RELA sections for a
>   * single PROGBITS section.
>   *
> - * "objname" is the name of the object being patched ("vmlinux" or a module
> - * name).  post-link uses it to name the resulting
> + * "objname" is the object whose loading gates the relocation: "vmlinux" for
> + * references to vmlinux symbols, otherwise the name of the module being
> + * patched.  post-link uses it to name the resulting
>   * .klp.rela.objname.section_name sections.
>   */
>  #define KLP_RELOCS_SEC "__klp_relocs"
> diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
> index a66049e0726a6..16681a76f13d0 100644
> --- a/tools/objtool/klp-diff.c
> +++ b/tools/objtool/klp-diff.c
> @@ -1344,13 +1344,14 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
>                            struct section *sec, unsigned long offset,
>                            struct export *export)
>  {
> +       const char *sym_modname, *sym_orig_name, *sec_objname;
>         struct symbol *patched_sym = patched_reloc->sym;
>         s64 addend = reloc_addend(patched_reloc);
> -       const char *sym_modname, *sym_orig_name;
> -       static struct section *klp_relocs;
>         char tombstone_name[SYM_NAME_LEN];
>         struct symbol *sym, *klp_sym;
>         unsigned long klp_reloc_off;
> +       struct section *klp_relocs;
> +       char sec_name[SEC_NAME_LEN];
>         char sym_name[SYM_NAME_LEN];
>         struct klp_reloc klp_reloc;
>         unsigned long sympos;
> @@ -1441,20 +1442,28 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
>          * This intermediate step is necessary to prevent corruption by the
>          * linker, which doesn't know how to properly handle two rela sections
>          * applying to the same base section.
> +        *
> +        * The objname decides when the reloc gets applied.  A reference to a
> +        * vmlinux symbol goes in the vmlinux section so it gets applied when
> +        * the patch module loads.  Everything else goes in the patched
> +        * object's section, applied when the patched module is loaded.
>          */
>
> +       if (!strcmp(sym_modname, "vmlinux")) {
> +               sec_objname = "vmlinux";
> +       } else {
> +               sec_objname = find_modname(e);
> +               if (!sec_objname)
> +                       return -1;
> +       }
> +
> +       /* section format: __klp_relocs.objname */
> +       if (snprintf_check(sec_name, SEC_NAME_LEN,
> +                          KLP_RELOCS_SEC ".%s", sec_objname))
> +               return -1;
> +
> +       klp_relocs = find_section_by_name(e->out, sec_name);
>         if (!klp_relocs) {
> -               const char *objname = find_modname(e);
> -               char sec_name[SEC_NAME_LEN];
> -
> -               if (!objname)
> -                       return -1;
> -
> -               /* section format: __klp_relocs.objname */
> -               if (snprintf_check(sec_name, SEC_NAME_LEN,
> -                                  KLP_RELOCS_SEC ".%s", objname))
> -                       return -1;
> -
>                 klp_relocs = elf_create_section(e->out, sec_name, 0,
>                                                 0, SHT_PROGBITS, 8, SHF_ALLOC);
>                 if (!klp_relocs)
> --
> 2.55.0
>
Tested-by: Dylan Hatch <dylanbhatch@google.com>

Tested with the reproducer patch I mentioned earlier:

https://github.com/dylanbhatch/linux/tree/mod-ns-lp

Also, are there integration test cases kept anywhere for klp-build?
And would this reproducer be helpful as a test case?

Thanks,
Dylan

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

* Re: [PATCH] objtool/klp: Fix vmlinux klp relocations for EXPORT_SYMBOL_FOR_MODULES()
  2026-08-17 16:21 ` Dylan Hatch
@ 2026-08-17 16:53   ` Joe Lawrence
  0 siblings, 0 replies; 4+ messages in thread
From: Joe Lawrence @ 2026-08-17 16:53 UTC (permalink / raw)
  To: Dylan Hatch
  Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Song Liu,
	Miroslav Benes, Petr Mladek, Josh Poimboeuf

On 8/17/26 12:21 PM, Dylan Hatch wrote:
> On Fri, Aug 14, 2026 at 7:36 PM Josh Poimboeuf <jpoimboe@kernel.org> wrote:
>>
>> When a module function references a vmlinux symbol which is exported
>> with EXPORT_SYMBOL_FOR_MODULES(), a patch to that function needs to use
>> a klp reloc.
>>
>> Currently, livepatch fails to load such a module:
>>
>>   livepatch: invalid access to vmlinux symbol 'get_task_policy' from module-specific livepatch relocation section
>>   livepatch: failed to initialize patch 'livepatch_test' for module 'testmod' (-22)
>>   livepatch: patch 'livepatch_test' failed for module 'testmod', refusing to load module 'testmod'
>>
>> klp diff puts all klp relocs in __klp_relocs.<patched object>, so
>> post-link names the section .klp.rela.<patched object>.<secname>, which the
>> kernel rejects for vmlinux symbols.
>>
>> Commit 07f14d6af9d77 ("objtool/klp: Fix cross-module klp relocation
>> section naming") changed the meaning of objname in the klp rela section
>> name to be where the referenced symbol is referenced rather than where
>> it lives.  That premise only holds for symbols in a module: the relocs
>> get applied when the patched module gets patched, and the module
>> dependency guarantees the referenced module is loaded by then.
>>
>> A vmlinux symbol needs the opposite.  It's always resolvable, and it has
>> to be applied when the patch module loads, before the module loader
>> initializes the patch module's special sections, which may reference it.
>> That's why livepatch rejects vmlinux symbols in module-specific
>> sections.
>>
>> Use "vmlinux" as the section objname when the referenced symbol lives in
>> vmlinux.  This moves such klp relocs from .klp.rela.kvm..text to
>> .klp.rela.vmlinux..text.
>>
>> Fixes: 07f14d6af9d77 ("objtool/klp: Fix cross-module klp relocation section naming")
>> Reported-by: Dylan Hatch <dylanbhatch@google.com>
>> Closes: https://lore.kernel.org/CADBMgpz7iWC0=t=_gE-tfvv0mTPq4kg0qQ2zgPH8DVPE6eQ9Kw@mail.gmail.com
>> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
>> ---
>>  tools/objtool/include/objtool/klp.h |  5 +++--
>>  tools/objtool/klp-diff.c            | 35 ++++++++++++++++++-----------
>>  2 files changed, 25 insertions(+), 15 deletions(-)
>>
>> diff --git a/tools/objtool/include/objtool/klp.h b/tools/objtool/include/objtool/klp.h
>> index 646d8e1f12eff..c57775d78c71e 100644
>> --- a/tools/objtool/include/objtool/klp.h
>> +++ b/tools/objtool/include/objtool/klp.h
>> @@ -20,8 +20,9 @@
>>   * SHF_RELA_LIVEPATCH, nor does it support having two RELA sections for a
>>   * single PROGBITS section.
>>   *
>> - * "objname" is the name of the object being patched ("vmlinux" or a module
>> - * name).  post-link uses it to name the resulting
>> + * "objname" is the object whose loading gates the relocation: "vmlinux" for
>> + * references to vmlinux symbols, otherwise the name of the module being
>> + * patched.  post-link uses it to name the resulting
>>   * .klp.rela.objname.section_name sections.
>>   */
>>  #define KLP_RELOCS_SEC "__klp_relocs"
>> diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
>> index a66049e0726a6..16681a76f13d0 100644
>> --- a/tools/objtool/klp-diff.c
>> +++ b/tools/objtool/klp-diff.c
>> @@ -1344,13 +1344,14 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
>>                            struct section *sec, unsigned long offset,
>>                            struct export *export)
>>  {
>> +       const char *sym_modname, *sym_orig_name, *sec_objname;
>>         struct symbol *patched_sym = patched_reloc->sym;
>>         s64 addend = reloc_addend(patched_reloc);
>> -       const char *sym_modname, *sym_orig_name;
>> -       static struct section *klp_relocs;
>>         char tombstone_name[SYM_NAME_LEN];
>>         struct symbol *sym, *klp_sym;
>>         unsigned long klp_reloc_off;
>> +       struct section *klp_relocs;
>> +       char sec_name[SEC_NAME_LEN];
>>         char sym_name[SYM_NAME_LEN];
>>         struct klp_reloc klp_reloc;
>>         unsigned long sympos;
>> @@ -1441,20 +1442,28 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
>>          * This intermediate step is necessary to prevent corruption by the
>>          * linker, which doesn't know how to properly handle two rela sections
>>          * applying to the same base section.
>> +        *
>> +        * The objname decides when the reloc gets applied.  A reference to a
>> +        * vmlinux symbol goes in the vmlinux section so it gets applied when
>> +        * the patch module loads.  Everything else goes in the patched
>> +        * object's section, applied when the patched module is loaded.
>>          */
>>
>> +       if (!strcmp(sym_modname, "vmlinux")) {
>> +               sec_objname = "vmlinux";
>> +       } else {
>> +               sec_objname = find_modname(e);
>> +               if (!sec_objname)
>> +                       return -1;
>> +       }
>> +
>> +       /* section format: __klp_relocs.objname */
>> +       if (snprintf_check(sec_name, SEC_NAME_LEN,
>> +                          KLP_RELOCS_SEC ".%s", sec_objname))
>> +               return -1;
>> +
>> +       klp_relocs = find_section_by_name(e->out, sec_name);
>>         if (!klp_relocs) {
>> -               const char *objname = find_modname(e);
>> -               char sec_name[SEC_NAME_LEN];
>> -
>> -               if (!objname)
>> -                       return -1;
>> -
>> -               /* section format: __klp_relocs.objname */
>> -               if (snprintf_check(sec_name, SEC_NAME_LEN,
>> -                                  KLP_RELOCS_SEC ".%s", objname))
>> -                       return -1;
>> -
>>                 klp_relocs = elf_create_section(e->out, sec_name, 0,
>>                                                 0, SHT_PROGBITS, 8, SHF_ALLOC);
>>                 if (!klp_relocs)
>> --
>> 2.55.0
>>
> Tested-by: Dylan Hatch <dylanbhatch@google.com>
> 
> Tested with the reproducer patch I mentioned earlier:
> 
> https://github.com/dylanbhatch/linux/tree/mod-ns-lp
> 
> Also, are there integration test cases kept anywhere for klp-build?
> And would this reproducer be helpful as a test case?
> 

Hi Dylan, timely question: Song and I are planning to talk about
klp-build unit/integration testing at upcoming LPC.

FWIW, I have some local test cases for exported symbols, including
EXPORT_SYMBOL_FOR_MODULES, but not the specific case that you ran into.
I'll be sure to add it to the suite.

LMK if you're interested in more details or have any suggestions on testing.

Regards,
-- 
Joe


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

end of thread, other threads:[~2026-08-17 16:53 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-15  2:36 [PATCH] objtool/klp: Fix vmlinux klp relocations for EXPORT_SYMBOL_FOR_MODULES() Josh Poimboeuf
2026-08-15 17:08 ` Song Liu
2026-08-17 16:21 ` Dylan Hatch
2026-08-17 16:53   ` Joe Lawrence

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox