From: Samuel Ortiz Date: Thu, 28 Sep 2006 03:05:38 +0000 (-0700) Subject: [IrDA]: af_irda.c cleanups X-Git-Tag: v2.6.19-rc1~858^2~28 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da349f1c2e0a0bf8958cdaf14e8f33acdf3182a5;p=linux-2.6 [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: Samuel Ortiz Signed-off-by: David S. Miller --- diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 17699eeb64..7b7cd5bd2a 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -132,13 +132,14 @@ static void irda_disconnect_indication(void *instance, void *sap, /* Prevent race conditions with irda_release() and irda_shutdown() */ if (!sock_flag(sk, SOCK_DEAD) && sk->sk_state != TCP_CLOSE) { + lock_sock(sk); sk->sk_state = TCP_CLOSE; sk->sk_err = ECONNRESET; sk->sk_shutdown |= SEND_SHUTDOWN; sk->sk_state_change(sk); - /* Uh-oh... Should use sock_orphan ? */ - sock_set_flag(sk, SOCK_DEAD); + sock_orphan(sk); + release_sock(sk); /* Close our TSAP. * If we leave it open, IrLMP put it back into the list of @@ -1212,6 +1213,7 @@ static int irda_release(struct socket *sock) if (sk == NULL) return 0; + lock_sock(sk); sk->sk_state = TCP_CLOSE; sk->sk_shutdown |= SEND_SHUTDOWN; sk->sk_state_change(sk); @@ -1221,6 +1223,7 @@ static int irda_release(struct socket *sock) sock_orphan(sk); sock->sk = NULL; + release_sock(sk); /* Purge queues (see sock_init_data()) */ skb_queue_purge(&sk->sk_receive_queue); @@ -1353,6 +1356,7 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(4, "%s()\n", __FUNCTION__); IRDA_ASSERT(self != NULL, return -1;); + IRDA_ASSERT(!sock_error(sk), return -1;); skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err); @@ -1405,6 +1409,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(3, "%s()\n", __FUNCTION__); IRDA_ASSERT(self != NULL, return -1;); + IRDA_ASSERT(!sock_error(sk), return -1;); if (sock->flags & __SO_ACCEPTCON) return(-EINVAL);