Re: [PATCH v3 14/21] objtool: Prevent kCFI hashes from being decoded as instructions

Josh Poimboeuf <[email protected]>
Newsgroups org.kernel.vger.live-patching,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <s275kky5bqb5w5agrseielj66zvm53hr3yv7n33tenz4swnvpb@c63r6czxpeil>
On Tue, Jun 30, 2026 at 02:40:42PM -0400, Joe Lawrence wrote:
> The root cause is that create_fake_symbols() skips the entire special
> section if any symbol exists at offset 0.  But Clang places a .Ltmp*
> label at the start of .kcfi_traps, so no per-entry fake symbols are
> created and clone_special_sections() extracts nothing.
> 
>   static int create_fake_symbols(struct elf *elf)
>   {
>   ...
>   	/*
>   	 * 2) Make symbols for sh_entsize, and simple arrays of pointers:
>   	 */
>   entsize:
>   	for_each_sec(elf, sec) {
>   		unsigned int entry_size;
>   		unsigned long offset;
> 
>   		if (!is_special_section(sec) || find_symbol_by_offset(sec, 0))
>   			continue;
> 
>   $ llvm-readelf --wide --symbols klp-tmp/3-checksum-patched/vmlinux.o | \
>           awk '$7 == 74993'
>    93266: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   74993 .Ltmp78
>    93544: 0000000000000000     0 SECTION LOCAL  DEFAULT   74993 .kcfi_traps
> 
> 
> Possible fix: ignore .L* assembler-local labels at section offset 0
> using the existing is_local_label() helper.
> 
> -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8-- -->8--
> 
> diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
> index b9624bd9439b..4ba400926647 100644
> --- a/tools/objtool/klp-diff.c
> +++ b/tools/objtool/klp-diff.c
> @@ -1860,8 +1860,17 @@ static int create_fake_symbols(struct elf *elf)
>  	for_each_sec(elf, sec) {
>  		unsigned int entry_size;
>  		unsigned long offset;
> +		struct symbol *sym_at_0;
> 
> -		if (!is_special_section(sec) || find_symbol_by_offset(sec, 0))
> +		if (!is_special_section(sec))
> +			continue;
> +
> +		/*
> +		 * Clang may place assembler-local .L* labels at offset 0;
> +		 * they must not prevent per-entry fake symbol creation.
> +		 */
> +		sym_at_0 = find_symbol_by_offset(sec, 0);
> +		if (sym_at_0 && !is_local_label(sym_at_0))
>  			continue;

Thanks, I'll fix this with my other series of fixes in the next version.

find_symbol_by_offset() might not work because there can be multiple
symbols at offset 0.  Instead we can just traverse the symbols in the
section, looking for sym->fake.

-- 
Josh
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.