blob: c4ce243824bb19c6e600dd98da2d8a6d16747dc1 [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>
Colin Cross2b15af62013-05-06 23:50:21 +0000117#include <linux/freezer.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000119struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000120EXPORT_SYMBOL_GPL(unix_socket_table);
121DEFINE_SPINLOCK(unix_table_lock);
122EXPORT_SYMBOL_GPL(unix_table_lock);
Eric Dumazet518de9b2010-10-26 14:22:44 -0700123static atomic_long_t unix_nr_socks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000126static struct hlist_head *unix_sockets_unbound(void *addr)
127{
128 unsigned long hash = (unsigned long)addr;
129
130 hash ^= hash >> 16;
131 hash ^= hash >> 8;
132 hash %= UNIX_HASH_SIZE;
133 return &unix_socket_table[UNIX_HASH_SIZE + hash];
134}
135
136#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash < UNIX_HASH_SIZE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700138#ifdef CONFIG_SECURITY_NETWORK
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700139static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700140{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700141 memcpy(UNIXSID(skb), &scm->secid, sizeof(u32));
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700142}
143
144static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
145{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700146 scm->secid = *UNIXSID(skb);
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700147}
148#else
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700149static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700150{ }
151
152static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
153{ }
154#endif /* CONFIG_SECURITY_NETWORK */
155
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156/*
157 * SMP locking strategy:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800158 * hash table is protected with spinlock unix_table_lock
Stephen Hemminger663717f2010-02-18 14:12:06 -0800159 * each socket state is protected by separate spin lock.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 */
161
Eric Dumazet95c96172012-04-15 05:58:06 +0000162static inline unsigned int unix_hash_fold(__wsum n)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163{
Eric Dumazet95c96172012-04-15 05:58:06 +0000164 unsigned int hash = (__force unsigned int)n;
165
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 hash ^= hash>>16;
167 hash ^= hash>>8;
168 return hash&(UNIX_HASH_SIZE-1);
169}
170
171#define unix_peer(sk) (unix_sk(sk)->peer)
172
173static inline int unix_our_peer(struct sock *sk, struct sock *osk)
174{
175 return unix_peer(osk) == sk;
176}
177
178static inline int unix_may_send(struct sock *sk, struct sock *osk)
179{
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800180 return unix_peer(osk) == NULL || unix_our_peer(sk, osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181}
182
Rainer Weikusat3c734192008-06-17 22:28:05 -0700183static inline int unix_recvq_full(struct sock const *sk)
184{
185 return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
186}
187
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000188struct sock *unix_peer_get(struct sock *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189{
190 struct sock *peer;
191
David S. Miller1c92b4e2007-05-31 13:24:26 -0700192 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 peer = unix_peer(s);
194 if (peer)
195 sock_hold(peer);
David S. Miller1c92b4e2007-05-31 13:24:26 -0700196 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 return peer;
198}
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000199EXPORT_SYMBOL_GPL(unix_peer_get);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
201static inline void unix_release_addr(struct unix_address *addr)
202{
203 if (atomic_dec_and_test(&addr->refcnt))
204 kfree(addr);
205}
206
207/*
208 * Check unix socket name:
209 * - should be not zero length.
210 * - if started by not zero, should be NULL terminated (FS object)
211 * - if started by zero, it is abstract name.
212 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900213
Eric Dumazet95c96172012-04-15 05:58:06 +0000214static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned int *hashp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215{
216 if (len <= sizeof(short) || len > sizeof(*sunaddr))
217 return -EINVAL;
218 if (!sunaddr || sunaddr->sun_family != AF_UNIX)
219 return -EINVAL;
220 if (sunaddr->sun_path[0]) {
221 /*
222 * This may look like an off by one error but it is a bit more
223 * subtle. 108 is the longest valid AF_UNIX path for a binding.
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300224 * sun_path[108] doesn't as such exist. However in kernel space
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 * we are guaranteed that it is a valid memory location in our
226 * kernel address buffer.
227 */
Jianjun Konge27dfce2008-11-01 21:38:31 -0700228 ((char *)sunaddr)[len] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 len = strlen(sunaddr->sun_path)+1+sizeof(short);
230 return len;
231 }
232
Joe Perches07f07572008-11-19 15:44:53 -0800233 *hashp = unix_hash_fold(csum_partial(sunaddr, len, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 return len;
235}
236
237static void __unix_remove_socket(struct sock *sk)
238{
239 sk_del_node_init(sk);
240}
241
242static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
243{
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700244 WARN_ON(!sk_unhashed(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 sk_add_node(sk, list);
246}
247
248static inline void unix_remove_socket(struct sock *sk)
249{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800250 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 __unix_remove_socket(sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800252 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253}
254
255static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
256{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800257 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 __unix_insert_socket(list, sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800259 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260}
261
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800262static struct sock *__unix_find_socket_byname(struct net *net,
263 struct sockaddr_un *sunname,
Eric Dumazet95c96172012-04-15 05:58:06 +0000264 int len, int type, unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265{
266 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267
Sasha Levinb67bfe02013-02-27 17:06:00 -0800268 sk_for_each(s, &unix_socket_table[hash ^ type]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 struct unix_sock *u = unix_sk(s);
270
YOSHIFUJI Hideaki878628f2008-03-26 03:57:35 +0900271 if (!net_eq(sock_net(s), net))
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800272 continue;
273
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 if (u->addr->len == len &&
275 !memcmp(u->addr->name, sunname, len))
276 goto found;
277 }
278 s = NULL;
279found:
280 return s;
281}
282
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800283static inline struct sock *unix_find_socket_byname(struct net *net,
284 struct sockaddr_un *sunname,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 int len, int type,
Eric Dumazet95c96172012-04-15 05:58:06 +0000286 unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287{
288 struct sock *s;
289
David S. Millerfbe9cc42005-12-13 23:26:29 -0800290 spin_lock(&unix_table_lock);
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800291 s = __unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 if (s)
293 sock_hold(s);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800294 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 return s;
296}
297
Eric W. Biederman6616f782010-06-13 03:35:48 +0000298static struct sock *unix_find_socket_byinode(struct inode *i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299{
300 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301
David S. Millerfbe9cc42005-12-13 23:26:29 -0800302 spin_lock(&unix_table_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800303 sk_for_each(s,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
Al Viro40ffe672012-03-14 21:54:32 -0400305 struct dentry *dentry = unix_sk(s)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800307 if (dentry && dentry->d_inode == i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 sock_hold(s);
309 goto found;
310 }
311 }
312 s = NULL;
313found:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800314 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 return s;
316}
317
318static inline int unix_writable(struct sock *sk)
319{
320 return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
321}
322
323static void unix_write_space(struct sock *sk)
324{
Eric Dumazet43815482010-04-29 11:01:49 +0000325 struct socket_wq *wq;
326
327 rcu_read_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 if (unix_writable(sk)) {
Eric Dumazet43815482010-04-29 11:01:49 +0000329 wq = rcu_dereference(sk->sk_wq);
330 if (wq_has_sleeper(wq))
Eric Dumazet67426b72010-10-29 20:44:44 +0000331 wake_up_interruptible_sync_poll(&wq->wait,
332 POLLOUT | POLLWRNORM | POLLWRBAND);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800333 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 }
Eric Dumazet43815482010-04-29 11:01:49 +0000335 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336}
337
338/* When dgram socket disconnects (or changes its peer), we clear its receive
339 * queue of packets arrived from previous peer. First, it allows to do
340 * flow control based only on wmem_alloc; second, sk connected to peer
341 * may receive messages only from that peer. */
342static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
343{
David S. Millerb03efcf2005-07-08 14:57:23 -0700344 if (!skb_queue_empty(&sk->sk_receive_queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 skb_queue_purge(&sk->sk_receive_queue);
346 wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
347
348 /* If one link of bidirectional dgram pipe is disconnected,
349 * we signal error. Messages are lost. Do not make this,
350 * when peer was not connected to us.
351 */
352 if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) {
353 other->sk_err = ECONNRESET;
354 other->sk_error_report(other);
355 }
356 }
357}
358
359static void unix_sock_destructor(struct sock *sk)
360{
361 struct unix_sock *u = unix_sk(sk);
362
363 skb_queue_purge(&sk->sk_receive_queue);
364
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700365 WARN_ON(atomic_read(&sk->sk_wmem_alloc));
366 WARN_ON(!sk_unhashed(sk));
367 WARN_ON(sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 if (!sock_flag(sk, SOCK_DEAD)) {
Eric Dumazet6b41e7d2008-11-19 15:48:09 -0800369 printk(KERN_INFO "Attempt to release alive unix socket: %p\n", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 return;
371 }
372
373 if (u->addr)
374 unix_release_addr(u->addr);
375
Eric Dumazet518de9b2010-10-26 14:22:44 -0700376 atomic_long_dec(&unix_nr_socks);
David S. Miller6f756a82008-11-23 17:34:03 -0800377 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800378 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
David S. Miller6f756a82008-11-23 17:34:03 -0800379 local_bh_enable();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380#ifdef UNIX_REFCNT_DEBUG
Eric Dumazet518de9b2010-10-26 14:22:44 -0700381 printk(KERN_DEBUG "UNIX %p is destroyed, %ld are still alive.\n", sk,
382 atomic_long_read(&unix_nr_socks));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383#endif
384}
385
Paul Mooreded34e02013-03-25 03:18:33 +0000386static void unix_release_sock(struct sock *sk, int embrion)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387{
388 struct unix_sock *u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400389 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 struct sock *skpair;
391 struct sk_buff *skb;
392 int state;
393
394 unix_remove_socket(sk);
395
396 /* Clear state */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700397 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 sock_orphan(sk);
399 sk->sk_shutdown = SHUTDOWN_MASK;
Al Viro40ffe672012-03-14 21:54:32 -0400400 path = u->path;
401 u->path.dentry = NULL;
402 u->path.mnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 state = sk->sk_state;
404 sk->sk_state = TCP_CLOSE;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700405 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
407 wake_up_interruptible_all(&u->peer_wait);
408
Jianjun Konge27dfce2008-11-01 21:38:31 -0700409 skpair = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Jianjun Konge27dfce2008-11-01 21:38:31 -0700411 if (skpair != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
David S. Miller1c92b4e2007-05-31 13:24:26 -0700413 unix_state_lock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 /* No more writes */
415 skpair->sk_shutdown = SHUTDOWN_MASK;
416 if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
417 skpair->sk_err = ECONNRESET;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700418 unix_state_unlock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 skpair->sk_state_change(skpair);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800420 sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 }
422 sock_put(skpair); /* It may now die */
423 unix_peer(sk) = NULL;
424 }
425
426 /* Try to flush out this socket. Throw out buffers at least */
427
428 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
Jianjun Konge27dfce2008-11-01 21:38:31 -0700429 if (state == TCP_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 unix_release_sock(skb->sk, 1);
431 /* passed fds are erased in the kfree_skb hook */
432 kfree_skb(skb);
433 }
434
Al Viro40ffe672012-03-14 21:54:32 -0400435 if (path.dentry)
436 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437
438 sock_put(sk);
439
440 /* ---- Socket is dead now and most probably destroyed ---- */
441
442 /*
Alan Coxe04dae82012-09-17 00:52:41 +0000443 * Fixme: BSD difference: In BSD all sockets connected to us get
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 * ECONNRESET and we die on the spot. In Linux we behave
445 * like files and pipes do and wait for the last
446 * dereference.
447 *
448 * Can't we simply set sock->err?
449 *
450 * What the above comment does talk about? --ANK(980817)
451 */
452
Pavel Emelyanov9305cfa2007-11-10 22:06:01 -0800453 if (unix_tot_inflight)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900454 unix_gc(); /* Garbage collect fds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455}
456
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000457static void init_peercred(struct sock *sk)
458{
459 put_pid(sk->sk_peer_pid);
460 if (sk->sk_peer_cred)
461 put_cred(sk->sk_peer_cred);
462 sk->sk_peer_pid = get_pid(task_tgid(current));
463 sk->sk_peer_cred = get_current_cred();
464}
465
466static void copy_peercred(struct sock *sk, struct sock *peersk)
467{
468 put_pid(sk->sk_peer_pid);
469 if (sk->sk_peer_cred)
470 put_cred(sk->sk_peer_cred);
471 sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
472 sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
473}
474
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475static int unix_listen(struct socket *sock, int backlog)
476{
477 int err;
478 struct sock *sk = sock->sk;
479 struct unix_sock *u = unix_sk(sk);
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000480 struct pid *old_pid = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
482 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800483 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
484 goto out; /* Only stream/seqpacket sockets accept */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 err = -EINVAL;
486 if (!u->addr)
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800487 goto out; /* No listens on an unbound socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700488 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
490 goto out_unlock;
491 if (backlog > sk->sk_max_ack_backlog)
492 wake_up_interruptible_all(&u->peer_wait);
493 sk->sk_max_ack_backlog = backlog;
494 sk->sk_state = TCP_LISTEN;
495 /* set credentials so connect can copy them */
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000496 init_peercred(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 err = 0;
498
499out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -0700500 unix_state_unlock(sk);
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000501 put_pid(old_pid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502out:
503 return err;
504}
505
506static int unix_release(struct socket *);
507static int unix_bind(struct socket *, struct sockaddr *, int);
508static int unix_stream_connect(struct socket *, struct sockaddr *,
509 int addr_len, int flags);
510static int unix_socketpair(struct socket *, struct socket *);
511static int unix_accept(struct socket *, struct socket *, int);
512static int unix_getname(struct socket *, struct sockaddr *, int *, int);
513static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
Rainer Weikusatec0d2152008-06-27 19:34:18 -0700514static unsigned int unix_dgram_poll(struct file *, struct socket *,
515 poll_table *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516static int unix_ioctl(struct socket *, unsigned int, unsigned long);
517static int unix_shutdown(struct socket *, int);
518static int unix_stream_sendmsg(struct kiocb *, struct socket *,
519 struct msghdr *, size_t);
520static int unix_stream_recvmsg(struct kiocb *, struct socket *,
521 struct msghdr *, size_t, int);
522static int unix_dgram_sendmsg(struct kiocb *, struct socket *,
523 struct msghdr *, size_t);
524static int unix_dgram_recvmsg(struct kiocb *, struct socket *,
525 struct msghdr *, size_t, int);
526static int unix_dgram_connect(struct socket *, struct sockaddr *,
527 int, int);
528static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
529 struct msghdr *, size_t);
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +0000530static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *,
531 struct msghdr *, size_t, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000533static void unix_set_peek_off(struct sock *sk, int val)
534{
535 struct unix_sock *u = unix_sk(sk);
536
537 mutex_lock(&u->readlock);
538 sk->sk_peek_off = val;
539 mutex_unlock(&u->readlock);
540}
541
542
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800543static const struct proto_ops unix_stream_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 .family = PF_UNIX,
545 .owner = THIS_MODULE,
546 .release = unix_release,
547 .bind = unix_bind,
548 .connect = unix_stream_connect,
549 .socketpair = unix_socketpair,
550 .accept = unix_accept,
551 .getname = unix_getname,
552 .poll = unix_poll,
553 .ioctl = unix_ioctl,
554 .listen = unix_listen,
555 .shutdown = unix_shutdown,
556 .setsockopt = sock_no_setsockopt,
557 .getsockopt = sock_no_getsockopt,
558 .sendmsg = unix_stream_sendmsg,
559 .recvmsg = unix_stream_recvmsg,
560 .mmap = sock_no_mmap,
561 .sendpage = sock_no_sendpage,
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +0000562 .set_peek_off = unix_set_peek_off,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563};
564
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800565static const struct proto_ops unix_dgram_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 .family = PF_UNIX,
567 .owner = THIS_MODULE,
568 .release = unix_release,
569 .bind = unix_bind,
570 .connect = unix_dgram_connect,
571 .socketpair = unix_socketpair,
572 .accept = sock_no_accept,
573 .getname = unix_getname,
Rainer Weikusatec0d2152008-06-27 19:34:18 -0700574 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 .ioctl = unix_ioctl,
576 .listen = sock_no_listen,
577 .shutdown = unix_shutdown,
578 .setsockopt = sock_no_setsockopt,
579 .getsockopt = sock_no_getsockopt,
580 .sendmsg = unix_dgram_sendmsg,
581 .recvmsg = unix_dgram_recvmsg,
582 .mmap = sock_no_mmap,
583 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000584 .set_peek_off = unix_set_peek_off,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585};
586
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800587static const struct proto_ops unix_seqpacket_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 .family = PF_UNIX,
589 .owner = THIS_MODULE,
590 .release = unix_release,
591 .bind = unix_bind,
592 .connect = unix_stream_connect,
593 .socketpair = unix_socketpair,
594 .accept = unix_accept,
595 .getname = unix_getname,
Rainer Weikusatec0d2152008-06-27 19:34:18 -0700596 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 .ioctl = unix_ioctl,
598 .listen = unix_listen,
599 .shutdown = unix_shutdown,
600 .setsockopt = sock_no_setsockopt,
601 .getsockopt = sock_no_getsockopt,
602 .sendmsg = unix_seqpacket_sendmsg,
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +0000603 .recvmsg = unix_seqpacket_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 .mmap = sock_no_mmap,
605 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000606 .set_peek_off = unix_set_peek_off,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607};
608
609static struct proto unix_proto = {
Eric Dumazet248969a2008-11-17 00:00:30 -0800610 .name = "UNIX",
611 .owner = THIS_MODULE,
Eric Dumazet248969a2008-11-17 00:00:30 -0800612 .obj_size = sizeof(struct unix_sock),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613};
614
Ingo Molnara09785a2006-07-03 00:25:12 -0700615/*
616 * AF_UNIX sockets do not interact with hardware, hence they
617 * dont trigger interrupts - so it's safe for them to have
618 * bh-unsafe locking for their sk_receive_queue.lock. Split off
619 * this special lock-class by reinitializing the spinlock key:
620 */
621static struct lock_class_key af_unix_sk_receive_queue_lock_key;
622
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800623static struct sock *unix_create1(struct net *net, struct socket *sock)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624{
625 struct sock *sk = NULL;
626 struct unix_sock *u;
627
Eric Dumazet518de9b2010-10-26 14:22:44 -0700628 atomic_long_inc(&unix_nr_socks);
629 if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 goto out;
631
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700632 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 if (!sk)
634 goto out;
635
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800636 sock_init_data(sock, sk);
Ingo Molnara09785a2006-07-03 00:25:12 -0700637 lockdep_set_class(&sk->sk_receive_queue.lock,
638 &af_unix_sk_receive_queue_lock_key);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639
640 sk->sk_write_space = unix_write_space;
Denis V. Luneva0a53c82007-12-11 04:19:17 -0800641 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 sk->sk_destruct = unix_sock_destructor;
643 u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400644 u->path.dentry = NULL;
645 u->path.mnt = NULL;
Benjamin LaHaisefd19f322006-01-03 14:10:46 -0800646 spin_lock_init(&u->lock);
Al Viro516e0cc2008-07-26 00:39:17 -0400647 atomic_long_set(&u->inflight, 0);
Miklos Szeredi1fd05ba2007-07-11 14:22:39 -0700648 INIT_LIST_HEAD(&u->link);
Ingo Molnar57b47a52006-03-20 22:35:41 -0800649 mutex_init(&u->readlock); /* single task reading lock */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 init_waitqueue_head(&u->peer_wait);
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000651 unix_insert_socket(unix_sockets_unbound(sk), sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652out:
Pavel Emelyanov284b3272007-11-10 22:08:30 -0800653 if (sk == NULL)
Eric Dumazet518de9b2010-10-26 14:22:44 -0700654 atomic_long_dec(&unix_nr_socks);
Eric Dumazet920de802008-11-24 00:09:29 -0800655 else {
656 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800657 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
Eric Dumazet920de802008-11-24 00:09:29 -0800658 local_bh_enable();
659 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 return sk;
661}
662
Eric Paris3f378b62009-11-05 22:18:14 -0800663static int unix_create(struct net *net, struct socket *sock, int protocol,
664 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665{
666 if (protocol && protocol != PF_UNIX)
667 return -EPROTONOSUPPORT;
668
669 sock->state = SS_UNCONNECTED;
670
671 switch (sock->type) {
672 case SOCK_STREAM:
673 sock->ops = &unix_stream_ops;
674 break;
675 /*
676 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
677 * nothing uses it.
678 */
679 case SOCK_RAW:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700680 sock->type = SOCK_DGRAM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 case SOCK_DGRAM:
682 sock->ops = &unix_dgram_ops;
683 break;
684 case SOCK_SEQPACKET:
685 sock->ops = &unix_seqpacket_ops;
686 break;
687 default:
688 return -ESOCKTNOSUPPORT;
689 }
690
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700691 return unix_create1(net, sock) ? 0 : -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692}
693
694static int unix_release(struct socket *sock)
695{
696 struct sock *sk = sock->sk;
697
698 if (!sk)
699 return 0;
700
Paul Mooreded34e02013-03-25 03:18:33 +0000701 unix_release_sock(sk, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 sock->sk = NULL;
703
Paul Mooreded34e02013-03-25 03:18:33 +0000704 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705}
706
707static int unix_autobind(struct socket *sock)
708{
709 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900710 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 struct unix_sock *u = unix_sk(sk);
712 static u32 ordernum = 1;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800713 struct unix_address *addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 int err;
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000715 unsigned int retries = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716
Ingo Molnar57b47a52006-03-20 22:35:41 -0800717 mutex_lock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718
719 err = 0;
720 if (u->addr)
721 goto out;
722
723 err = -ENOMEM;
Panagiotis Issaris0da974f2006-07-21 14:51:30 -0700724 addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 if (!addr)
726 goto out;
727
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 addr->name->sun_family = AF_UNIX;
729 atomic_set(&addr->refcnt, 1);
730
731retry:
732 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
Joe Perches07f07572008-11-19 15:44:53 -0800733 addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734
David S. Millerfbe9cc42005-12-13 23:26:29 -0800735 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 ordernum = (ordernum+1)&0xFFFFF;
737
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800738 if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 addr->hash)) {
David S. Millerfbe9cc42005-12-13 23:26:29 -0800740 spin_unlock(&unix_table_lock);
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000741 /*
742 * __unix_find_socket_byname() may take long time if many names
743 * are already in use.
744 */
745 cond_resched();
746 /* Give up if all names seems to be in use. */
747 if (retries++ == 0xFFFFF) {
748 err = -ENOSPC;
749 kfree(addr);
750 goto out;
751 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 goto retry;
753 }
754 addr->hash ^= sk->sk_type;
755
756 __unix_remove_socket(sk);
757 u->addr = addr;
758 __unix_insert_socket(&unix_socket_table[addr->hash], sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800759 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 err = 0;
761
Ingo Molnar57b47a52006-03-20 22:35:41 -0800762out: mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 return err;
764}
765
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800766static struct sock *unix_find_other(struct net *net,
767 struct sockaddr_un *sunname, int len,
Eric Dumazet95c96172012-04-15 05:58:06 +0000768 int type, unsigned int hash, int *error)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769{
770 struct sock *u;
Al Viro421748e2008-08-02 01:04:36 -0400771 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 int err = 0;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900773
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 if (sunname->sun_path[0]) {
Al Viro421748e2008-08-02 01:04:36 -0400775 struct inode *inode;
776 err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 if (err)
778 goto fail;
Al Viro421748e2008-08-02 01:04:36 -0400779 inode = path.dentry->d_inode;
780 err = inode_permission(inode, MAY_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 if (err)
782 goto put_fail;
783
784 err = -ECONNREFUSED;
Al Viro421748e2008-08-02 01:04:36 -0400785 if (!S_ISSOCK(inode->i_mode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 goto put_fail;
Eric W. Biederman6616f782010-06-13 03:35:48 +0000787 u = unix_find_socket_byinode(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 if (!u)
789 goto put_fail;
790
791 if (u->sk_type == type)
Al Viro68ac1232012-03-15 08:21:57 -0400792 touch_atime(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793
Al Viro421748e2008-08-02 01:04:36 -0400794 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795
Jianjun Konge27dfce2008-11-01 21:38:31 -0700796 err = -EPROTOTYPE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 if (u->sk_type != type) {
798 sock_put(u);
799 goto fail;
800 }
801 } else {
802 err = -ECONNREFUSED;
Jianjun Konge27dfce2008-11-01 21:38:31 -0700803 u = unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 if (u) {
805 struct dentry *dentry;
Al Viro40ffe672012-03-14 21:54:32 -0400806 dentry = unix_sk(u)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 if (dentry)
Al Viro68ac1232012-03-15 08:21:57 -0400808 touch_atime(&unix_sk(u)->path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 } else
810 goto fail;
811 }
812 return u;
813
814put_fail:
Al Viro421748e2008-08-02 01:04:36 -0400815 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816fail:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700817 *error = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 return NULL;
819}
820
Al Virofaf02012012-07-20 02:37:29 +0400821static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
822{
823 struct dentry *dentry;
824 struct path path;
825 int err = 0;
826 /*
827 * Get the parent directory, calculate the hash for last
828 * component.
829 */
830 dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
831 err = PTR_ERR(dentry);
832 if (IS_ERR(dentry))
833 return err;
834
835 /*
836 * All right, let's create it.
837 */
838 err = security_path_mknod(&path, dentry, mode, 0);
839 if (!err) {
840 err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
841 if (!err) {
842 res->mnt = mntget(path.mnt);
843 res->dentry = dget(dentry);
844 }
845 }
846 done_path_create(&path, dentry);
847 return err;
848}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849
850static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
851{
852 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900853 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 struct unix_sock *u = unix_sk(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -0700855 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Al Virodae6ad82011-06-26 11:50:15 -0400856 char *sun_path = sunaddr->sun_path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +0000858 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 struct unix_address *addr;
860 struct hlist_head *list;
861
862 err = -EINVAL;
863 if (sunaddr->sun_family != AF_UNIX)
864 goto out;
865
Jianjun Konge27dfce2008-11-01 21:38:31 -0700866 if (addr_len == sizeof(short)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 err = unix_autobind(sock);
868 goto out;
869 }
870
871 err = unix_mkname(sunaddr, addr_len, &hash);
872 if (err < 0)
873 goto out;
874 addr_len = err;
875
Ingo Molnar57b47a52006-03-20 22:35:41 -0800876 mutex_lock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877
878 err = -EINVAL;
879 if (u->addr)
880 goto out_up;
881
882 err = -ENOMEM;
883 addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
884 if (!addr)
885 goto out_up;
886
887 memcpy(addr->name, sunaddr, addr_len);
888 addr->len = addr_len;
889 addr->hash = hash ^ sk->sk_type;
890 atomic_set(&addr->refcnt, 1);
891
Al Virodae6ad82011-06-26 11:50:15 -0400892 if (sun_path[0]) {
Al Virofaf02012012-07-20 02:37:29 +0400893 struct path path;
894 umode_t mode = S_IFSOCK |
Al Viroce3b0f82009-03-29 19:08:22 -0400895 (SOCK_INODE(sock)->i_mode & ~current_umask());
Al Virofaf02012012-07-20 02:37:29 +0400896 err = unix_mknod(sun_path, mode, &path);
897 if (err) {
898 if (err == -EEXIST)
899 err = -EADDRINUSE;
900 unix_release_addr(addr);
901 goto out_up;
902 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 addr->hash = UNIX_HASH_SIZE;
Al Virofaf02012012-07-20 02:37:29 +0400904 hash = path.dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1);
905 spin_lock(&unix_table_lock);
906 u->path = path;
907 list = &unix_socket_table[hash];
908 } else {
909 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 err = -EADDRINUSE;
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800911 if (__unix_find_socket_byname(net, sunaddr, addr_len,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912 sk->sk_type, hash)) {
913 unix_release_addr(addr);
914 goto out_unlock;
915 }
916
917 list = &unix_socket_table[addr->hash];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 }
919
920 err = 0;
921 __unix_remove_socket(sk);
922 u->addr = addr;
923 __unix_insert_socket(list, sk);
924
925out_unlock:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800926 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927out_up:
Ingo Molnar57b47a52006-03-20 22:35:41 -0800928 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929out:
930 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931}
932
David S. Miller278a3de2007-05-31 15:19:20 -0700933static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
934{
935 if (unlikely(sk1 == sk2) || !sk2) {
936 unix_state_lock(sk1);
937 return;
938 }
939 if (sk1 < sk2) {
940 unix_state_lock(sk1);
941 unix_state_lock_nested(sk2);
942 } else {
943 unix_state_lock(sk2);
944 unix_state_lock_nested(sk1);
945 }
946}
947
948static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
949{
950 if (unlikely(sk1 == sk2) || !sk2) {
951 unix_state_unlock(sk1);
952 return;
953 }
954 unix_state_unlock(sk1);
955 unix_state_unlock(sk2);
956}
957
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
959 int alen, int flags)
960{
961 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900962 struct net *net = sock_net(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -0700963 struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964 struct sock *other;
Eric Dumazet95c96172012-04-15 05:58:06 +0000965 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 int err;
967
968 if (addr->sa_family != AF_UNSPEC) {
969 err = unix_mkname(sunaddr, alen, &hash);
970 if (err < 0)
971 goto out;
972 alen = err;
973
974 if (test_bit(SOCK_PASSCRED, &sock->flags) &&
975 !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
976 goto out;
977
David S. Miller278a3de2007-05-31 15:19:20 -0700978restart:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700979 other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980 if (!other)
981 goto out;
982
David S. Miller278a3de2007-05-31 15:19:20 -0700983 unix_state_double_lock(sk, other);
984
985 /* Apparently VFS overslept socket death. Retry. */
986 if (sock_flag(other, SOCK_DEAD)) {
987 unix_state_double_unlock(sk, other);
988 sock_put(other);
989 goto restart;
990 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991
992 err = -EPERM;
993 if (!unix_may_send(sk, other))
994 goto out_unlock;
995
996 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
997 if (err)
998 goto out_unlock;
999
1000 } else {
1001 /*
1002 * 1003.1g breaking connected state with AF_UNSPEC
1003 */
1004 other = NULL;
David S. Miller278a3de2007-05-31 15:19:20 -07001005 unix_state_double_lock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 }
1007
1008 /*
1009 * If it was connected, reconnect.
1010 */
1011 if (unix_peer(sk)) {
1012 struct sock *old_peer = unix_peer(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001013 unix_peer(sk) = other;
David S. Miller278a3de2007-05-31 15:19:20 -07001014 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
1016 if (other != old_peer)
1017 unix_dgram_disconnected(sk, old_peer);
1018 sock_put(old_peer);
1019 } else {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001020 unix_peer(sk) = other;
David S. Miller278a3de2007-05-31 15:19:20 -07001021 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 }
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001023 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024
1025out_unlock:
David S. Miller278a3de2007-05-31 15:19:20 -07001026 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 sock_put(other);
1028out:
1029 return err;
1030}
1031
1032static long unix_wait_for_peer(struct sock *other, long timeo)
1033{
1034 struct unix_sock *u = unix_sk(other);
1035 int sched;
1036 DEFINE_WAIT(wait);
1037
1038 prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
1039
1040 sched = !sock_flag(other, SOCK_DEAD) &&
1041 !(other->sk_shutdown & RCV_SHUTDOWN) &&
Rainer Weikusat3c734192008-06-17 22:28:05 -07001042 unix_recvq_full(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043
David S. Miller1c92b4e2007-05-31 13:24:26 -07001044 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045
1046 if (sched)
1047 timeo = schedule_timeout(timeo);
1048
1049 finish_wait(&u->peer_wait, &wait);
1050 return timeo;
1051}
1052
1053static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
1054 int addr_len, int flags)
1055{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001056 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001058 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 struct unix_sock *u = unix_sk(sk), *newu, *otheru;
1060 struct sock *newsk = NULL;
1061 struct sock *other = NULL;
1062 struct sk_buff *skb = NULL;
Eric Dumazet95c96172012-04-15 05:58:06 +00001063 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 int st;
1065 int err;
1066 long timeo;
1067
1068 err = unix_mkname(sunaddr, addr_len, &hash);
1069 if (err < 0)
1070 goto out;
1071 addr_len = err;
1072
Joe Perchesf64f9e72009-11-29 16:55:45 -08001073 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr &&
1074 (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 goto out;
1076
1077 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
1078
1079 /* First of all allocate resources.
1080 If we will make it after state is locked,
1081 we will have to recheck all again in any case.
1082 */
1083
1084 err = -ENOMEM;
1085
1086 /* create new sock for complete connection */
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001087 newsk = unix_create1(sock_net(sk), NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 if (newsk == NULL)
1089 goto out;
1090
1091 /* Allocate skb for sending to listening sock */
1092 skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL);
1093 if (skb == NULL)
1094 goto out;
1095
1096restart:
1097 /* Find listening sock. */
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001098 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 if (!other)
1100 goto out;
1101
1102 /* Latch state of peer */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001103 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104
1105 /* Apparently VFS overslept socket death. Retry. */
1106 if (sock_flag(other, SOCK_DEAD)) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001107 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 sock_put(other);
1109 goto restart;
1110 }
1111
1112 err = -ECONNREFUSED;
1113 if (other->sk_state != TCP_LISTEN)
1114 goto out_unlock;
Tomoki Sekiyama77238f22009-10-18 23:17:37 -07001115 if (other->sk_shutdown & RCV_SHUTDOWN)
1116 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
Rainer Weikusat3c734192008-06-17 22:28:05 -07001118 if (unix_recvq_full(other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 err = -EAGAIN;
1120 if (!timeo)
1121 goto out_unlock;
1122
1123 timeo = unix_wait_for_peer(other, timeo);
1124
1125 err = sock_intr_errno(timeo);
1126 if (signal_pending(current))
1127 goto out;
1128 sock_put(other);
1129 goto restart;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001130 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131
1132 /* Latch our state.
1133
Daniel Balutae5537bf2011-03-14 15:25:33 -07001134 It is tricky place. We need to grab our state lock and cannot
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 drop lock on peer. It is dangerous because deadlock is
1136 possible. Connect to self case and simultaneous
1137 attempt to connect are eliminated by checking socket
1138 state. other is TCP_LISTEN, if sk is TCP_LISTEN we
1139 check this before attempt to grab lock.
1140
1141 Well, and we have to recheck the state after socket locked.
1142 */
1143 st = sk->sk_state;
1144
1145 switch (st) {
1146 case TCP_CLOSE:
1147 /* This is ok... continue with connect */
1148 break;
1149 case TCP_ESTABLISHED:
1150 /* Socket is already connected */
1151 err = -EISCONN;
1152 goto out_unlock;
1153 default:
1154 err = -EINVAL;
1155 goto out_unlock;
1156 }
1157
David S. Miller1c92b4e2007-05-31 13:24:26 -07001158 unix_state_lock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159
1160 if (sk->sk_state != st) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001161 unix_state_unlock(sk);
1162 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 sock_put(other);
1164 goto restart;
1165 }
1166
David S. Miller3610cda2011-01-05 15:38:53 -08001167 err = security_unix_stream_connect(sk, other, newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 if (err) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001169 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 goto out_unlock;
1171 }
1172
1173 /* The way is open! Fastly set all the necessary fields... */
1174
1175 sock_hold(sk);
1176 unix_peer(newsk) = sk;
1177 newsk->sk_state = TCP_ESTABLISHED;
1178 newsk->sk_type = sk->sk_type;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001179 init_peercred(newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 newu = unix_sk(newsk);
Eric Dumazeteaefd112011-02-18 03:26:36 +00001181 RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 otheru = unix_sk(other);
1183
1184 /* copy address information from listening to new sock*/
1185 if (otheru->addr) {
1186 atomic_inc(&otheru->addr->refcnt);
1187 newu->addr = otheru->addr;
1188 }
Al Viro40ffe672012-03-14 21:54:32 -04001189 if (otheru->path.dentry) {
1190 path_get(&otheru->path);
1191 newu->path = otheru->path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 }
1193
1194 /* Set credentials */
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001195 copy_peercred(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 sock->state = SS_CONNECTED;
1198 sk->sk_state = TCP_ESTABLISHED;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001199 sock_hold(newsk);
1200
1201 smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */
1202 unix_peer(sk) = newsk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
David S. Miller1c92b4e2007-05-31 13:24:26 -07001204 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205
1206 /* take ten and and send info to listening sock */
1207 spin_lock(&other->sk_receive_queue.lock);
1208 __skb_queue_tail(&other->sk_receive_queue, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001210 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 other->sk_data_ready(other, 0);
1212 sock_put(other);
1213 return 0;
1214
1215out_unlock:
1216 if (other)
David S. Miller1c92b4e2007-05-31 13:24:26 -07001217 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
1219out:
Wei Yongjun40d44442009-02-25 00:32:45 +00001220 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 if (newsk)
1222 unix_release_sock(newsk, 0);
1223 if (other)
1224 sock_put(other);
1225 return err;
1226}
1227
1228static int unix_socketpair(struct socket *socka, struct socket *sockb)
1229{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001230 struct sock *ska = socka->sk, *skb = sockb->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231
1232 /* Join our sockets back to back */
1233 sock_hold(ska);
1234 sock_hold(skb);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001235 unix_peer(ska) = skb;
1236 unix_peer(skb) = ska;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001237 init_peercred(ska);
1238 init_peercred(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
1240 if (ska->sk_type != SOCK_DGRAM) {
1241 ska->sk_state = TCP_ESTABLISHED;
1242 skb->sk_state = TCP_ESTABLISHED;
1243 socka->state = SS_CONNECTED;
1244 sockb->state = SS_CONNECTED;
1245 }
1246 return 0;
1247}
1248
1249static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
1250{
1251 struct sock *sk = sock->sk;
1252 struct sock *tsk;
1253 struct sk_buff *skb;
1254 int err;
1255
1256 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001257 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258 goto out;
1259
1260 err = -EINVAL;
1261 if (sk->sk_state != TCP_LISTEN)
1262 goto out;
1263
1264 /* If socket state is TCP_LISTEN it cannot change (for now...),
1265 * so that no locks are necessary.
1266 */
1267
1268 skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
1269 if (!skb) {
1270 /* This means receive shutdown. */
1271 if (err == 0)
1272 err = -EINVAL;
1273 goto out;
1274 }
1275
1276 tsk = skb->sk;
1277 skb_free_datagram(sk, skb);
1278 wake_up_interruptible(&unix_sk(sk)->peer_wait);
1279
1280 /* attach accepted sock to socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001281 unix_state_lock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 newsock->state = SS_CONNECTED;
1283 sock_graft(tsk, newsock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001284 unix_state_unlock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 return 0;
1286
1287out:
1288 return err;
1289}
1290
1291
1292static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
1293{
1294 struct sock *sk = sock->sk;
1295 struct unix_sock *u;
Cyrill Gorcunov13cfa972009-11-08 05:51:19 +00001296 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 int err = 0;
1298
1299 if (peer) {
1300 sk = unix_peer_get(sk);
1301
1302 err = -ENOTCONN;
1303 if (!sk)
1304 goto out;
1305 err = 0;
1306 } else {
1307 sock_hold(sk);
1308 }
1309
1310 u = unix_sk(sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001311 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 if (!u->addr) {
1313 sunaddr->sun_family = AF_UNIX;
1314 sunaddr->sun_path[0] = 0;
1315 *uaddr_len = sizeof(short);
1316 } else {
1317 struct unix_address *addr = u->addr;
1318
1319 *uaddr_len = addr->len;
1320 memcpy(sunaddr, addr->name, *uaddr_len);
1321 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07001322 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323 sock_put(sk);
1324out:
1325 return err;
1326}
1327
1328static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1329{
1330 int i;
1331
1332 scm->fp = UNIXCB(skb).fp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 UNIXCB(skb).fp = NULL;
1334
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001335 for (i = scm->fp->count-1; i >= 0; i--)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 unix_notinflight(scm->fp->fp[i]);
1337}
1338
Eric W. Biederman7361c362010-06-13 03:34:33 +00001339static void unix_destruct_scm(struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340{
1341 struct scm_cookie scm;
1342 memset(&scm, 0, sizeof(scm));
Eric W. Biederman7361c362010-06-13 03:34:33 +00001343 scm.pid = UNIXCB(skb).pid;
Eric W. Biederman7361c362010-06-13 03:34:33 +00001344 if (UNIXCB(skb).fp)
1345 unix_detach_fds(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346
1347 /* Alas, it calls VFS */
1348 /* So fscking what? fput() had been SMP-safe since the last Summer */
1349 scm_destroy(&scm);
1350 sock_wfree(skb);
1351}
1352
Eric Dumazet25888e32010-11-25 04:11:39 +00001353#define MAX_RECURSION_LEVEL 4
1354
Miklos Szeredi62093442008-11-09 15:23:57 +01001355static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356{
1357 int i;
Eric Dumazet25888e32010-11-25 04:11:39 +00001358 unsigned char max_level = 0;
1359 int unix_sock_count = 0;
1360
1361 for (i = scm->fp->count - 1; i >= 0; i--) {
1362 struct sock *sk = unix_get_socket(scm->fp->fp[i]);
1363
1364 if (sk) {
1365 unix_sock_count++;
1366 max_level = max(max_level,
1367 unix_sk(sk)->recursion_level);
1368 }
1369 }
1370 if (unlikely(max_level > MAX_RECURSION_LEVEL))
1371 return -ETOOMANYREFS;
Miklos Szeredi62093442008-11-09 15:23:57 +01001372
1373 /*
1374 * Need to duplicate file references for the sake of garbage
1375 * collection. Otherwise a socket in the fps might become a
1376 * candidate for GC while the skb is not yet queued.
1377 */
1378 UNIXCB(skb).fp = scm_fp_dup(scm->fp);
1379 if (!UNIXCB(skb).fp)
1380 return -ENOMEM;
1381
Eric Dumazet25888e32010-11-25 04:11:39 +00001382 if (unix_sock_count) {
1383 for (i = scm->fp->count - 1; i >= 0; i--)
1384 unix_inflight(scm->fp->fp[i]);
1385 }
1386 return max_level;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387}
1388
David S. Millerf78a5fd2011-09-16 19:34:00 -04001389static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001390{
1391 int err = 0;
Eric Dumazet16e57262011-09-19 05:52:27 +00001392
David S. Millerf78a5fd2011-09-16 19:34:00 -04001393 UNIXCB(skb).pid = get_pid(scm->pid);
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001394 UNIXCB(skb).uid = scm->creds.uid;
1395 UNIXCB(skb).gid = scm->creds.gid;
Eric W. Biederman7361c362010-06-13 03:34:33 +00001396 UNIXCB(skb).fp = NULL;
1397 if (scm->fp && send_fds)
1398 err = unix_attach_fds(scm, skb);
1399
1400 skb->destructor = unix_destruct_scm;
1401 return err;
1402}
1403
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404/*
Eric Dumazet16e57262011-09-19 05:52:27 +00001405 * Some apps rely on write() giving SCM_CREDENTIALS
1406 * We include credentials if source or destination socket
1407 * asserted SOCK_PASSCRED.
1408 */
1409static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1410 const struct sock *other)
1411{
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001412 if (UNIXCB(skb).pid)
Eric Dumazet16e57262011-09-19 05:52:27 +00001413 return;
1414 if (test_bit(SOCK_PASSCRED, &sock->flags) ||
Eric W. Biederman25da0e32013-04-03 16:13:35 +00001415 !other->sk_socket ||
1416 test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
Eric Dumazet16e57262011-09-19 05:52:27 +00001417 UNIXCB(skb).pid = get_pid(task_tgid(current));
David S. Miller6e0895c2013-04-22 20:32:51 -04001418 current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
Eric Dumazet16e57262011-09-19 05:52:27 +00001419 }
1420}
1421
1422/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 * Send AF_UNIX data.
1424 */
1425
1426static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1427 struct msghdr *msg, size_t len)
1428{
1429 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1430 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001431 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 struct unix_sock *u = unix_sk(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001433 struct sockaddr_un *sunaddr = msg->msg_name;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 struct sock *other = NULL;
1435 int namelen = 0; /* fake GCC */
1436 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001437 unsigned int hash;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001438 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 long timeo;
1440 struct scm_cookie tmp_scm;
Eric Dumazet25888e32010-11-25 04:11:39 +00001441 int max_level;
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001442 int data_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443
1444 if (NULL == siocb->scm)
1445 siocb->scm = &tmp_scm;
dann frazier5f23b732008-11-26 15:32:27 -08001446 wait_for_unix_gc();
Eric Dumazete0e3cea2012-08-21 06:21:17 +00001447 err = scm_send(sock, msg, siocb->scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448 if (err < 0)
1449 return err;
1450
1451 err = -EOPNOTSUPP;
1452 if (msg->msg_flags&MSG_OOB)
1453 goto out;
1454
1455 if (msg->msg_namelen) {
1456 err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
1457 if (err < 0)
1458 goto out;
1459 namelen = err;
1460 } else {
1461 sunaddr = NULL;
1462 err = -ENOTCONN;
1463 other = unix_peer_get(sk);
1464 if (!other)
1465 goto out;
1466 }
1467
Joe Perchesf64f9e72009-11-29 16:55:45 -08001468 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr
1469 && (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 goto out;
1471
1472 err = -EMSGSIZE;
1473 if (len > sk->sk_sndbuf - 32)
1474 goto out;
1475
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001476 if (len > SKB_MAX_ALLOC)
1477 data_len = min_t(size_t,
1478 len - SKB_MAX_ALLOC,
1479 MAX_SKB_FRAGS * PAGE_SIZE);
1480
1481 skb = sock_alloc_send_pskb(sk, len - data_len, data_len,
1482 msg->msg_flags & MSG_DONTWAIT, &err);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001483 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 goto out;
1485
David S. Millerf78a5fd2011-09-16 19:34:00 -04001486 err = unix_scm_to_skb(siocb->scm, skb, true);
Eric Dumazet25888e32010-11-25 04:11:39 +00001487 if (err < 0)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001488 goto out_free;
Eric Dumazet25888e32010-11-25 04:11:39 +00001489 max_level = err + 1;
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07001490 unix_get_secdata(siocb->scm, skb);
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001491
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001492 skb_put(skb, len - data_len);
1493 skb->data_len = data_len;
1494 skb->len = len;
1495 err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov, 0, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 if (err)
1497 goto out_free;
1498
1499 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1500
1501restart:
1502 if (!other) {
1503 err = -ECONNRESET;
1504 if (sunaddr == NULL)
1505 goto out_free;
1506
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001507 other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 hash, &err);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001509 if (other == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 goto out_free;
1511 }
1512
Alban Crequyd6ae3ba2011-01-18 06:39:15 +00001513 if (sk_filter(other, skb) < 0) {
1514 /* Toss the packet but do not return any error to the sender */
1515 err = len;
1516 goto out_free;
1517 }
1518
David S. Miller1c92b4e2007-05-31 13:24:26 -07001519 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 err = -EPERM;
1521 if (!unix_may_send(sk, other))
1522 goto out_unlock;
1523
1524 if (sock_flag(other, SOCK_DEAD)) {
1525 /*
1526 * Check with 1003.1g - what should
1527 * datagram error
1528 */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001529 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 sock_put(other);
1531
1532 err = 0;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001533 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 if (unix_peer(sk) == other) {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001535 unix_peer(sk) = NULL;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001536 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537
1538 unix_dgram_disconnected(sk, other);
1539 sock_put(other);
1540 err = -ECONNREFUSED;
1541 } else {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001542 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 }
1544
1545 other = NULL;
1546 if (err)
1547 goto out_free;
1548 goto restart;
1549 }
1550
1551 err = -EPIPE;
1552 if (other->sk_shutdown & RCV_SHUTDOWN)
1553 goto out_unlock;
1554
1555 if (sk->sk_type != SOCK_SEQPACKET) {
1556 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1557 if (err)
1558 goto out_unlock;
1559 }
1560
Rainer Weikusat3c734192008-06-17 22:28:05 -07001561 if (unix_peer(other) != sk && unix_recvq_full(other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 if (!timeo) {
1563 err = -EAGAIN;
1564 goto out_unlock;
1565 }
1566
1567 timeo = unix_wait_for_peer(other, timeo);
1568
1569 err = sock_intr_errno(timeo);
1570 if (signal_pending(current))
1571 goto out_free;
1572
1573 goto restart;
1574 }
1575
Alban Crequy3f661162010-10-04 08:48:28 +00001576 if (sock_flag(other, SOCK_RCVTSTAMP))
1577 __net_timestamp(skb);
Eric Dumazet16e57262011-09-19 05:52:27 +00001578 maybe_add_creds(skb, sock, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 skb_queue_tail(&other->sk_receive_queue, skb);
Eric Dumazet25888e32010-11-25 04:11:39 +00001580 if (max_level > unix_sk(other)->recursion_level)
1581 unix_sk(other)->recursion_level = max_level;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001582 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 other->sk_data_ready(other, len);
1584 sock_put(other);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001585 scm_destroy(siocb->scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 return len;
1587
1588out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -07001589 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590out_free:
1591 kfree_skb(skb);
1592out:
1593 if (other)
1594 sock_put(other);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001595 scm_destroy(siocb->scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 return err;
1597}
1598
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001599
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1601 struct msghdr *msg, size_t len)
1602{
1603 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1604 struct sock *sk = sock->sk;
1605 struct sock *other = NULL;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001606 int err, size;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001607 struct sk_buff *skb;
Jianjun Konge27dfce2008-11-01 21:38:31 -07001608 int sent = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 struct scm_cookie tmp_scm;
Miklos Szeredi8ba69ba2009-09-11 11:31:45 -07001610 bool fds_sent = false;
Eric Dumazet25888e32010-11-25 04:11:39 +00001611 int max_level;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612
1613 if (NULL == siocb->scm)
1614 siocb->scm = &tmp_scm;
dann frazier5f23b732008-11-26 15:32:27 -08001615 wait_for_unix_gc();
Eric Dumazete0e3cea2012-08-21 06:21:17 +00001616 err = scm_send(sock, msg, siocb->scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 if (err < 0)
1618 return err;
1619
1620 err = -EOPNOTSUPP;
1621 if (msg->msg_flags&MSG_OOB)
1622 goto out_err;
1623
1624 if (msg->msg_namelen) {
1625 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
1626 goto out_err;
1627 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628 err = -ENOTCONN;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001629 other = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 if (!other)
1631 goto out_err;
1632 }
1633
1634 if (sk->sk_shutdown & SEND_SHUTDOWN)
1635 goto pipe_err;
1636
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001637 while (sent < len) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 /*
Benjamin LaHaisee9df7d7f2006-03-20 21:29:05 -08001639 * Optimisation for the fact that under 0.01% of X
1640 * messages typically need breaking up.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 */
1642
Benjamin LaHaisee9df7d7f2006-03-20 21:29:05 -08001643 size = len-sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644
1645 /* Keep two messages in the pipe so it schedules better */
Benjamin LaHaisee9df7d7f2006-03-20 21:29:05 -08001646 if (size > ((sk->sk_sndbuf >> 1) - 64))
1647 size = (sk->sk_sndbuf >> 1) - 64;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648
1649 if (size > SKB_MAX_ALLOC)
1650 size = SKB_MAX_ALLOC;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001651
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652 /*
1653 * Grab a buffer
1654 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001655
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001656 skb = sock_alloc_send_skb(sk, size, msg->msg_flags&MSG_DONTWAIT,
1657 &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658
Jianjun Konge27dfce2008-11-01 21:38:31 -07001659 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 goto out_err;
1661
1662 /*
1663 * If you pass two values to the sock_alloc_send_skb
1664 * it tries to grab the large buffer with GFP_NOFS
1665 * (which can fail easily), and if it fails grab the
1666 * fallback size buffer which is under a page and will
1667 * succeed. [Alan]
1668 */
1669 size = min_t(int, size, skb_tailroom(skb));
1670
Eric W. Biederman7361c362010-06-13 03:34:33 +00001671
David S. Millerf78a5fd2011-09-16 19:34:00 -04001672 /* Only send the fds in the first buffer */
1673 err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
Eric Dumazet25888e32010-11-25 04:11:39 +00001674 if (err < 0) {
Eric W. Biederman7361c362010-06-13 03:34:33 +00001675 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001676 goto out_err;
Miklos Szeredi62093442008-11-09 15:23:57 +01001677 }
Eric Dumazet25888e32010-11-25 04:11:39 +00001678 max_level = err + 1;
Eric W. Biederman7361c362010-06-13 03:34:33 +00001679 fds_sent = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001681 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
1682 if (err) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001684 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 }
1686
David S. Miller1c92b4e2007-05-31 13:24:26 -07001687 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
1689 if (sock_flag(other, SOCK_DEAD) ||
1690 (other->sk_shutdown & RCV_SHUTDOWN))
1691 goto pipe_err_free;
1692
Eric Dumazet16e57262011-09-19 05:52:27 +00001693 maybe_add_creds(skb, sock, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 skb_queue_tail(&other->sk_receive_queue, skb);
Eric Dumazet25888e32010-11-25 04:11:39 +00001695 if (max_level > unix_sk(other)->recursion_level)
1696 unix_sk(other)->recursion_level = max_level;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001697 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 other->sk_data_ready(other, size);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001699 sent += size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
David S. Millerf78a5fd2011-09-16 19:34:00 -04001702 scm_destroy(siocb->scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 siocb->scm = NULL;
1704
1705 return sent;
1706
1707pipe_err_free:
David S. Miller1c92b4e2007-05-31 13:24:26 -07001708 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 kfree_skb(skb);
1710pipe_err:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001711 if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
1712 send_sig(SIGPIPE, current, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 err = -EPIPE;
1714out_err:
David S. Millerf78a5fd2011-09-16 19:34:00 -04001715 scm_destroy(siocb->scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 siocb->scm = NULL;
1717 return sent ? : err;
1718}
1719
1720static int unix_seqpacket_sendmsg(struct kiocb *kiocb, struct socket *sock,
1721 struct msghdr *msg, size_t len)
1722{
1723 int err;
1724 struct sock *sk = sock->sk;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001725
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 err = sock_error(sk);
1727 if (err)
1728 return err;
1729
1730 if (sk->sk_state != TCP_ESTABLISHED)
1731 return -ENOTCONN;
1732
1733 if (msg->msg_namelen)
1734 msg->msg_namelen = 0;
1735
1736 return unix_dgram_sendmsg(kiocb, sock, msg, len);
1737}
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001738
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00001739static int unix_seqpacket_recvmsg(struct kiocb *iocb, struct socket *sock,
1740 struct msghdr *msg, size_t size,
1741 int flags)
1742{
1743 struct sock *sk = sock->sk;
1744
1745 if (sk->sk_state != TCP_ESTABLISHED)
1746 return -ENOTCONN;
1747
1748 return unix_dgram_recvmsg(iocb, sock, msg, size, flags);
1749}
1750
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
1752{
1753 struct unix_sock *u = unix_sk(sk);
1754
1755 msg->msg_namelen = 0;
1756 if (u->addr) {
1757 msg->msg_namelen = u->addr->len;
1758 memcpy(msg->msg_name, u->addr->name, u->addr->len);
1759 }
1760}
1761
1762static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1763 struct msghdr *msg, size_t size,
1764 int flags)
1765{
1766 struct sock_iocb *siocb = kiocb_to_siocb(iocb);
1767 struct scm_cookie tmp_scm;
1768 struct sock *sk = sock->sk;
1769 struct unix_sock *u = unix_sk(sk);
1770 int noblock = flags & MSG_DONTWAIT;
1771 struct sk_buff *skb;
1772 int err;
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00001773 int peeked, skip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774
1775 err = -EOPNOTSUPP;
1776 if (flags&MSG_OOB)
1777 goto out;
1778
1779 msg->msg_namelen = 0;
1780
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00001781 err = mutex_lock_interruptible(&u->readlock);
1782 if (err) {
1783 err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
1784 goto out;
1785 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00001787 skip = sk_peek_offset(sk, flags);
1788
1789 skb = __skb_recv_datagram(sk, flags, &peeked, &skip, &err);
Florian Zumbiehl0a112252007-11-29 23:19:23 +11001790 if (!skb) {
1791 unix_state_lock(sk);
1792 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
1793 if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
1794 (sk->sk_shutdown & RCV_SHUTDOWN))
1795 err = 0;
1796 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 goto out_unlock;
Florian Zumbiehl0a112252007-11-29 23:19:23 +11001798 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799
Eric Dumazet67426b72010-10-29 20:44:44 +00001800 wake_up_interruptible_sync_poll(&u->peer_wait,
1801 POLLOUT | POLLWRNORM | POLLWRBAND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802
1803 if (msg->msg_name)
1804 unix_copy_addr(msg, skb->sk);
1805
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00001806 if (size > skb->len - skip)
1807 size = skb->len - skip;
1808 else if (size < skb->len - skip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 msg->msg_flags |= MSG_TRUNC;
1810
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00001811 err = skb_copy_datagram_iovec(skb, skip, msg->msg_iov, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 if (err)
1813 goto out_free;
1814
Alban Crequy3f661162010-10-04 08:48:28 +00001815 if (sock_flag(sk, SOCK_RCVTSTAMP))
1816 __sock_recv_timestamp(msg, sk, skb);
1817
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 if (!siocb->scm) {
1819 siocb->scm = &tmp_scm;
1820 memset(&tmp_scm, 0, sizeof(tmp_scm));
1821 }
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001822 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001823 unix_set_secdata(siocb->scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001825 if (!(flags & MSG_PEEK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 if (UNIXCB(skb).fp)
1827 unix_detach_fds(siocb->scm, skb);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00001828
1829 sk_peek_offset_bwd(sk, skb->len);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001830 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 /* It is questionable: on PEEK we could:
1832 - do not return fds - good, but too simple 8)
1833 - return fds, and do not return them on read (old strategy,
1834 apparently wrong)
1835 - clone fds (I chose it for now, it is the most universal
1836 solution)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001837
1838 POSIX 1003.1g does not actually define this clearly
1839 at all. POSIX 1003.1g doesn't define a lot of things
1840 clearly however!
1841
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 */
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00001843
1844 sk_peek_offset_fwd(sk, size);
1845
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 if (UNIXCB(skb).fp)
1847 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
1848 }
Eric Dumazet9f6f9af2012-02-21 23:24:55 +00001849 err = (flags & MSG_TRUNC) ? skb->len - skip : size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850
1851 scm_recv(sock, msg, siocb->scm, flags);
1852
1853out_free:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001854 skb_free_datagram(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855out_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001856 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857out:
1858 return err;
1859}
1860
1861/*
Benjamin Poirier79f632c2013-04-29 11:42:14 +00001862 * Sleep until more data has arrived. But check for races..
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 */
Benjamin Poirier79f632c2013-04-29 11:42:14 +00001864static long unix_stream_data_wait(struct sock *sk, long timeo,
1865 struct sk_buff *last)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866{
1867 DEFINE_WAIT(wait);
1868
David S. Miller1c92b4e2007-05-31 13:24:26 -07001869 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870
1871 for (;;) {
Eric Dumazetaa395142010-04-20 13:03:51 +00001872 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
Benjamin Poirier79f632c2013-04-29 11:42:14 +00001874 if (skb_peek_tail(&sk->sk_receive_queue) != last ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 sk->sk_err ||
1876 (sk->sk_shutdown & RCV_SHUTDOWN) ||
1877 signal_pending(current) ||
1878 !timeo)
1879 break;
1880
1881 set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001882 unix_state_unlock(sk);
Colin Cross2b15af62013-05-06 23:50:21 +00001883 timeo = freezable_schedule_timeout(timeo);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001884 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
1886 }
1887
Eric Dumazetaa395142010-04-20 13:03:51 +00001888 finish_wait(sk_sleep(sk), &wait);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001889 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 return timeo;
1891}
1892
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1894 struct msghdr *msg, size_t size,
1895 int flags)
1896{
1897 struct sock_iocb *siocb = kiocb_to_siocb(iocb);
1898 struct scm_cookie tmp_scm;
1899 struct sock *sk = sock->sk;
1900 struct unix_sock *u = unix_sk(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001901 struct sockaddr_un *sunaddr = msg->msg_name;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 int copied = 0;
1903 int check_creds = 0;
1904 int target;
1905 int err = 0;
1906 long timeo;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00001907 int skip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908
1909 err = -EINVAL;
1910 if (sk->sk_state != TCP_ESTABLISHED)
1911 goto out;
1912
1913 err = -EOPNOTSUPP;
1914 if (flags&MSG_OOB)
1915 goto out;
1916
1917 target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
1918 timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
1919
1920 msg->msg_namelen = 0;
1921
1922 /* Lock the socket to prevent queue disordering
1923 * while sleeps in memcpy_tomsg
1924 */
1925
1926 if (!siocb->scm) {
1927 siocb->scm = &tmp_scm;
1928 memset(&tmp_scm, 0, sizeof(tmp_scm));
1929 }
1930
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00001931 err = mutex_lock_interruptible(&u->readlock);
1932 if (err) {
1933 err = sock_intr_errno(timeo);
1934 goto out;
1935 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001937 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 int chunk;
Benjamin Poirier79f632c2013-04-29 11:42:14 +00001939 struct sk_buff *skb, *last;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001941 unix_state_lock(sk);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00001942 last = skb = skb_peek(&sk->sk_receive_queue);
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00001943again:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001944 if (skb == NULL) {
Eric Dumazet25888e32010-11-25 04:11:39 +00001945 unix_sk(sk)->recursion_level = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 if (copied >= target)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001947 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948
1949 /*
1950 * POSIX 1003.1g mandates this order.
1951 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001952
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001953 err = sock_error(sk);
1954 if (err)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001955 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 if (sk->sk_shutdown & RCV_SHUTDOWN)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001957 goto unlock;
1958
1959 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 err = -EAGAIN;
1961 if (!timeo)
1962 break;
Ingo Molnar57b47a52006-03-20 22:35:41 -08001963 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964
Benjamin Poirier79f632c2013-04-29 11:42:14 +00001965 timeo = unix_stream_data_wait(sk, timeo, last);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00001967 if (signal_pending(current)
1968 || mutex_lock_interruptible(&u->readlock)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 err = sock_intr_errno(timeo);
1970 goto out;
1971 }
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00001972
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973 continue;
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001974 unlock:
1975 unix_state_unlock(sk);
1976 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 }
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00001978
Benjamin Poirier79f632c2013-04-29 11:42:14 +00001979 skip = sk_peek_offset(sk, flags);
1980 while (skip >= skb->len) {
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00001981 skip -= skb->len;
Benjamin Poirier79f632c2013-04-29 11:42:14 +00001982 last = skb;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00001983 skb = skb_peek_next(skb, &sk->sk_receive_queue);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00001984 if (!skb)
1985 goto again;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00001986 }
1987
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001988 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989
1990 if (check_creds) {
1991 /* Never glue messages from different writers */
Eric W. Biederman7361c362010-06-13 03:34:33 +00001992 if ((UNIXCB(skb).pid != siocb->scm->pid) ||
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001993 !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) ||
1994 !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995 break;
Eric W. Biederman0e82e7f6d2013-04-03 16:14:47 +00001996 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 /* Copy credentials */
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001998 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999 check_creds = 1;
2000 }
2001
2002 /* Copy address just once */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002003 if (sunaddr) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 unix_copy_addr(msg, skb->sk);
2005 sunaddr = NULL;
2006 }
2007
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002008 chunk = min_t(unsigned int, skb->len - skip, size);
2009 if (memcpy_toiovec(msg->msg_iov, skb->data + skip, chunk)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010 if (copied == 0)
2011 copied = -EFAULT;
2012 break;
2013 }
2014 copied += chunk;
2015 size -= chunk;
2016
2017 /* Mark read part of skb as used */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002018 if (!(flags & MSG_PEEK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019 skb_pull(skb, chunk);
2020
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002021 sk_peek_offset_bwd(sk, chunk);
2022
Linus Torvalds1da177e2005-04-16 15:20:36 -07002023 if (UNIXCB(skb).fp)
2024 unix_detach_fds(siocb->scm, skb);
2025
Eric Dumazet6f01fd62012-01-28 16:11:03 +00002026 if (skb->len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028
Eric Dumazet6f01fd62012-01-28 16:11:03 +00002029 skb_unlink(skb, &sk->sk_receive_queue);
Neil Horman70d4bf62010-07-20 06:45:56 +00002030 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031
2032 if (siocb->scm->fp)
2033 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002034 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035 /* It is questionable, see note in unix_dgram_recvmsg.
2036 */
2037 if (UNIXCB(skb).fp)
2038 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
2039
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002040 sk_peek_offset_fwd(sk, chunk);
2041
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042 break;
2043 }
2044 } while (size);
2045
Ingo Molnar57b47a52006-03-20 22:35:41 -08002046 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 scm_recv(sock, msg, siocb->scm, flags);
2048out:
2049 return copied ? : err;
2050}
2051
2052static int unix_shutdown(struct socket *sock, int mode)
2053{
2054 struct sock *sk = sock->sk;
2055 struct sock *other;
2056
Xi Wangfc61b922012-08-26 16:47:13 +00002057 if (mode < SHUT_RD || mode > SHUT_RDWR)
2058 return -EINVAL;
2059 /* This maps:
2060 * SHUT_RD (0) -> RCV_SHUTDOWN (1)
2061 * SHUT_WR (1) -> SEND_SHUTDOWN (2)
2062 * SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
2063 */
2064 ++mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065
Alban Crequy7180a032011-01-19 04:56:36 +00002066 unix_state_lock(sk);
2067 sk->sk_shutdown |= mode;
2068 other = unix_peer(sk);
2069 if (other)
2070 sock_hold(other);
2071 unix_state_unlock(sk);
2072 sk->sk_state_change(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073
Alban Crequy7180a032011-01-19 04:56:36 +00002074 if (other &&
2075 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076
Alban Crequy7180a032011-01-19 04:56:36 +00002077 int peer_mode = 0;
2078
2079 if (mode&RCV_SHUTDOWN)
2080 peer_mode |= SEND_SHUTDOWN;
2081 if (mode&SEND_SHUTDOWN)
2082 peer_mode |= RCV_SHUTDOWN;
2083 unix_state_lock(other);
2084 other->sk_shutdown |= peer_mode;
2085 unix_state_unlock(other);
2086 other->sk_state_change(other);
2087 if (peer_mode == SHUTDOWN_MASK)
2088 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
2089 else if (peer_mode & RCV_SHUTDOWN)
2090 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002091 }
Alban Crequy7180a032011-01-19 04:56:36 +00002092 if (other)
2093 sock_put(other);
2094
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095 return 0;
2096}
2097
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002098long unix_inq_len(struct sock *sk)
2099{
2100 struct sk_buff *skb;
2101 long amount = 0;
2102
2103 if (sk->sk_state == TCP_LISTEN)
2104 return -EINVAL;
2105
2106 spin_lock(&sk->sk_receive_queue.lock);
2107 if (sk->sk_type == SOCK_STREAM ||
2108 sk->sk_type == SOCK_SEQPACKET) {
2109 skb_queue_walk(&sk->sk_receive_queue, skb)
2110 amount += skb->len;
2111 } else {
2112 skb = skb_peek(&sk->sk_receive_queue);
2113 if (skb)
2114 amount = skb->len;
2115 }
2116 spin_unlock(&sk->sk_receive_queue.lock);
2117
2118 return amount;
2119}
2120EXPORT_SYMBOL_GPL(unix_inq_len);
2121
2122long unix_outq_len(struct sock *sk)
2123{
2124 return sk_wmem_alloc_get(sk);
2125}
2126EXPORT_SYMBOL_GPL(unix_outq_len);
2127
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2129{
2130 struct sock *sk = sock->sk;
Jianjun Konge27dfce2008-11-01 21:38:31 -07002131 long amount = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132 int err;
2133
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002134 switch (cmd) {
2135 case SIOCOUTQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002136 amount = unix_outq_len(sk);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002137 err = put_user(amount, (int __user *)arg);
2138 break;
2139 case SIOCINQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002140 amount = unix_inq_len(sk);
2141 if (amount < 0)
2142 err = amount;
2143 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 err = put_user(amount, (int __user *)arg);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002145 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002146 default:
2147 err = -ENOIOCTLCMD;
2148 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149 }
2150 return err;
2151}
2152
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002153static unsigned int unix_poll(struct file *file, struct socket *sock, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154{
2155 struct sock *sk = sock->sk;
2156 unsigned int mask;
2157
Eric Dumazetaa395142010-04-20 13:03:51 +00002158 sock_poll_wait(file, sk_sleep(sk), wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159 mask = 0;
2160
2161 /* exceptional events? */
2162 if (sk->sk_err)
2163 mask |= POLLERR;
2164 if (sk->sk_shutdown == SHUTDOWN_MASK)
2165 mask |= POLLHUP;
Davide Libenzif348d702006-03-25 03:07:39 -08002166 if (sk->sk_shutdown & RCV_SHUTDOWN)
Eric Dumazetdb409802010-09-06 11:13:50 +00002167 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168
2169 /* readable? */
Eric Dumazetdb409802010-09-06 11:13:50 +00002170 if (!skb_queue_empty(&sk->sk_receive_queue))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171 mask |= POLLIN | POLLRDNORM;
2172
2173 /* Connection-based need to check for termination and startup */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002174 if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
2175 sk->sk_state == TCP_CLOSE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176 mask |= POLLHUP;
2177
2178 /*
2179 * we set writable also when the other side has shut down the
2180 * connection. This prevents stuck sockets.
2181 */
2182 if (unix_writable(sk))
2183 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
2184
2185 return mask;
2186}
2187
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002188static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
2189 poll_table *wait)
Rainer Weikusat3c734192008-06-17 22:28:05 -07002190{
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002191 struct sock *sk = sock->sk, *other;
2192 unsigned int mask, writable;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002193
Eric Dumazetaa395142010-04-20 13:03:51 +00002194 sock_poll_wait(file, sk_sleep(sk), wait);
Rainer Weikusat3c734192008-06-17 22:28:05 -07002195 mask = 0;
2196
2197 /* exceptional events? */
2198 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +00002199 mask |= POLLERR |
Jacob Keller8facd5f2013-04-02 13:55:40 -07002200 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0);
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +00002201
Rainer Weikusat3c734192008-06-17 22:28:05 -07002202 if (sk->sk_shutdown & RCV_SHUTDOWN)
Eric Dumazet5456f092010-10-31 05:36:23 +00002203 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002204 if (sk->sk_shutdown == SHUTDOWN_MASK)
2205 mask |= POLLHUP;
2206
2207 /* readable? */
Eric Dumazet5456f092010-10-31 05:36:23 +00002208 if (!skb_queue_empty(&sk->sk_receive_queue))
Rainer Weikusat3c734192008-06-17 22:28:05 -07002209 mask |= POLLIN | POLLRDNORM;
2210
2211 /* Connection-based need to check for termination and startup */
2212 if (sk->sk_type == SOCK_SEQPACKET) {
2213 if (sk->sk_state == TCP_CLOSE)
2214 mask |= POLLHUP;
2215 /* connection hasn't started yet? */
2216 if (sk->sk_state == TCP_SYN_SENT)
2217 return mask;
2218 }
2219
Eric Dumazet973a34a2010-10-31 05:38:25 +00002220 /* No write status requested, avoid expensive OUT tests. */
Hans Verkuil626cf232012-03-23 15:02:27 -07002221 if (!(poll_requested_events(wait) & (POLLWRBAND|POLLWRNORM|POLLOUT)))
Eric Dumazet973a34a2010-10-31 05:38:25 +00002222 return mask;
2223
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002224 writable = unix_writable(sk);
Eric Dumazet5456f092010-10-31 05:36:23 +00002225 other = unix_peer_get(sk);
2226 if (other) {
2227 if (unix_peer(other) != sk) {
2228 sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
2229 if (unix_recvq_full(other))
2230 writable = 0;
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002231 }
Eric Dumazet5456f092010-10-31 05:36:23 +00002232 sock_put(other);
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002233 }
2234
2235 if (writable)
Rainer Weikusat3c734192008-06-17 22:28:05 -07002236 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
2237 else
2238 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
2239
Rainer Weikusat3c734192008-06-17 22:28:05 -07002240 return mask;
2241}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242
2243#ifdef CONFIG_PROC_FS
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002244
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002245#define BUCKET_SPACE (BITS_PER_LONG - (UNIX_HASH_BITS + 1) - 1)
2246
2247#define get_bucket(x) ((x) >> BUCKET_SPACE)
2248#define get_offset(x) ((x) & ((1L << BUCKET_SPACE) - 1))
2249#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002250
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002251static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252{
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002253 unsigned long offset = get_offset(*pos);
2254 unsigned long bucket = get_bucket(*pos);
2255 struct sock *sk;
2256 unsigned long count = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002258 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
2259 if (sock_net(sk) != seq_file_net(seq))
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002260 continue;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002261 if (++count == offset)
2262 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263 }
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002264
2265 return sk;
2266}
2267
2268static struct sock *unix_next_socket(struct seq_file *seq,
2269 struct sock *sk,
2270 loff_t *pos)
2271{
2272 unsigned long bucket;
2273
2274 while (sk > (struct sock *)SEQ_START_TOKEN) {
2275 sk = sk_next(sk);
2276 if (!sk)
2277 goto next_bucket;
2278 if (sock_net(sk) == seq_file_net(seq))
2279 return sk;
2280 }
2281
2282 do {
2283 sk = unix_from_bucket(seq, pos);
2284 if (sk)
2285 return sk;
2286
2287next_bucket:
2288 bucket = get_bucket(*pos) + 1;
2289 *pos = set_bucket_offset(bucket, 1);
2290 } while (bucket < ARRAY_SIZE(unix_socket_table));
2291
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292 return NULL;
2293}
2294
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002296 __acquires(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002298 spin_lock(&unix_table_lock);
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002299
2300 if (!*pos)
2301 return SEQ_START_TOKEN;
2302
2303 if (get_bucket(*pos) >= ARRAY_SIZE(unix_socket_table))
2304 return NULL;
2305
2306 return unix_next_socket(seq, NULL, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307}
2308
2309static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2310{
2311 ++*pos;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002312 return unix_next_socket(seq, v, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313}
2314
2315static void unix_seq_stop(struct seq_file *seq, void *v)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002316 __releases(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002318 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319}
2320
2321static int unix_seq_show(struct seq_file *seq, void *v)
2322{
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002323
Joe Perchesb9f31242008-04-12 19:04:38 -07002324 if (v == SEQ_START_TOKEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325 seq_puts(seq, "Num RefCount Protocol Flags Type St "
2326 "Inode Path\n");
2327 else {
2328 struct sock *s = v;
2329 struct unix_sock *u = unix_sk(s);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002330 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331
Dan Rosenberg71338aa2011-05-23 12:17:35 +00002332 seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333 s,
2334 atomic_read(&s->sk_refcnt),
2335 0,
2336 s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
2337 s->sk_type,
2338 s->sk_socket ?
2339 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
2340 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
2341 sock_i_ino(s));
2342
2343 if (u->addr) {
2344 int i, len;
2345 seq_putc(seq, ' ');
2346
2347 i = 0;
2348 len = u->addr->len - sizeof(short);
2349 if (!UNIX_ABSTRACT(s))
2350 len--;
2351 else {
2352 seq_putc(seq, '@');
2353 i++;
2354 }
2355 for ( ; i < len; i++)
2356 seq_putc(seq, u->addr->name->sun_path[i]);
2357 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07002358 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359 seq_putc(seq, '\n');
2360 }
2361
2362 return 0;
2363}
2364
Philippe De Muyter56b3d972007-07-10 23:07:31 -07002365static const struct seq_operations unix_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366 .start = unix_seq_start,
2367 .next = unix_seq_next,
2368 .stop = unix_seq_stop,
2369 .show = unix_seq_show,
2370};
2371
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372static int unix_seq_open(struct inode *inode, struct file *file)
2373{
Denis V. Luneve372c412007-11-19 22:31:54 -08002374 return seq_open_net(inode, file, &unix_seq_ops,
Eric Dumazet8b51b062012-06-08 22:10:20 +00002375 sizeof(struct seq_net_private));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376}
2377
Arjan van de Venda7071d2007-02-12 00:55:36 -08002378static const struct file_operations unix_seq_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 .owner = THIS_MODULE,
2380 .open = unix_seq_open,
2381 .read = seq_read,
2382 .llseek = seq_lseek,
Denis V. Luneve372c412007-11-19 22:31:54 -08002383 .release = seq_release_net,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384};
2385
2386#endif
2387
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00002388static const struct net_proto_family unix_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389 .family = PF_UNIX,
2390 .create = unix_create,
2391 .owner = THIS_MODULE,
2392};
2393
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002394
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002395static int __net_init unix_net_init(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002396{
2397 int error = -ENOMEM;
2398
Denis V. Luneva0a53c82007-12-11 04:19:17 -08002399 net->unx.sysctl_max_dgram_qlen = 10;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002400 if (unix_sysctl_register(net))
2401 goto out;
Pavel Emelyanovd392e492007-12-01 23:44:15 +11002402
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002403#ifdef CONFIG_PROC_FS
Gao fengd4beaa62013-02-18 01:34:54 +00002404 if (!proc_create("unix", 0, net->proc_net, &unix_seq_fops)) {
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002405 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002406 goto out;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002407 }
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002408#endif
2409 error = 0;
2410out:
Jianjun Kong48dcc33e2008-11-01 21:37:27 -07002411 return error;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002412}
2413
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002414static void __net_exit unix_net_exit(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002415{
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002416 unix_sysctl_unregister(net);
Gao fengece31ff2013-02-18 01:34:56 +00002417 remove_proc_entry("unix", net->proc_net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002418}
2419
2420static struct pernet_operations unix_net_ops = {
2421 .init = unix_net_init,
2422 .exit = unix_net_exit,
2423};
2424
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425static int __init af_unix_init(void)
2426{
2427 int rc = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428
YOSHIFUJI Hideaki / 吉藤英明b4fff5f2013-01-09 07:20:07 +00002429 BUILD_BUG_ON(sizeof(struct unix_skb_parms) > FIELD_SIZEOF(struct sk_buff, cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430
2431 rc = proto_register(&unix_proto, 1);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002432 if (rc != 0) {
2433 printk(KERN_CRIT "%s: Cannot create unix_sock SLAB cache!\n",
Harvey Harrison0dc47872008-03-05 20:47:47 -08002434 __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435 goto out;
2436 }
2437
2438 sock_register(&unix_family_ops);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002439 register_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440out:
2441 return rc;
2442}
2443
2444static void __exit af_unix_exit(void)
2445{
2446 sock_unregister(PF_UNIX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447 proto_unregister(&unix_proto);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002448 unregister_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449}
2450
David Woodhouse3d366962008-04-24 00:59:25 -07002451/* Earlier than device_initcall() so that other drivers invoking
2452 request_module() don't end up in a loop when modprobe tries
2453 to use a UNIX socket. But later than subsys_initcall() because
2454 we depend on stuff initialised there */
2455fs_initcall(af_unix_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456module_exit(af_unix_exit);
2457
2458MODULE_LICENSE("GPL");
2459MODULE_ALIAS_NETPROTO(PF_UNIX);