On Fri, Mar 10, 2023 at 10:15:41PM CET, Alexei Starovoitov wrote: > On Tue, Mar 07, 2023 at 04:01:28PM -0800, Andrii Nakryiko wrote: > > > > > > > > > > I agree this is simpler, but I'm not sure it will work properly. Verifier won't > > > > > know when the lifetime of the buffer ends, so if we disallow spills until its > > > > > written over it's going to be a pain for users. > > > > > > > > > > Something like: > > > > > > > > > > for (...) { > > > > > char buf[64]; > > > > > bpf_dynptr_slice_rdwr(..., buf, 64); > > > > > ... > > > > > } > > > > > > > > > > .. and then compiler decides to spill something where buf was located on stack > > > > > outside the for loop. The verifier can't know when buf goes out of scope to > > > > > unpoison the slots. > > > > > > > > You're saying the "verifier doesn't know when buf ...". > > > > The same applies to the compiler. It has no visibility > > > > into what bpf_dynptr_slice_rdwr is doing. > > > > > > That is true, it can't assume anything about the side effects. But I am talking > > > about the point in the program when the buffer object no longer lives. Use of > > > the escaped pointer to such an object any longer is UB. The compiler is well > > > within its rights to reuse its stack storage at that point, including for > > > spilling registers. Which is why "outside the for loop" in my earlier reply. > > > > > > > So it never spills into a declared C array > > > > as I tried to explain in the previous reply. > > > > Spill/fill slots are always invisible to C. > > > > (unless of course you do pointer arithmetic asm style) > > > > > > When the declared array's lifetime ends, it can. > > > https://godbolt.org/z/Ez7v4xfnv > > > > > > The 2nd call to bar as part of unrolled loop happens with fp-8, then it calls > > > baz, spills r0 to fp-8, and calls bar again with fp-8. > > Right. If user writes such program and does explicit store of spillable > pointer into a stack. > I was talking about compiler generated spill/fill and I still believe > that compiler will not be reusing variable's stack memory for them. > But that example on godbolt is about the _compiler_ doing spill into a variable's stack memory, once it is dead. There is no explicit store to spill from the user happening there. Maybe buffer in explicit program scope {} is not that common, but always_inline functions will have a similar effect, since they introduce a scope out of which poisoned buffer's storage can be reused. > [...]