On Sun, 2025-06-15 at 08:59 +0000, Anton Protopopov wrote: > When indirect jumps are enabled in LLVM, it might generate > unreachable instructions. For example, the following code > > SEC("syscall") int foo(struct simple_ctx *ctx) > { > switch (ctx->x) { > case 0: > ret_user = 2; > break; > case 11: > ret_user = 3; > break; > case 27: > ret_user = 4; > break; > case 31: > ret_user = 5; > break; > default: > ret_user = 19; > break; > } > > return 0; > } > > compiles into > > <foo>: > ; switch (ctx->x) { > 224: 79 11 00 00 00 00 00 00 r1 = *(u64 *)(r1 + 0x0) > 225: 25 01 0f 00 1f 00 00 00 if r1 > 0x1f goto +0xf <foo+0x88> > 226: 67 01 00 00 03 00 00 00 r1 <<= 0x3 > 227: 18 02 00 00 a8 00 00 00 00 00 00 00 00 00 00 00 r2 = 0xa8 ll > 0000000000000718: R_BPF_64_64 .rodata > 229: 0f 12 00 00 00 00 00 00 r2 += r1 > 230: 79 21 00 00 00 00 00 00 r1 = *(u64 *)(r2 + 0x0) > 231: 0d 01 00 00 00 00 00 00 gotox r1 > 232: 05 00 08 00 00 00 00 00 goto +0x8 <foo+0x88> > 233: b7 01 00 00 02 00 00 00 r1 = 0x2 > ; switch (ctx->x) { > 234: 05 00 07 00 00 00 00 00 goto +0x7 <foo+0x90> > 235: b7 01 00 00 04 00 00 00 r1 = 0x4 > ; break; > 236: 05 00 05 00 00 00 00 00 goto +0x5 <foo+0x90> > 237: b7 01 00 00 03 00 00 00 r1 = 0x3 > ; break; > 238: 05 00 03 00 00 00 00 00 goto +0x3 <foo+0x90> > 239: b7 01 00 00 05 00 00 00 r1 = 0x5 > ; break; > 240: 05 00 01 00 00 00 00 00 goto +0x1 <foo+0x90> > 241: b7 01 00 00 13 00 00 00 r1 = 0x13 > 242: 18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0x0 ll > 0000000000000790: R_BPF_64_64 ret_user > 244: 7b 12 00 00 00 00 00 00 *(u64 *)(r2 + 0x0) = r1 > ; return 0; > 245: b4 00 00 00 00 00 00 00 w0 = 0x0 > 246: 95 00 00 00 00 00 00 00 exit > > The jump table is > > 242, 241, 241, 241, 241, 241, 241, 241, > 241, 241, 241, 237, 241, 241, 241, 241, > 241, 241, 241, 241, 241, 241, 241, 241, > 241, 241, 241, 235, 241, 241, 241, 239 > > The check > > 225: 25 01 0f 00 1f 00 00 00 if r1 > 0x1f goto +0xf <foo+0x88> > > makes sure that the r1 register is always loaded from the jump table. > This makes the instruction > > 232: 05 00 08 00 00 00 00 00 goto +0x8 <foo+0x88> > > unreachable. > > Patch verifier to ignore such unreachable JA instructions. > > Signed-off-by: Anton Protopopov <a.s.protopopov@xxxxxxxxx> > --- This should be possible to handle on LLVM side, no need to deal with it in the kernel. [...]