[bpf-next v8 0/5] emit ENDBR/BTI instructions for indirect jump targets

Xu Kuohai posted 5 patches 1 month ago
There is a newer version of this series
arch/arc/net/bpf_jit_core.c      |  37 +++-----
arch/arm/net/bpf_jit_32.c        |  43 ++--------
arch/arm64/net/bpf_jit_comp.c    |  86 +++++++------------
arch/loongarch/net/bpf_jit.c     |  58 ++++---------
arch/mips/net/bpf_jit_comp.c     |  22 +----
arch/parisc/net/bpf_jit_core.c   |  40 ++-------
arch/powerpc/net/bpf_jit_comp.c  |  47 +++-------
arch/riscv/net/bpf_jit_core.c    |  47 +++-------
arch/s390/net/bpf_jit_comp.c     |  43 ++--------
arch/sparc/net/bpf_jit_comp_64.c |  43 ++--------
arch/x86/net/bpf_jit_comp.c      |  68 +++++----------
arch/x86/net/bpf_jit_comp32.c    |  35 ++------
include/linux/bpf.h              |   2 +
include/linux/bpf_verifier.h     |   9 +-
include/linux/filter.h           |  15 +++-
kernel/bpf/core.c                | 142 +++++++++----------------------
kernel/bpf/syscall.c             |   4 -
kernel/bpf/verifier.c            |  45 +++++++---
18 files changed, 233 insertions(+), 553 deletions(-)
[bpf-next v8 0/5] emit ENDBR/BTI instructions for indirect jump targets
Posted by Xu Kuohai 1 month ago
On architectures with CFI protection enabled that require landing pad
instructions at indirect jump targets, such as x86 with CET/IBT eanbled
and arm64 with BTI enabled, kernel panics when an indirect jump lands on
a target witout landing pad. Therefore, the JIT must emit landing pad
instructions for indirect jump targets.

The verifier already recognizes which instructions are indirect jump
targets during the verification phase. So we can stores this information
in env->insn_aux_data and pass it to the JIT as new parameter, so the JIT
knows which instructions are indirect jump targets.

During JIT, constants blinding is performed. It rewrites the private copy
of instructions for the JITed program, but it does not adjust the global
env->insn_aux_data array. As a result, after constants blinding, the
instruction indexes used by JIT may no longer match the indexes in
env->insn_aux_data, so the JIT can not lookup env->insn_aux_data directly.

To avoid this mistach, and considering that all existing arch-specific JITs
already implement constants blinding with largely duplicated code, move
constants blinding from JIT to generic code, before copying instructions
for each subprog.

v8:
- Define void bpf_jit_blind_constants() function when CONFIG_BPF_JIT is not set 
- Move indirect_target fixup for insn patching from bpf_jit_blind_constants()
  to adjust_insn_aux_data()

v7: https://lore.kernel.org/bpf/20260307103949.2340104-1-xukuohai@huaweicloud.com
- Move constants blinding logic back to bpf/core.c
- Compute ip address before switch statement in x86 JIT
- Clear JIT state from error path on arm64 and loongarch 

v6: https://lore.kernel.org/bpf/20260306102329.2056216-1-xukuohai@huaweicloud.com/
- Move constants blinding from JIT to verifier
- Move call to bpf_prog_select_runtime from bpf_prog_load to verifier

v5: https://lore.kernel.org/bpf/20260302102726.1126019-1-xukuohai@huaweicloud.com/
- Switch to pass env to JIT directly to get rid of coping private insn_aux_data for
  each prog

v4: https://lore.kernel.org/all/20260114093914.2403982-1-xukuohai@huaweicloud.com/
- Switch to the approach proposed by Eduard, using insn_aux_data to indentify indirect
  jump targets, and emit ENDBR on x86

v3: https://lore.kernel.org/bpf/20251227081033.240336-1-xukuohai@huaweicloud.com/
- Get rid of unnecessary enum definition (Yonghong Song, Anton Protopopov)

v2: https://lore.kernel.org/bpf/20251223085447.139301-1-xukuohai@huaweicloud.com/
- Exclude instruction arrays not used for indirect jumps (Anton Protopopov)

v1: https://lore.kernel.org/bpf/20251127140318.3944249-1-xukuohai@huaweicloud.com/

Xu Kuohai (5):
  bpf: Move constants blinding from JIT to verifier
  bpf: Pass bpf_verifier_env to JIT
  bpf: Add helper to detect indirect jump targets
  bpf, x86: Emit ENDBR for indirect jump targets
  bpf, arm64: Emit BTI for indirect jump target

 arch/arc/net/bpf_jit_core.c      |  37 +++-----
 arch/arm/net/bpf_jit_32.c        |  43 ++--------
 arch/arm64/net/bpf_jit_comp.c    |  86 +++++++------------
 arch/loongarch/net/bpf_jit.c     |  58 ++++---------
 arch/mips/net/bpf_jit_comp.c     |  22 +----
 arch/parisc/net/bpf_jit_core.c   |  40 ++-------
 arch/powerpc/net/bpf_jit_comp.c  |  47 +++-------
 arch/riscv/net/bpf_jit_core.c    |  47 +++-------
 arch/s390/net/bpf_jit_comp.c     |  43 ++--------
 arch/sparc/net/bpf_jit_comp_64.c |  43 ++--------
 arch/x86/net/bpf_jit_comp.c      |  68 +++++----------
 arch/x86/net/bpf_jit_comp32.c    |  35 ++------
 include/linux/bpf.h              |   2 +
 include/linux/bpf_verifier.h     |   9 +-
 include/linux/filter.h           |  15 +++-
 kernel/bpf/core.c                | 142 +++++++++----------------------
 kernel/bpf/syscall.c             |   4 -
 kernel/bpf/verifier.c            |  45 +++++++---
 18 files changed, 233 insertions(+), 553 deletions(-)

-- 
2.47.3
Re: [bpf-next v8 0/5] emit ENDBR/BTI instructions for indirect jump targets
Posted by Alexis Lothoré 1 month ago
Hi Xu,

On Mon Mar 9, 2026 at 3:00 PM CET, Xu Kuohai wrote:
> On architectures with CFI protection enabled that require landing pad
> instructions at indirect jump targets, such as x86 with CET/IBT eanbled
> and arm64 with BTI enabled, kernel panics when an indirect jump lands on
> a target witout landing pad. Therefore, the JIT must emit landing pad
> instructions for indirect jump targets.
>
> The verifier already recognizes which instructions are indirect jump
> targets during the verification phase. So we can stores this information
> in env->insn_aux_data and pass it to the JIT as new parameter, so the JIT
> knows which instructions are indirect jump targets.
>
> During JIT, constants blinding is performed. It rewrites the private copy
> of instructions for the JITed program, but it does not adjust the global
> env->insn_aux_data array. As a result, after constants blinding, the
> instruction indexes used by JIT may no longer match the indexes in
> env->insn_aux_data, so the JIT can not lookup env->insn_aux_data directly.
>
> To avoid this mistach, and considering that all existing arch-specific JITs
> already implement constants blinding with largely duplicated code, move
> constants blinding from JIT to generic code, before copying instructions
> for each subprog.

Could you please add me in CC for any future revision ?

Thanks,

Alexis

-- 
Alexis Lothoré, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Re: [bpf-next v8 0/5] emit ENDBR/BTI instructions for indirect jump targets
Posted by Xu Kuohai 1 month ago
On 3/9/2026 11:00 PM, Alexis Lothoré wrote:
> Hi Xu,
> 
> On Mon Mar 9, 2026 at 3:00 PM CET, Xu Kuohai wrote:
>> On architectures with CFI protection enabled that require landing pad
>> instructions at indirect jump targets, such as x86 with CET/IBT eanbled
>> and arm64 with BTI enabled, kernel panics when an indirect jump lands on
>> a target witout landing pad. Therefore, the JIT must emit landing pad
>> instructions for indirect jump targets.
>>
>> The verifier already recognizes which instructions are indirect jump
>> targets during the verification phase. So we can stores this information
>> in env->insn_aux_data and pass it to the JIT as new parameter, so the JIT
>> knows which instructions are indirect jump targets.
>>
>> During JIT, constants blinding is performed. It rewrites the private copy
>> of instructions for the JITed program, but it does not adjust the global
>> env->insn_aux_data array. As a result, after constants blinding, the
>> instruction indexes used by JIT may no longer match the indexes in
>> env->insn_aux_data, so the JIT can not lookup env->insn_aux_data directly.
>>
>> To avoid this mistach, and considering that all existing arch-specific JITs
>> already implement constants blinding with largely duplicated code, move
>> constants blinding from JIT to generic code, before copying instructions
>> for each subprog.
> 
> Could you please add me in CC for any future revision ?
>

Sure, will do.

> Thanks,
> 
> Alexis
> 

Re: [bpf-next v8 0/5] emit ENDBR/BTI instructions for indirect jump targets
Posted by Anton Protopopov 1 month ago
On 26/03/09 10:00PM, Xu Kuohai wrote:
> On architectures with CFI protection enabled that require landing pad
> instructions at indirect jump targets, such as x86 with CET/IBT eanbled
                                                                  ^ enabled
> and arm64 with BTI enabled, kernel panics when an indirect jump lands on
> a target witout landing pad. Therefore, the JIT must emit landing pad
           ^ without
> instructions for indirect jump targets.
> 
> The verifier already recognizes which instructions are indirect jump
> targets during the verification phase. So we can stores this information
                                                   ^ store
> in env->insn_aux_data and pass it to the JIT as new parameter, so the JIT
> knows which instructions are indirect jump targets.
> 
> During JIT, constants blinding is performed. It rewrites the private copy
> of instructions for the JITed program, but it does not adjust the global
> env->insn_aux_data array. As a result, after constants blinding, the
> instruction indexes used by JIT may no longer match the indexes in
> env->insn_aux_data, so the JIT can not lookup env->insn_aux_data directly.
> 
> To avoid this mistach, and considering that all existing arch-specific JITs
                ^ mismatch?
> already implement constants blinding with largely duplicated code, move
> constants blinding from JIT to generic code, before copying instructions
> for each subprog.
> 
> v8:
> - Define void bpf_jit_blind_constants() function when CONFIG_BPF_JIT is not set 
> - Move indirect_target fixup for insn patching from bpf_jit_blind_constants()
>   to adjust_insn_aux_data()
> 
> v7: https://lore.kernel.org/bpf/20260307103949.2340104-1-xukuohai@huaweicloud.com
> - Move constants blinding logic back to bpf/core.c
> - Compute ip address before switch statement in x86 JIT
> - Clear JIT state from error path on arm64 and loongarch 
> 
> v6: https://lore.kernel.org/bpf/20260306102329.2056216-1-xukuohai@huaweicloud.com/
> - Move constants blinding from JIT to verifier
> - Move call to bpf_prog_select_runtime from bpf_prog_load to verifier
> 
> v5: https://lore.kernel.org/bpf/20260302102726.1126019-1-xukuohai@huaweicloud.com/
> - Switch to pass env to JIT directly to get rid of coping private insn_aux_data for
>   each prog
> 
> v4: https://lore.kernel.org/all/20260114093914.2403982-1-xukuohai@huaweicloud.com/
> - Switch to the approach proposed by Eduard, using insn_aux_data to indentify indirect
>   jump targets, and emit ENDBR on x86
> 
> v3: https://lore.kernel.org/bpf/20251227081033.240336-1-xukuohai@huaweicloud.com/
> - Get rid of unnecessary enum definition (Yonghong Song, Anton Protopopov)
> 
> v2: https://lore.kernel.org/bpf/20251223085447.139301-1-xukuohai@huaweicloud.com/
> - Exclude instruction arrays not used for indirect jumps (Anton Protopopov)
> 
> v1: https://lore.kernel.org/bpf/20251127140318.3944249-1-xukuohai@huaweicloud.com/
> 
> Xu Kuohai (5):
>   bpf: Move constants blinding from JIT to verifier
>   bpf: Pass bpf_verifier_env to JIT
>   bpf: Add helper to detect indirect jump targets
>   bpf, x86: Emit ENDBR for indirect jump targets
>   bpf, arm64: Emit BTI for indirect jump target
> 
>  arch/arc/net/bpf_jit_core.c      |  37 +++-----
>  arch/arm/net/bpf_jit_32.c        |  43 ++--------
>  arch/arm64/net/bpf_jit_comp.c    |  86 +++++++------------
>  arch/loongarch/net/bpf_jit.c     |  58 ++++---------
>  arch/mips/net/bpf_jit_comp.c     |  22 +----
>  arch/parisc/net/bpf_jit_core.c   |  40 ++-------
>  arch/powerpc/net/bpf_jit_comp.c  |  47 +++-------
>  arch/riscv/net/bpf_jit_core.c    |  47 +++-------
>  arch/s390/net/bpf_jit_comp.c     |  43 ++--------
>  arch/sparc/net/bpf_jit_comp_64.c |  43 ++--------
>  arch/x86/net/bpf_jit_comp.c      |  68 +++++----------
>  arch/x86/net/bpf_jit_comp32.c    |  35 ++------
>  include/linux/bpf.h              |   2 +
>  include/linux/bpf_verifier.h     |   9 +-
>  include/linux/filter.h           |  15 +++-
>  kernel/bpf/core.c                | 142 +++++++++----------------------
>  kernel/bpf/syscall.c             |   4 -
>  kernel/bpf/verifier.c            |  45 +++++++---
>  18 files changed, 233 insertions(+), 553 deletions(-)
> 
> -- 
> 2.47.3
>
Re: [bpf-next v8 0/5] emit ENDBR/BTI instructions for indirect jump targets
Posted by Xu Kuohai 1 month ago
On 3/10/2026 1:34 AM, Anton Protopopov wrote:
> On 26/03/09 10:00PM, Xu Kuohai wrote:
>> On architectures with CFI protection enabled that require landing pad
>> instructions at indirect jump targets, such as x86 with CET/IBT eanbled
>                                                                    ^ enabled
>> and arm64 with BTI enabled, kernel panics when an indirect jump lands on
>> a target witout landing pad. Therefore, the JIT must emit landing pad
>             ^ without
>> instructions for indirect jump targets.
>>
>> The verifier already recognizes which instructions are indirect jump
>> targets during the verification phase. So we can stores this information
>                                                     ^ store
>> in env->insn_aux_data and pass it to the JIT as new parameter, so the JIT
>> knows which instructions are indirect jump targets.
>>
>> During JIT, constants blinding is performed. It rewrites the private copy
>> of instructions for the JITed program, but it does not adjust the global
>> env->insn_aux_data array. As a result, after constants blinding, the
>> instruction indexes used by JIT may no longer match the indexes in
>> env->insn_aux_data, so the JIT can not lookup env->insn_aux_data directly.
>>
>> To avoid this mistach, and considering that all existing arch-specific JITs
>                  ^ mismatch?

I'll fix them and run a spelling check before sending the next version, thanks.