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

Reply via email to