diff options
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r-- | net/unix/af_unix.c | 111 |
1 files changed, 49 insertions, 62 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f1dffe84f0d5..8309687a56b0 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 | } |
@@ -779,7 +779,8 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern) | |||
779 | spin_lock_init(&u->lock); | 779 | spin_lock_init(&u->lock); |
780 | atomic_long_set(&u->inflight, 0); | 780 | atomic_long_set(&u->inflight, 0); |
781 | INIT_LIST_HEAD(&u->link); | 781 | INIT_LIST_HEAD(&u->link); |
782 | 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 */ | ||
783 | init_waitqueue_head(&u->peer_wait); | 784 | init_waitqueue_head(&u->peer_wait); |
784 | 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); |
785 | unix_insert_socket(unix_sockets_unbound(sk), sk); | 786 | unix_insert_socket(unix_sockets_unbound(sk), sk); |
@@ -848,7 +849,7 @@ static int unix_autobind(struct socket *sock) | |||
848 | int err; | 849 | int err; |
849 | unsigned int retries = 0; | 850 | unsigned int retries = 0; |
850 | 851 | ||
851 | err = mutex_lock_interruptible(&u->readlock); | 852 | err = mutex_lock_interruptible(&u->bindlock); |
852 | if (err) | 853 | if (err) |
853 | return err; | 854 | return err; |
854 | 855 | ||
@@ -895,7 +896,7 @@ retry: | |||
895 | spin_unlock(&unix_table_lock); | 896 | spin_unlock(&unix_table_lock); |
896 | err = 0; | 897 | err = 0; |
897 | 898 | ||
898 | out: mutex_unlock(&u->readlock); | 899 | out: mutex_unlock(&u->bindlock); |
899 | return err; | 900 | return err; |
900 | } | 901 | } |
901 | 902 | ||
@@ -954,20 +955,32 @@ fail: | |||
954 | return NULL; | 955 | return NULL; |
955 | } | 956 | } |
956 | 957 | ||
957 | 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) |
958 | struct path *res) | ||
959 | { | 959 | { |
960 | 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; | ||
961 | 971 | ||
962 | 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); | ||
963 | if (!err) { | 976 | if (!err) { |
964 | err = vfs_mknod(d_inode(path->dentry), dentry, mode, 0); | 977 | err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0); |
965 | if (!err) { | 978 | if (!err) { |
966 | res->mnt = mntget(path->mnt); | 979 | res->mnt = mntget(path.mnt); |
967 | res->dentry = dget(dentry); | 980 | res->dentry = dget(dentry); |
968 | } | 981 | } |
969 | } | 982 | } |
970 | 983 | done_path_create(&path, dentry); | |
971 | return err; | 984 | return err; |
972 | } | 985 | } |
973 | 986 | ||
@@ -978,12 +991,10 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
978 | struct unix_sock *u = unix_sk(sk); | 991 | struct unix_sock *u = unix_sk(sk); |
979 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; | 992 | struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; |
980 | char *sun_path = sunaddr->sun_path; | 993 | char *sun_path = sunaddr->sun_path; |
981 | int err, name_err; | 994 | int err; |
982 | unsigned int hash; | 995 | unsigned int hash; |
983 | struct unix_address *addr; | 996 | struct unix_address *addr; |
984 | struct hlist_head *list; | 997 | struct hlist_head *list; |
985 | struct path path; | ||
986 | struct dentry *dentry; | ||
987 | 998 | ||
988 | err = -EINVAL; | 999 | err = -EINVAL; |
989 | if (sunaddr->sun_family != AF_UNIX) | 1000 | if (sunaddr->sun_family != AF_UNIX) |
@@ -999,34 +1010,14 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
999 | goto out; | 1010 | goto out; |
1000 | addr_len = err; | 1011 | addr_len = err; |
1001 | 1012 | ||
1002 | name_err = 0; | 1013 | err = mutex_lock_interruptible(&u->bindlock); |
1003 | dentry = NULL; | ||
1004 | if (sun_path[0]) { | ||
1005 | /* Get the parent directory, calculate the hash for last | ||
1006 | * component. | ||
1007 | */ | ||
1008 | dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0); | ||
1009 | |||
1010 | if (IS_ERR(dentry)) { | ||
1011 | /* delay report until after 'already bound' check */ | ||
1012 | name_err = PTR_ERR(dentry); | ||
1013 | dentry = NULL; | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | err = mutex_lock_interruptible(&u->readlock); | ||
1018 | if (err) | 1014 | if (err) |
1019 | goto out_path; | 1015 | goto out; |
1020 | 1016 | ||
1021 | err = -EINVAL; | 1017 | err = -EINVAL; |
1022 | if (u->addr) | 1018 | if (u->addr) |
1023 | goto out_up; | 1019 | goto out_up; |
1024 | 1020 | ||
1025 | if (name_err) { | ||
1026 | err = name_err == -EEXIST ? -EADDRINUSE : name_err; | ||
1027 | goto out_up; | ||
1028 | } | ||
1029 | |||
1030 | err = -ENOMEM; | 1021 | err = -ENOMEM; |
1031 | addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL); | 1022 | addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL); |
1032 | if (!addr) | 1023 | if (!addr) |
@@ -1037,11 +1028,11 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1037 | addr->hash = hash ^ sk->sk_type; | 1028 | addr->hash = hash ^ sk->sk_type; |
1038 | atomic_set(&addr->refcnt, 1); | 1029 | atomic_set(&addr->refcnt, 1); |
1039 | 1030 | ||
1040 | if (dentry) { | 1031 | if (sun_path[0]) { |
1041 | struct path u_path; | 1032 | struct path path; |
1042 | umode_t mode = S_IFSOCK | | 1033 | umode_t mode = S_IFSOCK | |
1043 | (SOCK_INODE(sock)->i_mode & ~current_umask()); | 1034 | (SOCK_INODE(sock)->i_mode & ~current_umask()); |
1044 | err = unix_mknod(dentry, &path, mode, &u_path); | 1035 | err = unix_mknod(sun_path, mode, &path); |
1045 | if (err) { | 1036 | if (err) { |
1046 | if (err == -EEXIST) | 1037 | if (err == -EEXIST) |
1047 | err = -EADDRINUSE; | 1038 | err = -EADDRINUSE; |
@@ -1049,9 +1040,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1049 | goto out_up; | 1040 | goto out_up; |
1050 | } | 1041 | } |
1051 | addr->hash = UNIX_HASH_SIZE; | 1042 | addr->hash = UNIX_HASH_SIZE; |
1052 | hash = d_real_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1); | 1043 | hash = d_real_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1); |
1053 | spin_lock(&unix_table_lock); | 1044 | spin_lock(&unix_table_lock); |
1054 | u->path = u_path; | 1045 | u->path = path; |
1055 | list = &unix_socket_table[hash]; | 1046 | list = &unix_socket_table[hash]; |
1056 | } else { | 1047 | } else { |
1057 | spin_lock(&unix_table_lock); | 1048 | spin_lock(&unix_table_lock); |
@@ -1073,11 +1064,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1073 | out_unlock: | 1064 | out_unlock: |
1074 | spin_unlock(&unix_table_lock); | 1065 | spin_unlock(&unix_table_lock); |
1075 | out_up: | 1066 | out_up: |
1076 | mutex_unlock(&u->readlock); | 1067 | mutex_unlock(&u->bindlock); |
1077 | out_path: | ||
1078 | if (dentry) | ||
1079 | done_path_create(&path, dentry); | ||
1080 | |||
1081 | out: | 1068 | out: |
1082 | return err; | 1069 | return err; |
1083 | } | 1070 | } |
@@ -1969,17 +1956,17 @@ static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, | |||
1969 | if (false) { | 1956 | if (false) { |
1970 | alloc_skb: | 1957 | alloc_skb: |
1971 | unix_state_unlock(other); | 1958 | unix_state_unlock(other); |
1972 | mutex_unlock(&unix_sk(other)->readlock); | 1959 | mutex_unlock(&unix_sk(other)->iolock); |
1973 | newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, | 1960 | newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, |
1974 | &err, 0); | 1961 | &err, 0); |
1975 | if (!newskb) | 1962 | if (!newskb) |
1976 | goto err; | 1963 | goto err; |
1977 | } | 1964 | } |
1978 | 1965 | ||
1979 | /* we must acquire readlock as we modify already present | 1966 | /* we must acquire iolock as we modify already present |
1980 | * skbs in the sk_receive_queue and mess with skb->len | 1967 | * skbs in the sk_receive_queue and mess with skb->len |
1981 | */ | 1968 | */ |
1982 | err = mutex_lock_interruptible(&unix_sk(other)->readlock); | 1969 | err = mutex_lock_interruptible(&unix_sk(other)->iolock); |
1983 | if (err) { | 1970 | if (err) { |
1984 | err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; | 1971 | err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS; |
1985 | goto err; | 1972 | goto err; |
@@ -2046,7 +2033,7 @@ alloc_skb: | |||
2046 | } | 2033 | } |
2047 | 2034 | ||
2048 | unix_state_unlock(other); | 2035 | unix_state_unlock(other); |
2049 | mutex_unlock(&unix_sk(other)->readlock); | 2036 | mutex_unlock(&unix_sk(other)->iolock); |
2050 | 2037 | ||
2051 | other->sk_data_ready(other); | 2038 | other->sk_data_ready(other); |
2052 | scm_destroy(&scm); | 2039 | scm_destroy(&scm); |
@@ -2055,7 +2042,7 @@ alloc_skb: | |||
2055 | err_state_unlock: | 2042 | err_state_unlock: |
2056 | unix_state_unlock(other); | 2043 | unix_state_unlock(other); |
2057 | err_unlock: | 2044 | err_unlock: |
2058 | mutex_unlock(&unix_sk(other)->readlock); | 2045 | mutex_unlock(&unix_sk(other)->iolock); |
2059 | err: | 2046 | err: |
2060 | kfree_skb(newskb); | 2047 | kfree_skb(newskb); |
2061 | if (send_sigpipe && !(flags & MSG_NOSIGNAL)) | 2048 | if (send_sigpipe && !(flags & MSG_NOSIGNAL)) |
@@ -2123,7 +2110,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2123 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | 2110 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
2124 | 2111 | ||
2125 | do { | 2112 | do { |
2126 | mutex_lock(&u->readlock); | 2113 | mutex_lock(&u->iolock); |
2127 | 2114 | ||
2128 | skip = sk_peek_offset(sk, flags); | 2115 | skip = sk_peek_offset(sk, flags); |
2129 | skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err, | 2116 | skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err, |
@@ -2131,14 +2118,14 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2131 | if (skb) | 2118 | if (skb) |
2132 | break; | 2119 | break; |
2133 | 2120 | ||
2134 | mutex_unlock(&u->readlock); | 2121 | mutex_unlock(&u->iolock); |
2135 | 2122 | ||
2136 | if (err != -EAGAIN) | 2123 | if (err != -EAGAIN) |
2137 | break; | 2124 | break; |
2138 | } while (timeo && | 2125 | } while (timeo && |
2139 | !__skb_wait_for_more_packets(sk, &err, &timeo, last)); | 2126 | !__skb_wait_for_more_packets(sk, &err, &timeo, last)); |
2140 | 2127 | ||
2141 | if (!skb) { /* implies readlock unlocked */ | 2128 | if (!skb) { /* implies iolock unlocked */ |
2142 | unix_state_lock(sk); | 2129 | unix_state_lock(sk); |
2143 | /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ | 2130 | /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ |
2144 | if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && | 2131 | if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && |
@@ -2203,7 +2190,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, | |||
2203 | 2190 | ||
2204 | out_free: | 2191 | out_free: |
2205 | skb_free_datagram(sk, skb); | 2192 | skb_free_datagram(sk, skb); |
2206 | mutex_unlock(&u->readlock); | 2193 | mutex_unlock(&u->iolock); |
2207 | out: | 2194 | out: |
2208 | return err; | 2195 | return err; |
2209 | } | 2196 | } |
@@ -2298,7 +2285,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state) | |||
2298 | /* Lock the socket to prevent queue disordering | 2285 | /* Lock the socket to prevent queue disordering |
2299 | * while sleeps in memcpy_tomsg | 2286 | * while sleeps in memcpy_tomsg |
2300 | */ | 2287 | */ |
2301 | mutex_lock(&u->readlock); | 2288 | mutex_lock(&u->iolock); |
2302 | 2289 | ||
2303 | if (flags & MSG_PEEK) | 2290 | if (flags & MSG_PEEK) |
2304 | skip = sk_peek_offset(sk, flags); | 2291 | skip = sk_peek_offset(sk, flags); |
@@ -2340,7 +2327,7 @@ again: | |||
2340 | break; | 2327 | break; |
2341 | } | 2328 | } |
2342 | 2329 | ||
2343 | mutex_unlock(&u->readlock); | 2330 | mutex_unlock(&u->iolock); |
2344 | 2331 | ||
2345 | timeo = unix_stream_data_wait(sk, timeo, last, | 2332 | timeo = unix_stream_data_wait(sk, timeo, last, |
2346 | last_len); | 2333 | last_len); |
@@ -2351,7 +2338,7 @@ again: | |||
2351 | goto out; | 2338 | goto out; |
2352 | } | 2339 | } |
2353 | 2340 | ||
2354 | mutex_lock(&u->readlock); | 2341 | mutex_lock(&u->iolock); |
2355 | goto redo; | 2342 | goto redo; |
2356 | unlock: | 2343 | unlock: |
2357 | unix_state_unlock(sk); | 2344 | unix_state_unlock(sk); |
@@ -2454,7 +2441,7 @@ unlock: | |||
2454 | } | 2441 | } |
2455 | } while (size); | 2442 | } while (size); |
2456 | 2443 | ||
2457 | mutex_unlock(&u->readlock); | 2444 | mutex_unlock(&u->iolock); |
2458 | if (state->msg) | 2445 | if (state->msg) |
2459 | scm_recv(sock, state->msg, &scm, flags); | 2446 | scm_recv(sock, state->msg, &scm, flags); |
2460 | else | 2447 | else |
@@ -2495,9 +2482,9 @@ static ssize_t skb_unix_socket_splice(struct sock *sk, | |||
2495 | int ret; | 2482 | int ret; |
2496 | struct unix_sock *u = unix_sk(sk); | 2483 | struct unix_sock *u = unix_sk(sk); |
2497 | 2484 | ||
2498 | mutex_unlock(&u->readlock); | 2485 | mutex_unlock(&u->iolock); |
2499 | ret = splice_to_pipe(pipe, spd); | 2486 | ret = splice_to_pipe(pipe, spd); |
2500 | mutex_lock(&u->readlock); | 2487 | mutex_lock(&u->iolock); |
2501 | 2488 | ||
2502 | return ret; | 2489 | return ret; |
2503 | } | 2490 | } |