diff options
Diffstat (limited to 'net/unix')
| -rw-r--r-- | net/unix/af_unix.c | 54 | ||||
| -rw-r--r-- | net/unix/garbage.c | 12 | 
2 files changed, 33 insertions, 33 deletions
| diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 51be64f163e..826e09938bf 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -382,7 +382,7 @@ static void unix_sock_destructor(struct sock *sk)  #endif  } -static int unix_release_sock(struct sock *sk, int embrion) +static void unix_release_sock(struct sock *sk, int embrion)  {  	struct unix_sock *u = unix_sk(sk);  	struct path path; @@ -451,8 +451,6 @@ static int unix_release_sock(struct sock *sk, int embrion)  	if (unix_tot_inflight)  		unix_gc();		/* Garbage collect fds */ - -	return 0;  }  static void init_peercred(struct sock *sk) @@ -699,9 +697,10 @@ static int unix_release(struct socket *sock)  	if (!sk)  		return 0; +	unix_release_sock(sk, 0);  	sock->sk = NULL; -	return unix_release_sock(sk, 0); +	return 0;  }  static int unix_autobind(struct socket *sock) @@ -1341,7 +1340,6 @@ static void unix_destruct_scm(struct sk_buff *skb)  	struct scm_cookie scm;  	memset(&scm, 0, sizeof(scm));  	scm.pid  = UNIXCB(skb).pid; -	scm.cred = UNIXCB(skb).cred;  	if (UNIXCB(skb).fp)  		unix_detach_fds(&scm, skb); @@ -1392,8 +1390,8 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen  	int err = 0;  	UNIXCB(skb).pid  = get_pid(scm->pid); -	if (scm->cred) -		UNIXCB(skb).cred = get_cred(scm->cred); +	UNIXCB(skb).uid = scm->creds.uid; +	UNIXCB(skb).gid = scm->creds.gid;  	UNIXCB(skb).fp = NULL;  	if (scm->fp && send_fds)  		err = unix_attach_fds(scm, skb); @@ -1410,13 +1408,13 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen  static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,  			    const struct sock *other)  { -	if (UNIXCB(skb).cred) +	if (UNIXCB(skb).pid)  		return;  	if (test_bit(SOCK_PASSCRED, &sock->flags) ||  	    !other->sk_socket ||  	    test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {  		UNIXCB(skb).pid  = get_pid(task_tgid(current)); -		UNIXCB(skb).cred = get_current_cred(); +		current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);  	}  } @@ -1820,7 +1818,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,  		siocb->scm = &tmp_scm;  		memset(&tmp_scm, 0, sizeof(tmp_scm));  	} -	scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); +	scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);  	unix_set_secdata(siocb->scm, skb);  	if (!(flags & MSG_PEEK)) { @@ -1860,10 +1858,10 @@ out:  }  /* - *	Sleep until data has arrive. But check for races.. + *	Sleep until more data has arrived. But check for races..   */ - -static long unix_stream_data_wait(struct sock *sk, long timeo) +static long unix_stream_data_wait(struct sock *sk, long timeo, +				  struct sk_buff *last)  {  	DEFINE_WAIT(wait); @@ -1872,7 +1870,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo)  	for (;;) {  		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); -		if (!skb_queue_empty(&sk->sk_receive_queue) || +		if (skb_peek_tail(&sk->sk_receive_queue) != last ||  		    sk->sk_err ||  		    (sk->sk_shutdown & RCV_SHUTDOWN) ||  		    signal_pending(current) || @@ -1891,8 +1889,6 @@ static long unix_stream_data_wait(struct sock *sk, long timeo)  	return timeo;  } - -  static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,  			       struct msghdr *msg, size_t size,  			       int flags) @@ -1937,14 +1933,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,  		goto out;  	} -	skip = sk_peek_offset(sk, flags); -  	do {  		int chunk; -		struct sk_buff *skb; +		struct sk_buff *skb, *last;  		unix_state_lock(sk); -		skb = skb_peek(&sk->sk_receive_queue); +		last = skb = skb_peek(&sk->sk_receive_queue);  again:  		if (skb == NULL) {  			unix_sk(sk)->recursion_level = 0; @@ -1967,7 +1961,7 @@ again:  				break;  			mutex_unlock(&u->readlock); -			timeo = unix_stream_data_wait(sk, timeo); +			timeo = unix_stream_data_wait(sk, timeo, last);  			if (signal_pending(current)  			    ||  mutex_lock_interruptible(&u->readlock)) { @@ -1981,10 +1975,13 @@ again:  			break;  		} -		if (skip >= skb->len) { +		skip = sk_peek_offset(sk, flags); +		while (skip >= skb->len) {  			skip -= skb->len; +			last = skb;  			skb = skb_peek_next(skb, &sk->sk_receive_queue); -			goto again; +			if (!skb) +				goto again;  		}  		unix_state_unlock(sk); @@ -1992,11 +1989,12 @@ again:  		if (check_creds) {  			/* Never glue messages from different writers */  			if ((UNIXCB(skb).pid  != siocb->scm->pid) || -			    (UNIXCB(skb).cred != siocb->scm->cred)) +			    !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) || +			    !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid))  				break; -		} else { +		} else if (test_bit(SOCK_PASSCRED, &sock->flags)) {  			/* Copy credentials */ -			scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); +			scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);  			check_creds = 1;  		} @@ -2197,7 +2195,9 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,  	/* exceptional events? */  	if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) -		mask |= POLLERR; +		mask |= POLLERR | +			(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0); +  	if (sk->sk_shutdown & RCV_SHUTDOWN)  		mask |= POLLRDHUP | POLLIN | POLLRDNORM;  	if (sk->sk_shutdown == SHUTDOWN_MASK) diff --git a/net/unix/garbage.c b/net/unix/garbage.c index d0f6545b001..9bc73f87f64 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -185,7 +185,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),  					 * have been added to the queues after  					 * starting the garbage collection  					 */ -					if (u->gc_candidate) { +					if (test_bit(UNIX_GC_CANDIDATE, &u->gc_flags)) {  						hit = true;  						func(u);  					} @@ -254,7 +254,7 @@ static void inc_inflight_move_tail(struct unix_sock *u)  	 * of the list, so that it's checked even if it was already  	 * passed over  	 */ -	if (u->gc_maybe_cycle) +	if (test_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags))  		list_move_tail(&u->link, &gc_candidates);  } @@ -315,8 +315,8 @@ void unix_gc(void)  		BUG_ON(total_refs < inflight_refs);  		if (total_refs == inflight_refs) {  			list_move_tail(&u->link, &gc_candidates); -			u->gc_candidate = 1; -			u->gc_maybe_cycle = 1; +			__set_bit(UNIX_GC_CANDIDATE, &u->gc_flags); +			__set_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags);  		}  	} @@ -344,7 +344,7 @@ void unix_gc(void)  		if (atomic_long_read(&u->inflight) > 0) {  			list_move_tail(&u->link, ¬_cycle_list); -			u->gc_maybe_cycle = 0; +			__clear_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags);  			scan_children(&u->sk, inc_inflight_move_tail, NULL);  		}  	} @@ -356,7 +356,7 @@ void unix_gc(void)  	 */  	while (!list_empty(¬_cycle_list)) {  		u = list_entry(not_cycle_list.next, struct unix_sock, link); -		u->gc_candidate = 0; +		__clear_bit(UNIX_GC_CANDIDATE, &u->gc_flags);  		list_move_tail(&u->link, &gc_inflight_list);  	} | 
