diff options
Diffstat (limited to 'net/unix/af_unix.c')
| -rw-r--r-- | net/unix/af_unix.c | 31 | 
1 files changed, 22 insertions, 9 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 86de99ad2976..a427623ee574 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -530,13 +530,17 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,  static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *,  				  struct msghdr *, size_t, int); -static void unix_set_peek_off(struct sock *sk, int val) +static int unix_set_peek_off(struct sock *sk, int val)  {  	struct unix_sock *u = unix_sk(sk); -	mutex_lock(&u->readlock); +	if (mutex_lock_interruptible(&u->readlock)) +		return -EINTR; +  	sk->sk_peek_off = val;  	mutex_unlock(&u->readlock); + +	return 0;  } @@ -714,7 +718,9 @@ static int unix_autobind(struct socket *sock)  	int err;  	unsigned int retries = 0; -	mutex_lock(&u->readlock); +	err = mutex_lock_interruptible(&u->readlock); +	if (err) +		return err;  	err = 0;  	if (u->addr) @@ -873,7 +879,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)  		goto out;  	addr_len = err; -	mutex_lock(&u->readlock); +	err = mutex_lock_interruptible(&u->readlock); +	if (err) +		goto out;  	err = -EINVAL;  	if (u->addr) @@ -1246,6 +1254,15 @@ static int unix_socketpair(struct socket *socka, struct socket *sockb)  	return 0;  } +static void unix_sock_inherit_flags(const struct socket *old, +				    struct socket *new) +{ +	if (test_bit(SOCK_PASSCRED, &old->flags)) +		set_bit(SOCK_PASSCRED, &new->flags); +	if (test_bit(SOCK_PASSSEC, &old->flags)) +		set_bit(SOCK_PASSSEC, &new->flags); +} +  static int unix_accept(struct socket *sock, struct socket *newsock, int flags)  {  	struct sock *sk = sock->sk; @@ -1280,6 +1297,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)  	/* attach accepted sock to socket */  	unix_state_lock(tsk);  	newsock->state = SS_CONNECTED; +	unix_sock_inherit_flags(sock, newsock);  	sock_graft(tsk, newsock);  	unix_state_unlock(tsk);  	return 0; @@ -1744,7 +1762,6 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)  {  	struct unix_sock *u = unix_sk(sk); -	msg->msg_namelen = 0;  	if (u->addr) {  		msg->msg_namelen = u->addr->len;  		memcpy(msg->msg_name, u->addr->name, u->addr->len); @@ -1768,8 +1785,6 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,  	if (flags&MSG_OOB)  		goto out; -	msg->msg_namelen = 0; -  	err = mutex_lock_interruptible(&u->readlock);  	if (err) {  		err = sock_intr_errno(sock_rcvtimeo(sk, noblock)); @@ -1914,8 +1929,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,  	target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);  	timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); -	msg->msg_namelen = 0; -  	/* Lock the socket to prevent queue disordering  	 * while sleeps in memcpy_tomsg  	 */  | 
