Re: [PATCH bpf-next v2 3/7] bpf: Add bpf_dynptr_from_mem, bpf_dynptr_alloc, bpf_dynptr_put

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

 



On Tue, Apr 26, 2022 at 4:45 PM Joanne Koong <joannelkoong@xxxxxxxxx> wrote:
> >
> > I guess it's ok to treat refcnted dynptr special like above.
> > I wonder whether we can reuse check_reference_leak logic?
> I like this idea! My reason for not storing dynptr reference ids in
> state->refs was because it's costly (eg we realloc_array every time we
> acquire a reference). But thinking about this some more, I like the
> idea of keeping everything unified by having all reference ids reside
> within state->refs and checking for leaks the same way. Perhaps we can
> optimize acquire_reference_state() as well where we upfront allocate
> more space for state->refs instead of having to do a realloc_array
> every time.

realloc is decently efficient underneath.
Probably not worth micro optimizing for it.
As far as ref state... Looks like dynptr patch is trying
hard to prevent writes into the stack area where dynptr
was allocated. Then cleans it up after dynptr_put.
For other pointers on stack we just mark the area as stack_misc
only when the stack slot was overwritten.
We don't mark the slot as 'misc' after the pointer was read from stack.
We can use the same approach with dynptr as long as dynptr
leaking is tracking through ref state
(instead of for(each stack slot) at the time of bpf_exit)

iirc we've debugged the case where clang reused stack area
with a scalar that was previously used for stack spill.
The dynptr on stack won't be seen as stack spill from compiler pov
but I worry about the case:
struct bpf_dynptr t;
bpf_dynptr_alloc(&t,..);
bpf_dynptr_put(&t);
// compiler thinks the stack area of 't' is dead and reuses
// it for something like scalar.
Even without dynptr_put above the compiler might
see that dynptr_alloc or another function stored
something into dynptr, but if nothing is using that
dynptr later it might consider the stack area as dead.
We cannot mark every dynptr variable as volatile.

Another point to consider...
This patch unconditionally tells the verifier to
unmark_stack_slots_dynptr() after bpf_dynptr_put().
But that's valid only for refcnt=1 -> 0 transition.
I'm not sure that will be forever the case even
for dynptr-s on stack.
If we allows refcnt=2,3,... on stack then
the verifier won't be able to clear stack slots
after bpf_dynptr_put and we will face the stack reuse issue.
I guess the idea is that refcnt-ed dynptr will be only in a map?
That might be inconvenient.
We allow refcnt-ed kptrs to be in a map, in a register,
and spilled to the stack.
Surely, dynptr are more complex in that sense.



[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