On Mon, Oct 05, 2026 at 12:51:45PM +0200, Jakub Jelinek wrote:
> What is reason to use movl + addl instead of just cmpl?
> I mean,
> int foo (int *p) { return *p == 0x12345678; }
> is compiled into
> cmpl $305419896, (%rdi)
> so I wonder why you can't just compare -4(%r11) with
> a 32-bit immediate.
> Are you trying to avoid the immediate to be present in the insn
> sequence, so that nothing can do an indirect call to the insn after this
> compare?
Right, though there are actually a couple reasons. And Peter, please
keep me honest here if I've forgotten something...
First is to keep the resulting live register contents free of
the hash value itself so it can't be used for register content
re-use/exfiltration/side-channels[0]. (While the emitted binary for KCFI
has "known" hashes, Linux mutates all hash locations on x86_64 with a
per-boot random value. This is another use of the trap annotation section:
all KCFI call sites are known, and similarly all KCFI targets are known,
so Linux XORs them all. And let me tell you how much fun it was to debug
THAT[1] when I messed up making the targets visible correctly.)
Second is to avoid always injecting a valid target into the insn sequence,
but this is less important because lots of modern hardware will have
IBT active, so it wouldn't actually be a usable entry point.
And then, pragmatically, it's what Linux expects there. The kernel's
KCFI FineIBT implementation[2] and the trap handlers[3] both expect
exactly that sequence of bytes today.
The commit log kind of hints at part of this, but you make a good point
that it is not really well spelled out. Should I improve the commit
log or the comments? It seems lengthy for a code comment, but it's less
discoverable in the commit log.
-Kees
[0]
https://lore.kernel.org/lkml/[email protected]/
[1] https://lore.kernel.org/lkml/[email protected]/
[2]
https://elixir.bootlin.com/linux/v7.3-rc2/source/arch/x86/kernel/alternative.c#L1316
[3]
https://elixir.bootlin.com/linux/v7.3-rc2/source/arch/x86/include/asm/cfi.h#L47
--
Kees Cook