Skip to content

Commit

Permalink
netrom: fix locking in nr_find_socket()
Browse files Browse the repository at this point in the history
nr_find_socket(), nr_find_peer() and nr_find_listener() lock the
sock after finding it in the global list. However, the call path
requires BH disabled for the sock lock consistently.

Actually the locking is unnecessary at this point, we can just hold
the sock refcnt to make sure it is not gone after we unlock the global
list, and lock it later only when needed.

Reported-and-tested-by: [email protected]
Signed-off-by: Cong Wang <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
congwang authored and davem330 committed Dec 31, 2018
1 parent d5c7c74 commit 7314f54
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions net/netrom/af_netrom.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ static struct sock *nr_find_listener(ax25_address *addr)
sk_for_each(s, &nr_list)
if (!ax25cmp(&nr_sk(s)->source_addr, addr) &&
s->sk_state == TCP_LISTEN) {
bh_lock_sock(s);
sock_hold(s);
goto found;
}
s = NULL;
Expand All @@ -174,7 +174,7 @@ static struct sock *nr_find_socket(unsigned char index, unsigned char id)
struct nr_sock *nr = nr_sk(s);

if (nr->my_index == index && nr->my_id == id) {
bh_lock_sock(s);
sock_hold(s);
goto found;
}
}
Expand All @@ -198,7 +198,7 @@ static struct sock *nr_find_peer(unsigned char index, unsigned char id,

if (nr->your_index == index && nr->your_id == id &&
!ax25cmp(&nr->dest_addr, dest)) {
bh_lock_sock(s);
sock_hold(s);
goto found;
}
}
Expand All @@ -224,7 +224,7 @@ static unsigned short nr_find_next_circuit(void)
if (i != 0 && j != 0) {
if ((sk=nr_find_socket(i, j)) == NULL)
break;
bh_unlock_sock(sk);
sock_put(sk);
}

id++;
Expand Down Expand Up @@ -920,6 +920,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
}

if (sk != NULL) {
bh_lock_sock(sk);
skb_reset_transport_header(skb);

if (frametype == NR_CONNACK && skb->len == 22)
Expand All @@ -929,6 +930,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)

ret = nr_process_rx_frame(sk, skb);
bh_unlock_sock(sk);
sock_put(sk);
return ret;
}

Expand Down Expand Up @@ -960,10 +962,12 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
(make = nr_make_new(sk)) == NULL) {
nr_transmit_refusal(skb, 0);
if (sk)
bh_unlock_sock(sk);
sock_put(sk);
return 0;
}

bh_lock_sock(sk);

window = skb->data[20];

skb->sk = make;
Expand Down Expand Up @@ -1016,6 +1020,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
sk->sk_data_ready(sk);

bh_unlock_sock(sk);
sock_put(sk);

nr_insert_socket(make);

Expand Down

0 comments on commit 7314f54

Please sign in to comment.