diff options
author | Jarek Poplawski <jarkao2@gmail.com> | 2008-04-01 23:56:17 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-01 23:56:17 -0700 |
commit | 4965291acf8cc2c31dcb2fc7d292a04ee08da2dd (patch) | |
tree | f38695b8fcdee173cf714222193c8f12274ba879 | |
parent | d43c7b37ad787173d08683f05eadeea0398fefdf (diff) | |
download | linux-4965291acf8cc2c31dcb2fc7d292a04ee08da2dd.tar.bz2 |
[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>
-rw-r--r-- | net/rose/af_rose.c | 9 |
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) if (sk == NULL) return 0; + sock_hold(sk); + sock_orphan(sk); + lock_sock(sk); rose = rose_sk(sk); switch (rose->state) { case ROSE_STATE_0: + release_sock(sk); rose_disconnect(sk, 0, -1, -1); + lock_sock(sk); rose_destroy_socket(sk); break; case ROSE_STATE_2: rose->neighbour->use--; + release_sock(sk); rose_disconnect(sk, 0, -1, -1); + lock_sock(sk); rose_destroy_socket(sk); break; @@ -633,6 +640,8 @@ static int rose_release(struct socket *sock) } sock->sk = NULL; + release_sock(sk); + sock_put(sk); return 0; } |