blob: ef4b780ef63df8428c0a70a32544fb145edd6cb4 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * NET4: Implementation of BSD Unix domain sockets.
3 *
Alan Cox113aa832008-10-13 19:01:08 -07004 * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk>
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 * Fixes:
12 * Linus Torvalds : Assorted bug cures.
13 * Niibe Yutaka : async I/O support.
14 * Carsten Paeth : PF_UNIX check, address fixes.
15 * Alan Cox : Limit size of allocated blocks.
16 * Alan Cox : Fixed the stupid socketpair bug.
17 * Alan Cox : BSD compatibility fine tuning.
18 * Alan Cox : Fixed a bug in connect when interrupted.
19 * Alan Cox : Sorted out a proper draft version of
20 * file descriptor passing hacked up from
21 * Mike Shaver's work.
22 * Marty Leisner : Fixes to fd passing
23 * Nick Nevin : recvmsg bugfix.
24 * Alan Cox : Started proper garbage collector
25 * Heiko EiBfeldt : Missing verify_area check
26 * Alan Cox : Started POSIXisms
27 * Andreas Schwab : Replace inode by dentry for proper
28 * reference counting
29 * Kirk Petersen : Made this a module
30 * Christoph Rohland : Elegant non-blocking accept/connect algorithm.
31 * Lots of bug fixes.
32 * Alexey Kuznetosv : Repaired (I hope) bugs introduces
33 * by above two patches.
34 * Andrea Arcangeli : If possible we block in connect(2)
35 * if the max backlog of the listen socket
36 * is been reached. This won't break
37 * old apps and it will avoid huge amount
38 * of socks hashed (this for unix_gc()
39 * performances reasons).
40 * Security fix that limits the max
41 * number of socks to 2*max_files and
42 * the number of skb queueable in the
43 * dgram receiver.
44 * Artur Skawina : Hash function optimizations
45 * Alexey Kuznetsov : Full scale SMP. Lot of bugs are introduced 8)
46 * Malcolm Beattie : Set peercred for socketpair
47 * Michal Ostrowski : Module initialization cleanup.
48 * Arnaldo C. Melo : Remove MOD_{INC,DEC}_USE_COUNT,
49 * the core infrastructure is doing that
50 * for all net proto families now (2.5.69+)
51 *
52 *
53 * Known differences from reference BSD that was tested:
54 *
55 * [TO FIX]
56 * ECONNREFUSED is not returned from one end of a connected() socket to the
57 * other the moment one end closes.
58 * fstat() doesn't return st_dev=0, and give the blksize as high water mark
59 * and a fake inode identifier (nor the BSD first socket fstat twice bug).
60 * [NOT TO FIX]
61 * accept() returns a path name even if the connecting socket has closed
62 * in the meantime (BSD loses the path and gives up).
63 * accept() returns 0 length path for an unbound connector. BSD returns 16
64 * and a null first byte in the path (but not for gethost/peername - BSD bug ??)
65 * socketpair(...SOCK_RAW..) doesn't panic the kernel.
66 * BSD af_unix apparently has connect forgetting to block properly.
67 * (need to check this with the POSIX spec in detail)
68 *
69 * Differences from 2.0.0-11-... (ANK)
70 * Bug fixes and improvements.
71 * - client shutdown killed server socket.
72 * - removed all useless cli/sti pairs.
73 *
74 * Semantic changes/extensions.
75 * - generic control message passing.
76 * - SCM_CREDENTIALS control message.
77 * - "Abstract" (not FS based) socket bindings.
78 * Abstract names are sequences of bytes (not zero terminated)
79 * started by 0, so that this name space does not intersect
80 * with BSD names.
81 */
82
83#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070084#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070085#include <linux/signal.h>
86#include <linux/sched.h>
87#include <linux/errno.h>
88#include <linux/string.h>
89#include <linux/stat.h>
90#include <linux/dcache.h>
91#include <linux/namei.h>
92#include <linux/socket.h>
93#include <linux/un.h>
94#include <linux/fcntl.h>
95#include <linux/termios.h>
96#include <linux/sockios.h>
97#include <linux/net.h>
98#include <linux/in.h>
99#include <linux/fs.h>
100#include <linux/slab.h>
101#include <asm/uaccess.h>
102#include <linux/skbuff.h>
103#include <linux/netdevice.h>
Eric W. Biederman457c4cb2007-09-12 12:01:34 +0200104#include <net/net_namespace.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105#include <net/sock.h>
Arnaldo Carvalho de Meloc752f072005-08-09 20:08:28 -0700106#include <net/tcp_states.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107#include <net/af_unix.h>
108#include <linux/proc_fs.h>
109#include <linux/seq_file.h>
110#include <net/scm.h>
111#include <linux/init.h>
112#include <linux/poll.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113#include <linux/rtnetlink.h>
114#include <linux/mount.h>
115#include <net/checksum.h>
116#include <linux/security.h>
117
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000118struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
119EXPORT_SYMBOL_GPL(unix_socket_table);
120DEFINE_SPINLOCK(unix_table_lock);
121EXPORT_SYMBOL_GPL(unix_table_lock);
Eric Dumazet518de9b2010-10-26 14:22:44 -0700122static atomic_long_t unix_nr_socks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
124#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE])
125
126#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE)
127
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700128#ifdef CONFIG_SECURITY_NETWORK
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700129static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700130{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700131 memcpy(UNIXSID(skb), &scm->secid, sizeof(u32));
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700132}
133
134static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
135{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700136 scm->secid = *UNIXSID(skb);
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700137}
138#else
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700139static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700140{ }
141
142static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
143{ }
144#endif /* CONFIG_SECURITY_NETWORK */
145
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146/*
147 * SMP locking strategy:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800148 * hash table is protected with spinlock unix_table_lock
Stephen Hemminger663717f2010-02-18 14:12:06 -0800149 * each socket state is protected by separate spin lock.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 */
151
Al Viro44bb9362006-11-14 21:36:14 -0800152static inline unsigned unix_hash_fold(__wsum n)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153{
Al Viro44bb9362006-11-14 21:36:14 -0800154 unsigned hash = (__force unsigned)n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 hash ^= hash>>16;
156 hash ^= hash>>8;
157 return hash&(UNIX_HASH_SIZE-1);
158}
159
160#define unix_peer(sk) (unix_sk(sk)->peer)
161
162static inline int unix_our_peer(struct sock *sk, struct sock *osk)
163{
164 return unix_peer(osk) == sk;
165}
166
167static inline int unix_may_send(struct sock *sk, struct sock *osk)
168{
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800169 return unix_peer(osk) == NULL || unix_our_peer(sk, osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170}
171
Rainer Weikusat3c734192008-06-17 22:28:05 -0700172static inline int unix_recvq_full(struct sock const *sk)
173{
174 return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
175}
176
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000177struct sock *unix_peer_get(struct sock *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178{
179 struct sock *peer;
180
David S. Miller1c92b4e2007-05-31 13:24:26 -0700181 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 peer = unix_peer(s);
183 if (peer)
184 sock_hold(peer);
David S. Miller1c92b4e2007-05-31 13:24:26 -0700185 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 return peer;
187}
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000188EXPORT_SYMBOL_GPL(unix_peer_get);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
190static inline void unix_release_addr(struct unix_address *addr)
191{
192 if (atomic_dec_and_test(&addr->refcnt))
193 kfree(addr);
194}
195
196/*
197 * Check unix socket name:
198 * - should be not zero length.
199 * - if started by not zero, should be NULL terminated (FS object)
200 * - if started by zero, it is abstract name.
201 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900202
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800203static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned *hashp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204{
205 if (len <= sizeof(short) || len > sizeof(*sunaddr))
206 return -EINVAL;
207 if (!sunaddr || sunaddr->sun_family != AF_UNIX)
208 return -EINVAL;
209 if (sunaddr->sun_path[0]) {
210 /*
211 * This may look like an off by one error but it is a bit more
212 * subtle. 108 is the longest valid AF_UNIX path for a binding.
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300213 * sun_path[108] doesn't as such exist. However in kernel space
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 * we are guaranteed that it is a valid memory location in our
215 * kernel address buffer.
216 */
Jianjun Konge27dfce2008-11-01 21:38:31 -0700217 ((char *)sunaddr)[len] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 len = strlen(sunaddr->sun_path)+1+sizeof(short);
219 return len;
220 }
221
Joe Perches07f07572008-11-19 15:44:53 -0800222 *hashp = unix_hash_fold(csum_partial(sunaddr, len, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 return len;
224}
225
226static void __unix_remove_socket(struct sock *sk)
227{
228 sk_del_node_init(sk);
229}
230
231static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
232{
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700233 WARN_ON(!sk_unhashed(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 sk_add_node(sk, list);
235}
236
237static inline void unix_remove_socket(struct sock *sk)
238{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800239 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 __unix_remove_socket(sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800241 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242}
243
244static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
245{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800246 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 __unix_insert_socket(list, sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800248 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249}
250
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800251static struct sock *__unix_find_socket_byname(struct net *net,
252 struct sockaddr_un *sunname,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 int len, int type, unsigned hash)
254{
255 struct sock *s;
256 struct hlist_node *node;
257
258 sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
259 struct unix_sock *u = unix_sk(s);
260
YOSHIFUJI Hideaki878628f2008-03-26 03:57:35 +0900261 if (!net_eq(sock_net(s), net))
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800262 continue;
263
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 if (u->addr->len == len &&
265 !memcmp(u->addr->name, sunname, len))
266 goto found;
267 }
268 s = NULL;
269found:
270 return s;
271}
272
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800273static inline struct sock *unix_find_socket_byname(struct net *net,
274 struct sockaddr_un *sunname,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 int len, int type,
276 unsigned hash)
277{
278 struct sock *s;
279
David S. Millerfbe9cc42005-12-13 23:26:29 -0800280 spin_lock(&unix_table_lock);
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800281 s = __unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 if (s)
283 sock_hold(s);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800284 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 return s;
286}
287
Eric W. Biederman6616f782010-06-13 03:35:48 +0000288static struct sock *unix_find_socket_byinode(struct inode *i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289{
290 struct sock *s;
291 struct hlist_node *node;
292
David S. Millerfbe9cc42005-12-13 23:26:29 -0800293 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 sk_for_each(s, node,
295 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
Al Viro40ffe672012-03-14 21:54:32 -0400296 struct dentry *dentry = unix_sk(s)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800298 if (dentry && dentry->d_inode == i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 sock_hold(s);
300 goto found;
301 }
302 }
303 s = NULL;
304found:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800305 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 return s;
307}
308
309static inline int unix_writable(struct sock *sk)
310{
311 return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
312}
313
314static void unix_write_space(struct sock *sk)
315{
Eric Dumazet43815482010-04-29 11:01:49 +0000316 struct socket_wq *wq;
317
318 rcu_read_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 if (unix_writable(sk)) {
Eric Dumazet43815482010-04-29 11:01:49 +0000320 wq = rcu_dereference(sk->sk_wq);
321 if (wq_has_sleeper(wq))
Eric Dumazet67426b72010-10-29 20:44:44 +0000322 wake_up_interruptible_sync_poll(&wq->wait,
323 POLLOUT | POLLWRNORM | POLLWRBAND);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800324 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 }
Eric Dumazet43815482010-04-29 11:01:49 +0000326 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327}
328
329/* When dgram socket disconnects (or changes its peer), we clear its receive
330 * queue of packets arrived from previous peer. First, it allows to do
331 * flow control based only on wmem_alloc; second, sk connected to peer
332 * may receive messages only from that peer. */
333static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
334{
David S. Millerb03efcf2005-07-08 14:57:23 -0700335 if (!skb_queue_empty(&sk->sk_receive_queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 skb_queue_purge(&sk->sk_receive_queue);
337 wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
338
339 /* If one link of bidirectional dgram pipe is disconnected,
340 * we signal error. Messages are lost. Do not make this,
341 * when peer was not connected to us.
342 */
343 if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) {
344 other->sk_err = ECONNRESET;
345 other->sk_error_report(other);
346 }
347 }
348}
349
350static void unix_sock_destructor(struct sock *sk)
351{
352 struct unix_sock *u = unix_sk(sk);
353
354 skb_queue_purge(&sk->sk_receive_queue);
355
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700356 WARN_ON(atomic_read(&sk->sk_wmem_alloc));
357 WARN_ON(!sk_unhashed(sk));
358 WARN_ON(sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 if (!sock_flag(sk, SOCK_DEAD)) {
Eric Dumazet6b41e7d2008-11-19 15:48:09 -0800360 printk(KERN_INFO "Attempt to release alive unix socket: %p\n", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 return;
362 }
363
364 if (u->addr)
365 unix_release_addr(u->addr);
366
Eric Dumazet518de9b2010-10-26 14:22:44 -0700367 atomic_long_dec(&unix_nr_socks);
David S. Miller6f756a82008-11-23 17:34:03 -0800368 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800369 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
David S. Miller6f756a82008-11-23 17:34:03 -0800370 local_bh_enable();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371#ifdef UNIX_REFCNT_DEBUG
Eric Dumazet518de9b2010-10-26 14:22:44 -0700372 printk(KERN_DEBUG "UNIX %p is destroyed, %ld are still alive.\n", sk,
373 atomic_long_read(&unix_nr_socks));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374#endif
375}
376
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800377static int unix_release_sock(struct sock *sk, int embrion)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378{
379 struct unix_sock *u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400380 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 struct sock *skpair;
382 struct sk_buff *skb;
383 int state;
384
385 unix_remove_socket(sk);
386
387 /* Clear state */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700388 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 sock_orphan(sk);
390 sk->sk_shutdown = SHUTDOWN_MASK;
Al Viro40ffe672012-03-14 21:54:32 -0400391 path = u->path;
392 u->path.dentry = NULL;
393 u->path.mnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 state = sk->sk_state;
395 sk->sk_state = TCP_CLOSE;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700396 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
398 wake_up_interruptible_all(&u->peer_wait);
399
Jianjun Konge27dfce2008-11-01 21:38:31 -0700400 skpair = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
Jianjun Konge27dfce2008-11-01 21:38:31 -0700402 if (skpair != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
David S. Miller1c92b4e2007-05-31 13:24:26 -0700404 unix_state_lock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 /* No more writes */
406 skpair->sk_shutdown = SHUTDOWN_MASK;
407 if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
408 skpair->sk_err = ECONNRESET;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700409 unix_state_unlock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 skpair->sk_state_change(skpair);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800411 sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 }
413 sock_put(skpair); /* It may now die */
414 unix_peer(sk) = NULL;
415 }
416
417 /* Try to flush out this socket. Throw out buffers at least */
418
419 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
Jianjun Konge27dfce2008-11-01 21:38:31 -0700420 if (state == TCP_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 unix_release_sock(skb->sk, 1);
422 /* passed fds are erased in the kfree_skb hook */
423 kfree_skb(skb);
424 }
425
Al Viro40ffe672012-03-14 21:54:32 -0400426 if (path.dentry)
427 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
429 sock_put(sk);
430
431 /* ---- Socket is dead now and most probably destroyed ---- */
432
433 /*
434 * Fixme: BSD difference: In BSD all sockets connected to use get
435 * ECONNRESET and we die on the spot. In Linux we behave
436 * like files and pipes do and wait for the last
437 * dereference.
438 *
439 * Can't we simply set sock->err?
440 *
441 * What the above comment does talk about? --ANK(980817)
442 */
443
Pavel Emelyanov9305cfa2007-11-10 22:06:01 -0800444 if (unix_tot_inflight)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900445 unix_gc(); /* Garbage collect fds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446
447 return 0;
448}
449
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000450static void init_peercred(struct sock *sk)
451{
452 put_pid(sk->sk_peer_pid);
453 if (sk->sk_peer_cred)
454 put_cred(sk->sk_peer_cred);
455 sk->sk_peer_pid = get_pid(task_tgid(current));
456 sk->sk_peer_cred = get_current_cred();
457}
458
459static void copy_peercred(struct sock *sk, struct sock *peersk)
460{
461 put_pid(sk->sk_peer_pid);
462 if (sk->sk_peer_cred)
463 put_cred(sk->sk_peer_cred);
464 sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
465 sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
466}
467
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468static int unix_listen(struct socket *sock, int backlog)
469{
470 int err;
471 struct sock *sk = sock->sk;
472 struct unix_sock *u = unix_sk(sk);
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000473 struct pid *old_pid = NULL;
474 const struct cred *old_cred = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475
476 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800477 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
478 goto out; /* Only stream/seqpacket sockets accept */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 err = -EINVAL;
480 if (!u->addr)
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800481 goto out; /* No listens on an unbound socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700482 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
484 goto out_unlock;
485 if (backlog > sk->sk_max_ack_backlog)
486 wake_up_interruptible_all(&u->peer_wait);
487 sk->sk_max_ack_backlog = backlog;
488 sk->sk_state = TCP_LISTEN;
489 /* set credentials so connect can copy them */
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000490 init_peercred(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 err = 0;
492
493out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -0700494 unix_state_unlock(sk);
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000495 put_pid(old_pid);
496 if (old_cred)
497 put_cred(old_cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498out:
499 return err;
500}
501
502static int unix_release(struct socket *);
503static int unix_bind(struct socket *, struct sockaddr *, int);
504static int unix_stream_connect(struct socket *, struct sockaddr *,
505 int addr_len, int flags);
506static int unix_socketpair(struct socket *, struct socket *);
507static int unix_accept(struct socket *, struct socket *, int);
508static int unix_getname(struct socket *, struct sockaddr *, int *, int);
509static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
Rainer Weikusatec0d2152008-06-27 19:34:18 -0700510static unsigned int unix_dgram_poll(struct file *, struct socket *,
511 poll_table *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512static int unix_ioctl(struct socket *, unsigned int, unsigned long);
513static int unix_shutdown(struct socket *, int);
514static int unix_stream_sendmsg(struct kiocb *, struct socket *,
515 struct msghdr *, size_t);
516static int unix_stream_recvmsg(struct kiocb *, struct socket *,
517 struct msghdr *, size_t, int);
518static int unix_dgram_sendmsg(struct kiocb *, struct socket *,
519 struct msghdr *, size_t);
520static int unix_dgram_recvmsg(struct kiocb *, struct socket *,
521 struct msghdr *, size_t, int);
522static int unix_dgram_connect(struct socket *, struct sockaddr *,
523 int, int);
524static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
525 struct msghdr *, size_t);
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +0000526static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *,
527 struct msghdr *, size_t, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800529static const struct proto_ops unix_stream_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 .family = PF_UNIX,
531 .owner = THIS_MODULE,
532 .release = unix_release,
533 .bind = unix_bind,
534 .connect = unix_stream_connect,
535 .socketpair = unix_socketpair,
536 .accept = unix_accept,
537 .getname = unix_getname,
538 .poll = unix_poll,
539 .ioctl = unix_ioctl,
540 .listen = unix_listen,
541 .shutdown = unix_shutdown,
542 .setsockopt = sock_no_setsockopt,
543 .getsockopt = sock_no_getsockopt,
544 .sendmsg = unix_stream_sendmsg,
545 .recvmsg = unix_stream_recvmsg,
546 .mmap = sock_no_mmap,
547 .sendpage = sock_no_sendpage,
548};
549
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800550static const struct proto_ops unix_dgram_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 .family = PF_UNIX,
552 .owner = THIS_MODULE,
553 .release = unix_release,
554 .bind = unix_bind,
555 .connect = unix_dgram_connect,
556 .socketpair = unix_socketpair,
557 .accept = sock_no_accept,
558 .getname = unix_getname,
Rainer Weikusatec0d2152008-06-27 19:34:18 -0700559 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 .ioctl = unix_ioctl,
561 .listen = sock_no_listen,
562 .shutdown = unix_shutdown,
563 .setsockopt = sock_no_setsockopt,
564 .getsockopt = sock_no_getsockopt,
565 .sendmsg = unix_dgram_sendmsg,
566 .recvmsg = unix_dgram_recvmsg,
567 .mmap = sock_no_mmap,
568 .sendpage = sock_no_sendpage,
569};
570
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800571static const struct proto_ops unix_seqpacket_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 .family = PF_UNIX,
573 .owner = THIS_MODULE,
574 .release = unix_release,
575 .bind = unix_bind,
576 .connect = unix_stream_connect,
577 .socketpair = unix_socketpair,
578 .accept = unix_accept,
579 .getname = unix_getname,
Rainer Weikusatec0d2152008-06-27 19:34:18 -0700580 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 .ioctl = unix_ioctl,
582 .listen = unix_listen,
583 .shutdown = unix_shutdown,
584 .setsockopt = sock_no_setsockopt,
585 .getsockopt = sock_no_getsockopt,
586 .sendmsg = unix_seqpacket_sendmsg,
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +0000587 .recvmsg = unix_seqpacket_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 .mmap = sock_no_mmap,
589 .sendpage = sock_no_sendpage,
590};
591
592static struct proto unix_proto = {
Eric Dumazet248969a2008-11-17 00:00:30 -0800593 .name = "UNIX",
594 .owner = THIS_MODULE,
Eric Dumazet248969a2008-11-17 00:00:30 -0800595 .obj_size = sizeof(struct unix_sock),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596};
597
Ingo Molnara09785a2006-07-03 00:25:12 -0700598/*
599 * AF_UNIX sockets do not interact with hardware, hence they
600 * dont trigger interrupts - so it's safe for them to have
601 * bh-unsafe locking for their sk_receive_queue.lock. Split off
602 * this special lock-class by reinitializing the spinlock key:
603 */
604static struct lock_class_key af_unix_sk_receive_queue_lock_key;
605
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800606static struct sock *unix_create1(struct net *net, struct socket *sock)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607{
608 struct sock *sk = NULL;
609 struct unix_sock *u;
610
Eric Dumazet518de9b2010-10-26 14:22:44 -0700611 atomic_long_inc(&unix_nr_socks);
612 if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 goto out;
614
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700615 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 if (!sk)
617 goto out;
618
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800619 sock_init_data(sock, sk);
Ingo Molnara09785a2006-07-03 00:25:12 -0700620 lockdep_set_class(&sk->sk_receive_queue.lock,
621 &af_unix_sk_receive_queue_lock_key);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
623 sk->sk_write_space = unix_write_space;
Denis V. Luneva0a53c82007-12-11 04:19:17 -0800624 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 sk->sk_destruct = unix_sock_destructor;
626 u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400627 u->path.dentry = NULL;
628 u->path.mnt = NULL;
Benjamin LaHaisefd19f322006-01-03 14:10:46 -0800629 spin_lock_init(&u->lock);
Al Viro516e0cc2008-07-26 00:39:17 -0400630 atomic_long_set(&u->inflight, 0);
Miklos Szeredi1fd05ba2007-07-11 14:22:39 -0700631 INIT_LIST_HEAD(&u->link);
Ingo Molnar57b47a52006-03-20 22:35:41 -0800632 mutex_init(&u->readlock); /* single task reading lock */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 init_waitqueue_head(&u->peer_wait);
634 unix_insert_socket(unix_sockets_unbound, sk);
635out:
Pavel Emelyanov284b3272007-11-10 22:08:30 -0800636 if (sk == NULL)
Eric Dumazet518de9b2010-10-26 14:22:44 -0700637 atomic_long_dec(&unix_nr_socks);
Eric Dumazet920de802008-11-24 00:09:29 -0800638 else {
639 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800640 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
Eric Dumazet920de802008-11-24 00:09:29 -0800641 local_bh_enable();
642 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 return sk;
644}
645
Eric Paris3f378b62009-11-05 22:18:14 -0800646static int unix_create(struct net *net, struct socket *sock, int protocol,
647 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648{
649 if (protocol && protocol != PF_UNIX)
650 return -EPROTONOSUPPORT;
651
652 sock->state = SS_UNCONNECTED;
653
654 switch (sock->type) {
655 case SOCK_STREAM:
656 sock->ops = &unix_stream_ops;
657 break;
658 /*
659 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
660 * nothing uses it.
661 */
662 case SOCK_RAW:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700663 sock->type = SOCK_DGRAM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 case SOCK_DGRAM:
665 sock->ops = &unix_dgram_ops;
666 break;
667 case SOCK_SEQPACKET:
668 sock->ops = &unix_seqpacket_ops;
669 break;
670 default:
671 return -ESOCKTNOSUPPORT;
672 }
673
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700674 return unix_create1(net, sock) ? 0 : -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675}
676
677static int unix_release(struct socket *sock)
678{
679 struct sock *sk = sock->sk;
680
681 if (!sk)
682 return 0;
683
684 sock->sk = NULL;
685
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800686 return unix_release_sock(sk, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687}
688
689static int unix_autobind(struct socket *sock)
690{
691 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900692 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 struct unix_sock *u = unix_sk(sk);
694 static u32 ordernum = 1;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800695 struct unix_address *addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 int err;
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000697 unsigned int retries = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698
Ingo Molnar57b47a52006-03-20 22:35:41 -0800699 mutex_lock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
701 err = 0;
702 if (u->addr)
703 goto out;
704
705 err = -ENOMEM;
Panagiotis Issaris0da974f2006-07-21 14:51:30 -0700706 addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 if (!addr)
708 goto out;
709
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 addr->name->sun_family = AF_UNIX;
711 atomic_set(&addr->refcnt, 1);
712
713retry:
714 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
Joe Perches07f07572008-11-19 15:44:53 -0800715 addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716
David S. Millerfbe9cc42005-12-13 23:26:29 -0800717 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 ordernum = (ordernum+1)&0xFFFFF;
719
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800720 if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 addr->hash)) {
David S. Millerfbe9cc42005-12-13 23:26:29 -0800722 spin_unlock(&unix_table_lock);
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000723 /*
724 * __unix_find_socket_byname() may take long time if many names
725 * are already in use.
726 */
727 cond_resched();
728 /* Give up if all names seems to be in use. */
729 if (retries++ == 0xFFFFF) {
730 err = -ENOSPC;
731 kfree(addr);
732 goto out;
733 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 goto retry;
735 }
736 addr->hash ^= sk->sk_type;
737
738 __unix_remove_socket(sk);
739 u->addr = addr;
740 __unix_insert_socket(&unix_socket_table[addr->hash], sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800741 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 err = 0;
743
Ingo Molnar57b47a52006-03-20 22:35:41 -0800744out: mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 return err;
746}
747
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800748static struct sock *unix_find_other(struct net *net,
749 struct sockaddr_un *sunname, int len,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 int type, unsigned hash, int *error)
751{
752 struct sock *u;
Al Viro421748e2008-08-02 01:04:36 -0400753 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 int err = 0;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900755
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 if (sunname->sun_path[0]) {
Al Viro421748e2008-08-02 01:04:36 -0400757 struct inode *inode;
758 err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 if (err)
760 goto fail;
Al Viro421748e2008-08-02 01:04:36 -0400761 inode = path.dentry->d_inode;
762 err = inode_permission(inode, MAY_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 if (err)
764 goto put_fail;
765
766 err = -ECONNREFUSED;
Al Viro421748e2008-08-02 01:04:36 -0400767 if (!S_ISSOCK(inode->i_mode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 goto put_fail;
Eric W. Biederman6616f782010-06-13 03:35:48 +0000769 u = unix_find_socket_byinode(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 if (!u)
771 goto put_fail;
772
773 if (u->sk_type == type)
Al Viro421748e2008-08-02 01:04:36 -0400774 touch_atime(path.mnt, path.dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775
Al Viro421748e2008-08-02 01:04:36 -0400776 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777
Jianjun Konge27dfce2008-11-01 21:38:31 -0700778 err = -EPROTOTYPE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 if (u->sk_type != type) {
780 sock_put(u);
781 goto fail;
782 }
783 } else {
784 err = -ECONNREFUSED;
Jianjun Konge27dfce2008-11-01 21:38:31 -0700785 u = unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 if (u) {
787 struct dentry *dentry;
Al Viro40ffe672012-03-14 21:54:32 -0400788 dentry = unix_sk(u)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 if (dentry)
Al Viro40ffe672012-03-14 21:54:32 -0400790 touch_atime(unix_sk(u)->path.mnt, dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 } else
792 goto fail;
793 }
794 return u;
795
796put_fail:
Al Viro421748e2008-08-02 01:04:36 -0400797 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798fail:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700799 *error = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 return NULL;
801}
802
803
804static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
805{
806 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900807 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 struct unix_sock *u = unix_sk(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -0700809 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Al Virodae6ad82011-06-26 11:50:15 -0400810 char *sun_path = sunaddr->sun_path;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800811 struct dentry *dentry = NULL;
Al Virodae6ad82011-06-26 11:50:15 -0400812 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 int err;
814 unsigned hash;
815 struct unix_address *addr;
816 struct hlist_head *list;
817
818 err = -EINVAL;
819 if (sunaddr->sun_family != AF_UNIX)
820 goto out;
821
Jianjun Konge27dfce2008-11-01 21:38:31 -0700822 if (addr_len == sizeof(short)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 err = unix_autobind(sock);
824 goto out;
825 }
826
827 err = unix_mkname(sunaddr, addr_len, &hash);
828 if (err < 0)
829 goto out;
830 addr_len = err;
831
Ingo Molnar57b47a52006-03-20 22:35:41 -0800832 mutex_lock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833
834 err = -EINVAL;
835 if (u->addr)
836 goto out_up;
837
838 err = -ENOMEM;
839 addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
840 if (!addr)
841 goto out_up;
842
843 memcpy(addr->name, sunaddr, addr_len);
844 addr->len = addr_len;
845 addr->hash = hash ^ sk->sk_type;
846 atomic_set(&addr->refcnt, 1);
847
Al Virodae6ad82011-06-26 11:50:15 -0400848 if (sun_path[0]) {
Al Viro04fc66e2011-11-21 14:58:38 -0500849 umode_t mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850 err = 0;
851 /*
852 * Get the parent directory, calculate the hash for last
853 * component.
854 */
Al Virodae6ad82011-06-26 11:50:15 -0400855 dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 err = PTR_ERR(dentry);
857 if (IS_ERR(dentry))
Al Virodae6ad82011-06-26 11:50:15 -0400858 goto out_mknod_parent;
Christoph Hellwigf81a0bf2005-05-19 12:26:43 -0700859
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 /*
861 * All right, let's create it.
862 */
863 mode = S_IFSOCK |
Al Viroce3b0f82009-03-29 19:08:22 -0400864 (SOCK_INODE(sock)->i_mode & ~current_umask());
Al Virodae6ad82011-06-26 11:50:15 -0400865 err = mnt_want_write(path.mnt);
Dave Hansen463c3192008-02-15 14:37:57 -0800866 if (err)
867 goto out_mknod_dput;
Al Virodae6ad82011-06-26 11:50:15 -0400868 err = security_path_mknod(&path, dentry, mode, 0);
Kentaro Takedabe6d3e52008-12-17 13:24:15 +0900869 if (err)
870 goto out_mknod_drop_write;
Al Virodae6ad82011-06-26 11:50:15 -0400871 err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
Kentaro Takedabe6d3e52008-12-17 13:24:15 +0900872out_mknod_drop_write:
Al Virodae6ad82011-06-26 11:50:15 -0400873 mnt_drop_write(path.mnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 if (err)
875 goto out_mknod_dput;
Al Virodae6ad82011-06-26 11:50:15 -0400876 mutex_unlock(&path.dentry->d_inode->i_mutex);
877 dput(path.dentry);
878 path.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
880 addr->hash = UNIX_HASH_SIZE;
881 }
882
David S. Millerfbe9cc42005-12-13 23:26:29 -0800883 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
Al Virodae6ad82011-06-26 11:50:15 -0400885 if (!sun_path[0]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 err = -EADDRINUSE;
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800887 if (__unix_find_socket_byname(net, sunaddr, addr_len,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 sk->sk_type, hash)) {
889 unix_release_addr(addr);
890 goto out_unlock;
891 }
892
893 list = &unix_socket_table[addr->hash];
894 } else {
895 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
Al Viro40ffe672012-03-14 21:54:32 -0400896 u->path = path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 }
898
899 err = 0;
900 __unix_remove_socket(sk);
901 u->addr = addr;
902 __unix_insert_socket(list, sk);
903
904out_unlock:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800905 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906out_up:
Ingo Molnar57b47a52006-03-20 22:35:41 -0800907 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908out:
909 return err;
910
911out_mknod_dput:
912 dput(dentry);
Al Virodae6ad82011-06-26 11:50:15 -0400913 mutex_unlock(&path.dentry->d_inode->i_mutex);
914 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915out_mknod_parent:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700916 if (err == -EEXIST)
917 err = -EADDRINUSE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 unix_release_addr(addr);
919 goto out_up;
920}
921
David S. Miller278a3de2007-05-31 15:19:20 -0700922static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
923{
924 if (unlikely(sk1 == sk2) || !sk2) {
925 unix_state_lock(sk1);
926 return;
927 }
928 if (sk1 < sk2) {
929 unix_state_lock(sk1);
930 unix_state_lock_nested(sk2);
931 } else {
932 unix_state_lock(sk2);
933 unix_state_lock_nested(sk1);
934 }
935}
936
937static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
938{
939 if (unlikely(sk1 == sk2) || !sk2) {
940 unix_state_unlock(sk1);
941 return;
942 }
943 unix_state_unlock(sk1);
944 unix_state_unlock(sk2);
945}
946
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
948 int alen, int flags)
949{
950 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900951 struct net *net = sock_net(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -0700952 struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 struct sock *other;
954 unsigned hash;
955 int err;
956
957 if (addr->sa_family != AF_UNSPEC) {
958 err = unix_mkname(sunaddr, alen, &hash);
959 if (err < 0)
960 goto out;
961 alen = err;
962
963 if (test_bit(SOCK_PASSCRED, &sock->flags) &&
964 !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
965 goto out;
966
David S. Miller278a3de2007-05-31 15:19:20 -0700967restart:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700968 other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 if (!other)
970 goto out;
971
David S. Miller278a3de2007-05-31 15:19:20 -0700972 unix_state_double_lock(sk, other);
973
974 /* Apparently VFS overslept socket death. Retry. */
975 if (sock_flag(other, SOCK_DEAD)) {
976 unix_state_double_unlock(sk, other);
977 sock_put(other);
978 goto restart;
979 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980
981 err = -EPERM;
982 if (!unix_may_send(sk, other))
983 goto out_unlock;
984
985 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
986 if (err)
987 goto out_unlock;
988
989 } else {
990 /*
991 * 1003.1g breaking connected state with AF_UNSPEC
992 */
993 other = NULL;
David S. Miller278a3de2007-05-31 15:19:20 -0700994 unix_state_double_lock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 }
996
997 /*
998 * If it was connected, reconnect.
999 */
1000 if (unix_peer(sk)) {
1001 struct sock *old_peer = unix_peer(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001002 unix_peer(sk) = other;
David S. Miller278a3de2007-05-31 15:19:20 -07001003 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004
1005 if (other != old_peer)
1006 unix_dgram_disconnected(sk, old_peer);
1007 sock_put(old_peer);
1008 } else {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001009 unix_peer(sk) = other;
David S. Miller278a3de2007-05-31 15:19:20 -07001010 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 }
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001012 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013
1014out_unlock:
David S. Miller278a3de2007-05-31 15:19:20 -07001015 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 sock_put(other);
1017out:
1018 return err;
1019}
1020
1021static long unix_wait_for_peer(struct sock *other, long timeo)
1022{
1023 struct unix_sock *u = unix_sk(other);
1024 int sched;
1025 DEFINE_WAIT(wait);
1026
1027 prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
1028
1029 sched = !sock_flag(other, SOCK_DEAD) &&
1030 !(other->sk_shutdown & RCV_SHUTDOWN) &&
Rainer Weikusat3c734192008-06-17 22:28:05 -07001031 unix_recvq_full(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032
David S. Miller1c92b4e2007-05-31 13:24:26 -07001033 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034
1035 if (sched)
1036 timeo = schedule_timeout(timeo);
1037
1038 finish_wait(&u->peer_wait, &wait);
1039 return timeo;
1040}
1041
1042static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
1043 int addr_len, int flags)
1044{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001045 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001047 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 struct unix_sock *u = unix_sk(sk), *newu, *otheru;
1049 struct sock *newsk = NULL;
1050 struct sock *other = NULL;
1051 struct sk_buff *skb = NULL;
1052 unsigned hash;
1053 int st;
1054 int err;
1055 long timeo;
1056
1057 err = unix_mkname(sunaddr, addr_len, &hash);
1058 if (err < 0)
1059 goto out;
1060 addr_len = err;
1061
Joe Perchesf64f9e72009-11-29 16:55:45 -08001062 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr &&
1063 (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 goto out;
1065
1066 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
1067
1068 /* First of all allocate resources.
1069 If we will make it after state is locked,
1070 we will have to recheck all again in any case.
1071 */
1072
1073 err = -ENOMEM;
1074
1075 /* create new sock for complete connection */
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001076 newsk = unix_create1(sock_net(sk), NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 if (newsk == NULL)
1078 goto out;
1079
1080 /* Allocate skb for sending to listening sock */
1081 skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL);
1082 if (skb == NULL)
1083 goto out;
1084
1085restart:
1086 /* Find listening sock. */
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001087 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 if (!other)
1089 goto out;
1090
1091 /* Latch state of peer */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001092 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093
1094 /* Apparently VFS overslept socket death. Retry. */
1095 if (sock_flag(other, SOCK_DEAD)) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001096 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 sock_put(other);
1098 goto restart;
1099 }
1100
1101 err = -ECONNREFUSED;
1102 if (other->sk_state != TCP_LISTEN)
1103 goto out_unlock;
Tomoki Sekiyama77238f22009-10-18 23:17:37 -07001104 if (other->sk_shutdown & RCV_SHUTDOWN)
1105 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106
Rainer Weikusat3c734192008-06-17 22:28:05 -07001107 if (unix_recvq_full(other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 err = -EAGAIN;
1109 if (!timeo)
1110 goto out_unlock;
1111
1112 timeo = unix_wait_for_peer(other, timeo);
1113
1114 err = sock_intr_errno(timeo);
1115 if (signal_pending(current))
1116 goto out;
1117 sock_put(other);
1118 goto restart;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001119 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120
1121 /* Latch our state.
1122
Daniel Balutae5537bf2011-03-14 15:25:33 -07001123 It is tricky place. We need to grab our state lock and cannot
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 drop lock on peer. It is dangerous because deadlock is
1125 possible. Connect to self case and simultaneous
1126 attempt to connect are eliminated by checking socket
1127 state. other is TCP_LISTEN, if sk is TCP_LISTEN we
1128 check this before attempt to grab lock.
1129
1130 Well, and we have to recheck the state after socket locked.
1131 */
1132 st = sk->sk_state;
1133
1134 switch (st) {
1135 case TCP_CLOSE:
1136 /* This is ok... continue with connect */
1137 break;
1138 case TCP_ESTABLISHED:
1139 /* Socket is already connected */
1140 err = -EISCONN;
1141 goto out_unlock;
1142 default:
1143 err = -EINVAL;
1144 goto out_unlock;
1145 }
1146
David S. Miller1c92b4e2007-05-31 13:24:26 -07001147 unix_state_lock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148
1149 if (sk->sk_state != st) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001150 unix_state_unlock(sk);
1151 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 sock_put(other);
1153 goto restart;
1154 }
1155
David S. Miller3610cda2011-01-05 15:38:53 -08001156 err = security_unix_stream_connect(sk, other, newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 if (err) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001158 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159 goto out_unlock;
1160 }
1161
1162 /* The way is open! Fastly set all the necessary fields... */
1163
1164 sock_hold(sk);
1165 unix_peer(newsk) = sk;
1166 newsk->sk_state = TCP_ESTABLISHED;
1167 newsk->sk_type = sk->sk_type;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001168 init_peercred(newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169 newu = unix_sk(newsk);
Eric Dumazeteaefd112011-02-18 03:26:36 +00001170 RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 otheru = unix_sk(other);
1172
1173 /* copy address information from listening to new sock*/
1174 if (otheru->addr) {
1175 atomic_inc(&otheru->addr->refcnt);
1176 newu->addr = otheru->addr;
1177 }
Al Viro40ffe672012-03-14 21:54:32 -04001178 if (otheru->path.dentry) {
1179 path_get(&otheru->path);
1180 newu->path = otheru->path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 }
1182
1183 /* Set credentials */
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001184 copy_peercred(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 sock->state = SS_CONNECTED;
1187 sk->sk_state = TCP_ESTABLISHED;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001188 sock_hold(newsk);
1189
1190 smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */
1191 unix_peer(sk) = newsk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192
David S. Miller1c92b4e2007-05-31 13:24:26 -07001193 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194
1195 /* take ten and and send info to listening sock */
1196 spin_lock(&other->sk_receive_queue.lock);
1197 __skb_queue_tail(&other->sk_receive_queue, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001199 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 other->sk_data_ready(other, 0);
1201 sock_put(other);
1202 return 0;
1203
1204out_unlock:
1205 if (other)
David S. Miller1c92b4e2007-05-31 13:24:26 -07001206 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207
1208out:
Wei Yongjun40d44442009-02-25 00:32:45 +00001209 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 if (newsk)
1211 unix_release_sock(newsk, 0);
1212 if (other)
1213 sock_put(other);
1214 return err;
1215}
1216
1217static int unix_socketpair(struct socket *socka, struct socket *sockb)
1218{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001219 struct sock *ska = socka->sk, *skb = sockb->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220
1221 /* Join our sockets back to back */
1222 sock_hold(ska);
1223 sock_hold(skb);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001224 unix_peer(ska) = skb;
1225 unix_peer(skb) = ska;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001226 init_peercred(ska);
1227 init_peercred(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228
1229 if (ska->sk_type != SOCK_DGRAM) {
1230 ska->sk_state = TCP_ESTABLISHED;
1231 skb->sk_state = TCP_ESTABLISHED;
1232 socka->state = SS_CONNECTED;
1233 sockb->state = SS_CONNECTED;
1234 }
1235 return 0;
1236}
1237
1238static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
1239{
1240 struct sock *sk = sock->sk;
1241 struct sock *tsk;
1242 struct sk_buff *skb;
1243 int err;
1244
1245 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001246 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 goto out;
1248
1249 err = -EINVAL;
1250 if (sk->sk_state != TCP_LISTEN)
1251 goto out;
1252
1253 /* If socket state is TCP_LISTEN it cannot change (for now...),
1254 * so that no locks are necessary.
1255 */
1256
1257 skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
1258 if (!skb) {
1259 /* This means receive shutdown. */
1260 if (err == 0)
1261 err = -EINVAL;
1262 goto out;
1263 }
1264
1265 tsk = skb->sk;
1266 skb_free_datagram(sk, skb);
1267 wake_up_interruptible(&unix_sk(sk)->peer_wait);
1268
1269 /* attach accepted sock to socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001270 unix_state_lock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 newsock->state = SS_CONNECTED;
1272 sock_graft(tsk, newsock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001273 unix_state_unlock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 return 0;
1275
1276out:
1277 return err;
1278}
1279
1280
1281static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
1282{
1283 struct sock *sk = sock->sk;
1284 struct unix_sock *u;
Cyrill Gorcunov13cfa972009-11-08 05:51:19 +00001285 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286 int err = 0;
1287
1288 if (peer) {
1289 sk = unix_peer_get(sk);
1290
1291 err = -ENOTCONN;
1292 if (!sk)
1293 goto out;
1294 err = 0;
1295 } else {
1296 sock_hold(sk);
1297 }
1298
1299 u = unix_sk(sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001300 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301 if (!u->addr) {
1302 sunaddr->sun_family = AF_UNIX;
1303 sunaddr->sun_path[0] = 0;
1304 *uaddr_len = sizeof(short);
1305 } else {
1306 struct unix_address *addr = u->addr;
1307
1308 *uaddr_len = addr->len;
1309 memcpy(sunaddr, addr->name, *uaddr_len);
1310 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07001311 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 sock_put(sk);
1313out:
1314 return err;
1315}
1316
1317static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1318{
1319 int i;
1320
1321 scm->fp = UNIXCB(skb).fp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 UNIXCB(skb).fp = NULL;
1323
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001324 for (i = scm->fp->count-1; i >= 0; i--)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 unix_notinflight(scm->fp->fp[i]);
1326}
1327
Eric W. Biederman7361c362010-06-13 03:34:33 +00001328static void unix_destruct_scm(struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329{
1330 struct scm_cookie scm;
1331 memset(&scm, 0, sizeof(scm));
Eric W. Biederman7361c362010-06-13 03:34:33 +00001332 scm.pid = UNIXCB(skb).pid;
1333 scm.cred = UNIXCB(skb).cred;
1334 if (UNIXCB(skb).fp)
1335 unix_detach_fds(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336
1337 /* Alas, it calls VFS */
1338 /* So fscking what? fput() had been SMP-safe since the last Summer */
1339 scm_destroy(&scm);
1340 sock_wfree(skb);
1341}
1342
Eric Dumazet25888e32010-11-25 04:11:39 +00001343#define MAX_RECURSION_LEVEL 4
1344
Miklos Szeredi62093442008-11-09 15:23:57 +01001345static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346{
1347 int i;
Eric Dumazet25888e32010-11-25 04:11:39 +00001348 unsigned char max_level = 0;
1349 int unix_sock_count = 0;
1350
1351 for (i = scm->fp->count - 1; i >= 0; i--) {
1352 struct sock *sk = unix_get_socket(scm->fp->fp[i]);
1353
1354 if (sk) {
1355 unix_sock_count++;
1356 max_level = max(max_level,
1357 unix_sk(sk)->recursion_level);
1358 }
1359 }
1360 if (unlikely(max_level > MAX_RECURSION_LEVEL))
1361 return -ETOOMANYREFS;
Miklos Szeredi62093442008-11-09 15:23:57 +01001362
1363 /*
1364 * Need to duplicate file references for the sake of garbage
1365 * collection. Otherwise a socket in the fps might become a
1366 * candidate for GC while the skb is not yet queued.
1367 */
1368 UNIXCB(skb).fp = scm_fp_dup(scm->fp);
1369 if (!UNIXCB(skb).fp)
1370 return -ENOMEM;
1371
Eric Dumazet25888e32010-11-25 04:11:39 +00001372 if (unix_sock_count) {
1373 for (i = scm->fp->count - 1; i >= 0; i--)
1374 unix_inflight(scm->fp->fp[i]);
1375 }
1376 return max_level;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377}
1378
David S. Millerf78a5fd2011-09-16 19:34:00 -04001379static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001380{
1381 int err = 0;
Eric Dumazet16e57262011-09-19 05:52:27 +00001382
David S. Millerf78a5fd2011-09-16 19:34:00 -04001383 UNIXCB(skb).pid = get_pid(scm->pid);
Eric Dumazet16e57262011-09-19 05:52:27 +00001384 if (scm->cred)
1385 UNIXCB(skb).cred = get_cred(scm->cred);
Eric W. Biederman7361c362010-06-13 03:34:33 +00001386 UNIXCB(skb).fp = NULL;
1387 if (scm->fp && send_fds)
1388 err = unix_attach_fds(scm, skb);
1389
1390 skb->destructor = unix_destruct_scm;
1391 return err;
1392}
1393
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394/*
Eric Dumazet16e57262011-09-19 05:52:27 +00001395 * Some apps rely on write() giving SCM_CREDENTIALS
1396 * We include credentials if source or destination socket
1397 * asserted SOCK_PASSCRED.
1398 */
1399static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1400 const struct sock *other)
1401{
1402 if (UNIXCB(skb).cred)
1403 return;
1404 if (test_bit(SOCK_PASSCRED, &sock->flags) ||
1405 !other->sk_socket ||
1406 test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
1407 UNIXCB(skb).pid = get_pid(task_tgid(current));
1408 UNIXCB(skb).cred = get_current_cred();
1409 }
1410}
1411
1412/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 * Send AF_UNIX data.
1414 */
1415
1416static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1417 struct msghdr *msg, size_t len)
1418{
1419 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1420 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001421 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 struct unix_sock *u = unix_sk(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001423 struct sockaddr_un *sunaddr = msg->msg_name;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 struct sock *other = NULL;
1425 int namelen = 0; /* fake GCC */
1426 int err;
1427 unsigned hash;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001428 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 long timeo;
1430 struct scm_cookie tmp_scm;
Eric Dumazet25888e32010-11-25 04:11:39 +00001431 int max_level;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432
1433 if (NULL == siocb->scm)
1434 siocb->scm = &tmp_scm;
dann frazier5f23b732008-11-26 15:32:27 -08001435 wait_for_unix_gc();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 err = scm_send(sock, msg, siocb->scm);
1437 if (err < 0)
1438 return err;
1439
1440 err = -EOPNOTSUPP;
1441 if (msg->msg_flags&MSG_OOB)
1442 goto out;
1443
1444 if (msg->msg_namelen) {
1445 err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
1446 if (err < 0)
1447 goto out;
1448 namelen = err;
1449 } else {
1450 sunaddr = NULL;
1451 err = -ENOTCONN;
1452 other = unix_peer_get(sk);
1453 if (!other)
1454 goto out;
1455 }
1456
Joe Perchesf64f9e72009-11-29 16:55:45 -08001457 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr
1458 && (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 goto out;
1460
1461 err = -EMSGSIZE;
1462 if (len > sk->sk_sndbuf - 32)
1463 goto out;
1464
1465 skb = sock_alloc_send_skb(sk, len, msg->msg_flags&MSG_DONTWAIT, &err);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001466 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 goto out;
1468
David S. Millerf78a5fd2011-09-16 19:34:00 -04001469 err = unix_scm_to_skb(siocb->scm, skb, true);
Eric Dumazet25888e32010-11-25 04:11:39 +00001470 if (err < 0)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001471 goto out_free;
Eric Dumazet25888e32010-11-25 04:11:39 +00001472 max_level = err + 1;
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07001473 unix_get_secdata(siocb->scm, skb);
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001474
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -03001475 skb_reset_transport_header(skb);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001476 err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 if (err)
1478 goto out_free;
1479
1480 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1481
1482restart:
1483 if (!other) {
1484 err = -ECONNRESET;
1485 if (sunaddr == NULL)
1486 goto out_free;
1487
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001488 other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 hash, &err);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001490 if (other == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 goto out_free;
1492 }
1493
Alban Crequyd6ae3ba2011-01-18 06:39:15 +00001494 if (sk_filter(other, skb) < 0) {
1495 /* Toss the packet but do not return any error to the sender */
1496 err = len;
1497 goto out_free;
1498 }
1499
David S. Miller1c92b4e2007-05-31 13:24:26 -07001500 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 err = -EPERM;
1502 if (!unix_may_send(sk, other))
1503 goto out_unlock;
1504
1505 if (sock_flag(other, SOCK_DEAD)) {
1506 /*
1507 * Check with 1003.1g - what should
1508 * datagram error
1509 */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001510 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 sock_put(other);
1512
1513 err = 0;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001514 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 if (unix_peer(sk) == other) {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001516 unix_peer(sk) = NULL;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001517 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518
1519 unix_dgram_disconnected(sk, other);
1520 sock_put(other);
1521 err = -ECONNREFUSED;
1522 } else {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001523 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 }
1525
1526 other = NULL;
1527 if (err)
1528 goto out_free;
1529 goto restart;
1530 }
1531
1532 err = -EPIPE;
1533 if (other->sk_shutdown & RCV_SHUTDOWN)
1534 goto out_unlock;
1535
1536 if (sk->sk_type != SOCK_SEQPACKET) {
1537 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1538 if (err)
1539 goto out_unlock;
1540 }
1541
Rainer Weikusat3c734192008-06-17 22:28:05 -07001542 if (unix_peer(other) != sk && unix_recvq_full(other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 if (!timeo) {
1544 err = -EAGAIN;
1545 goto out_unlock;
1546 }
1547
1548 timeo = unix_wait_for_peer(other, timeo);
1549
1550 err = sock_intr_errno(timeo);
1551 if (signal_pending(current))
1552 goto out_free;
1553
1554 goto restart;
1555 }
1556
Alban Crequy3f661162010-10-04 08:48:28 +00001557 if (sock_flag(other, SOCK_RCVTSTAMP))
1558 __net_timestamp(skb);
Eric Dumazet16e57262011-09-19 05:52:27 +00001559 maybe_add_creds(skb, sock, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 skb_queue_tail(&other->sk_receive_queue, skb);
Eric Dumazet25888e32010-11-25 04:11:39 +00001561 if (max_level > unix_sk(other)->recursion_level)
1562 unix_sk(other)->recursion_level = max_level;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001563 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 other->sk_data_ready(other, len);
1565 sock_put(other);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001566 scm_destroy(siocb->scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 return len;
1568
1569out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -07001570 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571out_free:
1572 kfree_skb(skb);
1573out:
1574 if (other)
1575 sock_put(other);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001576 scm_destroy(siocb->scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 return err;
1578}
1579
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001580
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1582 struct msghdr *msg, size_t len)
1583{
1584 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1585 struct sock *sk = sock->sk;
1586 struct sock *other = NULL;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001587 int err, size;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001588 struct sk_buff *skb;
Jianjun Konge27dfce2008-11-01 21:38:31 -07001589 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 struct scm_cookie tmp_scm;
Miklos Szeredi8ba69ba2009-09-11 11:31:45 -07001591 bool fds_sent = false;
Eric Dumazet25888e32010-11-25 04:11:39 +00001592 int max_level;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593
1594 if (NULL == siocb->scm)
1595 siocb->scm = &tmp_scm;
dann frazier5f23b732008-11-26 15:32:27 -08001596 wait_for_unix_gc();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 err = scm_send(sock, msg, siocb->scm);
1598 if (err < 0)
1599 return err;
1600
1601 err = -EOPNOTSUPP;
1602 if (msg->msg_flags&MSG_OOB)
1603 goto out_err;
1604
1605 if (msg->msg_namelen) {
1606 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
1607 goto out_err;
1608 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 err = -ENOTCONN;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001610 other = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 if (!other)
1612 goto out_err;
1613 }
1614
1615 if (sk->sk_shutdown & SEND_SHUTDOWN)
1616 goto pipe_err;
1617
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001618 while (sent < len) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 /*
Benjamin LaHaisee9df7d7f2006-03-20 21:29:05 -08001620 * Optimisation for the fact that under 0.01% of X
1621 * messages typically need breaking up.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 */
1623
Benjamin LaHaisee9df7d7f2006-03-20 21:29:05 -08001624 size = len-sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625
1626 /* Keep two messages in the pipe so it schedules better */
Benjamin LaHaisee9df7d7f2006-03-20 21:29:05 -08001627 if (size > ((sk->sk_sndbuf >> 1) - 64))
1628 size = (sk->sk_sndbuf >> 1) - 64;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629
1630 if (size > SKB_MAX_ALLOC)
1631 size = SKB_MAX_ALLOC;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001632
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633 /*
1634 * Grab a buffer
1635 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001636
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001637 skb = sock_alloc_send_skb(sk, size, msg->msg_flags&MSG_DONTWAIT,
1638 &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
Jianjun Konge27dfce2008-11-01 21:38:31 -07001640 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 goto out_err;
1642
1643 /*
1644 * If you pass two values to the sock_alloc_send_skb
1645 * it tries to grab the large buffer with GFP_NOFS
1646 * (which can fail easily), and if it fails grab the
1647 * fallback size buffer which is under a page and will
1648 * succeed. [Alan]
1649 */
1650 size = min_t(int, size, skb_tailroom(skb));
1651
Eric W. Biederman7361c362010-06-13 03:34:33 +00001652
David S. Millerf78a5fd2011-09-16 19:34:00 -04001653 /* Only send the fds in the first buffer */
1654 err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
Eric Dumazet25888e32010-11-25 04:11:39 +00001655 if (err < 0) {
Eric W. Biederman7361c362010-06-13 03:34:33 +00001656 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001657 goto out_err;
Miklos Szeredi62093442008-11-09 15:23:57 +01001658 }
Eric Dumazet25888e32010-11-25 04:11:39 +00001659 max_level = err + 1;
Eric W. Biederman7361c362010-06-13 03:34:33 +00001660 fds_sent = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001662 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
1663 if (err) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001665 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 }
1667
David S. Miller1c92b4e2007-05-31 13:24:26 -07001668 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669
1670 if (sock_flag(other, SOCK_DEAD) ||
1671 (other->sk_shutdown & RCV_SHUTDOWN))
1672 goto pipe_err_free;
1673
Eric Dumazet16e57262011-09-19 05:52:27 +00001674 maybe_add_creds(skb, sock, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 skb_queue_tail(&other->sk_receive_queue, skb);
Eric Dumazet25888e32010-11-25 04:11:39 +00001676 if (max_level > unix_sk(other)->recursion_level)
1677 unix_sk(other)->recursion_level = max_level;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001678 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 other->sk_data_ready(other, size);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001680 sent += size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682
David S. Millerf78a5fd2011-09-16 19:34:00 -04001683 scm_destroy(siocb->scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 siocb->scm = NULL;
1685
1686 return sent;
1687
1688pipe_err_free:
David S. Miller1c92b4e2007-05-31 13:24:26 -07001689 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 kfree_skb(skb);
1691pipe_err:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001692 if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
1693 send_sig(SIGPIPE, current, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 err = -EPIPE;
1695out_err:
David S. Millerf78a5fd2011-09-16 19:34:00 -04001696 scm_destroy(siocb->scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 siocb->scm = NULL;
1698 return sent ? : err;
1699}
1700
1701static int unix_seqpacket_sendmsg(struct kiocb *kiocb, struct socket *sock,
1702 struct msghdr *msg, size_t len)
1703{
1704 int err;
1705 struct sock *sk = sock->sk;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001706
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 err = sock_error(sk);
1708 if (err)
1709 return err;
1710
1711 if (sk->sk_state != TCP_ESTABLISHED)
1712 return -ENOTCONN;
1713
1714 if (msg->msg_namelen)
1715 msg->msg_namelen = 0;
1716
1717 return unix_dgram_sendmsg(kiocb, sock, msg, len);
1718}
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001719
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00001720static int unix_seqpacket_recvmsg(struct kiocb *iocb, struct socket *sock,
1721 struct msghdr *msg, size_t size,
1722 int flags)
1723{
1724 struct sock *sk = sock->sk;
1725
1726 if (sk->sk_state != TCP_ESTABLISHED)
1727 return -ENOTCONN;
1728
1729 return unix_dgram_recvmsg(iocb, sock, msg, size, flags);
1730}
1731
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
1733{
1734 struct unix_sock *u = unix_sk(sk);
1735
1736 msg->msg_namelen = 0;
1737 if (u->addr) {
1738 msg->msg_namelen = u->addr->len;
1739 memcpy(msg->msg_name, u->addr->name, u->addr->len);
1740 }
1741}
1742
1743static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1744 struct msghdr *msg, size_t size,
1745 int flags)
1746{
1747 struct sock_iocb *siocb = kiocb_to_siocb(iocb);
1748 struct scm_cookie tmp_scm;
1749 struct sock *sk = sock->sk;
1750 struct unix_sock *u = unix_sk(sk);
1751 int noblock = flags & MSG_DONTWAIT;
1752 struct sk_buff *skb;
1753 int err;
1754
1755 err = -EOPNOTSUPP;
1756 if (flags&MSG_OOB)
1757 goto out;
1758
1759 msg->msg_namelen = 0;
1760
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00001761 err = mutex_lock_interruptible(&u->readlock);
1762 if (err) {
1763 err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
1764 goto out;
1765 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766
1767 skb = skb_recv_datagram(sk, flags, noblock, &err);
Florian Zumbiehl0a112252007-11-29 23:19:23 +11001768 if (!skb) {
1769 unix_state_lock(sk);
1770 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
1771 if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
1772 (sk->sk_shutdown & RCV_SHUTDOWN))
1773 err = 0;
1774 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 goto out_unlock;
Florian Zumbiehl0a112252007-11-29 23:19:23 +11001776 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777
Eric Dumazet67426b72010-10-29 20:44:44 +00001778 wake_up_interruptible_sync_poll(&u->peer_wait,
1779 POLLOUT | POLLWRNORM | POLLWRBAND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780
1781 if (msg->msg_name)
1782 unix_copy_addr(msg, skb->sk);
1783
1784 if (size > skb->len)
1785 size = skb->len;
1786 else if (size < skb->len)
1787 msg->msg_flags |= MSG_TRUNC;
1788
1789 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
1790 if (err)
1791 goto out_free;
1792
Alban Crequy3f661162010-10-04 08:48:28 +00001793 if (sock_flag(sk, SOCK_RCVTSTAMP))
1794 __sock_recv_timestamp(msg, sk, skb);
1795
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 if (!siocb->scm) {
1797 siocb->scm = &tmp_scm;
1798 memset(&tmp_scm, 0, sizeof(tmp_scm));
1799 }
David S. Millerf78a5fd2011-09-16 19:34:00 -04001800 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001801 unix_set_secdata(siocb->scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001803 if (!(flags & MSG_PEEK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 if (UNIXCB(skb).fp)
1805 unix_detach_fds(siocb->scm, skb);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001806 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 /* It is questionable: on PEEK we could:
1808 - do not return fds - good, but too simple 8)
1809 - return fds, and do not return them on read (old strategy,
1810 apparently wrong)
1811 - clone fds (I chose it for now, it is the most universal
1812 solution)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001813
1814 POSIX 1003.1g does not actually define this clearly
1815 at all. POSIX 1003.1g doesn't define a lot of things
1816 clearly however!
1817
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 */
1819 if (UNIXCB(skb).fp)
1820 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
1821 }
1822 err = size;
1823
1824 scm_recv(sock, msg, siocb->scm, flags);
1825
1826out_free:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001827 skb_free_datagram(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828out_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001829 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830out:
1831 return err;
1832}
1833
1834/*
1835 * Sleep until data has arrive. But check for races..
1836 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001837
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001838static long unix_stream_data_wait(struct sock *sk, long timeo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839{
1840 DEFINE_WAIT(wait);
1841
David S. Miller1c92b4e2007-05-31 13:24:26 -07001842 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843
1844 for (;;) {
Eric Dumazetaa395142010-04-20 13:03:51 +00001845 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846
David S. Millerb03efcf2005-07-08 14:57:23 -07001847 if (!skb_queue_empty(&sk->sk_receive_queue) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 sk->sk_err ||
1849 (sk->sk_shutdown & RCV_SHUTDOWN) ||
1850 signal_pending(current) ||
1851 !timeo)
1852 break;
1853
1854 set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001855 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 timeo = schedule_timeout(timeo);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001857 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
1859 }
1860
Eric Dumazetaa395142010-04-20 13:03:51 +00001861 finish_wait(sk_sleep(sk), &wait);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001862 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 return timeo;
1864}
1865
1866
1867
1868static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1869 struct msghdr *msg, size_t size,
1870 int flags)
1871{
1872 struct sock_iocb *siocb = kiocb_to_siocb(iocb);
1873 struct scm_cookie tmp_scm;
1874 struct sock *sk = sock->sk;
1875 struct unix_sock *u = unix_sk(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001876 struct sockaddr_un *sunaddr = msg->msg_name;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 int copied = 0;
1878 int check_creds = 0;
1879 int target;
1880 int err = 0;
1881 long timeo;
1882
1883 err = -EINVAL;
1884 if (sk->sk_state != TCP_ESTABLISHED)
1885 goto out;
1886
1887 err = -EOPNOTSUPP;
1888 if (flags&MSG_OOB)
1889 goto out;
1890
1891 target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
1892 timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
1893
1894 msg->msg_namelen = 0;
1895
1896 /* Lock the socket to prevent queue disordering
1897 * while sleeps in memcpy_tomsg
1898 */
1899
1900 if (!siocb->scm) {
1901 siocb->scm = &tmp_scm;
1902 memset(&tmp_scm, 0, sizeof(tmp_scm));
1903 }
1904
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00001905 err = mutex_lock_interruptible(&u->readlock);
1906 if (err) {
1907 err = sock_intr_errno(timeo);
1908 goto out;
1909 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001911 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 int chunk;
1913 struct sk_buff *skb;
1914
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001915 unix_state_lock(sk);
Eric Dumazet6f01fd62012-01-28 16:11:03 +00001916 skb = skb_peek(&sk->sk_receive_queue);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001917 if (skb == NULL) {
Eric Dumazet25888e32010-11-25 04:11:39 +00001918 unix_sk(sk)->recursion_level = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 if (copied >= target)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001920 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921
1922 /*
1923 * POSIX 1003.1g mandates this order.
1924 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001925
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001926 err = sock_error(sk);
1927 if (err)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001928 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 if (sk->sk_shutdown & RCV_SHUTDOWN)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001930 goto unlock;
1931
1932 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 err = -EAGAIN;
1934 if (!timeo)
1935 break;
Ingo Molnar57b47a52006-03-20 22:35:41 -08001936 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937
1938 timeo = unix_stream_data_wait(sk, timeo);
1939
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00001940 if (signal_pending(current)
1941 || mutex_lock_interruptible(&u->readlock)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 err = sock_intr_errno(timeo);
1943 goto out;
1944 }
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00001945
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 continue;
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001947 unlock:
1948 unix_state_unlock(sk);
1949 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 }
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001951 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952
1953 if (check_creds) {
1954 /* Never glue messages from different writers */
Eric W. Biederman7361c362010-06-13 03:34:33 +00001955 if ((UNIXCB(skb).pid != siocb->scm->pid) ||
Eric Dumazet6f01fd62012-01-28 16:11:03 +00001956 (UNIXCB(skb).cred != siocb->scm->cred))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 } else {
1959 /* Copy credentials */
David S. Millerf78a5fd2011-09-16 19:34:00 -04001960 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 check_creds = 1;
1962 }
1963
1964 /* Copy address just once */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001965 if (sunaddr) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966 unix_copy_addr(msg, skb->sk);
1967 sunaddr = NULL;
1968 }
1969
1970 chunk = min_t(unsigned int, skb->len, size);
1971 if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972 if (copied == 0)
1973 copied = -EFAULT;
1974 break;
1975 }
1976 copied += chunk;
1977 size -= chunk;
1978
1979 /* Mark read part of skb as used */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001980 if (!(flags & MSG_PEEK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 skb_pull(skb, chunk);
1982
1983 if (UNIXCB(skb).fp)
1984 unix_detach_fds(siocb->scm, skb);
1985
Eric Dumazet6f01fd62012-01-28 16:11:03 +00001986 if (skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988
Eric Dumazet6f01fd62012-01-28 16:11:03 +00001989 skb_unlink(skb, &sk->sk_receive_queue);
Neil Horman70d4bf62010-07-20 06:45:56 +00001990 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991
1992 if (siocb->scm->fp)
1993 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001994 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995 /* It is questionable, see note in unix_dgram_recvmsg.
1996 */
1997 if (UNIXCB(skb).fp)
1998 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
1999
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 break;
2001 }
2002 } while (size);
2003
Ingo Molnar57b47a52006-03-20 22:35:41 -08002004 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005 scm_recv(sock, msg, siocb->scm, flags);
2006out:
2007 return copied ? : err;
2008}
2009
2010static int unix_shutdown(struct socket *sock, int mode)
2011{
2012 struct sock *sk = sock->sk;
2013 struct sock *other;
2014
2015 mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN);
2016
Alban Crequy7180a032011-01-19 04:56:36 +00002017 if (!mode)
2018 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019
Alban Crequy7180a032011-01-19 04:56:36 +00002020 unix_state_lock(sk);
2021 sk->sk_shutdown |= mode;
2022 other = unix_peer(sk);
2023 if (other)
2024 sock_hold(other);
2025 unix_state_unlock(sk);
2026 sk->sk_state_change(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027
Alban Crequy7180a032011-01-19 04:56:36 +00002028 if (other &&
2029 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030
Alban Crequy7180a032011-01-19 04:56:36 +00002031 int peer_mode = 0;
2032
2033 if (mode&RCV_SHUTDOWN)
2034 peer_mode |= SEND_SHUTDOWN;
2035 if (mode&SEND_SHUTDOWN)
2036 peer_mode |= RCV_SHUTDOWN;
2037 unix_state_lock(other);
2038 other->sk_shutdown |= peer_mode;
2039 unix_state_unlock(other);
2040 other->sk_state_change(other);
2041 if (peer_mode == SHUTDOWN_MASK)
2042 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
2043 else if (peer_mode & RCV_SHUTDOWN)
2044 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002045 }
Alban Crequy7180a032011-01-19 04:56:36 +00002046 if (other)
2047 sock_put(other);
2048
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 return 0;
2050}
2051
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002052long unix_inq_len(struct sock *sk)
2053{
2054 struct sk_buff *skb;
2055 long amount = 0;
2056
2057 if (sk->sk_state == TCP_LISTEN)
2058 return -EINVAL;
2059
2060 spin_lock(&sk->sk_receive_queue.lock);
2061 if (sk->sk_type == SOCK_STREAM ||
2062 sk->sk_type == SOCK_SEQPACKET) {
2063 skb_queue_walk(&sk->sk_receive_queue, skb)
2064 amount += skb->len;
2065 } else {
2066 skb = skb_peek(&sk->sk_receive_queue);
2067 if (skb)
2068 amount = skb->len;
2069 }
2070 spin_unlock(&sk->sk_receive_queue.lock);
2071
2072 return amount;
2073}
2074EXPORT_SYMBOL_GPL(unix_inq_len);
2075
2076long unix_outq_len(struct sock *sk)
2077{
2078 return sk_wmem_alloc_get(sk);
2079}
2080EXPORT_SYMBOL_GPL(unix_outq_len);
2081
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2083{
2084 struct sock *sk = sock->sk;
Jianjun Konge27dfce2008-11-01 21:38:31 -07002085 long amount = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 int err;
2087
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002088 switch (cmd) {
2089 case SIOCOUTQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002090 amount = unix_outq_len(sk);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002091 err = put_user(amount, (int __user *)arg);
2092 break;
2093 case SIOCINQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002094 amount = unix_inq_len(sk);
2095 if (amount < 0)
2096 err = amount;
2097 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 err = put_user(amount, (int __user *)arg);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002099 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002100 default:
2101 err = -ENOIOCTLCMD;
2102 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 }
2104 return err;
2105}
2106
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002107static unsigned int unix_poll(struct file *file, struct socket *sock, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108{
2109 struct sock *sk = sock->sk;
2110 unsigned int mask;
2111
Eric Dumazetaa395142010-04-20 13:03:51 +00002112 sock_poll_wait(file, sk_sleep(sk), wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113 mask = 0;
2114
2115 /* exceptional events? */
2116 if (sk->sk_err)
2117 mask |= POLLERR;
2118 if (sk->sk_shutdown == SHUTDOWN_MASK)
2119 mask |= POLLHUP;
Davide Libenzif348d702006-03-25 03:07:39 -08002120 if (sk->sk_shutdown & RCV_SHUTDOWN)
Eric Dumazetdb409802010-09-06 11:13:50 +00002121 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122
2123 /* readable? */
Eric Dumazetdb409802010-09-06 11:13:50 +00002124 if (!skb_queue_empty(&sk->sk_receive_queue))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125 mask |= POLLIN | POLLRDNORM;
2126
2127 /* Connection-based need to check for termination and startup */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002128 if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
2129 sk->sk_state == TCP_CLOSE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130 mask |= POLLHUP;
2131
2132 /*
2133 * we set writable also when the other side has shut down the
2134 * connection. This prevents stuck sockets.
2135 */
2136 if (unix_writable(sk))
2137 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
2138
2139 return mask;
2140}
2141
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002142static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
2143 poll_table *wait)
Rainer Weikusat3c734192008-06-17 22:28:05 -07002144{
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002145 struct sock *sk = sock->sk, *other;
2146 unsigned int mask, writable;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002147
Eric Dumazetaa395142010-04-20 13:03:51 +00002148 sock_poll_wait(file, sk_sleep(sk), wait);
Rainer Weikusat3c734192008-06-17 22:28:05 -07002149 mask = 0;
2150
2151 /* exceptional events? */
2152 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
2153 mask |= POLLERR;
2154 if (sk->sk_shutdown & RCV_SHUTDOWN)
Eric Dumazet5456f092010-10-31 05:36:23 +00002155 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002156 if (sk->sk_shutdown == SHUTDOWN_MASK)
2157 mask |= POLLHUP;
2158
2159 /* readable? */
Eric Dumazet5456f092010-10-31 05:36:23 +00002160 if (!skb_queue_empty(&sk->sk_receive_queue))
Rainer Weikusat3c734192008-06-17 22:28:05 -07002161 mask |= POLLIN | POLLRDNORM;
2162
2163 /* Connection-based need to check for termination and startup */
2164 if (sk->sk_type == SOCK_SEQPACKET) {
2165 if (sk->sk_state == TCP_CLOSE)
2166 mask |= POLLHUP;
2167 /* connection hasn't started yet? */
2168 if (sk->sk_state == TCP_SYN_SENT)
2169 return mask;
2170 }
2171
Eric Dumazet973a34a2010-10-31 05:38:25 +00002172 /* No write status requested, avoid expensive OUT tests. */
2173 if (wait && !(wait->key & (POLLWRBAND | POLLWRNORM | POLLOUT)))
2174 return mask;
2175
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002176 writable = unix_writable(sk);
Eric Dumazet5456f092010-10-31 05:36:23 +00002177 other = unix_peer_get(sk);
2178 if (other) {
2179 if (unix_peer(other) != sk) {
2180 sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
2181 if (unix_recvq_full(other))
2182 writable = 0;
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002183 }
Eric Dumazet5456f092010-10-31 05:36:23 +00002184 sock_put(other);
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002185 }
2186
2187 if (writable)
Rainer Weikusat3c734192008-06-17 22:28:05 -07002188 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
2189 else
2190 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
2191
Rainer Weikusat3c734192008-06-17 22:28:05 -07002192 return mask;
2193}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194
2195#ifdef CONFIG_PROC_FS
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002196static struct sock *first_unix_socket(int *i)
2197{
2198 for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
2199 if (!hlist_empty(&unix_socket_table[*i]))
2200 return __sk_head(&unix_socket_table[*i]);
2201 }
2202 return NULL;
2203}
2204
2205static struct sock *next_unix_socket(int *i, struct sock *s)
2206{
2207 struct sock *next = sk_next(s);
2208 /* More in this chain? */
2209 if (next)
2210 return next;
2211 /* Look for next non-empty chain. */
2212 for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
2213 if (!hlist_empty(&unix_socket_table[*i]))
2214 return __sk_head(&unix_socket_table[*i]);
2215 }
2216 return NULL;
2217}
2218
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002219struct unix_iter_state {
Denis V. Luneve372c412007-11-19 22:31:54 -08002220 struct seq_net_private p;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002221 int i;
2222};
Jianjun Konge27dfce2008-11-01 21:38:31 -07002223
YOSHIFUJI Hideaki12188542008-03-26 02:36:06 +09002224static struct sock *unix_seq_idx(struct seq_file *seq, loff_t pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002225{
YOSHIFUJI Hideaki12188542008-03-26 02:36:06 +09002226 struct unix_iter_state *iter = seq->private;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 loff_t off = 0;
2228 struct sock *s;
2229
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002230 for (s = first_unix_socket(&iter->i); s; s = next_unix_socket(&iter->i, s)) {
YOSHIFUJI Hideaki12188542008-03-26 02:36:06 +09002231 if (sock_net(s) != seq_file_net(seq))
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002232 continue;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002233 if (off == pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 return s;
2235 ++off;
2236 }
2237 return NULL;
2238}
2239
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002241 __acquires(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002243 spin_lock(&unix_table_lock);
Joe Perchesb9f31242008-04-12 19:04:38 -07002244 return *pos ? unix_seq_idx(seq, *pos - 1) : SEQ_START_TOKEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245}
2246
2247static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2248{
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002249 struct unix_iter_state *iter = seq->private;
2250 struct sock *sk = v;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251 ++*pos;
2252
Joe Perchesb9f31242008-04-12 19:04:38 -07002253 if (v == SEQ_START_TOKEN)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002254 sk = first_unix_socket(&iter->i);
2255 else
2256 sk = next_unix_socket(&iter->i, sk);
YOSHIFUJI Hideaki12188542008-03-26 02:36:06 +09002257 while (sk && (sock_net(sk) != seq_file_net(seq)))
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002258 sk = next_unix_socket(&iter->i, sk);
2259 return sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260}
2261
2262static void unix_seq_stop(struct seq_file *seq, void *v)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002263 __releases(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002265 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266}
2267
2268static int unix_seq_show(struct seq_file *seq, void *v)
2269{
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002270
Joe Perchesb9f31242008-04-12 19:04:38 -07002271 if (v == SEQ_START_TOKEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272 seq_puts(seq, "Num RefCount Protocol Flags Type St "
2273 "Inode Path\n");
2274 else {
2275 struct sock *s = v;
2276 struct unix_sock *u = unix_sk(s);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002277 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278
Dan Rosenberg71338aa2011-05-23 12:17:35 +00002279 seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280 s,
2281 atomic_read(&s->sk_refcnt),
2282 0,
2283 s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
2284 s->sk_type,
2285 s->sk_socket ?
2286 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
2287 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
2288 sock_i_ino(s));
2289
2290 if (u->addr) {
2291 int i, len;
2292 seq_putc(seq, ' ');
2293
2294 i = 0;
2295 len = u->addr->len - sizeof(short);
2296 if (!UNIX_ABSTRACT(s))
2297 len--;
2298 else {
2299 seq_putc(seq, '@');
2300 i++;
2301 }
2302 for ( ; i < len; i++)
2303 seq_putc(seq, u->addr->name->sun_path[i]);
2304 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07002305 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306 seq_putc(seq, '\n');
2307 }
2308
2309 return 0;
2310}
2311
Philippe De Muyter56b3d972007-07-10 23:07:31 -07002312static const struct seq_operations unix_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313 .start = unix_seq_start,
2314 .next = unix_seq_next,
2315 .stop = unix_seq_stop,
2316 .show = unix_seq_show,
2317};
2318
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319static int unix_seq_open(struct inode *inode, struct file *file)
2320{
Denis V. Luneve372c412007-11-19 22:31:54 -08002321 return seq_open_net(inode, file, &unix_seq_ops,
2322 sizeof(struct unix_iter_state));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323}
2324
Arjan van de Venda7071d2007-02-12 00:55:36 -08002325static const struct file_operations unix_seq_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 .owner = THIS_MODULE,
2327 .open = unix_seq_open,
2328 .read = seq_read,
2329 .llseek = seq_lseek,
Denis V. Luneve372c412007-11-19 22:31:54 -08002330 .release = seq_release_net,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331};
2332
2333#endif
2334
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00002335static const struct net_proto_family unix_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336 .family = PF_UNIX,
2337 .create = unix_create,
2338 .owner = THIS_MODULE,
2339};
2340
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002341
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002342static int __net_init unix_net_init(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002343{
2344 int error = -ENOMEM;
2345
Denis V. Luneva0a53c82007-12-11 04:19:17 -08002346 net->unx.sysctl_max_dgram_qlen = 10;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002347 if (unix_sysctl_register(net))
2348 goto out;
Pavel Emelyanovd392e492007-12-01 23:44:15 +11002349
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002350#ifdef CONFIG_PROC_FS
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002351 if (!proc_net_fops_create(net, "unix", 0, &unix_seq_fops)) {
2352 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002353 goto out;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002354 }
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002355#endif
2356 error = 0;
2357out:
Jianjun Kong48dcc33e2008-11-01 21:37:27 -07002358 return error;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002359}
2360
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002361static void __net_exit unix_net_exit(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002362{
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002363 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002364 proc_net_remove(net, "unix");
2365}
2366
2367static struct pernet_operations unix_net_ops = {
2368 .init = unix_net_init,
2369 .exit = unix_net_exit,
2370};
2371
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372static int __init af_unix_init(void)
2373{
2374 int rc = -1;
2375 struct sk_buff *dummy_skb;
2376
YOSHIFUJI Hideakief047f52006-09-01 00:29:06 -07002377 BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378
2379 rc = proto_register(&unix_proto, 1);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002380 if (rc != 0) {
2381 printk(KERN_CRIT "%s: Cannot create unix_sock SLAB cache!\n",
Harvey Harrison0dc47872008-03-05 20:47:47 -08002382 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383 goto out;
2384 }
2385
2386 sock_register(&unix_family_ops);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002387 register_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388out:
2389 return rc;
2390}
2391
2392static void __exit af_unix_exit(void)
2393{
2394 sock_unregister(PF_UNIX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395 proto_unregister(&unix_proto);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002396 unregister_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397}
2398
David Woodhouse3d366962008-04-24 00:59:25 -07002399/* Earlier than device_initcall() so that other drivers invoking
2400 request_module() don't end up in a loop when modprobe tries
2401 to use a UNIX socket. But later than subsys_initcall() because
2402 we depend on stuff initialised there */
2403fs_initcall(af_unix_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404module_exit(af_unix_exit);
2405
2406MODULE_LICENSE("GPL");
2407MODULE_ALIAS_NETPROTO(PF_UNIX);