aboutsummaryrefslogtreecommitdiffstats
path: root/net/rose/af_rose.c
diff options
context:
space:
mode:
authorJarek Poplawski <jarkao2@gmail.com>2008-04-02 02:56:17 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-02 02:56:17 -0400
commit4965291acf8cc2c31dcb2fc7d292a04ee08da2dd (patch)
treef38695b8fcdee173cf714222193c8f12274ba879 /net/rose/af_rose.c
parentd43c7b37ad787173d08683f05eadeea0398fefdf (diff)
[ROSE/AX25] af_rose: rose_release() fix
rose_release() doesn't release sockets properly, e.g. it skips sock_orphan(), so OOPSes are triggered in sock_def_write_space(), which was observed especially while ROSE skbs were kfreed from ax25_frames_acked(). There is also sock_hold() and lock_sock() added - similarly to ax25_release(). Thanks to Bernard Pidoux for substantial help in debugging this problem. Signed-off-by: Jarek Poplawski <jarkao2@gmail.com> Reported-and-tested-by: Bernard Pidoux <bpidoux@free.fr> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rose/af_rose.c')
-rw-r--r--net/rose/af_rose.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 4a31a81059ab..063cbc5c26b1 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -598,17 +598,24 @@ static int rose_release(struct socket *sock)
598 598
599 if (sk == NULL) return 0; 599 if (sk == NULL) return 0;
600 600
601 sock_hold(sk);
602 sock_orphan(sk);
603 lock_sock(sk);
601 rose = rose_sk(sk); 604 rose = rose_sk(sk);
602 605
603 switch (rose->state) { 606 switch (rose->state) {
604 case ROSE_STATE_0: 607 case ROSE_STATE_0:
608 release_sock(sk);
605 rose_disconnect(sk, 0, -1, -1); 609 rose_disconnect(sk, 0, -1, -1);
610 lock_sock(sk);
606 rose_destroy_socket(sk); 611 rose_destroy_socket(sk);
607 break; 612 break;
608 613
609 case ROSE_STATE_2: 614 case ROSE_STATE_2:
610 rose->neighbour->use--; 615 rose->neighbour->use--;
616 release_sock(sk);
611 rose_disconnect(sk, 0, -1, -1); 617 rose_disconnect(sk, 0, -1, -1);
618 lock_sock(sk);
612 rose_destroy_socket(sk); 619 rose_destroy_socket(sk);
613 break; 620 break;
614 621
@@ -633,6 +640,8 @@ static int rose_release(struct socket *sock)
633 } 640 }
634 641
635 sock->sk = NULL; 642 sock->sk = NULL;
643 release_sock(sk);
644 sock_put(sk);
636 645
637 return 0; 646 return 0;
638} 647}