• Daniel Borkmann's avatar
    packet: fix use after free race in send path when dev is released · e40526cb
    Daniel Borkmann authored
    Salam reported a use after free bug in PF_PACKET that occurs when
    we're sending out frames on a socket bound device and suddenly the
    net device is being unregistered. It appears that commit 827d9780
    introduced a possible race condition between {t,}packet_snd() and
    packet_notifier(). In the case of a bound socket, packet_notifier()
    can drop the last reference to the net_device and {t,}packet_snd()
    might end up suddenly sending a packet over a freed net_device.
    
    To avoid reverting 827d9780 and thus introducing a performance
    regression compared to the current state of things, we decided to
    hold a cached RCU protected pointer to the net device and maintain
    it on write side via bind spin_lock protected register_prot_hook()
    and __unregister_prot_hook() calls.
    
    In {t,}packet_snd() path, we access this pointer under rcu_read_lock
    through packet_cached_dev_get() that holds reference to the device
    to prevent it from being freed through packet_notifier() while
    we're in send path. This is okay to do as dev_put()/dev_hold() are
    per-cpu counters, so this should not be a performance issue. Also,
    the code simplifies a bit as we don't need need_rls_dev anymore.
    
    Fixes: 827d9780 ("af-packet: Use existing netdev reference for bound sockets.")
    Reported-by: default avatarSalam Noureddine <noureddine@aristanetworks.com>
    Signed-off-by: default avatarDaniel Borkmann <dborkman@redhat.com>
    Signed-off-by: default avatarSalam Noureddine <noureddine@aristanetworks.com>
    Cc: Ben Greear <greearb@candelatech.com>
    Cc: Eric Dumazet <eric.dumazet@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    e40526cb
af_packet.c 90.7 KB