On 05/15/2018 12:19 PM, Daniel Borkmann wrote:
> On 05/14/2018 07:00 PM, John Fastabend wrote:
> [...]


[...]

> 
> As you say in the comment above the function wrt locking notes that the
> __sock_map_ctx_update_elem() can be called concurrently.
> 
>   All operations operate on sock_map using cmpxchg and xchg operations to 
> ensure we
>   do not get stale references. Any reads into the map must be done with 
> READ_ONCE()
>   because of this.
> 
> You initially use the READ_ONCE() on the verdict/parse/tx_msg, but later on 
> when
> grabbing the reference you use again progs->bpf_verdict/bpf_parse/bpf_tx_msg 
> which
> would potentially refetch it, but if updates would happen concurrently e.g. 
> to the
> three progs, they could be NULL in the mean-time, no? bpf_prog_inc_not_zero() 
> would
> then crash. Why are not the ones used that you fetched previously via 
> READ_ONCE()
> for taking the ref?

Nice catch. We should use the reference fetched by READ_ONCE in all cases.

> 
> The second question I had is that verdict/parse/tx_msg are updated 
> independently
> from each other and each could be NULL or non-NULL. What if, say, parse is 
> NULL
> and verdict as well as tx_msg is non-NULL and the bpf_prog_inc_not_zero() on 
> the
> tx_msg prog fails. Doesn't this cause a use-after-free since a ref on verdict 
> wasn't
> taken earlier but the bpf_prog_put() will cause accidental misbalance/free of 
> the
> progs?

Also good catch. I'll send patches for both now. Thanks.

> 
> It would probably help to clarify the locking comment a bit more if indeed the
> above should be okay as is.
> 
> Thanks,
> Daniel
> 

Reply via email to