Message ID | 1511885010.16595.17.camel@gmail.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
Series | [v2,net] net/packet: fix a race in packet_bind() and packet_notifier() | expand |
From: Eric Dumazet <eric.dumazet@gmail.com> Date: Tue, 28 Nov 2017 08:03:30 -0800 > From: Eric Dumazet <edumazet@google.com> > > syzbot reported crashes [1] and provided a C repro easing bug hunting. > > When/if packet_do_bind() calls __unregister_prot_hook() and releases > po->bind_lock, another thread can run packet_notifier() and process an > NETDEV_UP event. > > This calls register_prot_hook() and hooks again the socket right before > first thread is able to grab again po->bind_lock. > > Fixes this issue by temporarily setting po->num to 0, as suggested by > David Miller. > > [1] ... > Fixes: 30f7ea1c2b5f ("packet: race condition in packet_bind") > Signed-off-by: Eric Dumazet <edumazet@google.com> > Reported-by: syzbot <syzkaller@googlegroups.com> > Cc: Francesco Ruggeri <fruggeri@aristanetworks.com> Applied and queued up for -stable.
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 737092ca9b4eed464b6c0907d85b679ae4da6046..cd454ca583d93841dcad4e1d83a660f15731c5fb 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -3097,6 +3097,10 @@ static int packet_do_bind(struct sock *sk, const char *name, int ifindex, if (need_rehook) { if (po->running) { rcu_read_unlock(); + /* prevents packet_notifier() from calling + * register_prot_hook() + */ + po->num = 0; __unregister_prot_hook(sk, true); rcu_read_lock(); dev_curr = po->prot_hook.dev; @@ -3105,6 +3109,7 @@ static int packet_do_bind(struct sock *sk, const char *name, int ifindex, dev->ifindex); } + BUG_ON(po->running); po->num = proto; po->prot_hook.type = proto;