aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBasil Gunn <basil@pacabunga.com>2016-06-16 12:42:30 -0400
committerDavid S. Miller <davem@davemloft.net>2016-06-18 23:55:34 -0400
commit4a7d99ea1b27734558feb6833f180cd38a159940 (patch)
tree3ef63dc61cd8243272b86213c933335b9f1bcb12
parent3bb549ae4c51028c1930528ae9fcd6eca0474724 (diff)
AX.25: Close socket connection on session completion
A socket connection made in ax.25 is not closed when session is completed. The heartbeat timer is stopped prematurely and this is where the socket gets closed. Allow heatbeat timer to run to close socket. Symptom occurs in kernels >= 4.2.0 Originally sent 6/15/2016. Resend with distribution list matching scripts/maintainer.pl output. Signed-off-by: Basil Gunn <basil@pacabunga.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ax25/af_ax25.c3
-rw-r--r--net/ax25/ax25_ds_timer.c5
-rw-r--r--net/ax25/ax25_std_timer.c5
-rw-r--r--net/ax25/ax25_subr.c3
4 files changed, 12 insertions, 4 deletions
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index fbd0acf80b13..2fdebabbfacd 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -976,7 +976,8 @@ static int ax25_release(struct socket *sock)
976 release_sock(sk); 976 release_sock(sk);
977 ax25_disconnect(ax25, 0); 977 ax25_disconnect(ax25, 0);
978 lock_sock(sk); 978 lock_sock(sk);
979 ax25_destroy_socket(ax25); 979 if (!sock_flag(ax25->sk, SOCK_DESTROY))
980 ax25_destroy_socket(ax25);
980 break; 981 break;
981 982
982 case AX25_STATE_3: 983 case AX25_STATE_3:
diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c
index 951cd57bb07d..5237dff6941d 100644
--- a/net/ax25/ax25_ds_timer.c
+++ b/net/ax25/ax25_ds_timer.c
@@ -102,6 +102,7 @@ void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
102 switch (ax25->state) { 102 switch (ax25->state) {
103 103
104 case AX25_STATE_0: 104 case AX25_STATE_0:
105 case AX25_STATE_2:
105 /* Magic here: If we listen() and a new link dies before it 106 /* Magic here: If we listen() and a new link dies before it
106 is accepted() it isn't 'dead' so doesn't get removed. */ 107 is accepted() it isn't 'dead' so doesn't get removed. */
107 if (!sk || sock_flag(sk, SOCK_DESTROY) || 108 if (!sk || sock_flag(sk, SOCK_DESTROY) ||
@@ -111,6 +112,7 @@ void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
111 sock_hold(sk); 112 sock_hold(sk);
112 ax25_destroy_socket(ax25); 113 ax25_destroy_socket(ax25);
113 bh_unlock_sock(sk); 114 bh_unlock_sock(sk);
115 /* Ungrab socket and destroy it */
114 sock_put(sk); 116 sock_put(sk);
115 } else 117 } else
116 ax25_destroy_socket(ax25); 118 ax25_destroy_socket(ax25);
@@ -213,7 +215,8 @@ void ax25_ds_t1_timeout(ax25_cb *ax25)
213 case AX25_STATE_2: 215 case AX25_STATE_2:
214 if (ax25->n2count == ax25->n2) { 216 if (ax25->n2count == ax25->n2) {
215 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); 217 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
216 ax25_disconnect(ax25, ETIMEDOUT); 218 if (!sock_flag(ax25->sk, SOCK_DESTROY))
219 ax25_disconnect(ax25, ETIMEDOUT);
217 return; 220 return;
218 } else { 221 } else {
219 ax25->n2count++; 222 ax25->n2count++;
diff --git a/net/ax25/ax25_std_timer.c b/net/ax25/ax25_std_timer.c
index 004467c9e6e1..2c0d6ef66f9d 100644
--- a/net/ax25/ax25_std_timer.c
+++ b/net/ax25/ax25_std_timer.c
@@ -38,6 +38,7 @@ void ax25_std_heartbeat_expiry(ax25_cb *ax25)
38 38
39 switch (ax25->state) { 39 switch (ax25->state) {
40 case AX25_STATE_0: 40 case AX25_STATE_0:
41 case AX25_STATE_2:
41 /* Magic here: If we listen() and a new link dies before it 42 /* Magic here: If we listen() and a new link dies before it
42 is accepted() it isn't 'dead' so doesn't get removed. */ 43 is accepted() it isn't 'dead' so doesn't get removed. */
43 if (!sk || sock_flag(sk, SOCK_DESTROY) || 44 if (!sk || sock_flag(sk, SOCK_DESTROY) ||
@@ -47,6 +48,7 @@ void ax25_std_heartbeat_expiry(ax25_cb *ax25)
47 sock_hold(sk); 48 sock_hold(sk);
48 ax25_destroy_socket(ax25); 49 ax25_destroy_socket(ax25);
49 bh_unlock_sock(sk); 50 bh_unlock_sock(sk);
51 /* Ungrab socket and destroy it */
50 sock_put(sk); 52 sock_put(sk);
51 } else 53 } else
52 ax25_destroy_socket(ax25); 54 ax25_destroy_socket(ax25);
@@ -144,7 +146,8 @@ void ax25_std_t1timer_expiry(ax25_cb *ax25)
144 case AX25_STATE_2: 146 case AX25_STATE_2:
145 if (ax25->n2count == ax25->n2) { 147 if (ax25->n2count == ax25->n2) {
146 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); 148 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
147 ax25_disconnect(ax25, ETIMEDOUT); 149 if (!sock_flag(ax25->sk, SOCK_DESTROY))
150 ax25_disconnect(ax25, ETIMEDOUT);
148 return; 151 return;
149 } else { 152 } else {
150 ax25->n2count++; 153 ax25->n2count++;
diff --git a/net/ax25/ax25_subr.c b/net/ax25/ax25_subr.c
index 3b78e8473a01..655a7d4c96e1 100644
--- a/net/ax25/ax25_subr.c
+++ b/net/ax25/ax25_subr.c
@@ -264,7 +264,8 @@ void ax25_disconnect(ax25_cb *ax25, int reason)
264{ 264{
265 ax25_clear_queues(ax25); 265 ax25_clear_queues(ax25);
266 266
267 ax25_stop_heartbeat(ax25); 267 if (!sock_flag(ax25->sk, SOCK_DESTROY))
268 ax25_stop_heartbeat(ax25);
268 ax25_stop_t1timer(ax25); 269 ax25_stop_t1timer(ax25);
269 ax25_stop_t2timer(ax25); 270 ax25_stop_t2timer(ax25);
270 ax25_stop_t3timer(ax25); 271 ax25_stop_t3timer(ax25);