diff options
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r-- | net/unix/af_unix.c | 128 |
1 files changed, 51 insertions, 77 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 735362c26c8e..5d1c14a2f268 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -661,11 +661,11 @@ static int unix_set_peek_off(struct sock *sk, int val) | |||
661 | { | 661 | { |
662 | struct unix_sock *u = unix_sk(sk); | 662 | struct unix_sock *u = unix_sk(sk); |
663 | 663 | ||
664 | if (mutex_lock_interruptible(&u->readlock)) | 664 | if (mutex_lock_interruptible(&u->iolock)) |
665 | return -EINTR; | 665 | return -EINTR; |
666 | 666 | ||
667 | sk->sk_peek_off = val; | 667 | sk->sk_peek_off = val; |
668 | mutex_unlock(&u->readlock); | 668 | mutex_unlock(&u->iolock); |
669 | 669 | ||
670 | return 0; | 670 | return 0; |
671 | } | 671 | } |
@@ -769,6 +769,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern) | |||
769 | lockdep_set_class(&sk->sk_receive_queue.lock, | 769 | lockdep_set_class(&sk->sk_receive_queue.lock, |
770 | &af_unix_sk_receive_queue_lock_key); | 770 | &af_unix_sk_receive_queue_lock_key); |
771 | 771 | ||
772 | sk->sk_allocation = GFP_KERNEL_ACCOUNT; | ||
772 | sk->sk_write_space = unix_write_space; | 773 | sk->sk_write_space = unix_write_space; |
773 | sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen; | 774 | sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen; |
774 | sk->sk_destruct = unix_sock_destructor; | 775 | sk->sk_destruct = unix_sock_destructor; |
@@ -778,7 +779,8 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern) | |||
778 | spin_lock_init(&u->lock); | 779 | spin_lock_init(&u->lock); |
779 | atomic_long_set(&u->inflight, 0); | 780 | atomic_long_set(&u->inflight, 0); |
780 | INIT_LIST_HEAD(&u->link); | 781 | INIT_LIST_HEAD(&u->link); |
781 | mutex_init(&u->readlock); /* single task reading lock */ | 782 | mutex_init(&u->iolock); /* single task reading lock */ |
783 | mutex_init(&u->bindlock); /* single task binding lock */ | ||
782 | init_waitqueue_head(&u->peer_wait); | 784 | init_waitqueue_head(&u->peer_wait); |
783 | init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); | 785 | init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); |
784 | unix_insert_socket(unix_sockets_unbound(sk), sk); | 786 | unix_insert_socket(unix_sockets_unbound(sk), sk); |
@@ -847,7 +849,7 @@ static int unix_autobind(struct socket *sock) | |||
847 | int err; | 849 | int err; |
848 | unsigned int retries = 0; | 850 | unsigned int retries = 0; |
849 | 851 | ||
850 | err = mutex_lock_interruptible(&u->readlock); | 852 | err = mutex_lock_interruptible(&u->bindlock); |
851 | if (err) | 853 | if (err) |
852 | return err; | 854 | return err; |
853 | 855 | ||
@@ -894,7 +896,7 @@ retry: | |||
894 | spin_unlock(&unix_table_lock); | 896 | spin_unlock(&unix_table_lock); |
895 | err = 0; | 897 | err = 0; |
896 | 898 | ||
897 | out: mutex_unlock(&u->readlock); | 899 | out: mutex_unlock(&u->bindlock); |
898 | return err; | 900 | return err; |
899 | } | 901 | } |
900 | 902 | ||
@@ -953,20 +955,32 @@ fail: | |||
953 | return NULL; | 955 | return NULL; |
954 | } | 956 | } |
955 | 957 | ||
956 | static int unix_mknod(struct dentry *dentry, const struct path *path, umode_t mode, | 958 | static int unix_mknod(const char *sun_path, umode_t mode, struct path *res) |
957 | struct path *res) | ||
958 | { | 959 | { |
959 | int err; | 960 | struct dentry *dentry; |
961 | struct path path; | ||
962 | int err = 0; | ||
963 | /* | ||
964 | * Get the parent directory, calculate the hash for last | ||
965 | * component. | ||
966 | */ | ||
967 | dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0); | ||
968 | err = PTR_ERR(dentry); | ||
969 | if (IS_ERR(dentry)) | ||
970 | return err; | ||
960 | 971 | ||
961 | err = security_path_mknod(path, dentry, mode, 0); | 972 | /* |
973 | * All right, let's create it. | ||
974 | */ | ||
975 | err = security_path_mknod(&path, dentry, mode, 0); | ||
962 | if (!err) { | 976 | if (!err) { |
963 | err = vfs_mknod(d_inode(path->dentry), dentry, mode, 0); | 977 | err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0); |
964 | if (!err) { | 978 | if (!err) { |
965 | res->mnt = mntget(path->mnt); | 979 | res->mnt = mntget(path.mnt); |
966 | res->dentry = dget(dentry); | 980 | res->dentry = dget(dentry); |
967 | } | 981 | } |
968 | } | 982 | } |
969 | 983 | done_path_create(&path, dentry); | |
970 | return err; | 984 | return err; |
971 | } | 985 | } |
972 | 986 | ||
@@ -977,12 +991,10 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
977 | struct unix_sock *u = unix_sk(sk); | 991 | struct unix_sock *u = unix_sk(sk); |
978 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; | 992 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; |
979 | char *sun_path = sunaddr->sun_path; | 993 | char *sun_path = sunaddr->sun_path; |
980 | int err, name_err; | 994 | int err; |
981 | unsigned int hash; | 995 | unsigned int hash; |
982 | struct unix_address *addr; | 996 | struct unix_address *addr; |
983 | struct hlist_head *list; | 997 | struct hlist_head *list; |
984 | struct path path; | ||
985 | struct dentry *dentry; | ||
986 | 998 | ||
987 | err = -EINVAL; | 999 | err = -EINVAL; |
988 | if (sunaddr->sun_family != AF_UNIX) | 1000 | if (sunaddr->sun_family != AF_UNIX) |
@@ -998,34 +1010,14 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
998 | goto out; | 1010 | goto out; |
999 | addr_len = err; | 1011 | addr_len = err; |
1000 | 1012 | ||
1001 | name_err = 0; | 1013 | err = mutex_lock_interruptible(&u->bindlock); |
1002 | dentry = NULL; | ||
1003 | if (sun_path[0]) { | ||
1004 | /* Get the parent directory, calculate the hash for last | ||
1005 | * component. | ||
1006 | */ | ||
1007 | dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0); | ||
1008 | |||
1009 | if (IS_ERR(dentry)) { | ||
1010 | /* delay report until after 'already bound' check */ | ||
1011 | name_err = PTR_ERR(dentry); | ||
1012 | dentry = NULL; | ||
1013 | } | ||
1014 | } | ||
1015 | |||
1016 | err = mutex_lock_interruptible(&u->readlock); | ||
1017 | if (err) | 1014 | if (err) |
1018 | goto out_path; | 1015 | goto out; |
1019 | 1016 | ||
1020 | err = -EINVAL; | 1017 | err = -EINVAL; |
1021 | if (u->addr) | 1018 | if (u->addr) |
1022 | goto out_up; | 1019 | goto out_up; |
1023 | 1020 | ||
1024 | if (name_err) { | ||
1025 | err = name_err == -EEXIST ? -EADDRINUSE : name_err; | ||
1026 | goto out_up; | ||
1027 | } | ||
1028 | |||
1029 | err = -ENOMEM; | 1021 | err = -ENOMEM; |
1030 | addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL); | 1022 | addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL); |
1031 | if (!addr) | 1023 | if (!addr) |
@@ -1036,11 +1028,11 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1036 | addr->hash = hash ^ sk->sk_type; | 1028 | addr->hash = hash ^ sk->sk_type; |
1037 | atomic_set(&addr->refcnt, 1); | 1029 | atomic_set(&addr->refcnt, 1); |
1038 | 1030 | ||
1039 | if (dentry) { | 1031 | if (sun_path[0]) { |
1040 | struct path u_path; | 1032 | struct path path; |
1041 | umode_t mode = S_IFSOCK | | 1033 | umode_t mode = S_IFSOCK | |
1042 | (SOCK_INODE(sock)->i_mode & ~current_umask()); | 1034 | (SOCK_INODE(sock)->i_mode & ~current_umask()); |
1043 | err = unix_mknod(dentry, &path, mode, &u_path); | 1035 | err = unix_mknod(sun_path, mode, &path); |
1044 | if (err) { | 1036 | if (err) { |
1045 | if (err == -EEXIST) | 1037 | if (err == -EEXIST) |
1046 | err = -EADDRINUSE; | 1038 | err = -EADDRINUSE; |
@@ -1048,9 +1040,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1048 | goto out_up; | 1040 | goto out_up; |
1049 | } | 1041 | } |
1050 | addr->hash = UNIX_HASH_SIZE; | 1042 | addr->hash = UNIX_HASH_SIZE; |
1051 | hash = d_real_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1); | 1043 | hash = d_real_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1); |
1052 | spin_lock(&unix_table_lock); | 1044 | spin_lock(&unix_table_lock); |
1053 | u->path = u_path; | 1045 | u->path = path; |
1054 | list = &unix_socket_table[hash]; | 1046 | list = &unix_socket_table[hash]; |
1055 | } else { | 1047 | } else { |
1056 | spin_lock(&unix_table_lock); | 1048 | spin_lock(&unix_table_lock); |
@@ -1072,11 +1064,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1072 | out_unlock: | 1064 | out_unlock: |
1073 | spin_unlock(&unix_table_lock); | 1065 | spin_unlock(&unix_table_lock); |
1074 | out_up: | 1066 | out_up: |
1075 | mutex_unlock(&u->readlock); | 1067 | mutex_unlock(&u->bindlock); |
1076 | out_path: | ||
1077 | if (dentry) | ||
1078 | done_path_create(&path, dentry); | ||
1079 | |||
1080 | out: | 1068 | out: |
1081 | return err; | 1069 | return err; |
1082 | } | 1070 | } |
@@ -1968,17 +1956,17 @@ static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, | |||
1968 | if (false) { | 1956 | if (false) { |
1969 | alloc_skb: | 1957 | alloc_skb: |
1970 | unix_state_unlock(other); | 1958 | unix_state_unlock(other); |
1971 | mutex_unlock(&unix_sk(other)->readlock); | 1959 | mutex_unlock(&unix_sk(other)->iolock); |
1972 | newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, | 1960 | newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, |
1973 | &err, 0); | 1961 | &err, 0); |
1974 | if (!newskb) | 1962 | if (!newskb) |
1975 | goto err; | 1963 | goto err; |
1976 | } | 1964 | } |
1977 | 1965 | ||
1978 | /* we must acquire readlock as we modify already present | 1966 | /* we must acquire iolock as we modify already present |
1979 | * skbs in the sk_receive_queue and mess with skb->len | 1967 | * skbs in the sk_receive_queue and mess with skb->len |
1980 | */ | 1968 | */ |
1981 | err = mutex_lock_interruptible(&unix_sk(other)->readlock); | 1969 | err = mutex_lock_interruptible(&unix_sk(other)->iolock); |
1982 | if (err) { | 1970 | if (err) { |
1983 | err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; | 1971 | err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; |
1984 | goto err; | 1972 | goto err; |
@@ -2045,7 +2033,7 @@ alloc_skb: | |||
2045 | } | 2033 | } |
2046 | 2034 | ||
2047 | unix_state_unlock(other); | 2035 | unix_state_unlock(other); |
2048 | mutex_unlock(&unix_sk(other)->readlock); | 2036 | mutex_unlock(&unix_sk(other)->iolock); |
2049 | 2037 | ||
2050 | other->sk_data_ready(other); | 2038 | other->sk_data_ready(other); |
2051 | scm_destroy(&scm); | 2039 | scm_destroy(&scm); |
@@ -2054,7 +2042,7 @@ alloc_skb: | |||
2054 | err_state_unlock: | 2042 | err_state_unlock: |
2055 | unix_state_unlock(other); | 2043 | unix_state_unlock(other); |
2056 | err_unlock: | 2044 | err_unlock: |
2057 | mutex_unlock(&unix_sk(other)->readlock); | 2045 | mutex_unlock(&unix_sk(other)->iolock); |
2058 | err: | 2046 | err: |
2059 | kfree_skb(newskb); | 2047 | kfree_skb(newskb); |
2060 | if (send_sigpipe && !(flags & MSG_NOSIGNAL)) | 2048 | if (send_sigpipe && !(flags & MSG_NOSIGNAL)) |
@@ -2122,7 +2110,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2122 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | 2110 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
2123 | 2111 | ||
2124 | do { | 2112 | do { |
2125 | mutex_lock(&u->readlock); | 2113 | mutex_lock(&u->iolock); |
2126 | 2114 | ||
2127 | skip = sk_peek_offset(sk, flags); | 2115 | skip = sk_peek_offset(sk, flags); |
2128 | skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err, | 2116 | skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err, |
@@ -2130,14 +2118,14 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2130 | if (skb) | 2118 | if (skb) |
2131 | break; | 2119 | break; |
2132 | 2120 | ||
2133 | mutex_unlock(&u->readlock); | 2121 | mutex_unlock(&u->iolock); |
2134 | 2122 | ||
2135 | if (err != -EAGAIN) | 2123 | if (err != -EAGAIN) |
2136 | break; | 2124 | break; |
2137 | } while (timeo && | 2125 | } while (timeo && |
2138 | !__skb_wait_for_more_packets(sk, &err, &timeo, last)); | 2126 | !__skb_wait_for_more_packets(sk, &err, &timeo, last)); |
2139 | 2127 | ||
2140 | if (!skb) { /* implies readlock unlocked */ | 2128 | if (!skb) { /* implies iolock unlocked */ |
2141 | unix_state_lock(sk); | 2129 | unix_state_lock(sk); |
2142 | /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ | 2130 | /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ |
2143 | if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && | 2131 | if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && |
@@ -2202,7 +2190,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2202 | 2190 | ||
2203 | out_free: | 2191 | out_free: |
2204 | skb_free_datagram(sk, skb); | 2192 | skb_free_datagram(sk, skb); |
2205 | mutex_unlock(&u->readlock); | 2193 | mutex_unlock(&u->iolock); |
2206 | out: | 2194 | out: |
2207 | return err; | 2195 | return err; |
2208 | } | 2196 | } |
@@ -2297,7 +2285,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state) | |||
2297 | /* Lock the socket to prevent queue disordering | 2285 | /* Lock the socket to prevent queue disordering |
2298 | * while sleeps in memcpy_tomsg | 2286 | * while sleeps in memcpy_tomsg |
2299 | */ | 2287 | */ |
2300 | mutex_lock(&u->readlock); | 2288 | mutex_lock(&u->iolock); |
2301 | 2289 | ||
2302 | if (flags & MSG_PEEK) | 2290 | if (flags & MSG_PEEK) |
2303 | skip = sk_peek_offset(sk, flags); | 2291 | skip = sk_peek_offset(sk, flags); |
@@ -2339,7 +2327,7 @@ again: | |||
2339 | break; | 2327 | break; |
2340 | } | 2328 | } |
2341 | 2329 | ||
2342 | mutex_unlock(&u->readlock); | 2330 | mutex_unlock(&u->iolock); |
2343 | 2331 | ||
2344 | timeo = unix_stream_data_wait(sk, timeo, last, | 2332 | timeo = unix_stream_data_wait(sk, timeo, last, |
2345 | last_len); | 2333 | last_len); |
@@ -2350,7 +2338,7 @@ again: | |||
2350 | goto out; | 2338 | goto out; |
2351 | } | 2339 | } |
2352 | 2340 | ||
2353 | mutex_lock(&u->readlock); | 2341 | mutex_lock(&u->iolock); |
2354 | goto redo; | 2342 | goto redo; |
2355 | unlock: | 2343 | unlock: |
2356 | unix_state_unlock(sk); | 2344 | unix_state_unlock(sk); |
@@ -2453,7 +2441,7 @@ unlock: | |||
2453 | } | 2441 | } |
2454 | } while (size); | 2442 | } while (size); |
2455 | 2443 | ||
2456 | mutex_unlock(&u->readlock); | 2444 | mutex_unlock(&u->iolock); |
2457 | if (state->msg) | 2445 | if (state->msg) |
2458 | scm_recv(sock, state->msg, &scm, flags); | 2446 | scm_recv(sock, state->msg, &scm, flags); |
2459 | else | 2447 | else |
@@ -2487,28 +2475,13 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2487 | return unix_stream_read_generic(&state); | 2475 | return unix_stream_read_generic(&state); |
2488 | } | 2476 | } |
2489 | 2477 | ||
2490 | static ssize_t skb_unix_socket_splice(struct sock *sk, | ||
2491 | struct pipe_inode_info *pipe, | ||
2492 | struct splice_pipe_desc *spd) | ||
2493 | { | ||
2494 | int ret; | ||
2495 | struct unix_sock *u = unix_sk(sk); | ||
2496 | |||
2497 | mutex_unlock(&u->readlock); | ||
2498 | ret = splice_to_pipe(pipe, spd); | ||
2499 | mutex_lock(&u->readlock); | ||
2500 | |||
2501 | return ret; | ||
2502 | } | ||
2503 | |||
2504 | static int unix_stream_splice_actor(struct sk_buff *skb, | 2478 | static int unix_stream_splice_actor(struct sk_buff *skb, |
2505 | int skip, int chunk, | 2479 | int skip, int chunk, |
2506 | struct unix_stream_read_state *state) | 2480 | struct unix_stream_read_state *state) |
2507 | { | 2481 | { |
2508 | return skb_splice_bits(skb, state->socket->sk, | 2482 | return skb_splice_bits(skb, state->socket->sk, |
2509 | UNIXCB(skb).consumed + skip, | 2483 | UNIXCB(skb).consumed + skip, |
2510 | state->pipe, chunk, state->splice_flags, | 2484 | state->pipe, chunk, state->splice_flags); |
2511 | skb_unix_socket_splice); | ||
2512 | } | 2485 | } |
2513 | 2486 | ||
2514 | static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos, | 2487 | static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos, |
@@ -2839,7 +2812,8 @@ static int unix_seq_show(struct seq_file *seq, void *v) | |||
2839 | i++; | 2812 | i++; |
2840 | } | 2813 | } |
2841 | for ( ; i < len; i++) | 2814 | for ( ; i < len; i++) |
2842 | seq_putc(seq, u->addr->name->sun_path[i]); | 2815 | seq_putc(seq, u->addr->name->sun_path[i] ?: |
2816 | '@'); | ||
2843 | } | 2817 | } |
2844 | unix_state_unlock(s); | 2818 | unix_state_unlock(s); |
2845 | seq_putc(seq, '\n'); | 2819 | seq_putc(seq, '\n'); |