diff options
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r-- | net/unix/af_unix.c | 164 |
1 files changed, 103 insertions, 61 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 3c95304a0817..1663e1a2efdd 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -316,7 +316,8 @@ static void unix_write_space(struct sock *sk) | |||
316 | if (unix_writable(sk)) { | 316 | if (unix_writable(sk)) { |
317 | wq = rcu_dereference(sk->sk_wq); | 317 | wq = rcu_dereference(sk->sk_wq); |
318 | if (wq_has_sleeper(wq)) | 318 | if (wq_has_sleeper(wq)) |
319 | wake_up_interruptible_sync(&wq->wait); | 319 | wake_up_interruptible_sync_poll(&wq->wait, |
320 | POLLOUT | POLLWRNORM | POLLWRBAND); | ||
320 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); | 321 | sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); |
321 | } | 322 | } |
322 | rcu_read_unlock(); | 323 | rcu_read_unlock(); |
@@ -849,7 +850,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
849 | * Get the parent directory, calculate the hash for last | 850 | * Get the parent directory, calculate the hash for last |
850 | * component. | 851 | * component. |
851 | */ | 852 | */ |
852 | err = path_lookup(sunaddr->sun_path, LOOKUP_PARENT, &nd); | 853 | err = kern_path_parent(sunaddr->sun_path, &nd); |
853 | if (err) | 854 | if (err) |
854 | goto out_mknod_parent; | 855 | goto out_mknod_parent; |
855 | 856 | ||
@@ -1123,7 +1124,7 @@ restart: | |||
1123 | 1124 | ||
1124 | /* Latch our state. | 1125 | /* Latch our state. |
1125 | 1126 | ||
1126 | It is tricky place. We need to grab write lock and cannot | 1127 | It is tricky place. We need to grab our state lock and cannot |
1127 | drop lock on peer. It is dangerous because deadlock is | 1128 | drop lock on peer. It is dangerous because deadlock is |
1128 | possible. Connect to self case and simultaneous | 1129 | possible. Connect to self case and simultaneous |
1129 | attempt to connect are eliminated by checking socket | 1130 | attempt to connect are eliminated by checking socket |
@@ -1156,7 +1157,7 @@ restart: | |||
1156 | goto restart; | 1157 | goto restart; |
1157 | } | 1158 | } |
1158 | 1159 | ||
1159 | err = security_unix_stream_connect(sock, other->sk_socket, newsk); | 1160 | err = security_unix_stream_connect(sk, other, newsk); |
1160 | if (err) { | 1161 | if (err) { |
1161 | unix_state_unlock(sk); | 1162 | unix_state_unlock(sk); |
1162 | goto out_unlock; | 1163 | goto out_unlock; |
@@ -1170,7 +1171,7 @@ restart: | |||
1170 | newsk->sk_type = sk->sk_type; | 1171 | newsk->sk_type = sk->sk_type; |
1171 | init_peercred(newsk); | 1172 | init_peercred(newsk); |
1172 | newu = unix_sk(newsk); | 1173 | newu = unix_sk(newsk); |
1173 | newsk->sk_wq = &newu->peer_wq; | 1174 | RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq); |
1174 | otheru = unix_sk(other); | 1175 | otheru = unix_sk(other); |
1175 | 1176 | ||
1176 | /* copy address information from listening to new sock*/ | 1177 | /* copy address information from listening to new sock*/ |
@@ -1343,9 +1344,25 @@ static void unix_destruct_scm(struct sk_buff *skb) | |||
1343 | sock_wfree(skb); | 1344 | sock_wfree(skb); |
1344 | } | 1345 | } |
1345 | 1346 | ||
1347 | #define MAX_RECURSION_LEVEL 4 | ||
1348 | |||
1346 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | 1349 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) |
1347 | { | 1350 | { |
1348 | int i; | 1351 | int i; |
1352 | unsigned char max_level = 0; | ||
1353 | int unix_sock_count = 0; | ||
1354 | |||
1355 | for (i = scm->fp->count - 1; i >= 0; i--) { | ||
1356 | struct sock *sk = unix_get_socket(scm->fp->fp[i]); | ||
1357 | |||
1358 | if (sk) { | ||
1359 | unix_sock_count++; | ||
1360 | max_level = max(max_level, | ||
1361 | unix_sk(sk)->recursion_level); | ||
1362 | } | ||
1363 | } | ||
1364 | if (unlikely(max_level > MAX_RECURSION_LEVEL)) | ||
1365 | return -ETOOMANYREFS; | ||
1349 | 1366 | ||
1350 | /* | 1367 | /* |
1351 | * Need to duplicate file references for the sake of garbage | 1368 | * Need to duplicate file references for the sake of garbage |
@@ -1356,9 +1373,11 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | |||
1356 | if (!UNIXCB(skb).fp) | 1373 | if (!UNIXCB(skb).fp) |
1357 | return -ENOMEM; | 1374 | return -ENOMEM; |
1358 | 1375 | ||
1359 | for (i = scm->fp->count-1; i >= 0; i--) | 1376 | if (unix_sock_count) { |
1360 | unix_inflight(scm->fp->fp[i]); | 1377 | for (i = scm->fp->count - 1; i >= 0; i--) |
1361 | return 0; | 1378 | unix_inflight(scm->fp->fp[i]); |
1379 | } | ||
1380 | return max_level; | ||
1362 | } | 1381 | } |
1363 | 1382 | ||
1364 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) | 1383 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) |
@@ -1393,6 +1412,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1393 | struct sk_buff *skb; | 1412 | struct sk_buff *skb; |
1394 | long timeo; | 1413 | long timeo; |
1395 | struct scm_cookie tmp_scm; | 1414 | struct scm_cookie tmp_scm; |
1415 | int max_level; | ||
1396 | 1416 | ||
1397 | if (NULL == siocb->scm) | 1417 | if (NULL == siocb->scm) |
1398 | siocb->scm = &tmp_scm; | 1418 | siocb->scm = &tmp_scm; |
@@ -1431,8 +1451,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1431 | goto out; | 1451 | goto out; |
1432 | 1452 | ||
1433 | err = unix_scm_to_skb(siocb->scm, skb, true); | 1453 | err = unix_scm_to_skb(siocb->scm, skb, true); |
1434 | if (err) | 1454 | if (err < 0) |
1435 | goto out_free; | 1455 | goto out_free; |
1456 | max_level = err + 1; | ||
1436 | unix_get_secdata(siocb->scm, skb); | 1457 | unix_get_secdata(siocb->scm, skb); |
1437 | 1458 | ||
1438 | skb_reset_transport_header(skb); | 1459 | skb_reset_transport_header(skb); |
@@ -1454,6 +1475,12 @@ restart: | |||
1454 | goto out_free; | 1475 | goto out_free; |
1455 | } | 1476 | } |
1456 | 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 | |||
1457 | unix_state_lock(other); | 1484 | unix_state_lock(other); |
1458 | err = -EPERM; | 1485 | err = -EPERM; |
1459 | if (!unix_may_send(sk, other)) | 1486 | if (!unix_may_send(sk, other)) |
@@ -1514,6 +1541,8 @@ restart: | |||
1514 | if (sock_flag(other, SOCK_RCVTSTAMP)) | 1541 | if (sock_flag(other, SOCK_RCVTSTAMP)) |
1515 | __net_timestamp(skb); | 1542 | __net_timestamp(skb); |
1516 | skb_queue_tail(&other->sk_receive_queue, skb); | 1543 | skb_queue_tail(&other->sk_receive_queue, skb); |
1544 | if (max_level > unix_sk(other)->recursion_level) | ||
1545 | unix_sk(other)->recursion_level = max_level; | ||
1517 | unix_state_unlock(other); | 1546 | unix_state_unlock(other); |
1518 | other->sk_data_ready(other, len); | 1547 | other->sk_data_ready(other, len); |
1519 | sock_put(other); | 1548 | sock_put(other); |
@@ -1538,12 +1567,12 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1538 | struct sock_iocb *siocb = kiocb_to_siocb(kiocb); | 1567 | struct sock_iocb *siocb = kiocb_to_siocb(kiocb); |
1539 | struct sock *sk = sock->sk; | 1568 | struct sock *sk = sock->sk; |
1540 | struct sock *other = NULL; | 1569 | struct sock *other = NULL; |
1541 | struct sockaddr_un *sunaddr = msg->msg_name; | ||
1542 | int err, size; | 1570 | int err, size; |
1543 | struct sk_buff *skb; | 1571 | struct sk_buff *skb; |
1544 | int sent = 0; | 1572 | int sent = 0; |
1545 | struct scm_cookie tmp_scm; | 1573 | struct scm_cookie tmp_scm; |
1546 | bool fds_sent = false; | 1574 | bool fds_sent = false; |
1575 | int max_level; | ||
1547 | 1576 | ||
1548 | if (NULL == siocb->scm) | 1577 | if (NULL == siocb->scm) |
1549 | siocb->scm = &tmp_scm; | 1578 | siocb->scm = &tmp_scm; |
@@ -1560,7 +1589,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1560 | err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; | 1589 | err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; |
1561 | goto out_err; | 1590 | goto out_err; |
1562 | } else { | 1591 | } else { |
1563 | sunaddr = NULL; | ||
1564 | err = -ENOTCONN; | 1592 | err = -ENOTCONN; |
1565 | other = unix_peer(sk); | 1593 | other = unix_peer(sk); |
1566 | if (!other) | 1594 | if (!other) |
@@ -1607,10 +1635,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1607 | 1635 | ||
1608 | /* Only send the fds in the first buffer */ | 1636 | /* Only send the fds in the first buffer */ |
1609 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); | 1637 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); |
1610 | if (err) { | 1638 | if (err < 0) { |
1611 | kfree_skb(skb); | 1639 | kfree_skb(skb); |
1612 | goto out_err; | 1640 | goto out_err; |
1613 | } | 1641 | } |
1642 | max_level = err + 1; | ||
1614 | fds_sent = true; | 1643 | fds_sent = true; |
1615 | 1644 | ||
1616 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 1645 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
@@ -1626,6 +1655,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1626 | goto pipe_err_free; | 1655 | goto pipe_err_free; |
1627 | 1656 | ||
1628 | skb_queue_tail(&other->sk_receive_queue, skb); | 1657 | skb_queue_tail(&other->sk_receive_queue, skb); |
1658 | if (max_level > unix_sk(other)->recursion_level) | ||
1659 | unix_sk(other)->recursion_level = max_level; | ||
1629 | unix_state_unlock(other); | 1660 | unix_state_unlock(other); |
1630 | other->sk_data_ready(other, size); | 1661 | other->sk_data_ready(other, size); |
1631 | sent += size; | 1662 | sent += size; |
@@ -1697,7 +1728,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1697 | 1728 | ||
1698 | msg->msg_namelen = 0; | 1729 | msg->msg_namelen = 0; |
1699 | 1730 | ||
1700 | 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 | } | ||
1701 | 1736 | ||
1702 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 1737 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
1703 | if (!skb) { | 1738 | if (!skb) { |
@@ -1710,7 +1745,8 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1710 | goto out_unlock; | 1745 | goto out_unlock; |
1711 | } | 1746 | } |
1712 | 1747 | ||
1713 | wake_up_interruptible_sync(&u->peer_wait); | 1748 | wake_up_interruptible_sync_poll(&u->peer_wait, |
1749 | POLLOUT | POLLWRNORM | POLLWRBAND); | ||
1714 | 1750 | ||
1715 | if (msg->msg_name) | 1751 | if (msg->msg_name) |
1716 | unix_copy_addr(msg, skb->sk); | 1752 | unix_copy_addr(msg, skb->sk); |
@@ -1836,7 +1872,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1836 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | 1872 | memset(&tmp_scm, 0, sizeof(tmp_scm)); |
1837 | } | 1873 | } |
1838 | 1874 | ||
1839 | mutex_lock(&u->readlock); | 1875 | err = mutex_lock_interruptible(&u->readlock); |
1876 | if (err) { | ||
1877 | err = sock_intr_errno(timeo); | ||
1878 | goto out; | ||
1879 | } | ||
1840 | 1880 | ||
1841 | do { | 1881 | do { |
1842 | int chunk; | 1882 | int chunk; |
@@ -1845,6 +1885,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1845 | unix_state_lock(sk); | 1885 | unix_state_lock(sk); |
1846 | skb = skb_dequeue(&sk->sk_receive_queue); | 1886 | skb = skb_dequeue(&sk->sk_receive_queue); |
1847 | if (skb == NULL) { | 1887 | if (skb == NULL) { |
1888 | unix_sk(sk)->recursion_level = 0; | ||
1848 | if (copied >= target) | 1889 | if (copied >= target) |
1849 | goto unlock; | 1890 | goto unlock; |
1850 | 1891 | ||
@@ -1866,11 +1907,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1866 | 1907 | ||
1867 | timeo = unix_stream_data_wait(sk, timeo); | 1908 | timeo = unix_stream_data_wait(sk, timeo); |
1868 | 1909 | ||
1869 | if (signal_pending(current)) { | 1910 | if (signal_pending(current) |
1911 | || mutex_lock_interruptible(&u->readlock)) { | ||
1870 | err = sock_intr_errno(timeo); | 1912 | err = sock_intr_errno(timeo); |
1871 | goto out; | 1913 | goto out; |
1872 | } | 1914 | } |
1873 | mutex_lock(&u->readlock); | 1915 | |
1874 | continue; | 1916 | continue; |
1875 | unlock: | 1917 | unlock: |
1876 | unix_state_unlock(sk); | 1918 | unix_state_unlock(sk); |
@@ -1949,36 +1991,38 @@ static int unix_shutdown(struct socket *sock, int mode) | |||
1949 | 1991 | ||
1950 | mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); | 1992 | mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); |
1951 | 1993 | ||
1952 | if (mode) { | 1994 | if (!mode) |
1953 | unix_state_lock(sk); | 1995 | return 0; |
1954 | sk->sk_shutdown |= mode; | 1996 | |
1955 | other = unix_peer(sk); | 1997 | unix_state_lock(sk); |
1956 | if (other) | 1998 | sk->sk_shutdown |= mode; |
1957 | sock_hold(other); | 1999 | other = unix_peer(sk); |
1958 | unix_state_unlock(sk); | 2000 | if (other) |
1959 | sk->sk_state_change(sk); | 2001 | sock_hold(other); |
1960 | 2002 | unix_state_unlock(sk); | |
1961 | if (other && | 2003 | sk->sk_state_change(sk); |
1962 | (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) { | 2004 | |
1963 | 2005 | if (other && | |
1964 | int peer_mode = 0; | 2006 | (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) { |
1965 | 2007 | ||
1966 | if (mode&RCV_SHUTDOWN) | 2008 | int peer_mode = 0; |
1967 | peer_mode |= SEND_SHUTDOWN; | 2009 | |
1968 | if (mode&SEND_SHUTDOWN) | 2010 | if (mode&RCV_SHUTDOWN) |
1969 | peer_mode |= RCV_SHUTDOWN; | 2011 | peer_mode |= SEND_SHUTDOWN; |
1970 | unix_state_lock(other); | 2012 | if (mode&SEND_SHUTDOWN) |
1971 | other->sk_shutdown |= peer_mode; | 2013 | peer_mode |= RCV_SHUTDOWN; |
1972 | unix_state_unlock(other); | 2014 | unix_state_lock(other); |
1973 | other->sk_state_change(other); | 2015 | other->sk_shutdown |= peer_mode; |
1974 | if (peer_mode == SHUTDOWN_MASK) | 2016 | unix_state_unlock(other); |
1975 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); | 2017 | other->sk_state_change(other); |
1976 | else if (peer_mode & RCV_SHUTDOWN) | 2018 | if (peer_mode == SHUTDOWN_MASK) |
1977 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); | 2019 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); |
1978 | } | 2020 | else if (peer_mode & RCV_SHUTDOWN) |
1979 | if (other) | 2021 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); |
1980 | sock_put(other); | ||
1981 | } | 2022 | } |
2023 | if (other) | ||
2024 | sock_put(other); | ||
2025 | |||
1982 | return 0; | 2026 | return 0; |
1983 | } | 2027 | } |
1984 | 2028 | ||
@@ -2072,13 +2116,12 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, | |||
2072 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) | 2116 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) |
2073 | mask |= POLLERR; | 2117 | mask |= POLLERR; |
2074 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 2118 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
2075 | mask |= POLLRDHUP; | 2119 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; |
2076 | if (sk->sk_shutdown == SHUTDOWN_MASK) | 2120 | if (sk->sk_shutdown == SHUTDOWN_MASK) |
2077 | mask |= POLLHUP; | 2121 | mask |= POLLHUP; |
2078 | 2122 | ||
2079 | /* readable? */ | 2123 | /* readable? */ |
2080 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 2124 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
2081 | (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
2082 | mask |= POLLIN | POLLRDNORM; | 2125 | mask |= POLLIN | POLLRDNORM; |
2083 | 2126 | ||
2084 | /* Connection-based need to check for termination and startup */ | 2127 | /* Connection-based need to check for termination and startup */ |
@@ -2090,20 +2133,19 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, | |||
2090 | return mask; | 2133 | return mask; |
2091 | } | 2134 | } |
2092 | 2135 | ||
2093 | /* writable? */ | 2136 | /* No write status requested, avoid expensive OUT tests. */ |
2094 | writable = unix_writable(sk); | 2137 | if (wait && !(wait->key & (POLLWRBAND | POLLWRNORM | POLLOUT))) |
2095 | if (writable) { | 2138 | return mask; |
2096 | other = unix_peer_get(sk); | ||
2097 | if (other) { | ||
2098 | if (unix_peer(other) != sk) { | ||
2099 | sock_poll_wait(file, &unix_sk(other)->peer_wait, | ||
2100 | wait); | ||
2101 | if (unix_recvq_full(other)) | ||
2102 | writable = 0; | ||
2103 | } | ||
2104 | 2139 | ||
2105 | sock_put(other); | 2140 | writable = unix_writable(sk); |
2141 | other = unix_peer_get(sk); | ||
2142 | if (other) { | ||
2143 | if (unix_peer(other) != sk) { | ||
2144 | sock_poll_wait(file, &unix_sk(other)->peer_wait, wait); | ||
2145 | if (unix_recvq_full(other)) | ||
2146 | writable = 0; | ||
2106 | } | 2147 | } |
2148 | sock_put(other); | ||
2107 | } | 2149 | } |
2108 | 2150 | ||
2109 | if (writable) | 2151 | if (writable) |