From nobody Wed Sep 30 13:30:08 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85821415F03; Fri, 7 Aug 2026 21:38:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138720; cv=none; b=qEVGfnMCIpmnGhuDnOBgymqmorGclJahoW819cttyi19vWA4ovBfTyuS4tnng5x0hRlAp89dlT7Hj9+JVGA2iVgEsX67ESPmSpzZnQk5RULYmxSOp9/LI8HfXcUB8pJSe4q8UtkfUY687DXBwZCu3AQfLlSAjozaawqylIhQZ/I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138720; c=relaxed/simple; bh=VXmRrWZVTHFaT7hofHWs3uSAAGiWMDQtf3H3uLLqqQg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pcxG9hgO7nwSvFyEAxStGPzBYKlz9zn90SNTDjjHOyR43SQ5Rcakfum8AMTAg0FU49+1TZFLY0sasEFjkmM6diL1KBTOsRqGjCNKbgsrMaF8NVCqktbJb45HMspcOPvBzEiJ5vCWKNs9cRQcAxNQLAwRhbPB4y4b++c1uKTGiX8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=M/LAlQUB; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="M/LAlQUB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 269361F00A3A; Fri, 7 Aug 2026 21:38:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786138719; bh=rUt6locn3ii5lFfPGy35WculRb7UPWo5ZkS+XRT+YPI=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=M/LAlQUBSGNbkBk8kNegLoB9psbIVq2hZ/NbKTfn0olLYFc5cff8MbMhT6zhxlmaM NYhZAvgzQhCVR5pfQbssRwF9KsTvngqTuduleVQ6fCFSvAfB8lnAKOorVePywTgQAv LN7cVz9CSi7RQbleoEUaS3ZoiAC1YpkB4grAIYJ5MuKqHpzdPF3oDQ063pMR0J1v7j qb0kPXFizm3WFzBHOePW/Wnf6VMV0gCQKO1J9XLFPSbOBM6RfyIfKxKMNVauxWMOIr iUfXJ7rSjFZ/uX9TdnJJH7N3eqxYKyC+Ay2sxjMa7A+eLkg7lsJDfn9ZlSOiKy8Hfk pevifzF7hK+OQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Miroslav Benes , Petr Mladek , Song Liu Subject: [PATCH v3 1/9] objtool/klp: Fix vmlinux .klp.symid link error for .no_trim_symbol symbols Date: Fri, 7 Aug 2026 14:37:46 -0700 Message-ID: <5a3cc4cded743167dd0878220201d80f7e48e5d7.1786138493.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Signed-off-by: Josh Poimboeuf Acked-by: Joe Lawrence --- 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[] =3D { ".discard", ".modinfo", + ".no_trim_symbol", "__tracepoint_check", }; =20 --=20 2.54.0 From nobody Wed Sep 30 13:30:08 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F1B5A42376E; Fri, 7 Aug 2026 21:38:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138721; cv=none; b=A6MOUTGuq+cGmb/PYgeQSTNsTj7cymTGzCTGP8pByYl4baPz87Xu8dtP3xjK2RfkHPcNydjv8p1kxY+zmm4I47d7LkGfPLi6Dt0A8D1B+wxvNOcHTHSXh2bQNXXYgC3Z42kIMbZM57EHd1Pd8foyIbux41nag8jGFIz7Ve1CYvo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138721; c=relaxed/simple; bh=+BzvaZZkVfJk3xOhpsyMKt5MWHinWb0UZMOk+WFSg8k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uVFUTSFRftZb90v6lhL2GUPtogAIr1fT1tnFR7bqXzcUfEHo5qMVDWoC9iNGu+FZxgNeButp2wqqp2/c4kY17IDsj9WYHb0wDwX6w0HYFaovOoowBolsoTkC6N8nJCckP4vDwJJzftRxKvOY2tkJm+Kzt18ikosZFbOktoMhYmA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bKqaPCb2; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bKqaPCb2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 92BB91F00AC4; Fri, 7 Aug 2026 21:38:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786138719; bh=5YxbHzQFTHjQ5H8M6FCESecxFZ6y2bsJGH2Pqky/X40=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bKqaPCb2e0xiWM2sLiAhdYmtNmUIDjnw3U6GlIs9RItkDz3Vu+Q7SjXVWqN/FtwM0 PGf6tvMV/Vj6D6aLMeX43TDyNrejA55Q7GQk2JWZB80fc1tKhKe0+5SKDCydzya7hp l/+tLJLYiQGdzE2ZqnbheqK+r125FBRMp+qR7isMusHc/Wulrw2BZya8LKU7uJBRGm TwiLzE3IzKAHredH1j2hjPpXV2qv5PEx8MFggJewO2llp+bjl3OgDQ+YnEPqMymlOP D+N6rLCXdY473fXy1M7PXRpXkAnsUBG4AGWwQ9JU96rHDX6D/HkuBb+rW7CzO9mq2d 58JueAT+eZzPg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Miroslav Benes , Petr Mladek , Song Liu Subject: [PATCH v3 2/9] objtool/klp: Fix size of empty special section entries Date: Fri, 7 Aug 2026 14:37:47 -0700 Message-ID: <913e691c5009397df832c7c9a18cd5cf71b42737.1786138493.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 diffin= g object files") Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Acked-by: Joe Lawrence --- 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 =3D true; =20 if (annotype(elf, sec, reloc) !=3D ANNOTYPE_DATA_SPECIAL) continue; =20 offset =3D reloc_addend(reloc); =20 - size =3D 0; + /* + * Find the start of the next entry so the fake symbol size can + * be calculated. + */ next_reloc =3D reloc; for_each_reloc_continue(sec->rsec, next_reloc) { if (annotype(elf, sec, next_reloc) !=3D ANNOTYPE_DATA_SPECIAL || @@ -1641,10 +1645,15 @@ static int create_fake_symbols(struct elf *elf) continue; =20 size =3D reloc_addend(next_reloc) - offset; + last =3D false; break; } =20 - 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 =3D sec_size(reloc->sym->sec) - offset; =20 if (create_fake_symbol(elf, reloc->sym->sec, offset, size)) --=20 2.54.0 From nobody Wed Sep 30 13:30:08 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8ED3D44B66B; Fri, 7 Aug 2026 21:38:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138722; cv=none; b=Z/wW3i8H/TvBeGvxklHcXMGbiJ9EvVPaooq4JPdlf8xmuzVJ1CeIYIG2rSuyWU1jhcsJf7pYpsoFiGlO4zyQhP4Opl+NttjTMN5ZqIzIagjvKZdHdkF4RkkVj1Al/VTpNmNRjLRYrwm460xDjNZ/ksONT6OFGrMTXWPGSIuQ6ig= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138722; c=relaxed/simple; bh=Oj0MZAFIPqcVhMYlFk7DZYnkLbGBbL1KOnHgLtS/EKw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cv8x5O28Y6egY78a/NeVKoi1Bl2JBfVOP7eMj35/RUiT0g/U/6BVF4YxhiLpVK25saAzw+4P36MkD8Gh16VKC+t0p81sxGrkrP02Cz3Djwk9NW69KnNhoQRQi6qbt70/gPHk+0pd75apnfZ8y9XdarOaKLuDnE9rhgyWhN3XT1E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lw2ml4nc; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lw2ml4nc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0C41D1F00A3D; Fri, 7 Aug 2026 21:38:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786138720; bh=6wmt6zx3S/sVJejR7/3VdUFxd34zawTVy2v30WJBpzY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=lw2ml4ncZukbNeWdzrZWCshMdjGy8qeVMv71sPHou5ZY54q/Gyj1/X4o8Jtvu2KQ9 BZzR0TDPu0DgHeJTpqP32rn/dYCmDQ+Kaculh7YU64LS1pfp3U94/2OgVpuzSFqqoS suYy+ZekDOo3pM78qw9zLIkAuGRgSy+nl4KsBsxxP9hiRdfs6mnjRuPUkVl3FaW2s4 eeNU888Hlf9XRfbX4xcZPm0KODCzt4z4ymkMFBguFF0Eg5h7cF1KVDiqF3RFjOqt/K Z/lcLJjGwH2QqzYjxNLpl3OC7o6wCinSeG6T9epKFqTPALE1vpa9TDKM5fGkSFOisR TQ+HE0zdiKJUg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Miroslav Benes , Petr Mladek , Song Liu Subject: [PATCH v3 3/9] objtool/klp: Ignore replacement offset of empty x86 alternatives Date: Fri, 7 Aug 2026 14:37:48 -0700 Message-ID: <7a885b70974795c3417f3358869e62aafd4ef783.1786138493.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 diffin= g object files") Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Acked-by: Joe Lawrence --- 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/spec= ial.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 =20 +#include #include #include #include @@ -9,6 +10,32 @@ /* cpu feature name array generated from cpufeatures.h */ #include "cpu-feature-names.c" =20 +/* + * 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 p= oints + * 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 =3D offset - (offset % ALT_ENTRY_SIZE); + + if (offset - entry_off !=3D 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/includ= e/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); =20 void arch_handle_alternative(struct special_alt *alt); =20 +/* + * Should the reloc at @offset -- the "new" (replacement) field of a speci= al + * section group entry -- be ignored? The meaning of a zero-length replac= ement + * 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 #include #include -#include +#include =20 #include #include @@ -1537,6 +1537,10 @@ static int clone_sym_relocs(struct elfs *e, struct s= ymbol *patched_sym) !strcmp(patched_reloc->sym->sec->name, ".altinstr_aux")) continue; =20 + if (arch_alt_ignore_new_reloc(patched_sym->sec, + reloc_offset(patched_reloc))) + continue; + ret =3D convert_reloc_sym(e->patched, patched_reloc); if (ret < 0) { ERROR_FUNC(patched_rsec->base, reloc_offset(patched_reloc), --=20 2.54.0 From nobody Wed Sep 30 13:30:08 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E404E451984; Fri, 7 Aug 2026 21:38:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138722; cv=none; b=YyVDE3GRs6N9qRt2xILm8ot10dVugVbU1uKkzUsCEdBMA6oYyDH3Mhv/KnYa4PWuzYI9iGSgz7TmD0yLCCCmyIetgUhN8WrWccXcV7WMHB7yY3LT9dAezbhOFIAlSP7N391uIEikOTBWREz9Mhba9C1FLERdYILnUys4oVBQk2I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138722; c=relaxed/simple; bh=bXKEGCDiURahuIcWqn7gu0B7fl5MuFihQ3kAmjaVRd0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s7/ucuXWYGGLJqxSskslYboYRnqcfBX1+U2YpTF/WE5LBCppl4upgepsgMIs9lXmb2t3Iv2LUAdeKZKj2a2IwQFxDC2wa3CRo2zfhbRsuiGHDCuHtKDvMvTK5kMOBAomfa808URbU+EjuNBGZOQ/1vYJgQRNb7Itb2AUS0U+I+s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GP8Zcy2b; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GP8Zcy2b" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7BA311F000E9; Fri, 7 Aug 2026 21:38:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786138720; bh=BqeFykBVHZByMoJTH9yxSh/5uI8akOGShaiCSHB7jhk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=GP8Zcy2bMiiezdGo2WbdbcBoK8dmjgDRBzg2M02DLuhGAlmPs0+8XtOquN/hdRapo ILf/MYvWHPnP8EEiBO5IQE4SjgbpS9fZ3Rr+nXNlGZ4xaTuRsTAyo39Ur1iUrZKTtC Km7TMqh1dePg4w7blG0/oDys+13903PEhQdsa+u+qTTxvt03/lP6jQkhLq0U5VnMKm gFadfGIbGXAkpoqUBxkIA5RGa8XqkvaV0ly0okbaG/O2u36gmPW4erqkeaqisWqJQq f6sw97qRWX5i9UVJLStnc5glJqj2yRRiY4qpr1ZPj3lVUwjyxEmCSEkm4/z65VFtJ+ SaLqPto8eZ4xA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Miroslav Benes , Petr Mladek , Song Liu Subject: [PATCH v3 4/9] objtool/klp: Explicitly disallow patching or referencing init code/data Date: Fri, 7 Aug 2026 14:37:49 -0700 Message-ID: <516e14f84cfbffa27dc19d3dcf35097504097966.1786138493.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Acked-by: Joe Lawrence Acked-by: Song Liu --- 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; } =20 +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 =3D false; struct symbol *s; =20 + if (is_init_sym(sym)) { + ERROR("%s: can't patch or reference init code/data", sym->name); + return ULONG_MAX; + } + if (sym->bind !=3D STB_LOCAL) return 0; =20 --=20 2.54.0 From nobody Wed Sep 30 13:30:08 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5935545349A; Fri, 7 Aug 2026 21:38:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138722; cv=none; b=grsk49V4sAu03D56dDcuCNtLQIgqQHAQGz8ofJ5rbrox+0Ee8e3YJYZSRF5rJPWEKnNpvBzalmbcc58S0v8VC8kJQ+IYn+z5XCWctx7hIoGeIj2pDO472tKPnkgBMvh+icpmFjSvTC8UTQwW4hltI08Glnrju5n0LyCimHlTg8A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138722; c=relaxed/simple; bh=IW9cNFoRiuJy4YzMq2KgLK/cOVTbSvW08rirZRcR+dw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W5x9GKW+6qNVZcy8dW+jdlxIOTZFjSejNXG9e4H46pDer9ZYOWXIi4SgR0lwRygjfPJ+ZfLH+VyJbbho4QBfCxuHyB0rHXFTOdF7jgZy2xS1Jxut+Df35Ab+T/BexGe08+2UyFxElxNHxXV/W/mXxYHR+HJp2TgNB25Z9AszmVo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JsefgDlh; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JsefgDlh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EC1911F00A3F; Fri, 7 Aug 2026 21:38:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786138721; bh=Ew7p+eDY/IuJsUiGQLZRB/XNmXqA8BRiHUnlU+zcnAg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=JsefgDlhYp6NMA/Wqa/iIjgTslALBSqUH40792URkWhc9qpUFc8ndOQL9Ddx6Df+b UstyBEwtlPxmZmRcLf0he4zHfNXKNgm7cmSZoD3O0HVnQDaAIqNeM9sTILCA6oUBZT P7aK9E8sP0bDwy4I3897aybkGSo7V0tIg4ETx4aOzwaoXKWHLjxgEkRkGnRkLms4Rq WpjLssSq36UrEoGsO/T92B67cWu1ZBrDHc22zUpHwGHsJaKe63zW6FYVMJndbvXYAE NwmeiOzeFctMf0pD1g949WCuIybV3+U8T2By++97rELXGmv3ltzDmjQEclDI2N7mgi ci/hxTZuRRdqw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Miroslav Benes , Petr Mladek , Song Liu Subject: [PATCH v3 5/9] objtool/klp: Fix cross-module klp relocation section naming Date: Fri, 7 Aug 2026 14:37:50 -0700 Message-ID: X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A klp relocation section is .klp.rela.., 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. so post-link can read the patched object's name from there. Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffin= g object files") Reported-by: Joe Lawrence Link: https://lore.kernel.org/20260720145658.1103243-2-joe.lawrence@redhat.= com Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Acked-by: Joe Lawrence --- 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/ob= jtool/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" =20 /* - * __klp_relocs is an intermediate section which are created by klp diff a= nd - * converted into KLP symbols/relas by "objtool klp post-link". This is n= eeded - * to work around the linker, which doesn't preserve SHN_LIVEPATCH or + * __klp_relocs. are intermediate sections which are created by k= lp + * 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_LIVEPAT= CH 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 rel= oc *patched_reloc, } =20 /* - * Create the __klp_relocs entry. This will be converted to an actual - * KLP rela by "objtool klp post-link". + * Create the __klp_relocs. 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 re= loc *patched_reloc, */ =20 if (!klp_relocs) { - klp_relocs =3D elf_create_section(e->out, KLP_RELOCS_SEC, 0, + const char *objname =3D 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 =3D 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 #include =20 -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 =3D find_section_by_name(elf, KLP_RELOCS_SEC); - if (!klp_relocs) - return 0; - - symtab =3D find_section_by_name(elf, ".symtab"); - if (!symtab) { - ERROR("missing .symtab"); - return -1; - } + /* section format: __klp_relocs.sec_objname */ + const char *sec_objname =3D klp_relocs->name + strlen(KLP_RELOCS_SEC "."); =20 for (int i =3D 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 =3D 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; } =20 @@ -66,17 +57,13 @@ static int fix_klp_relocs(struct elf *elf) reloc =3D 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; } =20 klp_sym =3D reloc->sym; addend =3D reloc_addend(reloc); =20 - /* symbol format: .klp.sym.modname.sym_name,sympos */ - if (sscanf(klp_sym->name + strlen(KLP_SYM_PREFIX), "%55[^.]", sym_modnam= e) !=3D 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; =20 klp_rsec =3D find_section_by_name(elf, rsec_name); @@ -134,10 +121,32 @@ static int fix_klp_relocs(struct elf *elf) return 0; } =20 +static int fix_klp_relocs(struct elf *elf) +{ + struct section *symtab, *sec; + + symtab =3D 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 t= o be - * processed by livepatch. This needs to run last to avoid linker wreckag= e. + * converts the intermediate __klp_relocs.* sections into proper KLP reloc= s to + * be processed by livepatch. This needs to run last to avoid linker wrec= kage. * Linkers don't tend to handle the "two rela sections for a single base * section" case very well, nor do they appreciate SHN_LIVEPATCH. */ --=20 2.54.0 From nobody Wed Sep 30 13:30:08 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E6B7F45516B; Fri, 7 Aug 2026 21:38:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138723; cv=none; b=j73dknKN8QxMaQrdzua2wiESl/T3UYFnDpOJuy0+fmIH1Of7mXagCcdlNPao7ZaFTtbLCRy16kpNBsdha3e2ivTDpt3ljNxxsCY6Ccj6uf8++H1GYcryKUuWDFLCrPls3OaWCpROePLCz2G/UDeA5fwuqTJmwqizqStHMXsZ/4M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138723; c=relaxed/simple; bh=nafCKiDx5wfPWcCW8RykKOt2cUm3pDGNRFonizi2nOE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KFkEfehVUIOZeRfa5HWTpktQcGLiS6K4IauYZZy5vxqTOeCmpraA0d/xJNdOxzuKh7THmTMq1BTVWKZJAZJ39lFK174hh3a+6IxD/bq4sH3EW1hnDBwj+s0kyDhDZGznIw8A+0v2XYiNrW0jK+nXz5Ozko/QJYR03BSRNdGlQBw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NbgJK0La; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NbgJK0La" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 64BEA1F00A3A; Fri, 7 Aug 2026 21:38:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786138721; bh=YTz9xOUv3hUl4ccUxxl7Lc5HUhJ0Of4V9r0GYOZtoZ4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=NbgJK0La6t300VRHLpHWA9GgxmjJ2Nn5pFhAgDtKwPnQZjAsxE5qLij/DLUO6h/mN Q0ND3KHTKdevJCeNRD5N4Up8McI+vaN441pASDeO49a+tiwpTms6rOSRUYLZ3NUIoQ VsuH6Ul8znX6Xi0k7UOrbDDXWr3E5ywz+Uja9LMkcHPu0bFDgADCjET5AYVWO/DZaQ VxeTY1IPZIqdPdm0e6NhgTdYOX7wQ0+iyrTm3/yRRSDi1rVHDJl+Q6h8GlhrTkDbCY pDa7kpkQ/MvGv9Osw1P+djR2QOK+mbHMTpgo3Hm7hX5mYRFBu5JgT4Fw345vDVb2MN l+sfoxzudOvPw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Miroslav Benes , Petr Mladek , Song Liu Subject: [PATCH v3 6/9] objtool/klp: Don't match local symbols against exports Date: Fri, 7 Aug 2026 14:37:51 -0700 Message-ID: X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 diffin= g object files") Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Acked-by: Joe Lawrence --- 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; =20 + 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; --=20 2.54.0 From nobody Wed Sep 30 13:30:08 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 48EF145518E; Fri, 7 Aug 2026 21:38:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138724; cv=none; b=bUfsQBhF9MuCu+e4yor6de8TTpZNDGJRptAAdROlJ90MxpB7+GlV32Vv7o5Qb3p8EQVXP/i62HaPHSeLc4na/BdzpdmQlaanQ3gXs5/XmIng0ta+XiU0AtYlWN6up4V/PZN6IBbpXd0EDWG7fkHsDb30NyG1kXwDYHivILDIH1s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138724; c=relaxed/simple; bh=asFX3CX0rlaBJ4ZrCVCjnhKEqTe/DPQwTAkuxFEeNIM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HOaz4731PRB0/mBcrKdnZWBBLMwqcXPuhgoskrMnVahNe3q4Kke+JujIoM2v2KDwtpMGcjdWPmgbfJ6PTL5C514FiFb9KmHzDwC9ejvOx85WUkI5CDNQbfXUP8uZcaANETnJCOPVdUFptqVv90nl2GR55Ietkvm9rFt1gEK+mtU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DV3zP+Dw; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DV3zP+Dw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D75041F00AC4; Fri, 7 Aug 2026 21:38:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786138722; bh=LbQAr6NzwALX9OiU99ghM44FeYC8mo3sdfunpkYkV80=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=DV3zP+DwNOyUE3AAA4OlS1fUrgTwLL9AS5ozgsxo+2O8qatube3QPve7KKbGIKtqQ l/LCf3qgzS4UOb71xgZ6+eGWgoSxx+yUu010FRLxNt6HxZVIsq07hVLqZ48BmQ4MdE zyQpiDKUq6KBgNOTSOi9IN/v2ydmIGx/NLAq+iNSFOSHYBs+pZg9+rNfV8+XpGNVkN TEyq/CmpmBgVoVo4iSPQKjuG4nkdErGHClrChH8CtCLyyAwXQGw0UnR51tPivYJ4OH /pxGMGAsfOKlw3S9M4RJfHSGFW4GxTNGznlLdu6M02vq3cdXfOjcmaXL1DFAISU/cD ElkcABwgkpvPg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Miroslav Benes , Petr Mladek , Song Liu Subject: [PATCH v3 7/9] objtool/klp: Allow new references to module exports Date: Fri, 7 Aug 2026 14:37:52 -0700 Message-ID: X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Joe Lawrence 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 Acked-by: Song Liu Signed-off-by: Josh Poimboeuf Acked-by: Joe Lawrence --- 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); } =20 +/* + * 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 =3D 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 re= loc *patched_reloc, unsigned long sympos; =20 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 undecla= red module dependency", + patched_sym->name, export->sym, export->mod); + return -1; + } } =20 /* --=20 2.54.0 From nobody Wed Sep 30 13:30:08 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 03C14456E01; Fri, 7 Aug 2026 21:38:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138725; cv=none; b=F3yseoPDHJVvvmE+KG45MelWAngqRPm3BEp2qfbMOvkUUXKDQVfOl0G8+FcXtow2Adv7hIXpBKeIwBQcE8T38qpnYM3WYoss0V2+8q9gp+u62rkHOiiqnyfCil53rXSjOV/I4OWrtIl0TxVnw3w2L0778EpM7QG3JziNOgThMfM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138725; c=relaxed/simple; bh=yfT83NfMmxwDWXpL0sZ8AgbRR1EuYgUXMPYYRIaEFsw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KaXqdjolrJbmV0gdEcyps6ZQ1Ix2nnSxnuwHZerHn/iO1uMkFLwH2ysh+rMah7JBMj7wYDV/X0/AjpFdk9gp6tqvaP3tFwiHJemT+5OZ9oz0OCf84kfYuG5qHBXjNfHPkX11i7IOhj3fkszuIHlM41l4L8eFFCpBuF8wpsm9wtw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F+31Xlz3; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="F+31Xlz3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 572581F000E9; Fri, 7 Aug 2026 21:38:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786138722; bh=kMHbMszEw8NgGlWDhFr8v0jHezHZ3bKkdPIBbxKNYvE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=F+31Xlz3Qz8WMuh2N/NSYc4tedQ3T07bpT/nNw8kmbeLj8BhT6y1gOAG+9Eyd3/me DJLWcXRabvBMSsaHAnFmSbNqiEyq2RySDfUDjyYFc6OCLLQT9mcl5XBF6szvKnX00k KIK1qeZTnNgR2L0XQADe3lt5WOFmMFSr7NGECjiaIGSlwUH5/2mJJTBTJSjPDNG7gK oItRGoIZwZGqQaC3Q8Vep2bB8d44qwpkEJcwYQUfH+QvbROeyWkWI76jj8dfaOiSY9 U9o/NpvvcGTBLgAmp17GZI3fXcqLLUDneCilh5q4aaORif16Lhgo81mkyWuU4hdJgq 0MykqNNsRvrUQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Miroslav Benes , Petr Mladek , Song Liu Subject: [PATCH v3 8/9] objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols Date: Fri, 7 Aug 2026 14:37:53 -0700 Message-ID: X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" EXPORT_SYMBOL_FOR_MODULES() puts a symbol in a "module:" 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_looku= p 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 namesp= ace 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 diffin= g object files") Reported-by: Joe Lawrence Link: https://lore.kernel.org/6a6608f4-0a05-4d75-8b7f-edddfac9c5d4@redhat.c= om Signed-off-by: Josh Poimboeuf Acked-by: Joe Lawrence Acked-by: Song Liu --- 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 { =20 struct export { struct hlist_node hash; - char *mod, *sym; + char *mod; + char *sym; + bool mod_ns; }; =20 bool debug, debug_correlate, debug_clone; @@ -135,7 +137,7 @@ static int read_exports(void) } =20 while (fgets(line, 1024, file)) { - char *sym, *mod, *type; + char *sym, *mod, *type, *namespace; struct export *export; =20 sym =3D strchr(line, '\t'); @@ -162,6 +164,14 @@ static int read_exports(void) =20 *type++ =3D '\0'; =20 + namespace =3D strchr(type, '\t'); + if (!namespace) { + ERROR("malformed Module.symvers (namespace) at line %d", line_num); + return -1; + } + + *namespace++ =3D '\0'; + if (*sym =3D=3D '\0' || *mod =3D=3D '\0') { ERROR("malformed Module.symvers at line %d", line_num); return -1; @@ -188,6 +198,9 @@ static int read_exports(void) return -1; } =20 + /* EXPORT_SYMBOL_FOR_MODULES() */ + export->mod_ns =3D strstarts(namespace, "module:"); + hash_add(exports, &export->hash, str_hash(sym)); } =20 @@ -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 =3D 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; + } =20 if (!patched_sym->twin) { /* --=20 2.54.0 From nobody Wed Sep 30 13:30:08 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6FBC745348A; Fri, 7 Aug 2026 21:38:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138726; cv=none; b=IplNh25ApIt8qe9I6eiAIEUQ21Xd7ObPI/PCn4wCusLiBozwY4SoAe3ufAMeOHRJI4iAT83ITtLOTW/g/AdXqIKSZQ4dbULg4WUjUsad2I9N4oWVeFtCzGpRc7BZl0uFnlxBZxlyzuyWPS/EYC8t0qldpOR+hplrL5Sa+jRVcLc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786138726; c=relaxed/simple; bh=to014yoJn5SqY4aGIU377Mjvt5TwEOJ3/fU4EEWIGBI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oD48XmmTkEDPJfHV9qbPokFEYp4wWLfkIZyUzKl+b/m9oS3WyLgYiWM27ffg4kkyrKwZ0jIZJNc1uCelucK6j0LxdjpyyTeRjlO0SIok9NGm/6n+9/AI6GUByawyy98qETGG9Y7LaqluJ7jaUDvOkLBWy1zrR0CO/xFIeser54M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VAENn2SO; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VAENn2SO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 133EA1F00A3D; Fri, 7 Aug 2026 21:38:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1786138723; bh=+JtDE3z43FY3vC+Fg2RKoa0AqAM9urWsBd92cv1rHHw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=VAENn2SOozRa+eELNIvecDhFB85Vpm1GZxAnyopUJfIru7H6fximuq+FdHFi8rgeR VOAG7i1KKhFP8H9SrqO/RvJvHKBEQ3q81f5G0EmdgXfbXy4OnBngcZoScCuG4PC8Ho koerRzP6Ped/pEogUd8XjcD4WvT1io5D0QLM7uoFhrYItlTCS+FdbmqNKif8/SJ0WP xpAEGdxk7/rXlF0XLy5lYzA1exvx+QVCuW1ppKIQtkphGz/dyVj4u7cVI0SKcqWNJw 5l3yGpZ4p2zAcP2h1H7XNqUq91e0n8ZxeOrza0/cxvPHOWIGDKV8eSb1jQFqr9tfjU BqcD6M6DziM+g== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, live-patching@vger.kernel.org, Peter Zijlstra , Joe Lawrence , Miroslav Benes , Petr Mladek , Song Liu Subject: [PATCH v3 9/9] objtool/klp: Fix line numbers in Module.symvers parse errors Date: Fri, 7 Aug 2026 14:37:54 -0700 Message-ID: <133e16bb0c7cb916f10bbfb017eba525449ad1d6.1786138493.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Acked-by: Joe Lawrence Acked-by: Song Liu --- 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 =3D "Module.symvers"; char line[1024], *path =3D NULL; - unsigned int line_num =3D 1; + unsigned int line_num =3D 0; FILE *file; =20 file =3D fopen(symvers, "r"); @@ -140,6 +140,8 @@ static int read_exports(void) char *sym, *mod, *type, *namespace; struct export *export; =20 + line_num++; + sym =3D strchr(line, '\t'); if (!sym) { ERROR("malformed Module.symvers (sym) at line %d", line_num); --=20 2.54.0