* [PATCH v3 1/9] objtool/klp: Fix vmlinux .klp.symid link error for .no_trim_symbol symbols
2026-08-07 21:37 [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Josh Poimboeuf
@ 2026-08-07 21:37 ` Josh Poimboeuf
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
2026-08-07 21:37 ` [PATCH v3 2/9] objtool/klp: Fix size of empty special section entries Josh Poimboeuf
` (8 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-07 21:37 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
Testing klp-build with arm64 produced the following linker error during
the original kernel build:
`__notrim.1' referenced in section `.klp.symid' of vmlinux.o: defined in discarded section `.no_trim_symbol' of vmlinux.o
symbol_get() puts a static __notrim[] in .no_trim_symbol, which GCC
names __notrim.1, __notrim.2, etc. Two or more built-in translation
units calling symbol_get() thus produce duplicate names, resulting in
corresponding .klp.symid references which trigger the above error.
Add .no_trim_symbol to the discarded section list so its symbols don't
get symids.
Note this issue is not specific to arm64: it just needs two built-in
symbol_get() callers. arm64 trips over it easily because it has KVM
always compiled in vmlinux, whereas on x86 it's typically a module.
Fixes: 029223d30162 ("objtool/klp: Add .klp.symid for sympos disambiguation")
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-symid.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/objtool/klp-symid.c b/tools/objtool/klp-symid.c
index cf188cdfa6079..21d8708013aba 100644
--- a/tools/objtool/klp-symid.c
+++ b/tools/objtool/klp-symid.c
@@ -31,6 +31,7 @@
static const char * const discarded_secs[] = {
".discard",
".modinfo",
+ ".no_trim_symbol",
"__tracepoint_check",
};
--
2.54.0
^ permalink raw reply [flat|nested] 28+ messages in thread* [tip: objtool/core] objtool/klp: Fix vmlinux .klp.symid link error for .no_trim_symbol symbols
2026-08-07 21:37 ` [PATCH v3 1/9] objtool/klp: Fix vmlinux .klp.symid link error for .no_trim_symbol symbols Josh Poimboeuf
@ 2026-08-13 11:16 ` tip-bot2 for Josh Poimboeuf
0 siblings, 0 replies; 28+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2026-08-13 11:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: Song Liu, Joe Lawrence, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 3a83d9cd3d0e66c0ef99ce84f972ed26f50c990f
Gitweb: https://git.kernel.org/tip/3a83d9cd3d0e66c0ef99ce84f972ed26f50c990f
Author: Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate: Fri, 07 Aug 2026 14:37:46 -07:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 11 Aug 2026 15:04:57 -07:00
objtool/klp: Fix vmlinux .klp.symid link error for .no_trim_symbol symbols
Testing klp-build with arm64 produced the following linker error during
the original kernel build:
`__notrim.1' referenced in section `.klp.symid' of vmlinux.o: defined in discarded section `.no_trim_symbol' of vmlinux.o
symbol_get() puts a static __notrim[] in .no_trim_symbol, which GCC
names __notrim.1, __notrim.2, etc. Two or more built-in translation
units calling symbol_get() thus produce duplicate names, resulting in
corresponding .klp.symid references which trigger the above error.
Add .no_trim_symbol to the discarded section list so its symbols don't
get symids.
Note this issue is not specific to arm64: it just needs two built-in
symbol_get() callers. arm64 trips over it easily because it has KVM
always compiled in vmlinux, whereas on x86 it's typically a module.
Fixes: 029223d30162 ("objtool/klp: Add .klp.symid for sympos disambiguation")
Acked-by: Song Liu <song@kernel.org>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://patch.msgid.link/5a3cc4cded743167dd0878220201d80f7e48e5d7.1786138493.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-symid.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/objtool/klp-symid.c b/tools/objtool/klp-symid.c
index cf188cd..21d8708 100644
--- a/tools/objtool/klp-symid.c
+++ b/tools/objtool/klp-symid.c
@@ -31,6 +31,7 @@
static const char * const discarded_secs[] = {
".discard",
".modinfo",
+ ".no_trim_symbol",
"__tracepoint_check",
};
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 2/9] objtool/klp: Fix size of empty special section entries
2026-08-07 21:37 [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Josh Poimboeuf
2026-08-07 21:37 ` [PATCH v3 1/9] objtool/klp: Fix vmlinux .klp.symid link error for .no_trim_symbol symbols Josh Poimboeuf
@ 2026-08-07 21:37 ` Josh Poimboeuf
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
2026-08-07 21:37 ` [PATCH v3 3/9] objtool/klp: Ignore replacement offset of empty x86 alternatives Josh Poimboeuf
` (7 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-07 21:37 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
create_fake_symbols() sizes each ANNOTATE_DATA_SPECIAL entry from the
offset of the next annotation, falling back to the end of the section
for the last entry. But the last entry is detected by a zero size,
which also happens for an *empty* entry: ALTERNATIVE(oldinstr, "", ft)
still annotates its zero-length replacement, at the same offset as the
next entry's annotation.
So every empty replacement gets a fake symbol spanning the entire rest
of .altinstr_replacement. That's harmless today only because
find_symbol_containing() picks the smaller of two overlapping symbols.
Track whether a next annotation was found rather than inferring it from
the size. A zero-length fake symbol is fine: find_symbol_containing()
skips those, so the properly sized symbol at the same offset still wins.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-diff.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 492d7a012cffe..38fae861d12c7 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1627,13 +1627,17 @@ static int create_fake_symbols(struct elf *elf)
for_each_reloc(sec->rsec, reloc) {
unsigned long offset, size;
struct reloc *next_reloc;
+ bool last = true;
if (annotype(elf, sec, reloc) != ANNOTYPE_DATA_SPECIAL)
continue;
offset = reloc_addend(reloc);
- size = 0;
+ /*
+ * Find the start of the next entry so the fake symbol size can
+ * be calculated.
+ */
next_reloc = reloc;
for_each_reloc_continue(sec->rsec, next_reloc) {
if (annotype(elf, sec, next_reloc) != ANNOTYPE_DATA_SPECIAL ||
@@ -1641,10 +1645,15 @@ static int create_fake_symbols(struct elf *elf)
continue;
size = reloc_addend(next_reloc) - offset;
+ last = false;
break;
}
- if (!size)
+ /*
+ * If no next entry found, this is the last entry, so its size
+ * is from the current offset to the end of the section.
+ */
+ if (last)
size = sec_size(reloc->sym->sec) - offset;
if (create_fake_symbol(elf, reloc->sym->sec, offset, size))
--
2.54.0
^ permalink raw reply [flat|nested] 28+ messages in thread* [tip: objtool/core] objtool/klp: Fix size of empty special section entries
2026-08-07 21:37 ` [PATCH v3 2/9] objtool/klp: Fix size of empty special section entries Josh Poimboeuf
@ 2026-08-13 11:16 ` tip-bot2 for Josh Poimboeuf
0 siblings, 0 replies; 28+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2026-08-13 11:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: Song Liu, Joe Lawrence, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 1ea786097cd79522b76cbd41beeb8f84ef3a76f4
Gitweb: https://git.kernel.org/tip/1ea786097cd79522b76cbd41beeb8f84ef3a76f4
Author: Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate: Fri, 07 Aug 2026 14:37:47 -07:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 11 Aug 2026 15:04:57 -07:00
objtool/klp: Fix size of empty special section entries
create_fake_symbols() sizes each ANNOTATE_DATA_SPECIAL entry from the
offset of the next annotation, falling back to the end of the section
for the last entry. But the last entry is detected by a zero size,
which also happens for an *empty* entry: ALTERNATIVE(oldinstr, "", ft)
still annotates its zero-length replacement, at the same offset as the
next entry's annotation.
So every empty replacement gets a fake symbol spanning the entire rest
of .altinstr_replacement. That's harmless today only because
find_symbol_containing() picks the smaller of two overlapping symbols.
Track whether a next annotation was found rather than inferring it from
the size. A zero-length fake symbol is fine: find_symbol_containing()
skips those, so the properly sized symbol at the same offset still wins.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Acked-by: Song Liu <song@kernel.org>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://patch.msgid.link/913e691c5009397df832c7c9a18cd5cf71b42737.1786138493.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-diff.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index c5284d2..b4220e1 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1628,13 +1628,17 @@ static int create_fake_symbols(struct elf *elf)
for_each_reloc(sec->rsec, reloc) {
unsigned long offset, size;
struct reloc *next_reloc;
+ bool last = true;
if (annotype(elf, sec, reloc) != ANNOTYPE_DATA_SPECIAL)
continue;
offset = reloc_addend(reloc);
- size = 0;
+ /*
+ * Find the start of the next entry so the fake symbol size can
+ * be calculated.
+ */
next_reloc = reloc;
for_each_reloc_continue(sec->rsec, next_reloc) {
if (annotype(elf, sec, next_reloc) != ANNOTYPE_DATA_SPECIAL ||
@@ -1642,10 +1646,15 @@ static int create_fake_symbols(struct elf *elf)
continue;
size = reloc_addend(next_reloc) - offset;
+ last = false;
break;
}
- if (!size)
+ /*
+ * If no next entry found, this is the last entry, so its size
+ * is from the current offset to the end of the section.
+ */
+ if (last)
size = sec_size(reloc->sym->sec) - offset;
if (create_fake_symbol(elf, reloc->sym->sec, offset, size))
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 3/9] objtool/klp: Ignore replacement offset of empty x86 alternatives
2026-08-07 21:37 [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Josh Poimboeuf
2026-08-07 21:37 ` [PATCH v3 1/9] objtool/klp: Fix vmlinux .klp.symid link error for .no_trim_symbol symbols Josh Poimboeuf
2026-08-07 21:37 ` [PATCH v3 2/9] objtool/klp: Fix size of empty special section entries Josh Poimboeuf
@ 2026-08-07 21:37 ` Josh Poimboeuf
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
2026-08-07 21:37 ` [PATCH v3 4/9] objtool/klp: Explicitly disallow patching or referencing init code/data Josh Poimboeuf
` (6 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-07 21:37 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
An x86 alternative with an empty replacement, e.g. the second entry of
ALTERNATIVE_2("orig", "repl", ft1, "", ft2)
has a replacementlen of zero. Its replacement offset still gets a
relocation, but the label it points at is the end of the previous
replacement, which is also the beginning of the *next* alternative's
replacement. The value is meaningless; get_alt_entry() already ignores
it for that reason.
klp diff doesn't ignore it. When such an alternative belongs to a
changed function, cloning its relocations drags in the unrelated
neighboring replacement, along with everything that replacement
references. On an x86 clang/lto build an empty alternative in
meminfo_proc_show() pulled in the replacement of an alternative in
proc_kcore_init(), silently emitting a klp relocation against init text
which has long since been freed by the time the patch is applied.
Add arch_alt_ignore_new_reloc() and skip such relocations when cloning.
This has to be arch specific: on arm64 a zero-length replacement instead
identifies an alternative callback, whose replacement offset points at
the callback function and must be preserved.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/arch/x86/special.c | 27 +++++++++++++++++++++++++
tools/objtool/include/objtool/special.h | 7 +++++++
tools/objtool/klp-diff.c | 6 +++++-
3 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/special.c
index e817a3fff4491..1e84c81bfcd81 100644
--- a/tools/objtool/arch/x86/special.c
+++ b/tools/objtool/arch/x86/special.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <string.h>
+#include <arch/special.h>
#include <objtool/special.h>
#include <objtool/builtin.h>
#include <objtool/warn.h>
@@ -9,6 +10,32 @@
/* cpu feature name array generated from cpufeatures.h */
#include "cpu-feature-names.c"
+/*
+ * An alternative with an empty replacement, e.g. the second entry of
+ *
+ * ALTERNATIVE_2("orig", "repl", ft1, "", ft2)
+ *
+ * still gets a relocation for its replacement offset. But the label it points
+ * at is the end of the previous entry's replacement, which is also the
+ * beginning of the *next* entry's replacement. The value is meaningless: it's
+ * only ever used with a length of zero.
+ */
+bool arch_alt_ignore_new_reloc(struct section *sec, unsigned long offset)
+{
+ unsigned long entry_off;
+
+ if (strcmp(sec->name, ".altinstructions"))
+ return false;
+
+ entry_off = offset - (offset % ALT_ENTRY_SIZE);
+
+ if (offset - entry_off != ALT_NEW_OFFSET)
+ return false;
+
+ return !*(unsigned char *)(sec->data->d_buf + entry_off +
+ ALT_NEW_LEN_OFFSET);
+}
+
void arch_handle_alternative(struct special_alt *alt)
{
static struct special_alt *group, *prev;
diff --git a/tools/objtool/include/objtool/special.h b/tools/objtool/include/objtool/special.h
index 121c3761899c1..620dbf6cb0e58 100644
--- a/tools/objtool/include/objtool/special.h
+++ b/tools/objtool/include/objtool/special.h
@@ -32,6 +32,13 @@ int special_get_alts(struct elf *elf, struct list_head *alts);
void arch_handle_alternative(struct special_alt *alt);
+/*
+ * Should the reloc at @offset -- the "new" (replacement) field of a special
+ * section group entry -- be ignored? The meaning of a zero-length replacement
+ * is arch specific, so the arch decides.
+ */
+bool arch_alt_ignore_new_reloc(struct section *sec, unsigned long offset);
+
bool arch_support_alt_relocation(struct special_alt *special_alt,
struct instruction *insn,
struct reloc *reloc);
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 38fae861d12c7..3923fabc13331 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -12,7 +12,7 @@
#include <objtool/arch.h>
#include <objtool/klp.h>
#include <objtool/util.h>
-#include <arch/special.h>
+#include <objtool/special.h>
#include <linux/align.h>
#include <linux/objtool_types.h>
@@ -1537,6 +1537,10 @@ static int clone_sym_relocs(struct elfs *e, struct symbol *patched_sym)
!strcmp(patched_reloc->sym->sec->name, ".altinstr_aux"))
continue;
+ if (arch_alt_ignore_new_reloc(patched_sym->sec,
+ reloc_offset(patched_reloc)))
+ continue;
+
ret = convert_reloc_sym(e->patched, patched_reloc);
if (ret < 0) {
ERROR_FUNC(patched_rsec->base, reloc_offset(patched_reloc),
--
2.54.0
^ permalink raw reply [flat|nested] 28+ messages in thread* [tip: objtool/core] objtool/klp: Ignore replacement offset of empty x86 alternatives
2026-08-07 21:37 ` [PATCH v3 3/9] objtool/klp: Ignore replacement offset of empty x86 alternatives Josh Poimboeuf
@ 2026-08-13 11:16 ` tip-bot2 for Josh Poimboeuf
0 siblings, 0 replies; 28+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2026-08-13 11:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: Song Liu, Joe Lawrence, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 636f230ce21e2730072c58280f1fa0bed4a00eed
Gitweb: https://git.kernel.org/tip/636f230ce21e2730072c58280f1fa0bed4a00eed
Author: Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate: Fri, 07 Aug 2026 14:37:48 -07:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 11 Aug 2026 15:04:57 -07:00
objtool/klp: Ignore replacement offset of empty x86 alternatives
An x86 alternative with an empty replacement, e.g. the second entry of
ALTERNATIVE_2("orig", "repl", ft1, "", ft2)
has a replacementlen of zero. Its replacement offset still gets a
relocation, but the label it points at is the end of the previous
replacement, which is also the beginning of the *next* alternative's
replacement. The value is meaningless; get_alt_entry() already ignores
it for that reason.
klp diff doesn't ignore it. When such an alternative belongs to a
changed function, cloning its relocations drags in the unrelated
neighboring replacement, along with everything that replacement
references. On an x86 clang/lto build an empty alternative in
meminfo_proc_show() pulled in the replacement of an alternative in
proc_kcore_init(), silently emitting a klp relocation against init text
which has long since been freed by the time the patch is applied.
Add arch_alt_ignore_new_reloc() and skip such relocations when cloning.
This has to be arch specific: on arm64 a zero-length replacement instead
identifies an alternative callback, whose replacement offset points at
the callback function and must be preserved.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Acked-by: Song Liu <song@kernel.org>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://patch.msgid.link/7a885b70974795c3417f3358869e62aafd4ef783.1786138493.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/arch/x86/special.c | 27 ++++++++++++++++++++++++-
tools/objtool/include/objtool/special.h | 7 ++++++-
tools/objtool/klp-diff.c | 6 ++++-
3 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/special.c
index e817a3f..1e84c81 100644
--- a/tools/objtool/arch/x86/special.c
+++ b/tools/objtool/arch/x86/special.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <string.h>
+#include <arch/special.h>
#include <objtool/special.h>
#include <objtool/builtin.h>
#include <objtool/warn.h>
@@ -9,6 +10,32 @@
/* cpu feature name array generated from cpufeatures.h */
#include "cpu-feature-names.c"
+/*
+ * An alternative with an empty replacement, e.g. the second entry of
+ *
+ * ALTERNATIVE_2("orig", "repl", ft1, "", ft2)
+ *
+ * still gets a relocation for its replacement offset. But the label it points
+ * at is the end of the previous entry's replacement, which is also the
+ * beginning of the *next* entry's replacement. The value is meaningless: it's
+ * only ever used with a length of zero.
+ */
+bool arch_alt_ignore_new_reloc(struct section *sec, unsigned long offset)
+{
+ unsigned long entry_off;
+
+ if (strcmp(sec->name, ".altinstructions"))
+ return false;
+
+ entry_off = offset - (offset % ALT_ENTRY_SIZE);
+
+ if (offset - entry_off != ALT_NEW_OFFSET)
+ return false;
+
+ return !*(unsigned char *)(sec->data->d_buf + entry_off +
+ ALT_NEW_LEN_OFFSET);
+}
+
void arch_handle_alternative(struct special_alt *alt)
{
static struct special_alt *group, *prev;
diff --git a/tools/objtool/include/objtool/special.h b/tools/objtool/include/objtool/special.h
index 121c376..620dbf6 100644
--- a/tools/objtool/include/objtool/special.h
+++ b/tools/objtool/include/objtool/special.h
@@ -32,6 +32,13 @@ int special_get_alts(struct elf *elf, struct list_head *alts);
void arch_handle_alternative(struct special_alt *alt);
+/*
+ * Should the reloc at @offset -- the "new" (replacement) field of a special
+ * section group entry -- be ignored? The meaning of a zero-length replacement
+ * is arch specific, so the arch decides.
+ */
+bool arch_alt_ignore_new_reloc(struct section *sec, unsigned long offset);
+
bool arch_support_alt_relocation(struct special_alt *special_alt,
struct instruction *insn,
struct reloc *reloc);
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index b4220e1..df2fe01 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -12,7 +12,7 @@
#include <objtool/arch.h>
#include <objtool/klp.h>
#include <objtool/util.h>
-#include <arch/special.h>
+#include <objtool/special.h>
#include <linux/align.h>
#include <linux/objtool_types.h>
@@ -1538,6 +1538,10 @@ static int clone_sym_relocs(struct elfs *e, struct symbol *patched_sym)
!strcmp(patched_reloc->sym->sec->name, ".altinstr_aux"))
continue;
+ if (arch_alt_ignore_new_reloc(patched_sym->sec,
+ reloc_offset(patched_reloc)))
+ continue;
+
ret = convert_reloc_sym(e->patched, patched_reloc);
if (ret < 0) {
ERROR_FUNC(patched_rsec->base, reloc_offset(patched_reloc),
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 4/9] objtool/klp: Explicitly disallow patching or referencing init code/data
2026-08-07 21:37 [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Josh Poimboeuf
` (2 preceding siblings ...)
2026-08-07 21:37 ` [PATCH v3 3/9] objtool/klp: Ignore replacement offset of empty x86 alternatives Josh Poimboeuf
@ 2026-08-07 21:37 ` Josh Poimboeuf
2026-08-11 22:32 ` Song Liu
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
2026-08-07 21:37 ` [PATCH v3 5/9] objtool/klp: Fix cross-module klp relocation section naming Josh Poimboeuf
` (5 subsequent siblings)
9 siblings, 2 replies; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-07 21:37 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
Explicitly disallow the patching and referencing of init code/data.
Otherwise it could potentially introduce some odd edge cases depending
on whether the target object's init section has been freed yet (note
that the init code still exists in the target module when doing late
module patching).
Such edge cases include sympos calculation and the patching and/or
referencing of non-existent (init-freed) code/data. Not to mention the
inherent differences in behavior that occur when the init code is only
patched *some* of the time depending on module loading order or kernel
config.
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-sympos.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/tools/objtool/klp-sympos.c b/tools/objtool/klp-sympos.c
index bbfae516d3395..dfca9dd746812 100644
--- a/tools/objtool/klp-sympos.c
+++ b/tools/objtool/klp-sympos.c
@@ -367,6 +367,11 @@ static unsigned long find_vmlinux_sympos(struct symbol *sym)
return sympos;
}
+static bool is_init_sym(struct symbol *sym)
+{
+ return strstarts(sym->sec->name, ".init");
+}
+
/*
* "sympos" is used by livepatch to disambiguate duplicate symbol names.
*/
@@ -376,6 +381,11 @@ unsigned long klp_find_sympos(struct elf *elf, struct symbol *sym)
bool has_dup = false;
struct symbol *s;
+ if (is_init_sym(sym)) {
+ ERROR("%s: can't patch or reference init code/data", sym->name);
+ return ULONG_MAX;
+ }
+
if (sym->bind != STB_LOCAL)
return 0;
--
2.54.0
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v3 4/9] objtool/klp: Explicitly disallow patching or referencing init code/data
2026-08-07 21:37 ` [PATCH v3 4/9] objtool/klp: Explicitly disallow patching or referencing init code/data Josh Poimboeuf
@ 2026-08-11 22:32 ` Song Liu
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
1 sibling, 0 replies; 28+ messages in thread
From: Song Liu @ 2026-08-11 22:32 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek
On Fri, Aug 7, 2026 at 2:38 PM Josh Poimboeuf <jpoimboe@kernel.org> wrote:
>
> Explicitly disallow the patching and referencing of init code/data.
> Otherwise it could potentially introduce some odd edge cases depending
> on whether the target object's init section has been freed yet (note
> that the init code still exists in the target module when doing late
> module patching).
>
> Such edge cases include sympos calculation and the patching and/or
> referencing of non-existent (init-freed) code/data. Not to mention the
> inherent differences in behavior that occur when the init code is only
> patched *some* of the time depending on module loading order or kernel
> config.
>
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Acked-by: Song Liu <song@kernel.org>
^ permalink raw reply [flat|nested] 28+ messages in thread
* [tip: objtool/core] objtool/klp: Explicitly disallow patching or referencing init code/data
2026-08-07 21:37 ` [PATCH v3 4/9] objtool/klp: Explicitly disallow patching or referencing init code/data Josh Poimboeuf
2026-08-11 22:32 ` Song Liu
@ 2026-08-13 11:16 ` tip-bot2 for Josh Poimboeuf
1 sibling, 0 replies; 28+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2026-08-13 11:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: Joe Lawrence, Song Liu, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 69f361b8a7a2f65c1bb236ea0899cdaad7267653
Gitweb: https://git.kernel.org/tip/69f361b8a7a2f65c1bb236ea0899cdaad7267653
Author: Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate: Fri, 07 Aug 2026 14:37:49 -07:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 11 Aug 2026 16:10:38 -07:00
objtool/klp: Explicitly disallow patching or referencing init code/data
Explicitly disallow the patching and referencing of init code/data.
Otherwise it could potentially introduce some odd edge cases depending
on whether the target object's init section has been freed yet (note
that the init code still exists in the target module when doing late
module patching).
Such edge cases include sympos calculation and the patching and/or
referencing of non-existent (init-freed) code/data. Not to mention the
inherent differences in behavior that occur when the init code is only
patched *some* of the time depending on module loading order or kernel
config.
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Song Liu <song@kernel.org>
Link: https://patch.msgid.link/516e14f84cfbffa27dc19d3dcf35097504097966.1786138493.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-sympos.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/tools/objtool/klp-sympos.c b/tools/objtool/klp-sympos.c
index bbfae51..dfca9dd 100644
--- a/tools/objtool/klp-sympos.c
+++ b/tools/objtool/klp-sympos.c
@@ -367,6 +367,11 @@ static unsigned long find_vmlinux_sympos(struct symbol *sym)
return sympos;
}
+static bool is_init_sym(struct symbol *sym)
+{
+ return strstarts(sym->sec->name, ".init");
+}
+
/*
* "sympos" is used by livepatch to disambiguate duplicate symbol names.
*/
@@ -376,6 +381,11 @@ unsigned long klp_find_sympos(struct elf *elf, struct symbol *sym)
bool has_dup = false;
struct symbol *s;
+ if (is_init_sym(sym)) {
+ ERROR("%s: can't patch or reference init code/data", sym->name);
+ return ULONG_MAX;
+ }
+
if (sym->bind != STB_LOCAL)
return 0;
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 5/9] objtool/klp: Fix cross-module klp relocation section naming
2026-08-07 21:37 [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Josh Poimboeuf
` (3 preceding siblings ...)
2026-08-07 21:37 ` [PATCH v3 4/9] objtool/klp: Explicitly disallow patching or referencing init code/data Josh Poimboeuf
@ 2026-08-07 21:37 ` Josh Poimboeuf
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
2026-08-07 21:37 ` [PATCH v3 6/9] objtool/klp: Don't match local symbols against exports Josh Poimboeuf
` (4 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-07 21:37 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
A klp relocation section is .klp.rela.<objname>.<secname>, where objname
is the object being patched.
klp-build wrongly derives objname from where the referenced symbol
lives, not where it's referenced. For a cross-module reference like
patched can_isotp code calling can.ko's can_rx_unregister(), that gives
.klp.rela.can..text rather than .klp.rela.can_isotp..text. Unless the
patch happens to patch can.ko as well, the relocation never gets applied
and the call goes off into the weeds.
Name the intermediate section __klp_relocs.<objname> so post-link can
read the patched object's name from there.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://lore.kernel.org/20260720145658.1103243-2-joe.lawrence@redhat.com
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/include/objtool/klp.h | 10 ++++--
tools/objtool/klp-diff.c | 17 +++++++--
tools/objtool/klp-post-link.c | 53 +++++++++++++++++------------
3 files changed, 52 insertions(+), 28 deletions(-)
diff --git a/tools/objtool/include/objtool/klp.h b/tools/objtool/include/objtool/klp.h
index 0118c2c170c3f..646d8e1f12eff 100644
--- a/tools/objtool/include/objtool/klp.h
+++ b/tools/objtool/include/objtool/klp.h
@@ -14,11 +14,15 @@
#define KLP_FUNCS_SEC ".init.klp_funcs"
/*
- * __klp_relocs is an intermediate section which are created by klp diff and
- * converted into KLP symbols/relas by "objtool klp post-link". This is needed
- * to work around the linker, which doesn't preserve SHN_LIVEPATCH or
+ * __klp_relocs.<objname> are intermediate sections which are created by klp
+ * diff and converted into KLP symbols/relas by "objtool klp post-link". This
+ * is needed to work around the linker, which doesn't preserve SHN_LIVEPATCH or
* 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
+ * .klp.rela.objname.section_name sections.
*/
#define KLP_RELOCS_SEC "__klp_relocs"
#define KLP_STRINGS_SEC ".rodata.klp.str1.1"
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 3923fabc13331..e2c6c69dbb4f0 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1380,8 +1380,8 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
}
/*
- * Create the __klp_relocs entry. This will be converted to an actual
- * KLP rela by "objtool klp post-link".
+ * Create the __klp_relocs.<objname> entry. This will be converted to
+ * an actual KLP rela by "objtool klp post-link".
*
* This intermediate step is necessary to prevent corruption by the
* linker, which doesn't know how to properly handle two rela sections
@@ -1389,7 +1389,18 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
*/
if (!klp_relocs) {
- klp_relocs = elf_create_section(e->out, KLP_RELOCS_SEC, 0,
+ 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)
return -1;
diff --git a/tools/objtool/klp-post-link.c b/tools/objtool/klp-post-link.c
index c013e39957b11..350d20495897b 100644
--- a/tools/objtool/klp-post-link.c
+++ b/tools/objtool/klp-post-link.c
@@ -19,19 +19,11 @@
#include <objtool/util.h>
#include <linux/livepatch_external.h>
-static int fix_klp_relocs(struct elf *elf)
+static int fix_klp_reloc_sec(struct elf *elf, struct section *symtab,
+ struct section *klp_relocs)
{
- struct section *symtab, *klp_relocs;
-
- klp_relocs = find_section_by_name(elf, KLP_RELOCS_SEC);
- if (!klp_relocs)
- return 0;
-
- symtab = find_section_by_name(elf, ".symtab");
- if (!symtab) {
- ERROR("missing .symtab");
- return -1;
- }
+ /* section format: __klp_relocs.sec_objname */
+ const char *sec_objname = klp_relocs->name + strlen(KLP_RELOCS_SEC ".");
for (int i = 0; i < sec_size(klp_relocs) / sizeof(struct klp_reloc); i++) {
struct klp_reloc *klp_reloc;
@@ -39,7 +31,6 @@ static int fix_klp_relocs(struct elf *elf)
struct section *sec, *tmp, *klp_rsec;
unsigned long offset;
struct reloc *reloc;
- char sym_modname[64];
char rsec_name[SEC_NAME_LEN];
u64 addend;
struct symbol *sym, *klp_sym;
@@ -55,7 +46,7 @@ static int fix_klp_relocs(struct elf *elf)
reloc = find_reloc_by_dest(elf, klp_relocs,
klp_reloc_off + offsetof(struct klp_reloc, offset));
if (!reloc) {
- ERROR("malformed " KLP_RELOCS_SEC " section");
+ ERROR("malformed %s section", klp_relocs->name);
return -1;
}
@@ -66,17 +57,13 @@ static int fix_klp_relocs(struct elf *elf)
reloc = find_reloc_by_dest(elf, klp_relocs,
klp_reloc_off + offsetof(struct klp_reloc, sym));
if (!reloc) {
- ERROR("malformed " KLP_RELOCS_SEC " section");
+ ERROR("malformed %s section", klp_relocs->name);
return -1;
}
klp_sym = reloc->sym;
addend = reloc_addend(reloc);
- /* symbol format: .klp.sym.modname.sym_name,sympos */
- if (sscanf(klp_sym->name + strlen(KLP_SYM_PREFIX), "%55[^.]", sym_modname) != 1)
- ERROR("can't find modname in klp symbol '%s'", klp_sym->name);
-
/*
* Create the KLP rela:
*/
@@ -84,7 +71,7 @@ static int fix_klp_relocs(struct elf *elf)
/* section format: .klp.rela.sec_objname.section_name */
if (snprintf_check(rsec_name, SEC_NAME_LEN,
KLP_RELOC_SEC_PREFIX "%s.%s",
- sym_modname, sec->name))
+ sec_objname, sec->name))
return -1;
klp_rsec = find_section_by_name(elf, rsec_name);
@@ -134,10 +121,32 @@ static int fix_klp_relocs(struct elf *elf)
return 0;
}
+static int fix_klp_relocs(struct elf *elf)
+{
+ struct section *symtab, *sec;
+
+ symtab = find_section_by_name(elf, ".symtab");
+ if (!symtab) {
+ ERROR("missing .symtab");
+ return -1;
+ }
+
+ for_each_sec(elf, sec) {
+ if (strncmp(sec->name, KLP_RELOCS_SEC ".",
+ strlen(KLP_RELOCS_SEC ".")))
+ continue;
+
+ if (fix_klp_reloc_sec(elf, symtab, sec))
+ return -1;
+ }
+
+ return 0;
+}
+
/*
* This runs on the livepatch module after all other linking has been done. It
- * converts the intermediate __klp_relocs section into proper KLP relocs to be
- * processed by livepatch. This needs to run last to avoid linker wreckage.
+ * converts the intermediate __klp_relocs.* sections into proper KLP relocs to
+ * be processed by livepatch. This needs to run last to avoid linker wreckage.
* Linkers don't tend to handle the "two rela sections for a single base
* section" case very well, nor do they appreciate SHN_LIVEPATCH.
*/
--
2.54.0
^ permalink raw reply [flat|nested] 28+ messages in thread* [tip: objtool/core] objtool/klp: Fix cross-module klp relocation section naming
2026-08-07 21:37 ` [PATCH v3 5/9] objtool/klp: Fix cross-module klp relocation section naming Josh Poimboeuf
@ 2026-08-13 11:16 ` tip-bot2 for Josh Poimboeuf
0 siblings, 0 replies; 28+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2026-08-13 11:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: Joe Lawrence, Song Liu, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 07f14d6af9d7791fdc2b44a3dd0693e42c71d2b8
Gitweb: https://git.kernel.org/tip/07f14d6af9d7791fdc2b44a3dd0693e42c71d2b8
Author: Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate: Fri, 07 Aug 2026 14:37:50 -07:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 11 Aug 2026 16:10:51 -07:00
objtool/klp: Fix cross-module klp relocation section naming
A klp relocation section is .klp.rela.<objname>.<secname>, where objname
is the object being patched.
klp-build wrongly derives objname from where the referenced symbol
lives, not where it's referenced. For a cross-module reference like
patched can_isotp code calling can.ko's can_rx_unregister(), that gives
.klp.rela.can..text rather than .klp.rela.can_isotp..text. Unless the
patch happens to patch can.ko as well, the relocation never gets applied
and the call goes off into the weeds.
Name the intermediate section __klp_relocs.<objname> so post-link can
read the patched object's name from there.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://lore.kernel.org/20260720145658.1103243-2-joe.lawrence@redhat.com
Acked-by: Song Liu <song@kernel.org>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://patch.msgid.link/ee93a08f3e55e76ffa67d04e283917ddaa893f09.1786138493.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/include/objtool/klp.h | 10 +++--
tools/objtool/klp-diff.c | 17 +++++++--
tools/objtool/klp-post-link.c | 53 ++++++++++++++++------------
3 files changed, 52 insertions(+), 28 deletions(-)
diff --git a/tools/objtool/include/objtool/klp.h b/tools/objtool/include/objtool/klp.h
index 0118c2c..646d8e1 100644
--- a/tools/objtool/include/objtool/klp.h
+++ b/tools/objtool/include/objtool/klp.h
@@ -14,11 +14,15 @@
#define KLP_FUNCS_SEC ".init.klp_funcs"
/*
- * __klp_relocs is an intermediate section which are created by klp diff and
- * converted into KLP symbols/relas by "objtool klp post-link". This is needed
- * to work around the linker, which doesn't preserve SHN_LIVEPATCH or
+ * __klp_relocs.<objname> are intermediate sections which are created by klp
+ * diff and converted into KLP symbols/relas by "objtool klp post-link". This
+ * is needed to work around the linker, which doesn't preserve SHN_LIVEPATCH or
* 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
+ * .klp.rela.objname.section_name sections.
*/
#define KLP_RELOCS_SEC "__klp_relocs"
#define KLP_STRINGS_SEC ".rodata.klp.str1.1"
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index df2fe01..e266a54 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1381,8 +1381,8 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
}
/*
- * Create the __klp_relocs entry. This will be converted to an actual
- * KLP rela by "objtool klp post-link".
+ * Create the __klp_relocs.<objname> entry. This will be converted to
+ * an actual KLP rela by "objtool klp post-link".
*
* This intermediate step is necessary to prevent corruption by the
* linker, which doesn't know how to properly handle two rela sections
@@ -1390,7 +1390,18 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
*/
if (!klp_relocs) {
- klp_relocs = elf_create_section(e->out, KLP_RELOCS_SEC, 0,
+ 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)
return -1;
diff --git a/tools/objtool/klp-post-link.c b/tools/objtool/klp-post-link.c
index c013e39..350d204 100644
--- a/tools/objtool/klp-post-link.c
+++ b/tools/objtool/klp-post-link.c
@@ -19,19 +19,11 @@
#include <objtool/util.h>
#include <linux/livepatch_external.h>
-static int fix_klp_relocs(struct elf *elf)
+static int fix_klp_reloc_sec(struct elf *elf, struct section *symtab,
+ struct section *klp_relocs)
{
- struct section *symtab, *klp_relocs;
-
- klp_relocs = find_section_by_name(elf, KLP_RELOCS_SEC);
- if (!klp_relocs)
- return 0;
-
- symtab = find_section_by_name(elf, ".symtab");
- if (!symtab) {
- ERROR("missing .symtab");
- return -1;
- }
+ /* section format: __klp_relocs.sec_objname */
+ const char *sec_objname = klp_relocs->name + strlen(KLP_RELOCS_SEC ".");
for (int i = 0; i < sec_size(klp_relocs) / sizeof(struct klp_reloc); i++) {
struct klp_reloc *klp_reloc;
@@ -39,7 +31,6 @@ static int fix_klp_relocs(struct elf *elf)
struct section *sec, *tmp, *klp_rsec;
unsigned long offset;
struct reloc *reloc;
- char sym_modname[64];
char rsec_name[SEC_NAME_LEN];
u64 addend;
struct symbol *sym, *klp_sym;
@@ -55,7 +46,7 @@ static int fix_klp_relocs(struct elf *elf)
reloc = find_reloc_by_dest(elf, klp_relocs,
klp_reloc_off + offsetof(struct klp_reloc, offset));
if (!reloc) {
- ERROR("malformed " KLP_RELOCS_SEC " section");
+ ERROR("malformed %s section", klp_relocs->name);
return -1;
}
@@ -66,17 +57,13 @@ static int fix_klp_relocs(struct elf *elf)
reloc = find_reloc_by_dest(elf, klp_relocs,
klp_reloc_off + offsetof(struct klp_reloc, sym));
if (!reloc) {
- ERROR("malformed " KLP_RELOCS_SEC " section");
+ ERROR("malformed %s section", klp_relocs->name);
return -1;
}
klp_sym = reloc->sym;
addend = reloc_addend(reloc);
- /* symbol format: .klp.sym.modname.sym_name,sympos */
- if (sscanf(klp_sym->name + strlen(KLP_SYM_PREFIX), "%55[^.]", sym_modname) != 1)
- ERROR("can't find modname in klp symbol '%s'", klp_sym->name);
-
/*
* Create the KLP rela:
*/
@@ -84,7 +71,7 @@ static int fix_klp_relocs(struct elf *elf)
/* section format: .klp.rela.sec_objname.section_name */
if (snprintf_check(rsec_name, SEC_NAME_LEN,
KLP_RELOC_SEC_PREFIX "%s.%s",
- sym_modname, sec->name))
+ sec_objname, sec->name))
return -1;
klp_rsec = find_section_by_name(elf, rsec_name);
@@ -134,10 +121,32 @@ static int fix_klp_relocs(struct elf *elf)
return 0;
}
+static int fix_klp_relocs(struct elf *elf)
+{
+ struct section *symtab, *sec;
+
+ symtab = find_section_by_name(elf, ".symtab");
+ if (!symtab) {
+ ERROR("missing .symtab");
+ return -1;
+ }
+
+ for_each_sec(elf, sec) {
+ if (strncmp(sec->name, KLP_RELOCS_SEC ".",
+ strlen(KLP_RELOCS_SEC ".")))
+ continue;
+
+ if (fix_klp_reloc_sec(elf, symtab, sec))
+ return -1;
+ }
+
+ return 0;
+}
+
/*
* This runs on the livepatch module after all other linking has been done. It
- * converts the intermediate __klp_relocs section into proper KLP relocs to be
- * processed by livepatch. This needs to run last to avoid linker wreckage.
+ * converts the intermediate __klp_relocs.* sections into proper KLP relocs to
+ * be processed by livepatch. This needs to run last to avoid linker wreckage.
* Linkers don't tend to handle the "two rela sections for a single base
* section" case very well, nor do they appreciate SHN_LIVEPATCH.
*/
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 6/9] objtool/klp: Don't match local symbols against exports
2026-08-07 21:37 [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Josh Poimboeuf
` (4 preceding siblings ...)
2026-08-07 21:37 ` [PATCH v3 5/9] objtool/klp: Fix cross-module klp relocation section naming Josh Poimboeuf
@ 2026-08-07 21:37 ` Josh Poimboeuf
2026-08-07 21:46 ` sashiko-bot
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
2026-08-07 21:37 ` [PATCH v3 7/9] objtool/klp: Allow new references to module exports Josh Poimboeuf
` (3 subsequent siblings)
9 siblings, 2 replies; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-07 21:37 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
While cloning a reloc, klp diff calls find_export() to determine whether
the referenced symbol is exported. That decides whether the reference
needs a klp reloc, which object the klp symbol belongs to, and whether
the symbol's data needs to be copied into the patch module.
But find_export() matches purely on symbol name, so a static function or
variable which happens to share its name with an export is mistaken for
a reference to that export:
- klp_reloc_needed() creates a klp reloc pointing at the exporting
module's symbol rather than the local one. For a vmlinux export it
skips the klp reloc altogether, leaving a normal reloc which the
module loader resolves to the vmlinux symbol.
- clone_reloc() treats the symbol as external and clones it without
its data, leaving a dangling reference.
- validate_special_section_klp_reloc() attributes a static branch or
call key to the wrong module, and for a vmlinux export skips the
unsupported-key check entirely.
Exports are always global, so ignore local symbols in find_export().
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-diff.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index e2c6c69dbb4f0..f5d5711623f03 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1101,6 +1101,9 @@ static struct export *find_export(struct symbol *sym)
{
struct export *export;
+ if (is_local_sym(sym))
+ return NULL;
+
hash_for_each_possible(exports, export, hash, str_hash(sym->name)) {
if (!strcmp(export->sym, sym->name))
return export;
--
2.54.0
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v3 6/9] objtool/klp: Don't match local symbols against exports
2026-08-07 21:37 ` [PATCH v3 6/9] objtool/klp: Don't match local symbols against exports Josh Poimboeuf
@ 2026-08-07 21:46 ` sashiko-bot
2026-08-08 22:27 ` Josh Poimboeuf
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
1 sibling, 1 reply; 28+ messages in thread
From: sashiko-bot @ 2026-08-07 21:46 UTC (permalink / raw)
To: x86
Cc: linux-kernel, Miroslav Benes, Joe Lawrence, live-patching,
Petr Mladek, Song Liu, Peter Zijlstra
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Unexported global symbols that share a name with an export are incorrectly matched against the global exports list, causing misrouted livepatch relocations.
--
--- Patch [6]: [PATCH v3 6/9] objtool/klp: Don't match local symbols against exports ---
commit 91941e947fdde72be13c7760463244a153a175ce
Author: Josh Poimboeuf <jpoimboe@kernel.org>
objtool/klp: Don't match local symbols against exports
This commit updates find_export() in klp-diff.c to ignore local symbols.
This addresses an issue where static functions or variables that share a
name with an export are incorrectly treated as export references during
livepatch generation.
> diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
> --- a/tools/objtool/klp-diff.c
> +++ b/tools/objtool/klp-diff.c
> @@ -1101,6 +1101,9 @@ static struct export *find_export(struct symbol *sym)
> {
> struct export *export;
>
> + if (is_local_sym(sym))
> + return NULL;
> +
> hash_for_each_possible(exports, export, hash, str_hash(sym->name)) {
> if (!strcmp(export->sym, sym->name))
> return export;
[Severity: High]
This is a pre-existing issue, but does this still leave unexported global
symbols vulnerable to incorrect matching?
If a module contains an unexported global symbol that shares its name with
an unrelated exported symbol, it will bypass the is_local_sym() check.
When the module is livepatched and klp-diff processes a relocation to this
internal symbol, find_export() will perform a string match and return the
unrelated export. Would this cause a KLP relocation to incorrectly point to
the external module's export instead of the internal symbol?
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1786138493.git.jpoimboe@kernel.org?part=6
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v3 6/9] objtool/klp: Don't match local symbols against exports
2026-08-07 21:46 ` sashiko-bot
@ 2026-08-08 22:27 ` Josh Poimboeuf
0 siblings, 0 replies; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-08 22:27 UTC (permalink / raw)
To: sashiko-bot
Cc: x86, linux-kernel, Miroslav Benes, Joe Lawrence, live-patching,
Petr Mladek, Song Liu, Peter Zijlstra
On Fri, Aug 07, 2026 at 09:46:11PM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] Unexported global symbols that share a name with an export are incorrectly matched against the global exports list, causing misrouted livepatch relocations.
> --
>
> --- Patch [6]: [PATCH v3 6/9] objtool/klp: Don't match local symbols against exports ---
> commit 91941e947fdde72be13c7760463244a153a175ce
> Author: Josh Poimboeuf <jpoimboe@kernel.org>
>
> objtool/klp: Don't match local symbols against exports
>
> This commit updates find_export() in klp-diff.c to ignore local symbols.
> This addresses an issue where static functions or variables that share a
> name with an export are incorrectly treated as export references during
> livepatch generation.
>
> > diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
> > --- a/tools/objtool/klp-diff.c
> > +++ b/tools/objtool/klp-diff.c
> > @@ -1101,6 +1101,9 @@ static struct export *find_export(struct symbol *sym)
> > {
> > struct export *export;
> >
> > + if (is_local_sym(sym))
> > + return NULL;
> > +
> > hash_for_each_possible(exports, export, hash, str_hash(sym->name)) {
> > if (!strcmp(export->sym, sym->name))
> > return export;
>
> [Severity: High]
> This is a pre-existing issue, but does this still leave unexported global
> symbols vulnerable to incorrect matching?
>
> If a module contains an unexported global symbol that shares its name with
> an unrelated exported symbol, it will bypass the is_local_sym() check.
>
> When the module is livepatched and klp-diff processes a relocation to this
> internal symbol, find_export() will perform a string match and return the
> unrelated export. Would this cause a KLP relocation to incorrectly point to
> the external module's export instead of the internal symbol?
I'm not convinced this is a realistic scenario (module having a global
symbol with the same name as an exported symbol), but as mentioned it's
a preexisting issue that can be fixed in a followup.
--
Josh
^ permalink raw reply [flat|nested] 28+ messages in thread
* [tip: objtool/core] objtool/klp: Don't match local symbols against exports
2026-08-07 21:37 ` [PATCH v3 6/9] objtool/klp: Don't match local symbols against exports Josh Poimboeuf
2026-08-07 21:46 ` sashiko-bot
@ 2026-08-13 11:16 ` tip-bot2 for Josh Poimboeuf
1 sibling, 0 replies; 28+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2026-08-13 11:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: Song Liu, Joe Lawrence, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 86a697572c6271083694025eefa8de518eeef623
Gitweb: https://git.kernel.org/tip/86a697572c6271083694025eefa8de518eeef623
Author: Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate: Fri, 07 Aug 2026 14:37:51 -07:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 11 Aug 2026 16:10:51 -07:00
objtool/klp: Don't match local symbols against exports
While cloning a reloc, klp diff calls find_export() to determine whether
the referenced symbol is exported. That decides whether the reference
needs a klp reloc, which object the klp symbol belongs to, and whether
the symbol's data needs to be copied into the patch module.
But find_export() matches purely on symbol name, so a static function or
variable which happens to share its name with an export is mistaken for
a reference to that export:
- klp_reloc_needed() creates a klp reloc pointing at the exporting
module's symbol rather than the local one. For a vmlinux export it
skips the klp reloc altogether, leaving a normal reloc which the
module loader resolves to the vmlinux symbol.
- clone_reloc() treats the symbol as external and clones it without
its data, leaving a dangling reference.
- validate_special_section_klp_reloc() attributes a static branch or
call key to the wrong module, and for a vmlinux export skips the
unsupported-key check entirely.
Exports are always global, so ignore local symbols in find_export().
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Acked-by: Song Liu <song@kernel.org>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://patch.msgid.link/dafc7c017d1f62e2190a20dc84a52fbfc4c70210.1786138493.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-diff.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index e266a54..a7cdba0 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1102,6 +1102,9 @@ static struct export *find_export(struct symbol *sym)
{
struct export *export;
+ if (is_local_sym(sym))
+ return NULL;
+
hash_for_each_possible(exports, export, hash, str_hash(sym->name)) {
if (!strcmp(export->sym, sym->name))
return export;
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 7/9] objtool/klp: Allow new references to module exports
2026-08-07 21:37 [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Josh Poimboeuf
` (5 preceding siblings ...)
2026-08-07 21:37 ` [PATCH v3 6/9] objtool/klp: Don't match local symbols against exports Josh Poimboeuf
@ 2026-08-07 21:37 ` Josh Poimboeuf
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Joe Lawrence
2026-08-07 21:37 ` [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols Josh Poimboeuf
` (2 subsequent siblings)
9 siblings, 1 reply; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-07 21:37 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
From: Joe Lawrence <joe.lawrence@redhat.com>
klp_reloc_needed() returns true for module exports to support
late-module patching. However, clone_reloc_klp() unconditionally
rejects symbols without a twin (i.e., new references added by the
patch), even when the symbol is a known export from Module.symvers.
Relax the check: allow new references to exported symbols by only
erroring on !twin when there is no export. The export metadata from
Module.symvers provides sufficient context to emit the klp-relocation
without a twin.
For a module export that isn't sufficient on its own though, as the
resulting klp relocation will only be resolved at patch-enable time if
the exporting module is loaded.
If the original (unpatched) module already depends on the exporting
module, the dependency is safe: the module loader ensures the dependency
is satisfied before the patched module can be loaded, so the
klp relocation target will exist.
However, if the patch introduces a reference to a module that the
original doesn't depend on, there is no such guarantee. The exporting
module could be absent or could be unloaded at any time, leading to a
relocation failure or use-after-free.
So also add a build-time check: when a new symbol reference (no twin)
targets a module export, verify that the original module already has at
least one UNDEF symbol resolving to that same exporting module. If not,
error out with a diagnostic message.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-diff.c | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index f5d5711623f03..6d34186d8b24c 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1294,6 +1294,28 @@ static int convert_reloc_sym(struct elf *elf, struct reloc *reloc)
return convert_reloc_secsym_to_sym(elf, reloc);
}
+/*
+ * Check if the original module already has a dependency on dep_mod, i.e. it
+ * already references at least one export from that module.
+ */
+static bool has_module_dep(struct elfs *e, const char *dep_mod)
+{
+ struct symbol *sym;
+
+ for_each_sym(e->orig, sym) {
+ struct export *exp;
+
+ if (!is_undef_sym(sym) || is_weak_sym(sym))
+ continue;
+
+ exp = find_export(sym);
+ if (exp && !strcmp(exp->mod, dep_mod))
+ return true;
+ }
+
+ return false;
+}
+
/*
* Convert a regular relocation to a klp relocation (sort of).
*/
@@ -1313,8 +1335,17 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
unsigned long sympos;
if (!patched_sym->twin) {
- ERROR("unexpected klp reloc for new symbol %s", patched_sym->name);
- return -1;
+ if (!export) {
+ ERROR("unexpected klp reloc for new symbol %s", patched_sym->name);
+ return -1;
+ }
+
+ if (strcmp(export->mod, "vmlinux") &&
+ !has_module_dep(e, export->mod)) {
+ ERROR("%s: new reference to %s (exported by %s) would create an undeclared module dependency",
+ patched_sym->name, export->sym, export->mod);
+ return -1;
+ }
}
/*
--
2.54.0
^ permalink raw reply [flat|nested] 28+ messages in thread* [tip: objtool/core] objtool/klp: Allow new references to module exports
2026-08-07 21:37 ` [PATCH v3 7/9] objtool/klp: Allow new references to module exports Josh Poimboeuf
@ 2026-08-13 11:16 ` tip-bot2 for Joe Lawrence
0 siblings, 0 replies; 28+ messages in thread
From: tip-bot2 for Joe Lawrence @ 2026-08-13 11:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: Joe Lawrence, Song Liu, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 72d76d0c18ebd40f6a32df875ff40528564849c1
Gitweb: https://git.kernel.org/tip/72d76d0c18ebd40f6a32df875ff40528564849c1
Author: Joe Lawrence <joe.lawrence@redhat.com>
AuthorDate: Fri, 07 Aug 2026 14:37:52 -07:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 11 Aug 2026 16:10:51 -07:00
objtool/klp: Allow new references to module exports
klp_reloc_needed() returns true for module exports to support
late-module patching. However, clone_reloc_klp() unconditionally
rejects symbols without a twin (i.e., new references added by the
patch), even when the symbol is a known export from Module.symvers.
Relax the check: allow new references to exported symbols by only
erroring on !twin when there is no export. The export metadata from
Module.symvers provides sufficient context to emit the klp-relocation
without a twin.
For a module export that isn't sufficient on its own though, as the
resulting klp relocation will only be resolved at patch-enable time if
the exporting module is loaded.
If the original (unpatched) module already depends on the exporting
module, the dependency is safe: the module loader ensures the dependency
is satisfied before the patched module can be loaded, so the
klp relocation target will exist.
However, if the patch introduces a reference to a module that the
original doesn't depend on, there is no such guarantee. The exporting
module could be absent or could be unloaded at any time, leading to a
relocation failure or use-after-free.
So also add a build-time check: when a new symbol reference (no twin)
targets a module export, verify that the original module already has at
least one UNDEF symbol resolving to that same exporting module. If not,
error out with a diagnostic message.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Song Liu <song@kernel.org>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://patch.msgid.link/e0d725acb4774747f0e271308b4ca33daae2d5db.1786138493.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-diff.c | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index a7cdba0..0211e5c 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1296,6 +1296,28 @@ static int convert_reloc_sym(struct elf *elf, struct reloc *reloc)
}
/*
+ * Check if the original module already has a dependency on dep_mod, i.e. it
+ * already references at least one export from that module.
+ */
+static bool has_module_dep(struct elfs *e, const char *dep_mod)
+{
+ struct symbol *sym;
+
+ for_each_sym(e->orig, sym) {
+ struct export *exp;
+
+ if (!is_undef_sym(sym) || is_weak_sym(sym))
+ continue;
+
+ exp = find_export(sym);
+ if (exp && !strcmp(exp->mod, dep_mod))
+ return true;
+ }
+
+ return false;
+}
+
+/*
* Convert a regular relocation to a klp relocation (sort of).
*/
static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
@@ -1314,8 +1336,17 @@ static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc,
unsigned long sympos;
if (!patched_sym->twin) {
- ERROR("unexpected klp reloc for new symbol %s", patched_sym->name);
- return -1;
+ if (!export) {
+ ERROR("unexpected klp reloc for new symbol %s", patched_sym->name);
+ return -1;
+ }
+
+ if (strcmp(export->mod, "vmlinux") &&
+ !has_module_dep(e, export->mod)) {
+ ERROR("%s: new reference to %s (exported by %s) would create an undeclared module dependency",
+ patched_sym->name, export->sym, export->mod);
+ return -1;
+ }
}
/*
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols
2026-08-07 21:37 [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Josh Poimboeuf
` (6 preceding siblings ...)
2026-08-07 21:37 ` [PATCH v3 7/9] objtool/klp: Allow new references to module exports Josh Poimboeuf
@ 2026-08-07 21:37 ` Josh Poimboeuf
2026-08-11 22:36 ` Song Liu
` (2 more replies)
2026-08-07 21:37 ` [PATCH v3 9/9] objtool/klp: Fix line numbers in Module.symvers parse errors Josh Poimboeuf
2026-08-11 20:36 ` [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Joe Lawrence
9 siblings, 3 replies; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-07 21:37 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
EXPORT_SYMBOL_FOR_MODULES() puts a symbol in a "module:<names>"
namespace, which the module loader grants access to by matching the
importing module's name against that list.
klp_reloc_needed() only creates a klp reloc for module-owned exports; a
vmlinux export gets a normal reloc. For a vmlinux symbol exported with
EXPORT_SYMBOL_FOR_MODULES(), using a normal reloc results in a modpost
failure in klp-build:
ERROR: modpost: module livepatch-foo uses symbol mpol_shared_policy_lookup from namespace module:kvm, but does not import it.
And the modpost error is correct: even with that error removed, the
patch module would fail to load:
livepatch_foo: module uses symbol (mpol_shared_policy_lookup) from namespace module:kvm, but does not import it.
livepatch_foo: Unknown symbol mpol_shared_policy_lookup (err -22)
Treat it like an unexported symbol by using a klp reloc.
Note this only affects "module:" namespaces. Ordinary namespaced
exports continue to work with normal relocs thanks to copy_import_ns(),
which propagates the patched object's import_ns tags to the patch
module.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://lore.kernel.org/6a6608f4-0a05-4d75-8b7f-edddfac9c5d4@redhat.com
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-diff.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 6d34186d8b24c..0f135b74a5b0c 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -30,7 +30,9 @@ struct elfs {
struct export {
struct hlist_node hash;
- char *mod, *sym;
+ char *mod;
+ char *sym;
+ bool mod_ns;
};
bool debug, debug_correlate, debug_clone;
@@ -135,7 +137,7 @@ static int read_exports(void)
}
while (fgets(line, 1024, file)) {
- char *sym, *mod, *type;
+ char *sym, *mod, *type, *namespace;
struct export *export;
sym = strchr(line, '\t');
@@ -162,6 +164,14 @@ static int read_exports(void)
*type++ = '\0';
+ namespace = strchr(type, '\t');
+ if (!namespace) {
+ ERROR("malformed Module.symvers (namespace) at line %d", line_num);
+ return -1;
+ }
+
+ *namespace++ = '\0';
+
if (*sym == '\0' || *mod == '\0') {
ERROR("malformed Module.symvers at line %d", line_num);
return -1;
@@ -188,6 +198,9 @@ static int read_exports(void)
return -1;
}
+ /* EXPORT_SYMBOL_FOR_MODULES() */
+ export->mod_ns = strstarts(namespace, "module:");
+
hash_add(exports, &export->hash, str_hash(sym));
}
@@ -1174,11 +1187,16 @@ static bool klp_reloc_needed(struct reloc *patched_reloc)
* clusterfunk that is late module patching, the patch module is
* allowed to be loaded before any modules it depends on.
*
- * If exported by vmlinux, a normal reloc will do.
+ * If exported by vmlinux to all modules, a normal reloc will do.
*/
export = find_export(patched_sym);
- if (export)
- return strcmp(export->mod, "vmlinux");
+ if (export) {
+ if (strcmp(export->mod, "vmlinux"))
+ return true;
+
+ /* EXPORT_SYMBOL_FOR_MODULES() gets a klp reloc */
+ return export->mod_ns;
+ }
if (!patched_sym->twin) {
/*
--
2.54.0
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols
2026-08-07 21:37 ` [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols Josh Poimboeuf
@ 2026-08-11 22:36 ` Song Liu
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
2026-08-14 21:05 ` [PATCH v3 8/9] " Dylan Hatch
2 siblings, 0 replies; 28+ messages in thread
From: Song Liu @ 2026-08-11 22:36 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek
On Fri, Aug 7, 2026 at 2:38 PM Josh Poimboeuf <jpoimboe@kernel.org> wrote:
>
> EXPORT_SYMBOL_FOR_MODULES() puts a symbol in a "module:<names>"
> namespace, which the module loader grants access to by matching the
> importing module's name against that list.
>
> klp_reloc_needed() only creates a klp reloc for module-owned exports; a
> vmlinux export gets a normal reloc. For a vmlinux symbol exported with
> EXPORT_SYMBOL_FOR_MODULES(), using a normal reloc results in a modpost
> failure in klp-build:
>
> ERROR: modpost: module livepatch-foo uses symbol mpol_shared_policy_lookup from namespace module:kvm, but does not import it.
>
> And the modpost error is correct: even with that error removed, the
> patch module would fail to load:
>
> livepatch_foo: module uses symbol (mpol_shared_policy_lookup) from namespace module:kvm, but does not import it.
> livepatch_foo: Unknown symbol mpol_shared_policy_lookup (err -22)
>
> Treat it like an unexported symbol by using a klp reloc.
>
> Note this only affects "module:" namespaces. Ordinary namespaced
> exports continue to work with normal relocs thanks to copy_import_ns(),
> which propagates the patched object's import_ns tags to the patch
> module.
>
> Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
> Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
> Link: https://lore.kernel.org/6a6608f4-0a05-4d75-8b7f-edddfac9c5d4@redhat.com
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Acked-by: Song Liu <song@kernel.org>
^ permalink raw reply [flat|nested] 28+ messages in thread* [tip: objtool/core] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols
2026-08-07 21:37 ` [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols Josh Poimboeuf
2026-08-11 22:36 ` Song Liu
@ 2026-08-13 11:16 ` tip-bot2 for Josh Poimboeuf
2026-08-14 21:05 ` [PATCH v3 8/9] " Dylan Hatch
2 siblings, 0 replies; 28+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2026-08-13 11:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: Joe Lawrence, Song Liu, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 4cd3cfb8b54feca89a682720434092a87bfa4967
Gitweb: https://git.kernel.org/tip/4cd3cfb8b54feca89a682720434092a87bfa4967
Author: Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate: Fri, 07 Aug 2026 14:37:53 -07:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 11 Aug 2026 16:10:51 -07:00
objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols
EXPORT_SYMBOL_FOR_MODULES() puts a symbol in a "module:<names>"
namespace, which the module loader grants access to by matching the
importing module's name against that list.
klp_reloc_needed() only creates a klp reloc for module-owned exports; a
vmlinux export gets a normal reloc. For a vmlinux symbol exported with
EXPORT_SYMBOL_FOR_MODULES(), using a normal reloc results in a modpost
failure in klp-build:
ERROR: modpost: module livepatch-foo uses symbol mpol_shared_policy_lookup from namespace module:kvm, but does not import it.
And the modpost error is correct: even with that error removed, the
patch module would fail to load:
livepatch_foo: module uses symbol (mpol_shared_policy_lookup) from namespace module:kvm, but does not import it.
livepatch_foo: Unknown symbol mpol_shared_policy_lookup (err -22)
Treat it like an unexported symbol by using a klp reloc.
Note this only affects "module:" namespaces. Ordinary namespaced
exports continue to work with normal relocs thanks to copy_import_ns(),
which propagates the patched object's import_ns tags to the patch
module.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://lore.kernel.org/6a6608f4-0a05-4d75-8b7f-edddfac9c5d4@redhat.com
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Song Liu <song@kernel.org>
Link: https://patch.msgid.link/fe5a00818e06ec613344d41d5944de054fcd8832.1786138493.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-diff.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 0211e5c..1f05646 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -30,7 +30,9 @@ struct elfs {
struct export {
struct hlist_node hash;
- char *mod, *sym;
+ char *mod;
+ char *sym;
+ bool mod_ns;
};
bool debug, debug_correlate, debug_clone;
@@ -135,7 +137,7 @@ static int read_exports(void)
}
while (fgets(line, 1024, file)) {
- char *sym, *mod, *type;
+ char *sym, *mod, *type, *namespace;
struct export *export;
sym = strchr(line, '\t');
@@ -162,6 +164,14 @@ static int read_exports(void)
*type++ = '\0';
+ namespace = strchr(type, '\t');
+ if (!namespace) {
+ ERROR("malformed Module.symvers (namespace) at line %d", line_num);
+ return -1;
+ }
+
+ *namespace++ = '\0';
+
if (*sym == '\0' || *mod == '\0') {
ERROR("malformed Module.symvers at line %d", line_num);
return -1;
@@ -188,6 +198,9 @@ static int read_exports(void)
return -1;
}
+ /* EXPORT_SYMBOL_FOR_MODULES() */
+ export->mod_ns = strstarts(namespace, "module:");
+
hash_add(exports, &export->hash, str_hash(sym));
}
@@ -1175,11 +1188,16 @@ static bool klp_reloc_needed(struct reloc *patched_reloc)
* clusterfunk that is late module patching, the patch module is
* allowed to be loaded before any modules it depends on.
*
- * If exported by vmlinux, a normal reloc will do.
+ * If exported by vmlinux to all modules, a normal reloc will do.
*/
export = find_export(patched_sym);
- if (export)
- return strcmp(export->mod, "vmlinux");
+ if (export) {
+ if (strcmp(export->mod, "vmlinux"))
+ return true;
+
+ /* EXPORT_SYMBOL_FOR_MODULES() gets a klp reloc */
+ return export->mod_ns;
+ }
if (!patched_sym->twin) {
/*
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols
2026-08-07 21:37 ` [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols Josh Poimboeuf
2026-08-11 22:36 ` Song Liu
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
@ 2026-08-14 21:05 ` Dylan Hatch
2026-08-15 0:18 ` Josh Poimboeuf
2 siblings, 1 reply; 28+ messages in thread
From: Dylan Hatch @ 2026-08-14 21:05 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
Hi Josh,
On Fri, Aug 7, 2026 at 2:42 PM Josh Poimboeuf <jpoimboe@kernel.org> wrote:
>
> EXPORT_SYMBOL_FOR_MODULES() puts a symbol in a "module:<names>"
> namespace, which the module loader grants access to by matching the
> importing module's name against that list.
>
> klp_reloc_needed() only creates a klp reloc for module-owned exports; a
> vmlinux export gets a normal reloc. For a vmlinux symbol exported with
> EXPORT_SYMBOL_FOR_MODULES(), using a normal reloc results in a modpost
> failure in klp-build:
>
> ERROR: modpost: module livepatch-foo uses symbol mpol_shared_policy_lookup from namespace module:kvm, but does not import it.
>
> And the modpost error is correct: even with that error removed, the
> patch module would fail to load:
>
> livepatch_foo: module uses symbol (mpol_shared_policy_lookup) from namespace module:kvm, but does not import it.
> livepatch_foo: Unknown symbol mpol_shared_policy_lookup (err -22)
>
> Treat it like an unexported symbol by using a klp reloc.
>
> Note this only affects "module:" namespaces. Ordinary namespaced
> exports continue to work with normal relocs thanks to copy_import_ns(),
> which propagates the patched object's import_ns tags to the patch
> module.
>
> Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
> Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
> Link: https://lore.kernel.org/6a6608f4-0a05-4d75-8b7f-edddfac9c5d4@redhat.com
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> ---
> tools/objtool/klp-diff.c | 28 +++++++++++++++++++++++-----
> 1 file changed, 23 insertions(+), 5 deletions(-)
>
> diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
> index 6d34186d8b24c..0f135b74a5b0c 100644
> --- a/tools/objtool/klp-diff.c
> +++ b/tools/objtool/klp-diff.c
> @@ -30,7 +30,9 @@ struct elfs {
>
> struct export {
> struct hlist_node hash;
> - char *mod, *sym;
> + char *mod;
> + char *sym;
> + bool mod_ns;
> };
>
> bool debug, debug_correlate, debug_clone;
> @@ -135,7 +137,7 @@ static int read_exports(void)
> }
>
> while (fgets(line, 1024, file)) {
> - char *sym, *mod, *type;
> + char *sym, *mod, *type, *namespace;
> struct export *export;
>
> sym = strchr(line, '\t');
> @@ -162,6 +164,14 @@ static int read_exports(void)
>
> *type++ = '\0';
>
> + namespace = strchr(type, '\t');
> + if (!namespace) {
> + ERROR("malformed Module.symvers (namespace) at line %d", line_num);
> + return -1;
> + }
> +
> + *namespace++ = '\0';
> +
> if (*sym == '\0' || *mod == '\0') {
> ERROR("malformed Module.symvers at line %d", line_num);
> return -1;
> @@ -188,6 +198,9 @@ static int read_exports(void)
> return -1;
> }
>
> + /* EXPORT_SYMBOL_FOR_MODULES() */
> + export->mod_ns = strstarts(namespace, "module:");
> +
> hash_add(exports, &export->hash, str_hash(sym));
> }
>
> @@ -1174,11 +1187,16 @@ static bool klp_reloc_needed(struct reloc *patched_reloc)
> * clusterfunk that is late module patching, the patch module is
> * allowed to be loaded before any modules it depends on.
> *
> - * If exported by vmlinux, a normal reloc will do.
> + * If exported by vmlinux to all modules, a normal reloc will do.
> */
> export = find_export(patched_sym);
> - if (export)
> - return strcmp(export->mod, "vmlinux");
> + if (export) {
> + if (strcmp(export->mod, "vmlinux"))
> + return true;
> +
> + /* EXPORT_SYMBOL_FOR_MODULES() gets a klp reloc */
> + return export->mod_ns;
> + }
>
> if (!patched_sym->twin) {
> /*
> --
> 2.54.0
>
>
Following up on the other thread [1], I noticed that when a patch is
touching a module function with a reference to one of these
module-exported symbols, the patch/module is rejected because KLP
relocs referencing vmlinux symbols are not allowed from
module-specific livepatch relocation sections. I was able to reproduce
this with a simple module/livepatch combo that depends on one of these
symbols [2] (see samples/livepatch/testmod.c and test.patch):
root@debian-vm:~$ insmod livepatch-test.ko
root@debian-vm:~$ insmod testmod.ko
insmod: ERROR: could not insert module testmod.ko: Invalid parameters
With dmesg:
[ 655.596876] livepatch_test: loading out-of-tree module taints kernel.
[ 655.600961] livepatch_test: tainting kernel with TAINT_LIVEPATCH
[ 655.605436] livepatch: enabling patch 'livepatch_test'
[ 655.609119] livepatch: 'livepatch_test': starting patching transition
[ 656.653454] livepatch: 'livepatch_test': patching complete
[ 738.777872] livepatch: invalid access to vmlinux symbol
'get_task_policy' from module-specific livepatch relocation section
[ 738.784899] livepatch: failed to initialize patch 'livepatch_test'
for module 'testmod' (-22)
[ 738.790371] livepatch: patch 'livepatch_test' failed for module
'testmod', refusing to load module 'testmod'
Do you recommend a strategy for working around this, or is this
something that would have to be fixed in the kernel?
Refs:
[1]: https://lore.kernel.org/all/CADBMgpyY6R_YmEqhZSw=88-Bfkv9=s-N-x1siE1uPAgH_fTURw@mail.gmail.com/
[2]: https://github.com/dylanbhatch/linux/tree/mod-ns-lp
Thanks,
Dylan
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols
2026-08-14 21:05 ` [PATCH v3 8/9] " Dylan Hatch
@ 2026-08-15 0:18 ` Josh Poimboeuf
2026-08-15 1:25 ` Josh Poimboeuf
0 siblings, 1 reply; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-15 0:18 UTC (permalink / raw)
To: Dylan Hatch
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
On Fri, Aug 14, 2026 at 02:05:48PM -0700, Dylan Hatch wrote:
> Following up on the other thread [1], I noticed that when a patch is
> touching a module function with a reference to one of these
> module-exported symbols, the patch/module is rejected because KLP
> relocs referencing vmlinux symbols are not allowed from
> module-specific livepatch relocation sections. I was able to reproduce
> this with a simple module/livepatch combo that depends on one of these
> symbols [2] (see samples/livepatch/testmod.c and test.patch):
>
> root@debian-vm:~$ insmod livepatch-test.ko
> root@debian-vm:~$ insmod testmod.ko
> insmod: ERROR: could not insert module testmod.ko: Invalid parameters
>
> With dmesg:
> [ 655.596876] livepatch_test: loading out-of-tree module taints kernel.
> [ 655.600961] livepatch_test: tainting kernel with TAINT_LIVEPATCH
> [ 655.605436] livepatch: enabling patch 'livepatch_test'
> [ 655.609119] livepatch: 'livepatch_test': starting patching transition
> [ 656.653454] livepatch: 'livepatch_test': patching complete
> [ 738.777872] livepatch: invalid access to vmlinux symbol
> 'get_task_policy' from module-specific livepatch relocation section
> [ 738.784899] livepatch: failed to initialize patch 'livepatch_test'
> for module 'testmod' (-22)
> [ 738.790371] livepatch: patch 'livepatch_test' failed for module
> 'testmod', refusing to load module 'testmod'
>
> Do you recommend a strategy for working around this, or is this
> something that would have to be fixed in the kernel?
Ah, this is another tooling issue, let me work up a patch.
--
Josh
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols
2026-08-15 0:18 ` Josh Poimboeuf
@ 2026-08-15 1:25 ` Josh Poimboeuf
0 siblings, 0 replies; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-15 1:25 UTC (permalink / raw)
To: Dylan Hatch
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
On Fri, Aug 14, 2026 at 05:18:19PM -0700, Josh Poimboeuf wrote:
> On Fri, Aug 14, 2026 at 02:05:48PM -0700, Dylan Hatch wrote:
> > Following up on the other thread [1], I noticed that when a patch is
> > touching a module function with a reference to one of these
> > module-exported symbols, the patch/module is rejected because KLP
> > relocs referencing vmlinux symbols are not allowed from
> > module-specific livepatch relocation sections. I was able to reproduce
> > this with a simple module/livepatch combo that depends on one of these
> > symbols [2] (see samples/livepatch/testmod.c and test.patch):
> >
> > root@debian-vm:~$ insmod livepatch-test.ko
> > root@debian-vm:~$ insmod testmod.ko
> > insmod: ERROR: could not insert module testmod.ko: Invalid parameters
> >
> > With dmesg:
> > [ 655.596876] livepatch_test: loading out-of-tree module taints kernel.
> > [ 655.600961] livepatch_test: tainting kernel with TAINT_LIVEPATCH
> > [ 655.605436] livepatch: enabling patch 'livepatch_test'
> > [ 655.609119] livepatch: 'livepatch_test': starting patching transition
> > [ 656.653454] livepatch: 'livepatch_test': patching complete
> > [ 738.777872] livepatch: invalid access to vmlinux symbol
> > 'get_task_policy' from module-specific livepatch relocation section
> > [ 738.784899] livepatch: failed to initialize patch 'livepatch_test'
> > for module 'testmod' (-22)
> > [ 738.790371] livepatch: patch 'livepatch_test' failed for module
> > 'testmod', refusing to load module 'testmod'
> >
> > Do you recommend a strategy for working around this, or is this
> > something that would have to be fixed in the kernel?
>
> Ah, this is another tooling issue, let me work up a patch.
Here is an untested diff, I'll post a proper patch once I get a chance
to test it.
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)
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 9/9] objtool/klp: Fix line numbers in Module.symvers parse errors
2026-08-07 21:37 [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Josh Poimboeuf
` (7 preceding siblings ...)
2026-08-07 21:37 ` [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols Josh Poimboeuf
@ 2026-08-07 21:37 ` Josh Poimboeuf
2026-08-11 22:36 ` Song Liu
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
2026-08-11 20:36 ` [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Joe Lawrence
9 siblings, 2 replies; 28+ messages in thread
From: Josh Poimboeuf @ 2026-08-07 21:37 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek, Song Liu
read_exports() reports the offending line number when it fails to parse
Module.symvers. The counter is initialized to 1 but never incremented,
so every error blames line 1 regardless of where the bad line is.
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-diff.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 0f135b74a5b0c..b6b72ed71bf02 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -118,7 +118,7 @@ static int read_exports(void)
{
const char *symvers = "Module.symvers";
char line[1024], *path = NULL;
- unsigned int line_num = 1;
+ unsigned int line_num = 0;
FILE *file;
file = fopen(symvers, "r");
@@ -140,6 +140,8 @@ static int read_exports(void)
char *sym, *mod, *type, *namespace;
struct export *export;
+ line_num++;
+
sym = strchr(line, '\t');
if (!sym) {
ERROR("malformed Module.symvers (sym) at line %d", line_num);
--
2.54.0
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH v3 9/9] objtool/klp: Fix line numbers in Module.symvers parse errors
2026-08-07 21:37 ` [PATCH v3 9/9] objtool/klp: Fix line numbers in Module.symvers parse errors Josh Poimboeuf
@ 2026-08-11 22:36 ` Song Liu
2026-08-13 11:16 ` [tip: objtool/core] " tip-bot2 for Josh Poimboeuf
1 sibling, 0 replies; 28+ messages in thread
From: Song Liu @ 2026-08-11 22:36 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Miroslav Benes, Petr Mladek
On Fri, Aug 7, 2026 at 2:38 PM Josh Poimboeuf <jpoimboe@kernel.org> wrote:
>
> read_exports() reports the offending line number when it fails to parse
> Module.symvers. The counter is initialized to 1 but never incremented,
> so every error blames line 1 regardless of where the bad line is.
>
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Acked-by: Song Liu <song@kernel.org>
^ permalink raw reply [flat|nested] 28+ messages in thread
* [tip: objtool/core] objtool/klp: Fix line numbers in Module.symvers parse errors
2026-08-07 21:37 ` [PATCH v3 9/9] objtool/klp: Fix line numbers in Module.symvers parse errors Josh Poimboeuf
2026-08-11 22:36 ` Song Liu
@ 2026-08-13 11:16 ` tip-bot2 for Josh Poimboeuf
1 sibling, 0 replies; 28+ messages in thread
From: tip-bot2 for Josh Poimboeuf @ 2026-08-13 11:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: Joe Lawrence, Song Liu, Josh Poimboeuf, x86, linux-kernel
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 51c1de13486315ad46a74b40ec17124916a08277
Gitweb: https://git.kernel.org/tip/51c1de13486315ad46a74b40ec17124916a08277
Author: Josh Poimboeuf <jpoimboe@kernel.org>
AuthorDate: Fri, 07 Aug 2026 14:37:54 -07:00
Committer: Josh Poimboeuf <jpoimboe@kernel.org>
CommitterDate: Tue, 11 Aug 2026 16:10:58 -07:00
objtool/klp: Fix line numbers in Module.symvers parse errors
read_exports() reports the offending line number when it fails to parse
Module.symvers. The counter is initialized to 1 but never incremented,
so every error blames line 1 regardless of where the bad line is.
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Song Liu <song@kernel.org>
Link: https://patch.msgid.link/133e16bb0c7cb916f10bbfb017eba525449ad1d6.1786138493.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/klp-diff.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 1f05646..cdc63ab 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -118,7 +118,7 @@ static int read_exports(void)
{
const char *symvers = "Module.symvers";
char line[1024], *path = NULL;
- unsigned int line_num = 1;
+ unsigned int line_num = 0;
FILE *file;
file = fopen(symvers, "r");
@@ -140,6 +140,8 @@ static int read_exports(void)
char *sym, *mod, *type, *namespace;
struct export *export;
+ line_num++;
+
sym = strchr(line, '\t');
if (!sym) {
ERROR("malformed Module.symvers (sym) at line %d", line_num);
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes
2026-08-07 21:37 [PATCH v3 0/9] objtool/klp: sympos/module/alternative/etc fixes Josh Poimboeuf
` (8 preceding siblings ...)
2026-08-07 21:37 ` [PATCH v3 9/9] objtool/klp: Fix line numbers in Module.symvers parse errors Josh Poimboeuf
@ 2026-08-11 20:36 ` Joe Lawrence
9 siblings, 0 replies; 28+ messages in thread
From: Joe Lawrence @ 2026-08-11 20:36 UTC (permalink / raw)
To: Josh Poimboeuf, x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Miroslav Benes,
Petr Mladek, Song Liu
On 8/7/26 5:37 PM, Josh Poimboeuf wrote:
> v3:
> - remove "size = 0" and add comments to create_fake_symbols()
> - add patches 8 & 9
>
> v2: https://lore.kernel.org/cover.1785939903.git.jpoimboe@kernel.org
> - rebased on tip/master (first 6 patches were merged)
> - dropped original patches 7-8 (will post followup)
> - added .klp.symid fix
>
> v1: https://lore.kernel.org/cover.1785727106.git.jpoimboe@kernel.org
>
> This consolidates fixes for the klp-build issues reported by Joe over
> the last several weeks, plus some more things I found while
> testing/reviewing.
>
> Joe Lawrence (1):
> objtool/klp: Allow new references to module exports
>
> Josh Poimboeuf (8):
> objtool/klp: Fix vmlinux .klp.symid link error for .no_trim_symbol
> symbols
> objtool/klp: Fix size of empty special section entries
> objtool/klp: Ignore replacement offset of empty x86 alternatives
> objtool/klp: Explicitly disallow patching or referencing init
> code/data
> objtool/klp: Fix cross-module klp relocation section naming
> objtool/klp: Don't match local symbols against exports
> objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols
> objtool/klp: Fix line numbers in Module.symvers parse errors
>
> tools/objtool/arch/x86/special.c | 27 ++++++
> tools/objtool/include/objtool/klp.h | 10 ++-
> tools/objtool/include/objtool/special.h | 7 ++
> tools/objtool/klp-diff.c | 106 ++++++++++++++++++++----
> tools/objtool/klp-post-link.c | 53 +++++++-----
> tools/objtool/klp-symid.c | 1 +
> tools/objtool/klp-sympos.c | 10 +++
> 7 files changed, 175 insertions(+), 39 deletions(-)
>
For the series:
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Previous test cases from the earlier parent patchsets and reports run
positive now.
Thanks,
--
Joe
^ permalink raw reply [flat|nested] 28+ messages in thread