aboutsummaryrefslogtreecommitdiffstats
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.c87
1 files changed, 51 insertions, 36 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index dd419d28620..de870184e45 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1171,7 +1171,7 @@ restart:
1171 newsk->sk_type = sk->sk_type; 1171 newsk->sk_type = sk->sk_type;
1172 init_peercred(newsk); 1172 init_peercred(newsk);
1173 newu = unix_sk(newsk); 1173 newu = unix_sk(newsk);
1174 newsk->sk_wq = &newu->peer_wq; 1174 RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
1175 otheru = unix_sk(other); 1175 otheru = unix_sk(other);
1176 1176
1177 /* copy address information from listening to new sock*/ 1177 /* copy address information from listening to new sock*/
@@ -1475,6 +1475,12 @@ restart:
1475 goto out_free; 1475 goto out_free;
1476 } 1476 }
1477 1477
1478 if (sk_filter(other, skb) < 0) {
1479 /* Toss the packet but do not return any error to the sender */
1480 err = len;
1481 goto out_free;
1482 }
1483
1478 unix_state_lock(other); 1484 unix_state_lock(other);
1479 err = -EPERM; 1485 err = -EPERM;
1480 if (!unix_may_send(sk, other)) 1486 if (!unix_may_send(sk, other))
@@ -1561,7 +1567,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1561 struct sock_iocb *siocb = kiocb_to_siocb(kiocb); 1567 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1562 struct sock *sk = sock->sk; 1568 struct sock *sk = sock->sk;
1563 struct sock *other = NULL; 1569 struct sock *other = NULL;
1564 struct sockaddr_un *sunaddr = msg->msg_name;
1565 int err, size; 1570 int err, size;
1566 struct sk_buff *skb; 1571 struct sk_buff *skb;
1567 int sent = 0; 1572 int sent = 0;
@@ -1584,7 +1589,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1584 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; 1589 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
1585 goto out_err; 1590 goto out_err;
1586 } else { 1591 } else {
1587 sunaddr = NULL;
1588 err = -ENOTCONN; 1592 err = -ENOTCONN;
1589 other = unix_peer(sk); 1593 other = unix_peer(sk);
1590 if (!other) 1594 if (!other)
@@ -1724,7 +1728,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1724 1728
1725 msg->msg_namelen = 0; 1729 msg->msg_namelen = 0;
1726 1730
1727 mutex_lock(&u->readlock); 1731 err = mutex_lock_interruptible(&u->readlock);
1732 if (err) {
1733 err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
1734 goto out;
1735 }
1728 1736
1729 skb = skb_recv_datagram(sk, flags, noblock, &err); 1737 skb = skb_recv_datagram(sk, flags, noblock, &err);
1730 if (!skb) { 1738 if (!skb) {
@@ -1864,7 +1872,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1864 memset(&tmp_scm, 0, sizeof(tmp_scm)); 1872 memset(&tmp_scm, 0, sizeof(tmp_scm));
1865 } 1873 }
1866 1874
1867 mutex_lock(&u->readlock); 1875 err = mutex_lock_interruptible(&u->readlock);
1876 if (err) {
1877 err = sock_intr_errno(timeo);
1878 goto out;
1879 }
1868 1880
1869 do { 1881 do {
1870 int chunk; 1882 int chunk;
@@ -1895,11 +1907,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1895 1907
1896 timeo = unix_stream_data_wait(sk, timeo); 1908 timeo = unix_stream_data_wait(sk, timeo);
1897 1909
1898 if (signal_pending(current)) { 1910 if (signal_pending(current)
1911 || mutex_lock_interruptible(&u->readlock)) {
1899 err = sock_intr_errno(timeo); 1912 err = sock_intr_errno(timeo);
1900 goto out; 1913 goto out;
1901 } 1914 }
1902 mutex_lock(&u->readlock); 1915
1903 continue; 1916 continue;
1904 unlock: 1917 unlock:
1905 unix_state_unlock(sk); 1918 unix_state_unlock(sk);
@@ -1978,36 +1991,38 @@ static int unix_shutdown(struct socket *sock, int mode)
1978 1991
1979 mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); 1992 mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN);
1980 1993
1981 if (mode) { 1994 if (!mode)
1982 unix_state_lock(sk); 1995 return 0;
1983 sk->sk_shutdown |= mode; 1996
1984 other = unix_peer(sk); 1997 unix_state_lock(sk);
1985 if (other) 1998 sk->sk_shutdown |= mode;
1986 sock_hold(other); 1999 other = unix_peer(sk);
1987 unix_state_unlock(sk); 2000 if (other)
1988 sk->sk_state_change(sk); 2001 sock_hold(other);
1989 2002 unix_state_unlock(sk);
1990 if (other && 2003 sk->sk_state_change(sk);
1991 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) { 2004
1992 2005 if (other &&
1993 int peer_mode = 0; 2006 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
1994 2007
1995 if (mode&RCV_SHUTDOWN) 2008 int peer_mode = 0;
1996 peer_mode |= SEND_SHUTDOWN; 2009
1997 if (mode&SEND_SHUTDOWN) 2010 if (mode&RCV_SHUTDOWN)
1998 peer_mode |= RCV_SHUTDOWN; 2011 peer_mode |= SEND_SHUTDOWN;
1999 unix_state_lock(other); 2012 if (mode&SEND_SHUTDOWN)
2000 other->sk_shutdown |= peer_mode; 2013 peer_mode |= RCV_SHUTDOWN;
2001 unix_state_unlock(other); 2014 unix_state_lock(other);
2002 other->sk_state_change(other); 2015 other->sk_shutdown |= peer_mode;
2003 if (peer_mode == SHUTDOWN_MASK) 2016 unix_state_unlock(other);
2004 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); 2017 other->sk_state_change(other);
2005 else if (peer_mode & RCV_SHUTDOWN) 2018 if (peer_mode == SHUTDOWN_MASK)
2006 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); 2019 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
2007 } 2020 else if (peer_mode & RCV_SHUTDOWN)
2008 if (other) 2021 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
2009 sock_put(other);
2010 } 2022 }
2023 if (other)
2024 sock_put(other);
2025
2011 return 0; 2026 return 0;
2012} 2027}
2013 2028