diff options
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r-- | net/unix/af_unix.c | 24 |
1 files changed, 1 insertions, 23 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 7b52a380d710..5c53f22d62e8 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1528,26 +1528,13 @@ static inline bool too_many_unix_fds(struct task_struct *p) | |||
1528 | return false; | 1528 | return false; |
1529 | } | 1529 | } |
1530 | 1530 | ||
1531 | #define MAX_RECURSION_LEVEL 4 | ||
1532 | |||
1533 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | 1531 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) |
1534 | { | 1532 | { |
1535 | int i; | 1533 | int i; |
1536 | unsigned char max_level = 0; | ||
1537 | 1534 | ||
1538 | if (too_many_unix_fds(current)) | 1535 | if (too_many_unix_fds(current)) |
1539 | return -ETOOMANYREFS; | 1536 | return -ETOOMANYREFS; |
1540 | 1537 | ||
1541 | for (i = scm->fp->count - 1; i >= 0; i--) { | ||
1542 | struct sock *sk = unix_get_socket(scm->fp->fp[i]); | ||
1543 | |||
1544 | if (sk) | ||
1545 | max_level = max(max_level, | ||
1546 | unix_sk(sk)->recursion_level); | ||
1547 | } | ||
1548 | if (unlikely(max_level > MAX_RECURSION_LEVEL)) | ||
1549 | return -ETOOMANYREFS; | ||
1550 | |||
1551 | /* | 1538 | /* |
1552 | * Need to duplicate file references for the sake of garbage | 1539 | * Need to duplicate file references for the sake of garbage |
1553 | * collection. Otherwise a socket in the fps might become a | 1540 | * collection. Otherwise a socket in the fps might become a |
@@ -1559,7 +1546,7 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | |||
1559 | 1546 | ||
1560 | for (i = scm->fp->count - 1; i >= 0; i--) | 1547 | for (i = scm->fp->count - 1; i >= 0; i--) |
1561 | unix_inflight(scm->fp->user, scm->fp->fp[i]); | 1548 | unix_inflight(scm->fp->user, scm->fp->fp[i]); |
1562 | return max_level; | 1549 | return 0; |
1563 | } | 1550 | } |
1564 | 1551 | ||
1565 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) | 1552 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) |
@@ -1649,7 +1636,6 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1649 | struct sk_buff *skb; | 1636 | struct sk_buff *skb; |
1650 | long timeo; | 1637 | long timeo; |
1651 | struct scm_cookie scm; | 1638 | struct scm_cookie scm; |
1652 | int max_level; | ||
1653 | int data_len = 0; | 1639 | int data_len = 0; |
1654 | int sk_locked; | 1640 | int sk_locked; |
1655 | 1641 | ||
@@ -1701,7 +1687,6 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1701 | err = unix_scm_to_skb(&scm, skb, true); | 1687 | err = unix_scm_to_skb(&scm, skb, true); |
1702 | if (err < 0) | 1688 | if (err < 0) |
1703 | goto out_free; | 1689 | goto out_free; |
1704 | max_level = err + 1; | ||
1705 | 1690 | ||
1706 | skb_put(skb, len - data_len); | 1691 | skb_put(skb, len - data_len); |
1707 | skb->data_len = data_len; | 1692 | skb->data_len = data_len; |
@@ -1819,8 +1804,6 @@ restart_locked: | |||
1819 | __net_timestamp(skb); | 1804 | __net_timestamp(skb); |
1820 | maybe_add_creds(skb, sock, other); | 1805 | maybe_add_creds(skb, sock, other); |
1821 | skb_queue_tail(&other->sk_receive_queue, skb); | 1806 | skb_queue_tail(&other->sk_receive_queue, skb); |
1822 | if (max_level > unix_sk(other)->recursion_level) | ||
1823 | unix_sk(other)->recursion_level = max_level; | ||
1824 | unix_state_unlock(other); | 1807 | unix_state_unlock(other); |
1825 | other->sk_data_ready(other); | 1808 | other->sk_data_ready(other); |
1826 | sock_put(other); | 1809 | sock_put(other); |
@@ -1855,7 +1838,6 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1855 | int sent = 0; | 1838 | int sent = 0; |
1856 | struct scm_cookie scm; | 1839 | struct scm_cookie scm; |
1857 | bool fds_sent = false; | 1840 | bool fds_sent = false; |
1858 | int max_level; | ||
1859 | int data_len; | 1841 | int data_len; |
1860 | 1842 | ||
1861 | wait_for_unix_gc(); | 1843 | wait_for_unix_gc(); |
@@ -1905,7 +1887,6 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1905 | kfree_skb(skb); | 1887 | kfree_skb(skb); |
1906 | goto out_err; | 1888 | goto out_err; |
1907 | } | 1889 | } |
1908 | max_level = err + 1; | ||
1909 | fds_sent = true; | 1890 | fds_sent = true; |
1910 | 1891 | ||
1911 | skb_put(skb, size - data_len); | 1892 | skb_put(skb, size - data_len); |
@@ -1925,8 +1906,6 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, | |||
1925 | 1906 | ||
1926 | maybe_add_creds(skb, sock, other); | 1907 | maybe_add_creds(skb, sock, other); |
1927 | skb_queue_tail(&other->sk_receive_queue, skb); | 1908 | skb_queue_tail(&other->sk_receive_queue, skb); |
1928 | if (max_level > unix_sk(other)->recursion_level) | ||
1929 | unix_sk(other)->recursion_level = max_level; | ||
1930 | unix_state_unlock(other); | 1909 | unix_state_unlock(other); |
1931 | other->sk_data_ready(other); | 1910 | other->sk_data_ready(other); |
1932 | sent += size; | 1911 | sent += size; |
@@ -2324,7 +2303,6 @@ redo: | |||
2324 | last_len = last ? last->len : 0; | 2303 | last_len = last ? last->len : 0; |
2325 | again: | 2304 | again: |
2326 | if (skb == NULL) { | 2305 | if (skb == NULL) { |
2327 | unix_sk(sk)->recursion_level = 0; | ||
2328 | if (copied >= target) | 2306 | if (copied >= target) |
2329 | goto unlock; | 2307 | goto unlock; |
2330 | 2308 | ||