]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.170/netrom-fix-locking-in-nr_find_socket.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.4.170 / netrom-fix-locking-in-nr_find_socket.patch
CommitLineData
e7503a51
GKH
1From foo@baz Sat Jan 5 08:30:28 CET 2019
2From: Cong Wang <xiyou.wangcong@gmail.com>
3Date: Sat, 29 Dec 2018 13:56:38 -0800
4Subject: netrom: fix locking in nr_find_socket()
5
6From: Cong Wang <xiyou.wangcong@gmail.com>
7
8[ Upstream commit 7314f5480f3e37e570104dc5e0f28823ef849e72 ]
9
10nr_find_socket(), nr_find_peer() and nr_find_listener() lock the
11sock after finding it in the global list. However, the call path
12requires BH disabled for the sock lock consistently.
13
14Actually the locking is unnecessary at this point, we can just hold
15the sock refcnt to make sure it is not gone after we unlock the global
16list, and lock it later only when needed.
17
18Reported-and-tested-by: syzbot+f621cda8b7e598908efa@syzkaller.appspotmail.com
19Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
20Signed-off-by: David S. Miller <davem@davemloft.net>
21Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
22---
23 net/netrom/af_netrom.c | 15 ++++++++++-----
24 1 file changed, 10 insertions(+), 5 deletions(-)
25
26--- a/net/netrom/af_netrom.c
27+++ b/net/netrom/af_netrom.c
28@@ -153,7 +153,7 @@ static struct sock *nr_find_listener(ax2
29 sk_for_each(s, &nr_list)
30 if (!ax25cmp(&nr_sk(s)->source_addr, addr) &&
31 s->sk_state == TCP_LISTEN) {
32- bh_lock_sock(s);
33+ sock_hold(s);
34 goto found;
35 }
36 s = NULL;
37@@ -174,7 +174,7 @@ static struct sock *nr_find_socket(unsig
38 struct nr_sock *nr = nr_sk(s);
39
40 if (nr->my_index == index && nr->my_id == id) {
41- bh_lock_sock(s);
42+ sock_hold(s);
43 goto found;
44 }
45 }
46@@ -198,7 +198,7 @@ static struct sock *nr_find_peer(unsigne
47
48 if (nr->your_index == index && nr->your_id == id &&
49 !ax25cmp(&nr->dest_addr, dest)) {
50- bh_lock_sock(s);
51+ sock_hold(s);
52 goto found;
53 }
54 }
55@@ -224,7 +224,7 @@ static unsigned short nr_find_next_circu
56 if (i != 0 && j != 0) {
57 if ((sk=nr_find_socket(i, j)) == NULL)
58 break;
59- bh_unlock_sock(sk);
60+ sock_put(sk);
61 }
62
63 id++;
64@@ -918,6 +918,7 @@ int nr_rx_frame(struct sk_buff *skb, str
65 }
66
67 if (sk != NULL) {
68+ bh_lock_sock(sk);
69 skb_reset_transport_header(skb);
70
71 if (frametype == NR_CONNACK && skb->len == 22)
72@@ -927,6 +928,7 @@ int nr_rx_frame(struct sk_buff *skb, str
73
74 ret = nr_process_rx_frame(sk, skb);
75 bh_unlock_sock(sk);
76+ sock_put(sk);
77 return ret;
78 }
79
80@@ -958,10 +960,12 @@ int nr_rx_frame(struct sk_buff *skb, str
81 (make = nr_make_new(sk)) == NULL) {
82 nr_transmit_refusal(skb, 0);
83 if (sk)
84- bh_unlock_sock(sk);
85+ sock_put(sk);
86 return 0;
87 }
88
89+ bh_lock_sock(sk);
90+
91 window = skb->data[20];
92
93 skb->sk = make;
94@@ -1014,6 +1018,7 @@ int nr_rx_frame(struct sk_buff *skb, str
95 sk->sk_data_ready(sk);
96
97 bh_unlock_sock(sk);
98+ sock_put(sk);
99
100 nr_insert_socket(make);
101