diff options
Diffstat (limited to 'net/unix/af_unix.c')
| -rw-r--r-- | net/unix/af_unix.c | 13 | 
1 files changed, 10 insertions, 3 deletions
| diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e5473c03d667..74d1eed7cbd4 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -225,6 +225,8 @@ static inline void unix_release_addr(struct unix_address *addr)  static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned int *hashp)  { +	*hashp = 0; +  	if (len <= sizeof(short) || len > sizeof(*sunaddr))  		return -EINVAL;  	if (!sunaddr || sunaddr->sun_family != AF_UNIX) @@ -430,7 +432,12 @@ static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)  	connected = unix_dgram_peer_wake_connect(sk, other); -	if (unix_recvq_full(other)) +	/* If other is SOCK_DEAD, we want to make sure we signal +	 * POLLOUT, such that a subsequent write() can get a +	 * -ECONNREFUSED. Otherwise, if we haven't queued any skbs +	 * to other and its full, we will hang waiting for POLLOUT. +	 */ +	if (unix_recvq_full(other) && !sock_flag(other, SOCK_DEAD))  		return 1;  	if (connected) @@ -2635,7 +2642,7 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa  	struct sock *sk = sock->sk;  	__poll_t mask; -	sock_poll_wait(file, sk_sleep(sk), wait); +	sock_poll_wait(file, sock, wait);  	mask = 0;  	/* exceptional events? */ @@ -2672,7 +2679,7 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,  	unsigned int writable;  	__poll_t mask; -	sock_poll_wait(file, sk_sleep(sk), wait); +	sock_poll_wait(file, sock, wait);  	mask = 0;  	/* exceptional events? */ |