Commit da349f1c authored by Samuel Ortiz's avatar Samuel Ortiz Committed by David S. Miller

[IrDA]: af_irda.c cleanups

We lock the socket when both releasing and getting a disconnected
notification. In the latter case, we also ste the socket as orphan.
This fixes a potential kernel bug that can be triggered when we get the
disconnection notification before closing the socket.
Signed-off-by: default avatarSamuel Ortiz <samuel@sortiz.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a9e9ef6
...@@ -132,13 +132,14 @@ static void irda_disconnect_indication(void *instance, void *sap, ...@@ -132,13 +132,14 @@ static void irda_disconnect_indication(void *instance, void *sap,
/* Prevent race conditions with irda_release() and irda_shutdown() */ /* Prevent race conditions with irda_release() and irda_shutdown() */
if (!sock_flag(sk, SOCK_DEAD) && sk->sk_state != TCP_CLOSE) { if (!sock_flag(sk, SOCK_DEAD) && sk->sk_state != TCP_CLOSE) {
lock_sock(sk);
sk->sk_state = TCP_CLOSE; sk->sk_state = TCP_CLOSE;
sk->sk_err = ECONNRESET; sk->sk_err = ECONNRESET;
sk->sk_shutdown |= SEND_SHUTDOWN; sk->sk_shutdown |= SEND_SHUTDOWN;
sk->sk_state_change(sk); sk->sk_state_change(sk);
/* Uh-oh... Should use sock_orphan ? */ sock_orphan(sk);
sock_set_flag(sk, SOCK_DEAD); release_sock(sk);
/* Close our TSAP. /* Close our TSAP.
* If we leave it open, IrLMP put it back into the list of * If we leave it open, IrLMP put it back into the list of
...@@ -1212,6 +1213,7 @@ static int irda_release(struct socket *sock) ...@@ -1212,6 +1213,7 @@ static int irda_release(struct socket *sock)
if (sk == NULL) if (sk == NULL)
return 0; return 0;
lock_sock(sk);
sk->sk_state = TCP_CLOSE; sk->sk_state = TCP_CLOSE;
sk->sk_shutdown |= SEND_SHUTDOWN; sk->sk_shutdown |= SEND_SHUTDOWN;
sk->sk_state_change(sk); sk->sk_state_change(sk);
...@@ -1221,6 +1223,7 @@ static int irda_release(struct socket *sock) ...@@ -1221,6 +1223,7 @@ static int irda_release(struct socket *sock)
sock_orphan(sk); sock_orphan(sk);
sock->sk = NULL; sock->sk = NULL;
release_sock(sk);
/* Purge queues (see sock_init_data()) */ /* Purge queues (see sock_init_data()) */
skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_receive_queue);
...@@ -1353,6 +1356,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, ...@@ -1353,6 +1356,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(4, "%s()\n", __FUNCTION__); IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self != NULL, return -1;);
IRDA_ASSERT(!sock_error(sk), return -1;);
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err); flags & MSG_DONTWAIT, &err);
...@@ -1405,6 +1409,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, ...@@ -1405,6 +1409,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(3, "%s()\n", __FUNCTION__); IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self != NULL, return -1;);
IRDA_ASSERT(!sock_error(sk), return -1;);
if (sock->flags & __SO_ACCEPTCON) if (sock->flags & __SO_ACCEPTCON)
return(-EINVAL); return(-EINVAL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment