• John Fastabend's avatar
    bpf: parse and verdict prog attach may race with bpf map update · 96174560
    John Fastabend authored
    In the sockmap design BPF programs (SK_SKB_STREAM_PARSER,
    SK_SKB_STREAM_VERDICT and SK_MSG_VERDICT) are attached to the sockmap
    map type and when a sock is added to the map the programs are used by
    the socket. However, sockmap updates from both userspace and BPF
    programs can happen concurrently with the attach and detach of these
    programs.
    
    To resolve this we use the bpf_prog_inc_not_zero and a READ_ONCE()
    primitive to ensure the program pointer is not refeched and
    possibly NULL'd before the refcnt increment. This happens inside
    a RCU critical section so although the pointer reference in the map
    object may be NULL (by a concurrent detach operation) the reference
    from READ_ONCE will not be free'd until after grace period. This
    ensures the object returned by READ_ONCE() is valid through the
    RCU criticl section and safe to use as long as we "know" it may
    be free'd shortly.
    
    Daniel spotted a case in the sock update API where instead of using
    the READ_ONCE() program reference we used the pointer from the
    original map, stab->bpf_{verdict|parse|txmsg}. The problem with this
    is the logic checks the object returned from the READ_ONCE() is not
    NULL and then tries to reference the object again but using the
    above map pointer, which may have already been NULL'd by a parallel
    detach operation. If this happened bpf_porg_inc_not_zero could
    dereference a NULL pointer.
    
    Fix this by using variable returned by READ_ONCE() that is checked
    for NULL.
    
    Fixes: 2f857d04 ("bpf: sockmap, remove STRPARSER map_flags and add multi-map support")
    Reported-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
    Acked-by: default avatarMartin KaFai Lau <kafai@fb.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    96174560
sockmap.c 44.4 KB