On 4/2/26 10:02 AM, David Faust wrote:
And again, what precisely is problematic about generating rN = rM
for this set?
Verifier trips up, #12 attach _probe
(tools/testing/selftests/bpf/progs/test_attach_probe.c)
If %r1 is subsequently used as the int argument to a function call,
then it is valid as is.
If it would be passed as a 'unsigned long' or something else requiring
a conversion then we would rather have e.g. a zero_extend:DI to do that,
not a simple set.
The rN based move copies the full 64-bits, but the subsequent arg is
int: verifier wants to make sure top bits are cleared, which is not
guaranteed given the current codegen.
Ahhhhhh, so it is a verifier issue! Not a code correctness issue.
OK, that makes more sense.
Yeah and my bad for not calling it in the changelog, but it was a
logistics issue as I'd seperated it out of ABI change but needed ABI
changes for the exact context.
Full log below, relevant snippets extracted:
22: (85) call bpf_copy_from_user_str#85440 ; R0=scalar()
...
24: (bf) r7 = r0 ; R0=scalar(id=1) R7=scalar(id=1)
...
29: (85) call bpf_strncmp#182 ; R0=scalar()
30: (55) if r0 != 0x0 goto pc+1 ; R0=0
31: (16) if w7 == 0x4 goto pc+2 34: R0=0
R6=map_value(map=test_att.bss,ks=4,vs=56)
R7=scalar(id=1,smin=0x8000000000000004,smax=0x7fffffff00000004,umin=smin32=umin32=4,umax=0xffffffff00000004,smax32=umax32=4,var_off=(0x4;
0xffffffff00000000)) R10=fp0 fp-16=???????m fp-24=mmmmmmmm fp-88=????mmmm
...
36: (bf) r2 = r7 ;
R2=scalar(id=1,smin=0x8000000000000004,smax=0x7fffffff00000004,umin=smin32=umin32=4,umax=0xffffffff00000004,smax32=umax32=4,var_off=(0x4;
0xffffffff00000000))
R7=scalar(id=1,smin=0x8000000000000004,smax=0x7fffffff00000004,umin=smin32=umin32=4,umax=0xffffffff00000004,smax32=umax32=4,var_off=(0x4;
0xffffffff00000000))
...
39: (85) call bpf_copy_from_user_str#85440
R2 min value is negative, either use unsigned or 'var &= const'
Now, thinking about it, part of the problem could also be #31 using w7
reg for comparison. If it had used the rN reg too, maybe verifier would
be confident about the top bits too and won't trip up. But that again
would point to impedance mismatch between movsi (only using rN regs) and
branch_on_si, which would use wN regs.
Hmm, looking at these verifier logs (thanks for providing), I think
the issue may stem from the bpf_copy_from_user_str call.
Ultimately the return value propagates r0 -> r7 -> r2.
Exactly.
BUT, I am confused. This test passes on my system compiled with
gcc trunk. After the call, we emit a movs32 when moving the return value
to a different register, which is enough for the verifier to know the
value is restricted to signed integer range.
Are you seeing this with trunk or with the PROMOTE_MODE or some other
change applied?
Yeah it's specifically with PROMOTE_MODE part of the ABI change, w/o
touching target hooks.
Thx,
-Vineet