Skip to content

Commit

Permalink
netrom: fix locking in nr_find_socket()
Browse files Browse the repository at this point in the history
[ Upstream commit 7314f54 ]

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]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
congwang authored and gregkh committed Jan 13, 2019
1 parent 3f31288 commit 1c85a90
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 @@ -918,6 +918,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 @@ -927,6 +928,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 @@ -958,10 +960,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 @@ -1014,6 +1018,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 1c85a90

Please sign in to comment.