diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-06-28 02:00:25 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-06-28 02:00:25 -0400 |
commit | 31881d74b6dd1a6c530cff61248def4f2da38bee (patch) | |
tree | be62420cf39192074e13b25553d172b9d5e58a33 /net/unix/af_unix.c | |
parent | 8855f30cd2b68012571932c7b01290c20be4508c (diff) | |
parent | 257867dc8d893690c175c1f717f91c3b6d44a63d (diff) |
Merge branch 'for-next' of git://github.com/rydberg/linux into next
Pull in changes from Henrik: "a trivial MT documentation fix".
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r-- | net/unix/af_unix.c | 54 |
1 files changed, 27 insertions, 27 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 51be64f163ec..826e09938bff 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) | |||
382 | #endif | 382 | #endif |
383 | } | 383 | } |
384 | 384 | ||
385 | static int unix_release_sock(struct sock *sk, int embrion) | 385 | static void unix_release_sock(struct sock *sk, int embrion) |
386 | { | 386 | { |
387 | struct unix_sock *u = unix_sk(sk); | 387 | struct unix_sock *u = unix_sk(sk); |
388 | struct path path; | 388 | struct path path; |
@@ -451,8 +451,6 @@ static int unix_release_sock(struct sock *sk, int embrion) | |||
451 | 451 | ||
452 | if (unix_tot_inflight) | 452 | if (unix_tot_inflight) |
453 | unix_gc(); /* Garbage collect fds */ | 453 | unix_gc(); /* Garbage collect fds */ |
454 | |||
455 | return 0; | ||
456 | } | 454 | } |
457 | 455 | ||
458 | static void init_peercred(struct sock *sk) | 456 | static void init_peercred(struct sock *sk) |
@@ -699,9 +697,10 @@ static int unix_release(struct socket *sock) | |||
699 | if (!sk) | 697 | if (!sk) |
700 | return 0; | 698 | return 0; |
701 | 699 | ||
700 | unix_release_sock(sk, 0); | ||
702 | sock->sk = NULL; | 701 | sock->sk = NULL; |
703 | 702 | ||
704 | return unix_release_sock(sk, 0); | 703 | return 0; |
705 | } | 704 | } |
706 | 705 | ||
707 | static int unix_autobind(struct socket *sock) | 706 | static int unix_autobind(struct socket *sock) |
@@ -1341,7 +1340,6 @@ static void unix_destruct_scm(struct sk_buff *skb) | |||
1341 | struct scm_cookie scm; | 1340 | struct scm_cookie scm; |
1342 | memset(&scm, 0, sizeof(scm)); | 1341 | memset(&scm, 0, sizeof(scm)); |
1343 | scm.pid = UNIXCB(skb).pid; | 1342 | scm.pid = UNIXCB(skb).pid; |
1344 | scm.cred = UNIXCB(skb).cred; | ||
1345 | if (UNIXCB(skb).fp) | 1343 | if (UNIXCB(skb).fp) |
1346 | unix_detach_fds(&scm, skb); | 1344 | unix_detach_fds(&scm, skb); |
1347 | 1345 | ||
@@ -1392,8 +1390,8 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen | |||
1392 | int err = 0; | 1390 | int err = 0; |
1393 | 1391 | ||
1394 | UNIXCB(skb).pid = get_pid(scm->pid); | 1392 | UNIXCB(skb).pid = get_pid(scm->pid); |
1395 | if (scm->cred) | 1393 | UNIXCB(skb).uid = scm->creds.uid; |
1396 | UNIXCB(skb).cred = get_cred(scm->cred); | 1394 | UNIXCB(skb).gid = scm->creds.gid; |
1397 | UNIXCB(skb).fp = NULL; | 1395 | UNIXCB(skb).fp = NULL; |
1398 | if (scm->fp && send_fds) | 1396 | if (scm->fp && send_fds) |
1399 | err = unix_attach_fds(scm, skb); | 1397 | 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 | |||
1410 | static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, | 1408 | static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, |
1411 | const struct sock *other) | 1409 | const struct sock *other) |
1412 | { | 1410 | { |
1413 | if (UNIXCB(skb).cred) | 1411 | if (UNIXCB(skb).pid) |
1414 | return; | 1412 | return; |
1415 | if (test_bit(SOCK_PASSCRED, &sock->flags) || | 1413 | if (test_bit(SOCK_PASSCRED, &sock->flags) || |
1416 | !other->sk_socket || | 1414 | !other->sk_socket || |
1417 | test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { | 1415 | test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { |
1418 | UNIXCB(skb).pid = get_pid(task_tgid(current)); | 1416 | UNIXCB(skb).pid = get_pid(task_tgid(current)); |
1419 | UNIXCB(skb).cred = get_current_cred(); | 1417 | current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); |
1420 | } | 1418 | } |
1421 | } | 1419 | } |
1422 | 1420 | ||
@@ -1820,7 +1818,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1820 | siocb->scm = &tmp_scm; | 1818 | siocb->scm = &tmp_scm; |
1821 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | 1819 | memset(&tmp_scm, 0, sizeof(tmp_scm)); |
1822 | } | 1820 | } |
1823 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); | 1821 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); |
1824 | unix_set_secdata(siocb->scm, skb); | 1822 | unix_set_secdata(siocb->scm, skb); |
1825 | 1823 | ||
1826 | if (!(flags & MSG_PEEK)) { | 1824 | if (!(flags & MSG_PEEK)) { |
@@ -1860,10 +1858,10 @@ out: | |||
1860 | } | 1858 | } |
1861 | 1859 | ||
1862 | /* | 1860 | /* |
1863 | * Sleep until data has arrive. But check for races.. | 1861 | * Sleep until more data has arrived. But check for races.. |
1864 | */ | 1862 | */ |
1865 | 1863 | static long unix_stream_data_wait(struct sock *sk, long timeo, | |
1866 | static long unix_stream_data_wait(struct sock *sk, long timeo) | 1864 | struct sk_buff *last) |
1867 | { | 1865 | { |
1868 | DEFINE_WAIT(wait); | 1866 | DEFINE_WAIT(wait); |
1869 | 1867 | ||
@@ -1872,7 +1870,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo) | |||
1872 | for (;;) { | 1870 | for (;;) { |
1873 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 1871 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1874 | 1872 | ||
1875 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 1873 | if (skb_peek_tail(&sk->sk_receive_queue) != last || |
1876 | sk->sk_err || | 1874 | sk->sk_err || |
1877 | (sk->sk_shutdown & RCV_SHUTDOWN) || | 1875 | (sk->sk_shutdown & RCV_SHUTDOWN) || |
1878 | signal_pending(current) || | 1876 | signal_pending(current) || |
@@ -1891,8 +1889,6 @@ static long unix_stream_data_wait(struct sock *sk, long timeo) | |||
1891 | return timeo; | 1889 | return timeo; |
1892 | } | 1890 | } |
1893 | 1891 | ||
1894 | |||
1895 | |||
1896 | static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | 1892 | static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, |
1897 | struct msghdr *msg, size_t size, | 1893 | struct msghdr *msg, size_t size, |
1898 | int flags) | 1894 | int flags) |
@@ -1937,14 +1933,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1937 | goto out; | 1933 | goto out; |
1938 | } | 1934 | } |
1939 | 1935 | ||
1940 | skip = sk_peek_offset(sk, flags); | ||
1941 | |||
1942 | do { | 1936 | do { |
1943 | int chunk; | 1937 | int chunk; |
1944 | struct sk_buff *skb; | 1938 | struct sk_buff *skb, *last; |
1945 | 1939 | ||
1946 | unix_state_lock(sk); | 1940 | unix_state_lock(sk); |
1947 | skb = skb_peek(&sk->sk_receive_queue); | 1941 | last = skb = skb_peek(&sk->sk_receive_queue); |
1948 | again: | 1942 | again: |
1949 | if (skb == NULL) { | 1943 | if (skb == NULL) { |
1950 | unix_sk(sk)->recursion_level = 0; | 1944 | unix_sk(sk)->recursion_level = 0; |
@@ -1967,7 +1961,7 @@ again: | |||
1967 | break; | 1961 | break; |
1968 | mutex_unlock(&u->readlock); | 1962 | mutex_unlock(&u->readlock); |
1969 | 1963 | ||
1970 | timeo = unix_stream_data_wait(sk, timeo); | 1964 | timeo = unix_stream_data_wait(sk, timeo, last); |
1971 | 1965 | ||
1972 | if (signal_pending(current) | 1966 | if (signal_pending(current) |
1973 | || mutex_lock_interruptible(&u->readlock)) { | 1967 | || mutex_lock_interruptible(&u->readlock)) { |
@@ -1981,10 +1975,13 @@ again: | |||
1981 | break; | 1975 | break; |
1982 | } | 1976 | } |
1983 | 1977 | ||
1984 | if (skip >= skb->len) { | 1978 | skip = sk_peek_offset(sk, flags); |
1979 | while (skip >= skb->len) { | ||
1985 | skip -= skb->len; | 1980 | skip -= skb->len; |
1981 | last = skb; | ||
1986 | skb = skb_peek_next(skb, &sk->sk_receive_queue); | 1982 | skb = skb_peek_next(skb, &sk->sk_receive_queue); |
1987 | goto again; | 1983 | if (!skb) |
1984 | goto again; | ||
1988 | } | 1985 | } |
1989 | 1986 | ||
1990 | unix_state_unlock(sk); | 1987 | unix_state_unlock(sk); |
@@ -1992,11 +1989,12 @@ again: | |||
1992 | if (check_creds) { | 1989 | if (check_creds) { |
1993 | /* Never glue messages from different writers */ | 1990 | /* Never glue messages from different writers */ |
1994 | if ((UNIXCB(skb).pid != siocb->scm->pid) || | 1991 | if ((UNIXCB(skb).pid != siocb->scm->pid) || |
1995 | (UNIXCB(skb).cred != siocb->scm->cred)) | 1992 | !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) || |
1993 | !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid)) | ||
1996 | break; | 1994 | break; |
1997 | } else { | 1995 | } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { |
1998 | /* Copy credentials */ | 1996 | /* Copy credentials */ |
1999 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); | 1997 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); |
2000 | check_creds = 1; | 1998 | check_creds = 1; |
2001 | } | 1999 | } |
2002 | 2000 | ||
@@ -2197,7 +2195,9 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, | |||
2197 | 2195 | ||
2198 | /* exceptional events? */ | 2196 | /* exceptional events? */ |
2199 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) | 2197 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) |
2200 | mask |= POLLERR; | 2198 | mask |= POLLERR | |
2199 | (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0); | ||
2200 | |||
2201 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 2201 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
2202 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; | 2202 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; |
2203 | if (sk->sk_shutdown == SHUTDOWN_MASK) | 2203 | if (sk->sk_shutdown == SHUTDOWN_MASK) |