aboutsummaryrefslogtreecommitdiff
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 22acb0c7522..0580865bf36 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1257,14 +1257,12 @@ restart:
}
/* Latch our state.
-
It is tricky place. We need to grab our state lock and cannot
drop lock on peer. It is dangerous because deadlock is
possible. Connect to self case and simultaneous
attempt to connect are eliminated by checking socket
state. other is TCP_LISTEN, if sk is TCP_LISTEN we
check this before attempt to grab lock.
-
Well, and we have to recheck the state after socket locked.
*/
st = sk->sk_state;
@@ -1470,7 +1468,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
UNIXCB(skb).fp = NULL;
for (i = scm->fp->count-1; i >= 0; i--)
- unix_notinflight(scm->fp->user, scm->fp->fp[i]);
+ unix_notinflight(scm->fp->fp[i]);
}
static void unix_destruct_scm(struct sk_buff *skb)
@@ -1536,7 +1534,7 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
return -ENOMEM;
for (i = scm->fp->count - 1; i >= 0; i--)
- unix_inflight(scm->fp->user, scm->fp->fp[i]);
+ unix_inflight(scm->fp->fp[i]);
return max_level;
}
@@ -2010,11 +2008,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
apparently wrong)
- clone fds (I chose it for now, it is the most universal
solution)
-
POSIX 1003.1g does not actually define this clearly
at all. POSIX 1003.1g doesn't define a lot of things
clearly however!
-
*/
sk_peek_offset_fwd(sk, size);
@@ -2058,6 +2054,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo)
unix_state_unlock(sk);
timeo = freezable_schedule_timeout(timeo);
unix_state_lock(sk);
+
+ if (sock_flag(sk, SOCK_DEAD))
+ break;
+
clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
}
@@ -2121,6 +2121,10 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sk_buff *skb;
unix_state_lock(sk);
+ if (sock_flag(sk, SOCK_DEAD)) {
+ err = -ECONNRESET;
+ goto unlock;
+ }
skb = skb_peek(&sk->sk_receive_queue);
again:
if (skb == NULL) {