[PATCH v4 3/7] test/bpf: add test for large shift

Marat Khalili marat.khalili at huawei.com
Wed Jun 24 15:44:45 CEST 2026


> > +/*
> > + * Shift by an immediate that doesn't fit in a signed byte: the C1 shift
> > + * group takes a fixed 1-byte immediate, but imm_size() returns 4 for
> > + * counts >= 128, so the x86 JIT emits 3 stray bytes and desyncs the
> > + * instruction stream. The shift results are discarded (a count >= 64 is
> > + * UB in the interpreter); the test returns a known constant, which the
> > + * corrupted stream fails to produce.
> > + */
> > +static const struct ebpf_insn test_shift_big_imm_prog[] = {
> > +	{
> > +		.code = (BPF_ALU | EBPF_MOV | BPF_K),
> > +		.dst_reg = EBPF_REG_2,
> > +		.imm = 0x1,
> > +	},
> > +	{
> > +		.code = (EBPF_ALU64 | BPF_LSH | BPF_K),
> > +		.dst_reg = EBPF_REG_2,
> > +		.imm = 137,
> > +	},
> > +	{
> > +		.code = (EBPF_ALU64 | BPF_RSH | BPF_K),
> > +		.dst_reg = EBPF_REG_2,
> > +		.imm = 200,
> > +	},
> > +	{
> > +		.code = (EBPF_ALU64 | EBPF_ARSH | BPF_K),
> > +		.dst_reg = EBPF_REG_2,
> > +		.imm = 255,
> > +	},
> > +	/* known result; a desynced stream won't reproduce it */
> > +	{
> > +		.code = (BPF_ALU | EBPF_MOV | BPF_K),
> > +		.dst_reg = EBPF_REG_0,
> > +		.imm = 0x55,
> > +	},
> > +	{
> > +		.code = (BPF_JMP | EBPF_EXIT),
> > +	},
> > +};
> 
> // snip the rest
> 
> Thanks a lot for adding this test. Can we use the shift results though, instead
> of discarding them, maybe as another test case? If the interpreter is unable to
> reproduce them or triggers sanitizer it needs to be fixed as well. (Apologies
> for this scope creep but I hope we get to the bottom of it eventually.)

Speaking of scope creep, this currently fails on ARM since emit_lsl (as well as 
emit_lsr, emit_asr) does not clear unused immediate bits and thus the value 
does not fit in the encoding.


More information about the dev mailing list