blob: eea75888805e151d2d26ffae2518971ee330349d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * NET4: Implementation of BSD Unix domain sockets.
3 *
4 * Authors: Alan Cox, <alan.cox@linux.org>
5 *
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 *
11 * Version: $Id: af_unix.c,v 1.133 2002/02/08 03:57:19 davem Exp $
12 *
13 * Fixes:
14 * Linus Torvalds : Assorted bug cures.
15 * Niibe Yutaka : async I/O support.
16 * Carsten Paeth : PF_UNIX check, address fixes.
17 * Alan Cox : Limit size of allocated blocks.
18 * Alan Cox : Fixed the stupid socketpair bug.
19 * Alan Cox : BSD compatibility fine tuning.
20 * Alan Cox : Fixed a bug in connect when interrupted.
21 * Alan Cox : Sorted out a proper draft version of
22 * file descriptor passing hacked up from
23 * Mike Shaver's work.
24 * Marty Leisner : Fixes to fd passing
25 * Nick Nevin : recvmsg bugfix.
26 * Alan Cox : Started proper garbage collector
27 * Heiko EiBfeldt : Missing verify_area check
28 * Alan Cox : Started POSIXisms
29 * Andreas Schwab : Replace inode by dentry for proper
30 * reference counting
31 * Kirk Petersen : Made this a module
32 * Christoph Rohland : Elegant non-blocking accept/connect algorithm.
33 * Lots of bug fixes.
34 * Alexey Kuznetosv : Repaired (I hope) bugs introduces
35 * by above two patches.
36 * Andrea Arcangeli : If possible we block in connect(2)
37 * if the max backlog of the listen socket
38 * is been reached. This won't break
39 * old apps and it will avoid huge amount
40 * of socks hashed (this for unix_gc()
41 * performances reasons).
42 * Security fix that limits the max
43 * number of socks to 2*max_files and
44 * the number of skb queueable in the
45 * dgram receiver.
46 * Artur Skawina : Hash function optimizations
47 * Alexey Kuznetsov : Full scale SMP. Lot of bugs are introduced 8)
48 * Malcolm Beattie : Set peercred for socketpair
49 * Michal Ostrowski : Module initialization cleanup.
50 * Arnaldo C. Melo : Remove MOD_{INC,DEC}_USE_COUNT,
51 * the core infrastructure is doing that
52 * for all net proto families now (2.5.69+)
53 *
54 *
55 * Known differences from reference BSD that was tested:
56 *
57 * [TO FIX]
58 * ECONNREFUSED is not returned from one end of a connected() socket to the
59 * other the moment one end closes.
60 * fstat() doesn't return st_dev=0, and give the blksize as high water mark
61 * and a fake inode identifier (nor the BSD first socket fstat twice bug).
62 * [NOT TO FIX]
63 * accept() returns a path name even if the connecting socket has closed
64 * in the meantime (BSD loses the path and gives up).
65 * accept() returns 0 length path for an unbound connector. BSD returns 16
66 * and a null first byte in the path (but not for gethost/peername - BSD bug ??)
67 * socketpair(...SOCK_RAW..) doesn't panic the kernel.
68 * BSD af_unix apparently has connect forgetting to block properly.
69 * (need to check this with the POSIX spec in detail)
70 *
71 * Differences from 2.0.0-11-... (ANK)
72 * Bug fixes and improvements.
73 * - client shutdown killed server socket.
74 * - removed all useless cli/sti pairs.
75 *
76 * Semantic changes/extensions.
77 * - generic control message passing.
78 * - SCM_CREDENTIALS control message.
79 * - "Abstract" (not FS based) socket bindings.
80 * Abstract names are sequences of bytes (not zero terminated)
81 * started by 0, so that this name space does not intersect
82 * with BSD names.
83 */
84
85#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070086#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070087#include <linux/signal.h>
88#include <linux/sched.h>
89#include <linux/errno.h>
90#include <linux/string.h>
91#include <linux/stat.h>
92#include <linux/dcache.h>
93#include <linux/namei.h>
94#include <linux/socket.h>
95#include <linux/un.h>
96#include <linux/fcntl.h>
97#include <linux/termios.h>
98#include <linux/sockios.h>
99#include <linux/net.h>
100#include <linux/in.h>
101#include <linux/fs.h>
102#include <linux/slab.h>
103#include <asm/uaccess.h>
104#include <linux/skbuff.h>
105#include <linux/netdevice.h>
Eric W. Biederman457c4cb2007-09-12 12:01:34 +0200106#include <net/net_namespace.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107#include <net/sock.h>
Arnaldo Carvalho de Meloc752f072005-08-09 20:08:28 -0700108#include <net/tcp_states.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109#include <net/af_unix.h>
110#include <linux/proc_fs.h>
111#include <linux/seq_file.h>
112#include <net/scm.h>
113#include <linux/init.h>
114#include <linux/poll.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115#include <linux/rtnetlink.h>
116#include <linux/mount.h>
117#include <net/checksum.h>
118#include <linux/security.h>
119
Adrian Bunk13111692007-07-30 18:05:45 -0700120static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
121static DEFINE_SPINLOCK(unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122static atomic_t unix_nr_socks = ATOMIC_INIT(0);
123
124#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE])
125
126#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE)
127
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700128#ifdef CONFIG_SECURITY_NETWORK
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700129static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700130{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700131 memcpy(UNIXSID(skb), &scm->secid, sizeof(u32));
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700132}
133
134static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
135{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700136 scm->secid = *UNIXSID(skb);
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700137}
138#else
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700139static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700140{ }
141
142static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
143{ }
144#endif /* CONFIG_SECURITY_NETWORK */
145
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146/*
147 * SMP locking strategy:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800148 * hash table is protected with spinlock unix_table_lock
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 * each socket state is protected by separate rwlock.
150 */
151
Al Viro44bb9362006-11-14 21:36:14 -0800152static inline unsigned unix_hash_fold(__wsum n)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153{
Al Viro44bb9362006-11-14 21:36:14 -0800154 unsigned hash = (__force unsigned)n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 hash ^= hash>>16;
156 hash ^= hash>>8;
157 return hash&(UNIX_HASH_SIZE-1);
158}
159
160#define unix_peer(sk) (unix_sk(sk)->peer)
161
162static inline int unix_our_peer(struct sock *sk, struct sock *osk)
163{
164 return unix_peer(osk) == sk;
165}
166
167static inline int unix_may_send(struct sock *sk, struct sock *osk)
168{
169 return (unix_peer(osk) == NULL || unix_our_peer(sk, osk));
170}
171
172static struct sock *unix_peer_get(struct sock *s)
173{
174 struct sock *peer;
175
David S. Miller1c92b4e2007-05-31 13:24:26 -0700176 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 peer = unix_peer(s);
178 if (peer)
179 sock_hold(peer);
David S. Miller1c92b4e2007-05-31 13:24:26 -0700180 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 return peer;
182}
183
184static inline void unix_release_addr(struct unix_address *addr)
185{
186 if (atomic_dec_and_test(&addr->refcnt))
187 kfree(addr);
188}
189
190/*
191 * Check unix socket name:
192 * - should be not zero length.
193 * - if started by not zero, should be NULL terminated (FS object)
194 * - if started by zero, it is abstract name.
195 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900196
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197static int unix_mkname(struct sockaddr_un * sunaddr, int len, unsigned *hashp)
198{
199 if (len <= sizeof(short) || len > sizeof(*sunaddr))
200 return -EINVAL;
201 if (!sunaddr || sunaddr->sun_family != AF_UNIX)
202 return -EINVAL;
203 if (sunaddr->sun_path[0]) {
204 /*
205 * This may look like an off by one error but it is a bit more
206 * subtle. 108 is the longest valid AF_UNIX path for a binding.
207 * sun_path[108] doesnt as such exist. However in kernel space
208 * we are guaranteed that it is a valid memory location in our
209 * kernel address buffer.
210 */
211 ((char *)sunaddr)[len]=0;
212 len = strlen(sunaddr->sun_path)+1+sizeof(short);
213 return len;
214 }
215
216 *hashp = unix_hash_fold(csum_partial((char*)sunaddr, len, 0));
217 return len;
218}
219
220static void __unix_remove_socket(struct sock *sk)
221{
222 sk_del_node_init(sk);
223}
224
225static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
226{
227 BUG_TRAP(sk_unhashed(sk));
228 sk_add_node(sk, list);
229}
230
231static inline void unix_remove_socket(struct sock *sk)
232{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800233 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 __unix_remove_socket(sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800235 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236}
237
238static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
239{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800240 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 __unix_insert_socket(list, sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800242 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243}
244
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800245static struct sock *__unix_find_socket_byname(struct net *net,
246 struct sockaddr_un *sunname,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 int len, int type, unsigned hash)
248{
249 struct sock *s;
250 struct hlist_node *node;
251
252 sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
253 struct unix_sock *u = unix_sk(s);
254
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800255 if (s->sk_net != net)
256 continue;
257
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 if (u->addr->len == len &&
259 !memcmp(u->addr->name, sunname, len))
260 goto found;
261 }
262 s = NULL;
263found:
264 return s;
265}
266
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800267static inline struct sock *unix_find_socket_byname(struct net *net,
268 struct sockaddr_un *sunname,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 int len, int type,
270 unsigned hash)
271{
272 struct sock *s;
273
David S. Millerfbe9cc42005-12-13 23:26:29 -0800274 spin_lock(&unix_table_lock);
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800275 s = __unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 if (s)
277 sock_hold(s);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800278 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 return s;
280}
281
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800282static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283{
284 struct sock *s;
285 struct hlist_node *node;
286
David S. Millerfbe9cc42005-12-13 23:26:29 -0800287 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 sk_for_each(s, node,
289 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
290 struct dentry *dentry = unix_sk(s)->dentry;
291
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800292 if (s->sk_net != net)
293 continue;
294
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 if(dentry && dentry->d_inode == i)
296 {
297 sock_hold(s);
298 goto found;
299 }
300 }
301 s = NULL;
302found:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800303 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 return s;
305}
306
307static inline int unix_writable(struct sock *sk)
308{
309 return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
310}
311
312static void unix_write_space(struct sock *sk)
313{
314 read_lock(&sk->sk_callback_lock);
315 if (unix_writable(sk)) {
316 if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
Ingo Molnar71e20f12007-10-15 17:00:19 +0200317 wake_up_interruptible_sync(sk->sk_sleep);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800318 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 }
320 read_unlock(&sk->sk_callback_lock);
321}
322
323/* When dgram socket disconnects (or changes its peer), we clear its receive
324 * queue of packets arrived from previous peer. First, it allows to do
325 * flow control based only on wmem_alloc; second, sk connected to peer
326 * may receive messages only from that peer. */
327static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
328{
David S. Millerb03efcf2005-07-08 14:57:23 -0700329 if (!skb_queue_empty(&sk->sk_receive_queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 skb_queue_purge(&sk->sk_receive_queue);
331 wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
332
333 /* If one link of bidirectional dgram pipe is disconnected,
334 * we signal error. Messages are lost. Do not make this,
335 * when peer was not connected to us.
336 */
337 if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) {
338 other->sk_err = ECONNRESET;
339 other->sk_error_report(other);
340 }
341 }
342}
343
344static void unix_sock_destructor(struct sock *sk)
345{
346 struct unix_sock *u = unix_sk(sk);
347
348 skb_queue_purge(&sk->sk_receive_queue);
349
350 BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc));
351 BUG_TRAP(sk_unhashed(sk));
352 BUG_TRAP(!sk->sk_socket);
353 if (!sock_flag(sk, SOCK_DEAD)) {
354 printk("Attempt to release alive unix socket: %p\n", sk);
355 return;
356 }
357
358 if (u->addr)
359 unix_release_addr(u->addr);
360
361 atomic_dec(&unix_nr_socks);
362#ifdef UNIX_REFCNT_DEBUG
363 printk(KERN_DEBUG "UNIX %p is destroyed, %d are still alive.\n", sk, atomic_read(&unix_nr_socks));
364#endif
365}
366
367static int unix_release_sock (struct sock *sk, int embrion)
368{
369 struct unix_sock *u = unix_sk(sk);
370 struct dentry *dentry;
371 struct vfsmount *mnt;
372 struct sock *skpair;
373 struct sk_buff *skb;
374 int state;
375
376 unix_remove_socket(sk);
377
378 /* Clear state */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700379 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 sock_orphan(sk);
381 sk->sk_shutdown = SHUTDOWN_MASK;
382 dentry = u->dentry;
383 u->dentry = NULL;
384 mnt = u->mnt;
385 u->mnt = NULL;
386 state = sk->sk_state;
387 sk->sk_state = TCP_CLOSE;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700388 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389
390 wake_up_interruptible_all(&u->peer_wait);
391
392 skpair=unix_peer(sk);
393
394 if (skpair!=NULL) {
395 if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
David S. Miller1c92b4e2007-05-31 13:24:26 -0700396 unix_state_lock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 /* No more writes */
398 skpair->sk_shutdown = SHUTDOWN_MASK;
399 if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
400 skpair->sk_err = ECONNRESET;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700401 unix_state_unlock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 skpair->sk_state_change(skpair);
403 read_lock(&skpair->sk_callback_lock);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800404 sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 read_unlock(&skpair->sk_callback_lock);
406 }
407 sock_put(skpair); /* It may now die */
408 unix_peer(sk) = NULL;
409 }
410
411 /* Try to flush out this socket. Throw out buffers at least */
412
413 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
414 if (state==TCP_LISTEN)
415 unix_release_sock(skb->sk, 1);
416 /* passed fds are erased in the kfree_skb hook */
417 kfree_skb(skb);
418 }
419
420 if (dentry) {
421 dput(dentry);
422 mntput(mnt);
423 }
424
425 sock_put(sk);
426
427 /* ---- Socket is dead now and most probably destroyed ---- */
428
429 /*
430 * Fixme: BSD difference: In BSD all sockets connected to use get
431 * ECONNRESET and we die on the spot. In Linux we behave
432 * like files and pipes do and wait for the last
433 * dereference.
434 *
435 * Can't we simply set sock->err?
436 *
437 * What the above comment does talk about? --ANK(980817)
438 */
439
Pavel Emelyanov9305cfa2007-11-10 22:06:01 -0800440 if (unix_tot_inflight)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900441 unix_gc(); /* Garbage collect fds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442
443 return 0;
444}
445
446static int unix_listen(struct socket *sock, int backlog)
447{
448 int err;
449 struct sock *sk = sock->sk;
450 struct unix_sock *u = unix_sk(sk);
451
452 err = -EOPNOTSUPP;
453 if (sock->type!=SOCK_STREAM && sock->type!=SOCK_SEQPACKET)
454 goto out; /* Only stream/seqpacket sockets accept */
455 err = -EINVAL;
456 if (!u->addr)
457 goto out; /* No listens on an unbound socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700458 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
460 goto out_unlock;
461 if (backlog > sk->sk_max_ack_backlog)
462 wake_up_interruptible_all(&u->peer_wait);
463 sk->sk_max_ack_backlog = backlog;
464 sk->sk_state = TCP_LISTEN;
465 /* set credentials so connect can copy them */
Pavel Emelyanovb4888932007-10-18 23:40:14 -0700466 sk->sk_peercred.pid = task_tgid_vnr(current);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 sk->sk_peercred.uid = current->euid;
468 sk->sk_peercred.gid = current->egid;
469 err = 0;
470
471out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -0700472 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473out:
474 return err;
475}
476
477static int unix_release(struct socket *);
478static int unix_bind(struct socket *, struct sockaddr *, int);
479static int unix_stream_connect(struct socket *, struct sockaddr *,
480 int addr_len, int flags);
481static int unix_socketpair(struct socket *, struct socket *);
482static int unix_accept(struct socket *, struct socket *, int);
483static int unix_getname(struct socket *, struct sockaddr *, int *, int);
484static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
485static int unix_ioctl(struct socket *, unsigned int, unsigned long);
486static int unix_shutdown(struct socket *, int);
487static int unix_stream_sendmsg(struct kiocb *, struct socket *,
488 struct msghdr *, size_t);
489static int unix_stream_recvmsg(struct kiocb *, struct socket *,
490 struct msghdr *, size_t, int);
491static int unix_dgram_sendmsg(struct kiocb *, struct socket *,
492 struct msghdr *, size_t);
493static int unix_dgram_recvmsg(struct kiocb *, struct socket *,
494 struct msghdr *, size_t, int);
495static int unix_dgram_connect(struct socket *, struct sockaddr *,
496 int, int);
497static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
498 struct msghdr *, size_t);
499
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800500static const struct proto_ops unix_stream_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 .family = PF_UNIX,
502 .owner = THIS_MODULE,
503 .release = unix_release,
504 .bind = unix_bind,
505 .connect = unix_stream_connect,
506 .socketpair = unix_socketpair,
507 .accept = unix_accept,
508 .getname = unix_getname,
509 .poll = unix_poll,
510 .ioctl = unix_ioctl,
511 .listen = unix_listen,
512 .shutdown = unix_shutdown,
513 .setsockopt = sock_no_setsockopt,
514 .getsockopt = sock_no_getsockopt,
515 .sendmsg = unix_stream_sendmsg,
516 .recvmsg = unix_stream_recvmsg,
517 .mmap = sock_no_mmap,
518 .sendpage = sock_no_sendpage,
519};
520
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800521static const struct proto_ops unix_dgram_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 .family = PF_UNIX,
523 .owner = THIS_MODULE,
524 .release = unix_release,
525 .bind = unix_bind,
526 .connect = unix_dgram_connect,
527 .socketpair = unix_socketpair,
528 .accept = sock_no_accept,
529 .getname = unix_getname,
530 .poll = datagram_poll,
531 .ioctl = unix_ioctl,
532 .listen = sock_no_listen,
533 .shutdown = unix_shutdown,
534 .setsockopt = sock_no_setsockopt,
535 .getsockopt = sock_no_getsockopt,
536 .sendmsg = unix_dgram_sendmsg,
537 .recvmsg = unix_dgram_recvmsg,
538 .mmap = sock_no_mmap,
539 .sendpage = sock_no_sendpage,
540};
541
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800542static const struct proto_ops unix_seqpacket_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 .family = PF_UNIX,
544 .owner = THIS_MODULE,
545 .release = unix_release,
546 .bind = unix_bind,
547 .connect = unix_stream_connect,
548 .socketpair = unix_socketpair,
549 .accept = unix_accept,
550 .getname = unix_getname,
551 .poll = datagram_poll,
552 .ioctl = unix_ioctl,
553 .listen = unix_listen,
554 .shutdown = unix_shutdown,
555 .setsockopt = sock_no_setsockopt,
556 .getsockopt = sock_no_getsockopt,
557 .sendmsg = unix_seqpacket_sendmsg,
558 .recvmsg = unix_dgram_recvmsg,
559 .mmap = sock_no_mmap,
560 .sendpage = sock_no_sendpage,
561};
562
563static struct proto unix_proto = {
564 .name = "UNIX",
565 .owner = THIS_MODULE,
566 .obj_size = sizeof(struct unix_sock),
567};
568
Ingo Molnara09785a2006-07-03 00:25:12 -0700569/*
570 * AF_UNIX sockets do not interact with hardware, hence they
571 * dont trigger interrupts - so it's safe for them to have
572 * bh-unsafe locking for their sk_receive_queue.lock. Split off
573 * this special lock-class by reinitializing the spinlock key:
574 */
575static struct lock_class_key af_unix_sk_receive_queue_lock_key;
576
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700577static struct sock * unix_create1(struct net *net, struct socket *sock)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578{
579 struct sock *sk = NULL;
580 struct unix_sock *u;
581
Pavel Emelyanov284b3272007-11-10 22:08:30 -0800582 atomic_inc(&unix_nr_socks);
583 if (atomic_read(&unix_nr_socks) > 2 * get_max_files())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 goto out;
585
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700586 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 if (!sk)
588 goto out;
589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 sock_init_data(sock,sk);
Ingo Molnara09785a2006-07-03 00:25:12 -0700591 lockdep_set_class(&sk->sk_receive_queue.lock,
592 &af_unix_sk_receive_queue_lock_key);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593
594 sk->sk_write_space = unix_write_space;
Denis V. Luneva0a53c82007-12-11 04:19:17 -0800595 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 sk->sk_destruct = unix_sock_destructor;
597 u = unix_sk(sk);
598 u->dentry = NULL;
599 u->mnt = NULL;
Benjamin LaHaisefd19f322006-01-03 14:10:46 -0800600 spin_lock_init(&u->lock);
Miklos Szeredi1fd05ba2007-07-11 14:22:39 -0700601 atomic_set(&u->inflight, 0);
602 INIT_LIST_HEAD(&u->link);
Ingo Molnar57b47a52006-03-20 22:35:41 -0800603 mutex_init(&u->readlock); /* single task reading lock */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 init_waitqueue_head(&u->peer_wait);
605 unix_insert_socket(unix_sockets_unbound, sk);
606out:
Pavel Emelyanov284b3272007-11-10 22:08:30 -0800607 if (sk == NULL)
608 atomic_dec(&unix_nr_socks);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 return sk;
610}
611
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700612static int unix_create(struct net *net, struct socket *sock, int protocol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613{
614 if (protocol && protocol != PF_UNIX)
615 return -EPROTONOSUPPORT;
616
617 sock->state = SS_UNCONNECTED;
618
619 switch (sock->type) {
620 case SOCK_STREAM:
621 sock->ops = &unix_stream_ops;
622 break;
623 /*
624 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
625 * nothing uses it.
626 */
627 case SOCK_RAW:
628 sock->type=SOCK_DGRAM;
629 case SOCK_DGRAM:
630 sock->ops = &unix_dgram_ops;
631 break;
632 case SOCK_SEQPACKET:
633 sock->ops = &unix_seqpacket_ops;
634 break;
635 default:
636 return -ESOCKTNOSUPPORT;
637 }
638
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700639 return unix_create1(net, sock) ? 0 : -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640}
641
642static int unix_release(struct socket *sock)
643{
644 struct sock *sk = sock->sk;
645
646 if (!sk)
647 return 0;
648
649 sock->sk = NULL;
650
651 return unix_release_sock (sk, 0);
652}
653
654static int unix_autobind(struct socket *sock)
655{
656 struct sock *sk = sock->sk;
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800657 struct net *net = sk->sk_net;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 struct unix_sock *u = unix_sk(sk);
659 static u32 ordernum = 1;
660 struct unix_address * addr;
661 int err;
662
Ingo Molnar57b47a52006-03-20 22:35:41 -0800663 mutex_lock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664
665 err = 0;
666 if (u->addr)
667 goto out;
668
669 err = -ENOMEM;
Panagiotis Issaris0da974f2006-07-21 14:51:30 -0700670 addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 if (!addr)
672 goto out;
673
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 addr->name->sun_family = AF_UNIX;
675 atomic_set(&addr->refcnt, 1);
676
677retry:
678 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
679 addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0));
680
David S. Millerfbe9cc42005-12-13 23:26:29 -0800681 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 ordernum = (ordernum+1)&0xFFFFF;
683
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800684 if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 addr->hash)) {
David S. Millerfbe9cc42005-12-13 23:26:29 -0800686 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 /* Sanity yield. It is unusual case, but yet... */
688 if (!(ordernum&0xFF))
689 yield();
690 goto retry;
691 }
692 addr->hash ^= sk->sk_type;
693
694 __unix_remove_socket(sk);
695 u->addr = addr;
696 __unix_insert_socket(&unix_socket_table[addr->hash], sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800697 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 err = 0;
699
Ingo Molnar57b47a52006-03-20 22:35:41 -0800700out: mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 return err;
702}
703
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800704static struct sock *unix_find_other(struct net *net,
705 struct sockaddr_un *sunname, int len,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 int type, unsigned hash, int *error)
707{
708 struct sock *u;
709 struct nameidata nd;
710 int err = 0;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900711
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 if (sunname->sun_path[0]) {
713 err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
714 if (err)
715 goto fail;
Christoph Hellwige4543ed2005-11-08 21:35:04 -0800716 err = vfs_permission(&nd, MAY_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 if (err)
718 goto put_fail;
719
720 err = -ECONNREFUSED;
721 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
722 goto put_fail;
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800723 u=unix_find_socket_byinode(net, nd.dentry->d_inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 if (!u)
725 goto put_fail;
726
727 if (u->sk_type == type)
728 touch_atime(nd.mnt, nd.dentry);
729
730 path_release(&nd);
731
732 err=-EPROTOTYPE;
733 if (u->sk_type != type) {
734 sock_put(u);
735 goto fail;
736 }
737 } else {
738 err = -ECONNREFUSED;
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800739 u=unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 if (u) {
741 struct dentry *dentry;
742 dentry = unix_sk(u)->dentry;
743 if (dentry)
744 touch_atime(unix_sk(u)->mnt, dentry);
745 } else
746 goto fail;
747 }
748 return u;
749
750put_fail:
751 path_release(&nd);
752fail:
753 *error=err;
754 return NULL;
755}
756
757
758static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
759{
760 struct sock *sk = sock->sk;
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800761 struct net *net = sk->sk_net;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 struct unix_sock *u = unix_sk(sk);
763 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
764 struct dentry * dentry = NULL;
765 struct nameidata nd;
766 int err;
767 unsigned hash;
768 struct unix_address *addr;
769 struct hlist_head *list;
770
771 err = -EINVAL;
772 if (sunaddr->sun_family != AF_UNIX)
773 goto out;
774
775 if (addr_len==sizeof(short)) {
776 err = unix_autobind(sock);
777 goto out;
778 }
779
780 err = unix_mkname(sunaddr, addr_len, &hash);
781 if (err < 0)
782 goto out;
783 addr_len = err;
784
Ingo Molnar57b47a52006-03-20 22:35:41 -0800785 mutex_lock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786
787 err = -EINVAL;
788 if (u->addr)
789 goto out_up;
790
791 err = -ENOMEM;
792 addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
793 if (!addr)
794 goto out_up;
795
796 memcpy(addr->name, sunaddr, addr_len);
797 addr->len = addr_len;
798 addr->hash = hash ^ sk->sk_type;
799 atomic_set(&addr->refcnt, 1);
800
801 if (sunaddr->sun_path[0]) {
802 unsigned int mode;
803 err = 0;
804 /*
805 * Get the parent directory, calculate the hash for last
806 * component.
807 */
808 err = path_lookup(sunaddr->sun_path, LOOKUP_PARENT, &nd);
809 if (err)
810 goto out_mknod_parent;
Christoph Hellwigf81a0bf2005-05-19 12:26:43 -0700811
812 dentry = lookup_create(&nd, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 err = PTR_ERR(dentry);
814 if (IS_ERR(dentry))
815 goto out_mknod_unlock;
Christoph Hellwigf81a0bf2005-05-19 12:26:43 -0700816
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 /*
818 * All right, let's create it.
819 */
820 mode = S_IFSOCK |
821 (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
822 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
823 if (err)
824 goto out_mknod_dput;
Jes Sorensen1b1dcc12006-01-09 15:59:24 -0800825 mutex_unlock(&nd.dentry->d_inode->i_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 dput(nd.dentry);
827 nd.dentry = dentry;
828
829 addr->hash = UNIX_HASH_SIZE;
830 }
831
David S. Millerfbe9cc42005-12-13 23:26:29 -0800832 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833
834 if (!sunaddr->sun_path[0]) {
835 err = -EADDRINUSE;
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800836 if (__unix_find_socket_byname(net, sunaddr, addr_len,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 sk->sk_type, hash)) {
838 unix_release_addr(addr);
839 goto out_unlock;
840 }
841
842 list = &unix_socket_table[addr->hash];
843 } else {
844 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
845 u->dentry = nd.dentry;
846 u->mnt = nd.mnt;
847 }
848
849 err = 0;
850 __unix_remove_socket(sk);
851 u->addr = addr;
852 __unix_insert_socket(list, sk);
853
854out_unlock:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800855 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856out_up:
Ingo Molnar57b47a52006-03-20 22:35:41 -0800857 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858out:
859 return err;
860
861out_mknod_dput:
862 dput(dentry);
863out_mknod_unlock:
Jes Sorensen1b1dcc12006-01-09 15:59:24 -0800864 mutex_unlock(&nd.dentry->d_inode->i_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 path_release(&nd);
866out_mknod_parent:
867 if (err==-EEXIST)
868 err=-EADDRINUSE;
869 unix_release_addr(addr);
870 goto out_up;
871}
872
David S. Miller278a3de2007-05-31 15:19:20 -0700873static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
874{
875 if (unlikely(sk1 == sk2) || !sk2) {
876 unix_state_lock(sk1);
877 return;
878 }
879 if (sk1 < sk2) {
880 unix_state_lock(sk1);
881 unix_state_lock_nested(sk2);
882 } else {
883 unix_state_lock(sk2);
884 unix_state_lock_nested(sk1);
885 }
886}
887
888static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
889{
890 if (unlikely(sk1 == sk2) || !sk2) {
891 unix_state_unlock(sk1);
892 return;
893 }
894 unix_state_unlock(sk1);
895 unix_state_unlock(sk2);
896}
897
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
899 int alen, int flags)
900{
901 struct sock *sk = sock->sk;
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800902 struct net *net = sk->sk_net;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 struct sockaddr_un *sunaddr=(struct sockaddr_un*)addr;
904 struct sock *other;
905 unsigned hash;
906 int err;
907
908 if (addr->sa_family != AF_UNSPEC) {
909 err = unix_mkname(sunaddr, alen, &hash);
910 if (err < 0)
911 goto out;
912 alen = err;
913
914 if (test_bit(SOCK_PASSCRED, &sock->flags) &&
915 !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
916 goto out;
917
David S. Miller278a3de2007-05-31 15:19:20 -0700918restart:
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800919 other=unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 if (!other)
921 goto out;
922
David S. Miller278a3de2007-05-31 15:19:20 -0700923 unix_state_double_lock(sk, other);
924
925 /* Apparently VFS overslept socket death. Retry. */
926 if (sock_flag(other, SOCK_DEAD)) {
927 unix_state_double_unlock(sk, other);
928 sock_put(other);
929 goto restart;
930 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
932 err = -EPERM;
933 if (!unix_may_send(sk, other))
934 goto out_unlock;
935
936 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
937 if (err)
938 goto out_unlock;
939
940 } else {
941 /*
942 * 1003.1g breaking connected state with AF_UNSPEC
943 */
944 other = NULL;
David S. Miller278a3de2007-05-31 15:19:20 -0700945 unix_state_double_lock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 }
947
948 /*
949 * If it was connected, reconnect.
950 */
951 if (unix_peer(sk)) {
952 struct sock *old_peer = unix_peer(sk);
953 unix_peer(sk)=other;
David S. Miller278a3de2007-05-31 15:19:20 -0700954 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955
956 if (other != old_peer)
957 unix_dgram_disconnected(sk, old_peer);
958 sock_put(old_peer);
959 } else {
960 unix_peer(sk)=other;
David S. Miller278a3de2007-05-31 15:19:20 -0700961 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 }
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900963 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964
965out_unlock:
David S. Miller278a3de2007-05-31 15:19:20 -0700966 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 sock_put(other);
968out:
969 return err;
970}
971
972static long unix_wait_for_peer(struct sock *other, long timeo)
973{
974 struct unix_sock *u = unix_sk(other);
975 int sched;
976 DEFINE_WAIT(wait);
977
978 prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
979
980 sched = !sock_flag(other, SOCK_DEAD) &&
981 !(other->sk_shutdown & RCV_SHUTDOWN) &&
David S. Miller64a14652007-03-06 11:21:05 -0800982 (skb_queue_len(&other->sk_receive_queue) >
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 other->sk_max_ack_backlog);
984
David S. Miller1c92b4e2007-05-31 13:24:26 -0700985 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986
987 if (sched)
988 timeo = schedule_timeout(timeo);
989
990 finish_wait(&u->peer_wait, &wait);
991 return timeo;
992}
993
994static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
995 int addr_len, int flags)
996{
997 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
998 struct sock *sk = sock->sk;
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800999 struct net *net = sk->sk_net;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 struct unix_sock *u = unix_sk(sk), *newu, *otheru;
1001 struct sock *newsk = NULL;
1002 struct sock *other = NULL;
1003 struct sk_buff *skb = NULL;
1004 unsigned hash;
1005 int st;
1006 int err;
1007 long timeo;
1008
1009 err = unix_mkname(sunaddr, addr_len, &hash);
1010 if (err < 0)
1011 goto out;
1012 addr_len = err;
1013
1014 if (test_bit(SOCK_PASSCRED, &sock->flags)
1015 && !u->addr && (err = unix_autobind(sock)) != 0)
1016 goto out;
1017
1018 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
1019
1020 /* First of all allocate resources.
1021 If we will make it after state is locked,
1022 we will have to recheck all again in any case.
1023 */
1024
1025 err = -ENOMEM;
1026
1027 /* create new sock for complete connection */
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -07001028 newsk = unix_create1(sk->sk_net, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 if (newsk == NULL)
1030 goto out;
1031
1032 /* Allocate skb for sending to listening sock */
1033 skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL);
1034 if (skb == NULL)
1035 goto out;
1036
1037restart:
1038 /* Find listening sock. */
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001039 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040 if (!other)
1041 goto out;
1042
1043 /* Latch state of peer */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001044 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045
1046 /* Apparently VFS overslept socket death. Retry. */
1047 if (sock_flag(other, SOCK_DEAD)) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001048 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 sock_put(other);
1050 goto restart;
1051 }
1052
1053 err = -ECONNREFUSED;
1054 if (other->sk_state != TCP_LISTEN)
1055 goto out_unlock;
1056
David S. Miller64a14652007-03-06 11:21:05 -08001057 if (skb_queue_len(&other->sk_receive_queue) >
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 other->sk_max_ack_backlog) {
1059 err = -EAGAIN;
1060 if (!timeo)
1061 goto out_unlock;
1062
1063 timeo = unix_wait_for_peer(other, timeo);
1064
1065 err = sock_intr_errno(timeo);
1066 if (signal_pending(current))
1067 goto out;
1068 sock_put(other);
1069 goto restart;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001070 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
1072 /* Latch our state.
1073
1074 It is tricky place. We need to grab write lock and cannot
1075 drop lock on peer. It is dangerous because deadlock is
1076 possible. Connect to self case and simultaneous
1077 attempt to connect are eliminated by checking socket
1078 state. other is TCP_LISTEN, if sk is TCP_LISTEN we
1079 check this before attempt to grab lock.
1080
1081 Well, and we have to recheck the state after socket locked.
1082 */
1083 st = sk->sk_state;
1084
1085 switch (st) {
1086 case TCP_CLOSE:
1087 /* This is ok... continue with connect */
1088 break;
1089 case TCP_ESTABLISHED:
1090 /* Socket is already connected */
1091 err = -EISCONN;
1092 goto out_unlock;
1093 default:
1094 err = -EINVAL;
1095 goto out_unlock;
1096 }
1097
David S. Miller1c92b4e2007-05-31 13:24:26 -07001098 unix_state_lock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
1100 if (sk->sk_state != st) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001101 unix_state_unlock(sk);
1102 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 sock_put(other);
1104 goto restart;
1105 }
1106
1107 err = security_unix_stream_connect(sock, other->sk_socket, newsk);
1108 if (err) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001109 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 goto out_unlock;
1111 }
1112
1113 /* The way is open! Fastly set all the necessary fields... */
1114
1115 sock_hold(sk);
1116 unix_peer(newsk) = sk;
1117 newsk->sk_state = TCP_ESTABLISHED;
1118 newsk->sk_type = sk->sk_type;
Pavel Emelyanovb4888932007-10-18 23:40:14 -07001119 newsk->sk_peercred.pid = task_tgid_vnr(current);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 newsk->sk_peercred.uid = current->euid;
1121 newsk->sk_peercred.gid = current->egid;
1122 newu = unix_sk(newsk);
1123 newsk->sk_sleep = &newu->peer_wait;
1124 otheru = unix_sk(other);
1125
1126 /* copy address information from listening to new sock*/
1127 if (otheru->addr) {
1128 atomic_inc(&otheru->addr->refcnt);
1129 newu->addr = otheru->addr;
1130 }
1131 if (otheru->dentry) {
1132 newu->dentry = dget(otheru->dentry);
1133 newu->mnt = mntget(otheru->mnt);
1134 }
1135
1136 /* Set credentials */
1137 sk->sk_peercred = other->sk_peercred;
1138
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 sock->state = SS_CONNECTED;
1140 sk->sk_state = TCP_ESTABLISHED;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001141 sock_hold(newsk);
1142
1143 smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */
1144 unix_peer(sk) = newsk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145
David S. Miller1c92b4e2007-05-31 13:24:26 -07001146 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147
1148 /* take ten and and send info to listening sock */
1149 spin_lock(&other->sk_receive_queue.lock);
1150 __skb_queue_tail(&other->sk_receive_queue, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001152 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 other->sk_data_ready(other, 0);
1154 sock_put(other);
1155 return 0;
1156
1157out_unlock:
1158 if (other)
David S. Miller1c92b4e2007-05-31 13:24:26 -07001159 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160
1161out:
1162 if (skb)
1163 kfree_skb(skb);
1164 if (newsk)
1165 unix_release_sock(newsk, 0);
1166 if (other)
1167 sock_put(other);
1168 return err;
1169}
1170
1171static int unix_socketpair(struct socket *socka, struct socket *sockb)
1172{
1173 struct sock *ska=socka->sk, *skb = sockb->sk;
1174
1175 /* Join our sockets back to back */
1176 sock_hold(ska);
1177 sock_hold(skb);
1178 unix_peer(ska)=skb;
1179 unix_peer(skb)=ska;
Pavel Emelyanovb4888932007-10-18 23:40:14 -07001180 ska->sk_peercred.pid = skb->sk_peercred.pid = task_tgid_vnr(current);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 ska->sk_peercred.uid = skb->sk_peercred.uid = current->euid;
1182 ska->sk_peercred.gid = skb->sk_peercred.gid = current->egid;
1183
1184 if (ska->sk_type != SOCK_DGRAM) {
1185 ska->sk_state = TCP_ESTABLISHED;
1186 skb->sk_state = TCP_ESTABLISHED;
1187 socka->state = SS_CONNECTED;
1188 sockb->state = SS_CONNECTED;
1189 }
1190 return 0;
1191}
1192
1193static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
1194{
1195 struct sock *sk = sock->sk;
1196 struct sock *tsk;
1197 struct sk_buff *skb;
1198 int err;
1199
1200 err = -EOPNOTSUPP;
1201 if (sock->type!=SOCK_STREAM && sock->type!=SOCK_SEQPACKET)
1202 goto out;
1203
1204 err = -EINVAL;
1205 if (sk->sk_state != TCP_LISTEN)
1206 goto out;
1207
1208 /* If socket state is TCP_LISTEN it cannot change (for now...),
1209 * so that no locks are necessary.
1210 */
1211
1212 skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
1213 if (!skb) {
1214 /* This means receive shutdown. */
1215 if (err == 0)
1216 err = -EINVAL;
1217 goto out;
1218 }
1219
1220 tsk = skb->sk;
1221 skb_free_datagram(sk, skb);
1222 wake_up_interruptible(&unix_sk(sk)->peer_wait);
1223
1224 /* attach accepted sock to socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001225 unix_state_lock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 newsock->state = SS_CONNECTED;
1227 sock_graft(tsk, newsock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001228 unix_state_unlock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 return 0;
1230
1231out:
1232 return err;
1233}
1234
1235
1236static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
1237{
1238 struct sock *sk = sock->sk;
1239 struct unix_sock *u;
1240 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
1241 int err = 0;
1242
1243 if (peer) {
1244 sk = unix_peer_get(sk);
1245
1246 err = -ENOTCONN;
1247 if (!sk)
1248 goto out;
1249 err = 0;
1250 } else {
1251 sock_hold(sk);
1252 }
1253
1254 u = unix_sk(sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001255 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 if (!u->addr) {
1257 sunaddr->sun_family = AF_UNIX;
1258 sunaddr->sun_path[0] = 0;
1259 *uaddr_len = sizeof(short);
1260 } else {
1261 struct unix_address *addr = u->addr;
1262
1263 *uaddr_len = addr->len;
1264 memcpy(sunaddr, addr->name, *uaddr_len);
1265 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07001266 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 sock_put(sk);
1268out:
1269 return err;
1270}
1271
1272static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1273{
1274 int i;
1275
1276 scm->fp = UNIXCB(skb).fp;
1277 skb->destructor = sock_wfree;
1278 UNIXCB(skb).fp = NULL;
1279
1280 for (i=scm->fp->count-1; i>=0; i--)
1281 unix_notinflight(scm->fp->fp[i]);
1282}
1283
1284static void unix_destruct_fds(struct sk_buff *skb)
1285{
1286 struct scm_cookie scm;
1287 memset(&scm, 0, sizeof(scm));
1288 unix_detach_fds(&scm, skb);
1289
1290 /* Alas, it calls VFS */
1291 /* So fscking what? fput() had been SMP-safe since the last Summer */
1292 scm_destroy(&scm);
1293 sock_wfree(skb);
1294}
1295
1296static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1297{
1298 int i;
1299 for (i=scm->fp->count-1; i>=0; i--)
1300 unix_inflight(scm->fp->fp[i]);
1301 UNIXCB(skb).fp = scm->fp;
1302 skb->destructor = unix_destruct_fds;
1303 scm->fp = NULL;
1304}
1305
1306/*
1307 * Send AF_UNIX data.
1308 */
1309
1310static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1311 struct msghdr *msg, size_t len)
1312{
1313 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1314 struct sock *sk = sock->sk;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001315 struct net *net = sk->sk_net;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 struct unix_sock *u = unix_sk(sk);
1317 struct sockaddr_un *sunaddr=msg->msg_name;
1318 struct sock *other = NULL;
1319 int namelen = 0; /* fake GCC */
1320 int err;
1321 unsigned hash;
1322 struct sk_buff *skb;
1323 long timeo;
1324 struct scm_cookie tmp_scm;
1325
1326 if (NULL == siocb->scm)
1327 siocb->scm = &tmp_scm;
1328 err = scm_send(sock, msg, siocb->scm);
1329 if (err < 0)
1330 return err;
1331
1332 err = -EOPNOTSUPP;
1333 if (msg->msg_flags&MSG_OOB)
1334 goto out;
1335
1336 if (msg->msg_namelen) {
1337 err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
1338 if (err < 0)
1339 goto out;
1340 namelen = err;
1341 } else {
1342 sunaddr = NULL;
1343 err = -ENOTCONN;
1344 other = unix_peer_get(sk);
1345 if (!other)
1346 goto out;
1347 }
1348
1349 if (test_bit(SOCK_PASSCRED, &sock->flags)
1350 && !u->addr && (err = unix_autobind(sock)) != 0)
1351 goto out;
1352
1353 err = -EMSGSIZE;
1354 if (len > sk->sk_sndbuf - 32)
1355 goto out;
1356
1357 skb = sock_alloc_send_skb(sk, len, msg->msg_flags&MSG_DONTWAIT, &err);
1358 if (skb==NULL)
1359 goto out;
1360
1361 memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
1362 if (siocb->scm->fp)
1363 unix_attach_fds(siocb->scm, skb);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07001364 unix_get_secdata(siocb->scm, skb);
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001365
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -03001366 skb_reset_transport_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367 err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
1368 if (err)
1369 goto out_free;
1370
1371 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1372
1373restart:
1374 if (!other) {
1375 err = -ECONNRESET;
1376 if (sunaddr == NULL)
1377 goto out_free;
1378
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001379 other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 hash, &err);
1381 if (other==NULL)
1382 goto out_free;
1383 }
1384
David S. Miller1c92b4e2007-05-31 13:24:26 -07001385 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 err = -EPERM;
1387 if (!unix_may_send(sk, other))
1388 goto out_unlock;
1389
1390 if (sock_flag(other, SOCK_DEAD)) {
1391 /*
1392 * Check with 1003.1g - what should
1393 * datagram error
1394 */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001395 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 sock_put(other);
1397
1398 err = 0;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001399 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 if (unix_peer(sk) == other) {
1401 unix_peer(sk)=NULL;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001402 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
1404 unix_dgram_disconnected(sk, other);
1405 sock_put(other);
1406 err = -ECONNREFUSED;
1407 } else {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001408 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 }
1410
1411 other = NULL;
1412 if (err)
1413 goto out_free;
1414 goto restart;
1415 }
1416
1417 err = -EPIPE;
1418 if (other->sk_shutdown & RCV_SHUTDOWN)
1419 goto out_unlock;
1420
1421 if (sk->sk_type != SOCK_SEQPACKET) {
1422 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1423 if (err)
1424 goto out_unlock;
1425 }
1426
1427 if (unix_peer(other) != sk &&
David S. Miller64a14652007-03-06 11:21:05 -08001428 (skb_queue_len(&other->sk_receive_queue) >
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 other->sk_max_ack_backlog)) {
1430 if (!timeo) {
1431 err = -EAGAIN;
1432 goto out_unlock;
1433 }
1434
1435 timeo = unix_wait_for_peer(other, timeo);
1436
1437 err = sock_intr_errno(timeo);
1438 if (signal_pending(current))
1439 goto out_free;
1440
1441 goto restart;
1442 }
1443
1444 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001445 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 other->sk_data_ready(other, len);
1447 sock_put(other);
1448 scm_destroy(siocb->scm);
1449 return len;
1450
1451out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -07001452 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453out_free:
1454 kfree_skb(skb);
1455out:
1456 if (other)
1457 sock_put(other);
1458 scm_destroy(siocb->scm);
1459 return err;
1460}
1461
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001462
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1464 struct msghdr *msg, size_t len)
1465{
1466 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1467 struct sock *sk = sock->sk;
1468 struct sock *other = NULL;
1469 struct sockaddr_un *sunaddr=msg->msg_name;
1470 int err,size;
1471 struct sk_buff *skb;
1472 int sent=0;
1473 struct scm_cookie tmp_scm;
1474
1475 if (NULL == siocb->scm)
1476 siocb->scm = &tmp_scm;
1477 err = scm_send(sock, msg, siocb->scm);
1478 if (err < 0)
1479 return err;
1480
1481 err = -EOPNOTSUPP;
1482 if (msg->msg_flags&MSG_OOB)
1483 goto out_err;
1484
1485 if (msg->msg_namelen) {
1486 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
1487 goto out_err;
1488 } else {
1489 sunaddr = NULL;
1490 err = -ENOTCONN;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001491 other = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 if (!other)
1493 goto out_err;
1494 }
1495
1496 if (sk->sk_shutdown & SEND_SHUTDOWN)
1497 goto pipe_err;
1498
1499 while(sent < len)
1500 {
1501 /*
Benjamin LaHaisee9df7d72006-03-20 21:29:05 -08001502 * Optimisation for the fact that under 0.01% of X
1503 * messages typically need breaking up.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 */
1505
Benjamin LaHaisee9df7d72006-03-20 21:29:05 -08001506 size = len-sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507
1508 /* Keep two messages in the pipe so it schedules better */
Benjamin LaHaisee9df7d72006-03-20 21:29:05 -08001509 if (size > ((sk->sk_sndbuf >> 1) - 64))
1510 size = (sk->sk_sndbuf >> 1) - 64;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511
1512 if (size > SKB_MAX_ALLOC)
1513 size = SKB_MAX_ALLOC;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001514
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 /*
1516 * Grab a buffer
1517 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001518
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519 skb=sock_alloc_send_skb(sk,size,msg->msg_flags&MSG_DONTWAIT, &err);
1520
1521 if (skb==NULL)
1522 goto out_err;
1523
1524 /*
1525 * If you pass two values to the sock_alloc_send_skb
1526 * it tries to grab the large buffer with GFP_NOFS
1527 * (which can fail easily), and if it fails grab the
1528 * fallback size buffer which is under a page and will
1529 * succeed. [Alan]
1530 */
1531 size = min_t(int, size, skb_tailroom(skb));
1532
1533 memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
1534 if (siocb->scm->fp)
1535 unix_attach_fds(siocb->scm, skb);
1536
1537 if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) {
1538 kfree_skb(skb);
1539 goto out_err;
1540 }
1541
David S. Miller1c92b4e2007-05-31 13:24:26 -07001542 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543
1544 if (sock_flag(other, SOCK_DEAD) ||
1545 (other->sk_shutdown & RCV_SHUTDOWN))
1546 goto pipe_err_free;
1547
1548 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001549 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 other->sk_data_ready(other, size);
1551 sent+=size;
1552 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553
1554 scm_destroy(siocb->scm);
1555 siocb->scm = NULL;
1556
1557 return sent;
1558
1559pipe_err_free:
David S. Miller1c92b4e2007-05-31 13:24:26 -07001560 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 kfree_skb(skb);
1562pipe_err:
1563 if (sent==0 && !(msg->msg_flags&MSG_NOSIGNAL))
1564 send_sig(SIGPIPE,current,0);
1565 err = -EPIPE;
1566out_err:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 scm_destroy(siocb->scm);
1568 siocb->scm = NULL;
1569 return sent ? : err;
1570}
1571
1572static int unix_seqpacket_sendmsg(struct kiocb *kiocb, struct socket *sock,
1573 struct msghdr *msg, size_t len)
1574{
1575 int err;
1576 struct sock *sk = sock->sk;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001577
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 err = sock_error(sk);
1579 if (err)
1580 return err;
1581
1582 if (sk->sk_state != TCP_ESTABLISHED)
1583 return -ENOTCONN;
1584
1585 if (msg->msg_namelen)
1586 msg->msg_namelen = 0;
1587
1588 return unix_dgram_sendmsg(kiocb, sock, msg, len);
1589}
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001590
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
1592{
1593 struct unix_sock *u = unix_sk(sk);
1594
1595 msg->msg_namelen = 0;
1596 if (u->addr) {
1597 msg->msg_namelen = u->addr->len;
1598 memcpy(msg->msg_name, u->addr->name, u->addr->len);
1599 }
1600}
1601
1602static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1603 struct msghdr *msg, size_t size,
1604 int flags)
1605{
1606 struct sock_iocb *siocb = kiocb_to_siocb(iocb);
1607 struct scm_cookie tmp_scm;
1608 struct sock *sk = sock->sk;
1609 struct unix_sock *u = unix_sk(sk);
1610 int noblock = flags & MSG_DONTWAIT;
1611 struct sk_buff *skb;
1612 int err;
1613
1614 err = -EOPNOTSUPP;
1615 if (flags&MSG_OOB)
1616 goto out;
1617
1618 msg->msg_namelen = 0;
1619
Ingo Molnar57b47a52006-03-20 22:35:41 -08001620 mutex_lock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621
1622 skb = skb_recv_datagram(sk, flags, noblock, &err);
Florian Zumbiehl0a112252007-11-29 23:19:23 +11001623 if (!skb) {
1624 unix_state_lock(sk);
1625 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
1626 if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
1627 (sk->sk_shutdown & RCV_SHUTDOWN))
1628 err = 0;
1629 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 goto out_unlock;
Florian Zumbiehl0a112252007-11-29 23:19:23 +11001631 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632
Ingo Molnar71e20f12007-10-15 17:00:19 +02001633 wake_up_interruptible_sync(&u->peer_wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634
1635 if (msg->msg_name)
1636 unix_copy_addr(msg, skb->sk);
1637
1638 if (size > skb->len)
1639 size = skb->len;
1640 else if (size < skb->len)
1641 msg->msg_flags |= MSG_TRUNC;
1642
1643 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
1644 if (err)
1645 goto out_free;
1646
1647 if (!siocb->scm) {
1648 siocb->scm = &tmp_scm;
1649 memset(&tmp_scm, 0, sizeof(tmp_scm));
1650 }
1651 siocb->scm->creds = *UNIXCREDS(skb);
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001652 unix_set_secdata(siocb->scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653
1654 if (!(flags & MSG_PEEK))
1655 {
1656 if (UNIXCB(skb).fp)
1657 unix_detach_fds(siocb->scm, skb);
1658 }
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001659 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 {
1661 /* It is questionable: on PEEK we could:
1662 - do not return fds - good, but too simple 8)
1663 - return fds, and do not return them on read (old strategy,
1664 apparently wrong)
1665 - clone fds (I chose it for now, it is the most universal
1666 solution)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001667
1668 POSIX 1003.1g does not actually define this clearly
1669 at all. POSIX 1003.1g doesn't define a lot of things
1670 clearly however!
1671
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 */
1673 if (UNIXCB(skb).fp)
1674 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
1675 }
1676 err = size;
1677
1678 scm_recv(sock, msg, siocb->scm, flags);
1679
1680out_free:
1681 skb_free_datagram(sk,skb);
1682out_unlock:
Ingo Molnar57b47a52006-03-20 22:35:41 -08001683 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684out:
1685 return err;
1686}
1687
1688/*
1689 * Sleep until data has arrive. But check for races..
1690 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001691
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692static long unix_stream_data_wait(struct sock * sk, long timeo)
1693{
1694 DEFINE_WAIT(wait);
1695
David S. Miller1c92b4e2007-05-31 13:24:26 -07001696 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
1698 for (;;) {
1699 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
1700
David S. Millerb03efcf2005-07-08 14:57:23 -07001701 if (!skb_queue_empty(&sk->sk_receive_queue) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 sk->sk_err ||
1703 (sk->sk_shutdown & RCV_SHUTDOWN) ||
1704 signal_pending(current) ||
1705 !timeo)
1706 break;
1707
1708 set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001709 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 timeo = schedule_timeout(timeo);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001711 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
1713 }
1714
1715 finish_wait(sk->sk_sleep, &wait);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001716 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 return timeo;
1718}
1719
1720
1721
1722static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1723 struct msghdr *msg, size_t size,
1724 int flags)
1725{
1726 struct sock_iocb *siocb = kiocb_to_siocb(iocb);
1727 struct scm_cookie tmp_scm;
1728 struct sock *sk = sock->sk;
1729 struct unix_sock *u = unix_sk(sk);
1730 struct sockaddr_un *sunaddr=msg->msg_name;
1731 int copied = 0;
1732 int check_creds = 0;
1733 int target;
1734 int err = 0;
1735 long timeo;
1736
1737 err = -EINVAL;
1738 if (sk->sk_state != TCP_ESTABLISHED)
1739 goto out;
1740
1741 err = -EOPNOTSUPP;
1742 if (flags&MSG_OOB)
1743 goto out;
1744
1745 target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
1746 timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
1747
1748 msg->msg_namelen = 0;
1749
1750 /* Lock the socket to prevent queue disordering
1751 * while sleeps in memcpy_tomsg
1752 */
1753
1754 if (!siocb->scm) {
1755 siocb->scm = &tmp_scm;
1756 memset(&tmp_scm, 0, sizeof(tmp_scm));
1757 }
1758
Ingo Molnar57b47a52006-03-20 22:35:41 -08001759 mutex_lock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
1761 do
1762 {
1763 int chunk;
1764 struct sk_buff *skb;
1765
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001766 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 skb = skb_dequeue(&sk->sk_receive_queue);
1768 if (skb==NULL)
1769 {
1770 if (copied >= target)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001771 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772
1773 /*
1774 * POSIX 1003.1g mandates this order.
1775 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001776
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 if ((err = sock_error(sk)) != 0)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001778 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 if (sk->sk_shutdown & RCV_SHUTDOWN)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001780 goto unlock;
1781
1782 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 err = -EAGAIN;
1784 if (!timeo)
1785 break;
Ingo Molnar57b47a52006-03-20 22:35:41 -08001786 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787
1788 timeo = unix_stream_data_wait(sk, timeo);
1789
1790 if (signal_pending(current)) {
1791 err = sock_intr_errno(timeo);
1792 goto out;
1793 }
Ingo Molnar57b47a52006-03-20 22:35:41 -08001794 mutex_lock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 continue;
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001796 unlock:
1797 unix_state_unlock(sk);
1798 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 }
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07001800 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801
1802 if (check_creds) {
1803 /* Never glue messages from different writers */
1804 if (memcmp(UNIXCREDS(skb), &siocb->scm->creds, sizeof(siocb->scm->creds)) != 0) {
1805 skb_queue_head(&sk->sk_receive_queue, skb);
1806 break;
1807 }
1808 } else {
1809 /* Copy credentials */
1810 siocb->scm->creds = *UNIXCREDS(skb);
1811 check_creds = 1;
1812 }
1813
1814 /* Copy address just once */
1815 if (sunaddr)
1816 {
1817 unix_copy_addr(msg, skb->sk);
1818 sunaddr = NULL;
1819 }
1820
1821 chunk = min_t(unsigned int, skb->len, size);
1822 if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
1823 skb_queue_head(&sk->sk_receive_queue, skb);
1824 if (copied == 0)
1825 copied = -EFAULT;
1826 break;
1827 }
1828 copied += chunk;
1829 size -= chunk;
1830
1831 /* Mark read part of skb as used */
1832 if (!(flags & MSG_PEEK))
1833 {
1834 skb_pull(skb, chunk);
1835
1836 if (UNIXCB(skb).fp)
1837 unix_detach_fds(siocb->scm, skb);
1838
1839 /* put the skb back if we didn't use it up.. */
1840 if (skb->len)
1841 {
1842 skb_queue_head(&sk->sk_receive_queue, skb);
1843 break;
1844 }
1845
1846 kfree_skb(skb);
1847
1848 if (siocb->scm->fp)
1849 break;
1850 }
1851 else
1852 {
1853 /* It is questionable, see note in unix_dgram_recvmsg.
1854 */
1855 if (UNIXCB(skb).fp)
1856 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
1857
1858 /* put message back and return */
1859 skb_queue_head(&sk->sk_receive_queue, skb);
1860 break;
1861 }
1862 } while (size);
1863
Ingo Molnar57b47a52006-03-20 22:35:41 -08001864 mutex_unlock(&u->readlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 scm_recv(sock, msg, siocb->scm, flags);
1866out:
1867 return copied ? : err;
1868}
1869
1870static int unix_shutdown(struct socket *sock, int mode)
1871{
1872 struct sock *sk = sock->sk;
1873 struct sock *other;
1874
1875 mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN);
1876
1877 if (mode) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001878 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 sk->sk_shutdown |= mode;
1880 other=unix_peer(sk);
1881 if (other)
1882 sock_hold(other);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001883 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 sk->sk_state_change(sk);
1885
1886 if (other &&
1887 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
1888
1889 int peer_mode = 0;
1890
1891 if (mode&RCV_SHUTDOWN)
1892 peer_mode |= SEND_SHUTDOWN;
1893 if (mode&SEND_SHUTDOWN)
1894 peer_mode |= RCV_SHUTDOWN;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001895 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 other->sk_shutdown |= peer_mode;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001897 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 other->sk_state_change(other);
1899 read_lock(&other->sk_callback_lock);
1900 if (peer_mode == SHUTDOWN_MASK)
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +08001901 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 else if (peer_mode & RCV_SHUTDOWN)
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +08001903 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 read_unlock(&other->sk_callback_lock);
1905 }
1906 if (other)
1907 sock_put(other);
1908 }
1909 return 0;
1910}
1911
1912static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1913{
1914 struct sock *sk = sock->sk;
1915 long amount=0;
1916 int err;
1917
1918 switch(cmd)
1919 {
1920 case SIOCOUTQ:
1921 amount = atomic_read(&sk->sk_wmem_alloc);
1922 err = put_user(amount, (int __user *)arg);
1923 break;
1924 case SIOCINQ:
1925 {
1926 struct sk_buff *skb;
1927
1928 if (sk->sk_state == TCP_LISTEN) {
1929 err = -EINVAL;
1930 break;
1931 }
1932
1933 spin_lock(&sk->sk_receive_queue.lock);
1934 if (sk->sk_type == SOCK_STREAM ||
1935 sk->sk_type == SOCK_SEQPACKET) {
1936 skb_queue_walk(&sk->sk_receive_queue, skb)
1937 amount += skb->len;
1938 } else {
1939 skb = skb_peek(&sk->sk_receive_queue);
1940 if (skb)
1941 amount=skb->len;
1942 }
1943 spin_unlock(&sk->sk_receive_queue.lock);
1944 err = put_user(amount, (int __user *)arg);
1945 break;
1946 }
1947
1948 default:
Christoph Hellwigb5e5fa52006-01-03 14:18:33 -08001949 err = -ENOIOCTLCMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 break;
1951 }
1952 return err;
1953}
1954
1955static unsigned int unix_poll(struct file * file, struct socket *sock, poll_table *wait)
1956{
1957 struct sock *sk = sock->sk;
1958 unsigned int mask;
1959
1960 poll_wait(file, sk->sk_sleep, wait);
1961 mask = 0;
1962
1963 /* exceptional events? */
1964 if (sk->sk_err)
1965 mask |= POLLERR;
1966 if (sk->sk_shutdown == SHUTDOWN_MASK)
1967 mask |= POLLHUP;
Davide Libenzif348d702006-03-25 03:07:39 -08001968 if (sk->sk_shutdown & RCV_SHUTDOWN)
1969 mask |= POLLRDHUP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970
1971 /* readable? */
1972 if (!skb_queue_empty(&sk->sk_receive_queue) ||
1973 (sk->sk_shutdown & RCV_SHUTDOWN))
1974 mask |= POLLIN | POLLRDNORM;
1975
1976 /* Connection-based need to check for termination and startup */
1977 if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) && sk->sk_state == TCP_CLOSE)
1978 mask |= POLLHUP;
1979
1980 /*
1981 * we set writable also when the other side has shut down the
1982 * connection. This prevents stuck sockets.
1983 */
1984 if (unix_writable(sk))
1985 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
1986
1987 return mask;
1988}
1989
1990
1991#ifdef CONFIG_PROC_FS
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08001992static struct sock *first_unix_socket(int *i)
1993{
1994 for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
1995 if (!hlist_empty(&unix_socket_table[*i]))
1996 return __sk_head(&unix_socket_table[*i]);
1997 }
1998 return NULL;
1999}
2000
2001static struct sock *next_unix_socket(int *i, struct sock *s)
2002{
2003 struct sock *next = sk_next(s);
2004 /* More in this chain? */
2005 if (next)
2006 return next;
2007 /* Look for next non-empty chain. */
2008 for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
2009 if (!hlist_empty(&unix_socket_table[*i]))
2010 return __sk_head(&unix_socket_table[*i]);
2011 }
2012 return NULL;
2013}
2014
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002015struct unix_iter_state {
Denis V. Luneve372c412007-11-19 22:31:54 -08002016 struct seq_net_private p;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002017 int i;
2018};
2019static struct sock *unix_seq_idx(struct unix_iter_state *iter, loff_t pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020{
2021 loff_t off = 0;
2022 struct sock *s;
2023
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002024 for (s = first_unix_socket(&iter->i); s; s = next_unix_socket(&iter->i, s)) {
Denis V. Luneve372c412007-11-19 22:31:54 -08002025 if (s->sk_net != iter->p.net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002026 continue;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002027 if (off == pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 return s;
2029 ++off;
2030 }
2031 return NULL;
2032}
2033
2034
2035static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002036 __acquires(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037{
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002038 struct unix_iter_state *iter = seq->private;
David S. Millerfbe9cc42005-12-13 23:26:29 -08002039 spin_lock(&unix_table_lock);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002040 return *pos ? unix_seq_idx(iter, *pos - 1) : ((void *) 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041}
2042
2043static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2044{
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002045 struct unix_iter_state *iter = seq->private;
2046 struct sock *sk = v;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 ++*pos;
2048
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002049 if (v == (void *)1)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002050 sk = first_unix_socket(&iter->i);
2051 else
2052 sk = next_unix_socket(&iter->i, sk);
Denis V. Luneve372c412007-11-19 22:31:54 -08002053 while (sk && (sk->sk_net != iter->p.net))
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002054 sk = next_unix_socket(&iter->i, sk);
2055 return sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056}
2057
2058static void unix_seq_stop(struct seq_file *seq, void *v)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002059 __releases(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002061 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062}
2063
2064static int unix_seq_show(struct seq_file *seq, void *v)
2065{
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002066
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067 if (v == (void *)1)
2068 seq_puts(seq, "Num RefCount Protocol Flags Type St "
2069 "Inode Path\n");
2070 else {
2071 struct sock *s = v;
2072 struct unix_sock *u = unix_sk(s);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002073 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074
2075 seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu",
2076 s,
2077 atomic_read(&s->sk_refcnt),
2078 0,
2079 s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
2080 s->sk_type,
2081 s->sk_socket ?
2082 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
2083 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
2084 sock_i_ino(s));
2085
2086 if (u->addr) {
2087 int i, len;
2088 seq_putc(seq, ' ');
2089
2090 i = 0;
2091 len = u->addr->len - sizeof(short);
2092 if (!UNIX_ABSTRACT(s))
2093 len--;
2094 else {
2095 seq_putc(seq, '@');
2096 i++;
2097 }
2098 for ( ; i < len; i++)
2099 seq_putc(seq, u->addr->name->sun_path[i]);
2100 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07002101 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102 seq_putc(seq, '\n');
2103 }
2104
2105 return 0;
2106}
2107
Philippe De Muyter56b3d972007-07-10 23:07:31 -07002108static const struct seq_operations unix_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109 .start = unix_seq_start,
2110 .next = unix_seq_next,
2111 .stop = unix_seq_stop,
2112 .show = unix_seq_show,
2113};
2114
2115
2116static int unix_seq_open(struct inode *inode, struct file *file)
2117{
Denis V. Luneve372c412007-11-19 22:31:54 -08002118 return seq_open_net(inode, file, &unix_seq_ops,
2119 sizeof(struct unix_iter_state));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120}
2121
Arjan van de Venda7071d2007-02-12 00:55:36 -08002122static const struct file_operations unix_seq_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 .owner = THIS_MODULE,
2124 .open = unix_seq_open,
2125 .read = seq_read,
2126 .llseek = seq_lseek,
Denis V. Luneve372c412007-11-19 22:31:54 -08002127 .release = seq_release_net,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128};
2129
2130#endif
2131
2132static struct net_proto_family unix_family_ops = {
2133 .family = PF_UNIX,
2134 .create = unix_create,
2135 .owner = THIS_MODULE,
2136};
2137
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002138
2139static int unix_net_init(struct net *net)
2140{
2141 int error = -ENOMEM;
2142
Denis V. Luneva0a53c82007-12-11 04:19:17 -08002143 net->unx.sysctl_max_dgram_qlen = 10;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002144 if (unix_sysctl_register(net))
2145 goto out;
Pavel Emelyanovd392e492007-12-01 23:44:15 +11002146
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002147#ifdef CONFIG_PROC_FS
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002148 if (!proc_net_fops_create(net, "unix", 0, &unix_seq_fops)) {
2149 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002150 goto out;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002151 }
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002152#endif
2153 error = 0;
2154out:
2155 return 0;
2156}
2157
2158static void unix_net_exit(struct net *net)
2159{
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002160 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002161 proc_net_remove(net, "unix");
2162}
2163
2164static struct pernet_operations unix_net_ops = {
2165 .init = unix_net_init,
2166 .exit = unix_net_exit,
2167};
2168
Linus Torvalds1da177e2005-04-16 15:20:36 -07002169static int __init af_unix_init(void)
2170{
2171 int rc = -1;
2172 struct sk_buff *dummy_skb;
2173
YOSHIFUJI Hideakief047f52006-09-01 00:29:06 -07002174 BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175
2176 rc = proto_register(&unix_proto, 1);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002177 if (rc != 0) {
2178 printk(KERN_CRIT "%s: Cannot create unix_sock SLAB cache!\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179 __FUNCTION__);
2180 goto out;
2181 }
2182
2183 sock_register(&unix_family_ops);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002184 register_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002185out:
2186 return rc;
2187}
2188
2189static void __exit af_unix_exit(void)
2190{
2191 sock_unregister(PF_UNIX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192 proto_unregister(&unix_proto);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002193 unregister_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194}
2195
2196module_init(af_unix_init);
2197module_exit(af_unix_exit);
2198
2199MODULE_LICENSE("GPL");
2200MODULE_ALIAS_NETPROTO(PF_UNIX);