summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2015-11-26 06:08:18 -0500
committerDavid S. Miller <davem@davemloft.net>2015-11-30 15:16:06 -0500
commit9490f886b192964796285907d777ff00fba1fa0f (patch)
tree8aab488f73d4fe6c24788fef4c2615c4fe45e399 /net
parent6e0f0331a3546b713ea61c42fe9a252bef0bb886 (diff)
af-unix: passcred support for sendpage
sendpage did not care about credentials at all. This could lead to situations in which because of fd passing between processes we could append data to skbs with different scm data. It is illegal to splice those skbs together. Instead we have to allocate a new skb and if requested fill out the scm details. Fixes: 869e7c62486ec ("net: af_unix: implement stream sendpage support") Reported-by: Al Viro <viro@zeniv.linux.org.uk> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Eric Dumazet <edumazet@google.com> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/unix/af_unix.c79
1 files changed, 64 insertions, 15 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 4e95bdf973d9..6ced74690eee 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1551,6 +1551,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
1551 return err; 1551 return err;
1552} 1552}
1553 1553
1554static bool unix_passcred_enabled(const struct socket *sock,
1555 const struct sock *other)
1556{
1557 return test_bit(SOCK_PASSCRED, &sock->flags) ||
1558 !other->sk_socket ||
1559 test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
1560}
1561
1554/* 1562/*
1555 * Some apps rely on write() giving SCM_CREDENTIALS 1563 * Some apps rely on write() giving SCM_CREDENTIALS
1556 * We include credentials if source or destination socket 1564 * We include credentials if source or destination socket
@@ -1561,14 +1569,41 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1561{ 1569{
1562 if (UNIXCB(skb).pid) 1570 if (UNIXCB(skb).pid)
1563 return; 1571 return;
1564 if (test_bit(SOCK_PASSCRED, &sock->flags) || 1572 if (unix_passcred_enabled(sock, other)) {
1565 !other->sk_socket ||
1566 test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
1567 UNIXCB(skb).pid = get_pid(task_tgid(current)); 1573 UNIXCB(skb).pid = get_pid(task_tgid(current));
1568 current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); 1574 current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
1569 } 1575 }
1570} 1576}
1571 1577
1578static int maybe_init_creds(struct scm_cookie *scm,
1579 struct socket *socket,
1580 const struct sock *other)
1581{
1582 int err;
1583 struct msghdr msg = { .msg_controllen = 0 };
1584
1585 err = scm_send(socket, &msg, scm, false);
1586 if (err)
1587 return err;
1588
1589 if (unix_passcred_enabled(socket, other)) {
1590 scm->pid = get_pid(task_tgid(current));
1591 current_uid_gid(&scm->creds.uid, &scm->creds.gid);
1592 }
1593 return err;
1594}
1595
1596static bool unix_skb_scm_eq(struct sk_buff *skb,
1597 struct scm_cookie *scm)
1598{
1599 const struct unix_skb_parms *u = &UNIXCB(skb);
1600
1601 return u->pid == scm->pid &&
1602 uid_eq(u->uid, scm->creds.uid) &&
1603 gid_eq(u->gid, scm->creds.gid) &&
1604 unix_secdata_eq(scm, skb);
1605}
1606
1572/* 1607/*
1573 * Send AF_UNIX data. 1608 * Send AF_UNIX data.
1574 */ 1609 */
@@ -1884,8 +1919,10 @@ out_err:
1884static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, 1919static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
1885 int offset, size_t size, int flags) 1920 int offset, size_t size, int flags)
1886{ 1921{
1887 int err = 0; 1922 int err;
1888 bool send_sigpipe = true; 1923 bool send_sigpipe = false;
1924 bool init_scm = true;
1925 struct scm_cookie scm;
1889 struct sock *other, *sk = socket->sk; 1926 struct sock *other, *sk = socket->sk;
1890 struct sk_buff *skb, *newskb = NULL, *tail = NULL; 1927 struct sk_buff *skb, *newskb = NULL, *tail = NULL;
1891 1928
@@ -1903,7 +1940,7 @@ alloc_skb:
1903 newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, 1940 newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
1904 &err, 0); 1941 &err, 0);
1905 if (!newskb) 1942 if (!newskb)
1906 return err; 1943 goto err;
1907 } 1944 }
1908 1945
1909 /* we must acquire readlock as we modify already present 1946 /* we must acquire readlock as we modify already present
@@ -1912,12 +1949,12 @@ alloc_skb:
1912 err = mutex_lock_interruptible(&unix_sk(other)->readlock); 1949 err = mutex_lock_interruptible(&unix_sk(other)->readlock);
1913 if (err) { 1950 if (err) {
1914 err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; 1951 err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
1915 send_sigpipe = false;
1916 goto err; 1952 goto err;
1917 } 1953 }
1918 1954
1919 if (sk->sk_shutdown & SEND_SHUTDOWN) { 1955 if (sk->sk_shutdown & SEND_SHUTDOWN) {
1920 err = -EPIPE; 1956 err = -EPIPE;
1957 send_sigpipe = true;
1921 goto err_unlock; 1958 goto err_unlock;
1922 } 1959 }
1923 1960
@@ -1926,17 +1963,27 @@ alloc_skb:
1926 if (sock_flag(other, SOCK_DEAD) || 1963 if (sock_flag(other, SOCK_DEAD) ||
1927 other->sk_shutdown & RCV_SHUTDOWN) { 1964 other->sk_shutdown & RCV_SHUTDOWN) {
1928 err = -EPIPE; 1965 err = -EPIPE;
1966 send_sigpipe = true;
1929 goto err_state_unlock; 1967 goto err_state_unlock;
1930 } 1968 }
1931 1969
1970 if (init_scm) {
1971 err = maybe_init_creds(&scm, socket, other);
1972 if (err)
1973 goto err_state_unlock;
1974 init_scm = false;
1975 }
1976
1932 skb = skb_peek_tail(&other->sk_receive_queue); 1977 skb = skb_peek_tail(&other->sk_receive_queue);
1933 if (tail && tail == skb) { 1978 if (tail && tail == skb) {
1934 skb = newskb; 1979 skb = newskb;
1935 } else if (!skb) { 1980 } else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
1936 if (newskb) 1981 if (newskb) {
1937 skb = newskb; 1982 skb = newskb;
1938 else 1983 } else {
1984 tail = skb;
1939 goto alloc_skb; 1985 goto alloc_skb;
1986 }
1940 } else if (newskb) { 1987 } else if (newskb) {
1941 /* this is fast path, we don't necessarily need to 1988 /* this is fast path, we don't necessarily need to
1942 * call to kfree_skb even though with newskb == NULL 1989 * call to kfree_skb even though with newskb == NULL
@@ -1957,6 +2004,9 @@ alloc_skb:
1957 atomic_add(size, &sk->sk_wmem_alloc); 2004 atomic_add(size, &sk->sk_wmem_alloc);
1958 2005
1959 if (newskb) { 2006 if (newskb) {
2007 err = unix_scm_to_skb(&scm, skb, false);
2008 if (err)
2009 goto err_state_unlock;
1960 spin_lock(&other->sk_receive_queue.lock); 2010 spin_lock(&other->sk_receive_queue.lock);
1961 __skb_queue_tail(&other->sk_receive_queue, newskb); 2011 __skb_queue_tail(&other->sk_receive_queue, newskb);
1962 spin_unlock(&other->sk_receive_queue.lock); 2012 spin_unlock(&other->sk_receive_queue.lock);
@@ -1966,7 +2016,7 @@ alloc_skb:
1966 mutex_unlock(&unix_sk(other)->readlock); 2016 mutex_unlock(&unix_sk(other)->readlock);
1967 2017
1968 other->sk_data_ready(other); 2018 other->sk_data_ready(other);
1969 2019 scm_destroy(&scm);
1970 return size; 2020 return size;
1971 2021
1972err_state_unlock: 2022err_state_unlock:
@@ -1977,6 +2027,8 @@ err:
1977 kfree_skb(newskb); 2027 kfree_skb(newskb);
1978 if (send_sigpipe && !(flags & MSG_NOSIGNAL)) 2028 if (send_sigpipe && !(flags & MSG_NOSIGNAL))
1979 send_sig(SIGPIPE, current, 0); 2029 send_sig(SIGPIPE, current, 0);
2030 if (!init_scm)
2031 scm_destroy(&scm);
1980 return err; 2032 return err;
1981} 2033}
1982 2034
@@ -2280,10 +2332,7 @@ unlock:
2280 2332
2281 if (check_creds) { 2333 if (check_creds) {
2282 /* Never glue messages from different writers */ 2334 /* Never glue messages from different writers */
2283 if ((UNIXCB(skb).pid != scm.pid) || 2335 if (!unix_skb_scm_eq(skb, &scm))
2284 !uid_eq(UNIXCB(skb).uid, scm.creds.uid) ||
2285 !gid_eq(UNIXCB(skb).gid, scm.creds.gid) ||
2286 !unix_secdata_eq(&scm, skb))
2287 break; 2336 break;
2288 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { 2337 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
2289 /* Copy credentials */ 2338 /* Copy credentials */