On Tue, May 19, 2026 at 10:33:45AM +0100, David Laight wrote:
> Isn't using 'notrack jmp *reg' for jump tables actually more secure?
> If an attacker can write code it doesn't matter.
> The jump table in is RO memory so can't be written.
> But if there are ENDBR on all the jump table targets they become
> possibly useful code addresses to arrange to write into some RW
> function pointer table - which might be useful.
You're right. I was worried about an invalid jump table index at first.
Clang 22 happily optimizes away jump table index bounds checks. GCC 16
seems to be more careful. We should probably patch LLVM to never
optimize it away, e.g.:
// funny.c
// clang -c -fcf-protection=branch -O2 -o funny.o funny.c
// objdump -d funny.o -M intel
int t0(void), t1(void), t2(void), t3(void);
int funny(unsigned long target) {
__builtin_assume(target < 4);
switch (target) {
case 0: return t0();
case 1: return t1();
case 2: return t2();
case 3: return t3();
}
}
// Clang 22
0000000000000000 <funny>:
0: f3 0f 1e fa endbr64
4: 55 push rbp
5: 48 89 e5 mov rbp, rsp
8: 3e ff 24 fd 00 00 00 00 notrack jmp qword ptr
[rdi*8+0x0] // vulnerable
10: 5d pop rbp
11: e9 00 00 00 00 jmp 0x16 <funny+0x16>
16: 5d pop rbp
17: e9 00 00 00 00 jmp 0x1c <funny+0x1c>
1c: 5d pop rbp
1d: e9 00 00 00 00 jmp 0x22 <funny+0x22>
22: 5d pop rbp
23: e9 00 00 00 00 jmp 0x28 <funny+0x28>
-Richard