Skip to content

Commit 4971613

Browse files
wdebruijdavem330
authored andcommitted
packet: in packet_do_bind, test fanout with bind_lock held
Once a socket has po->fanout set, it remains a member of the group until it is destroyed. The prot_hook must be constant and identical across sockets in the group. If fanout_add races with packet_do_bind between the test of po->fanout and taking the lock, the bind call may make type or dev inconsistent with that of the fanout group. Hold po->bind_lock when testing po->fanout to avoid this race. I had to introduce artificial delay (local_bh_enable) to actually observe the race. Fixes: dc99f60 ("packet: Add fanout support.") Signed-off-by: Willem de Bruijn <willemb@google.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 1579f67 commit 4971613

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

net/packet/af_packet.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3069,13 +3069,15 @@ static int packet_do_bind(struct sock *sk, const char *name, int ifindex,
30693069
int ret = 0;
30703070
bool unlisted = false;
30713071

3072-
if (po->fanout)
3073-
return -EINVAL;
3074-
30753072
lock_sock(sk);
30763073
spin_lock(&po->bind_lock);
30773074
rcu_read_lock();
30783075

3076+
if (po->fanout) {
3077+
ret = -EINVAL;
3078+
goto out_unlock;
3079+
}
3080+
30793081
if (name) {
30803082
dev = dev_get_by_name_rcu(sock_net(sk), name);
30813083
if (!dev) {

0 commit comments

Comments
 (0)