Re: [RFC bpf-next 6/9] bpf: workaround llvm behaviour with indirect jumps

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

[...]







[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux