blob: 050eed3b30dc4241bb3dc9207f70eabeb49ab68d [file] [log] [blame]
Thomas Gleixner2874c5f2019-05-27 08:55:01 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * NET4: Implementation of BSD Unix domain sockets.
4 *
Alan Cox113aa832008-10-13 19:01:08 -07005 * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk>
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 * Fixes:
8 * Linus Torvalds : Assorted bug cures.
9 * Niibe Yutaka : async I/O support.
10 * Carsten Paeth : PF_UNIX check, address fixes.
11 * Alan Cox : Limit size of allocated blocks.
12 * Alan Cox : Fixed the stupid socketpair bug.
13 * Alan Cox : BSD compatibility fine tuning.
14 * Alan Cox : Fixed a bug in connect when interrupted.
15 * Alan Cox : Sorted out a proper draft version of
16 * file descriptor passing hacked up from
17 * Mike Shaver's work.
18 * Marty Leisner : Fixes to fd passing
19 * Nick Nevin : recvmsg bugfix.
20 * Alan Cox : Started proper garbage collector
21 * Heiko EiBfeldt : Missing verify_area check
22 * Alan Cox : Started POSIXisms
23 * Andreas Schwab : Replace inode by dentry for proper
24 * reference counting
25 * Kirk Petersen : Made this a module
26 * Christoph Rohland : Elegant non-blocking accept/connect algorithm.
27 * Lots of bug fixes.
28 * Alexey Kuznetosv : Repaired (I hope) bugs introduces
29 * by above two patches.
30 * Andrea Arcangeli : If possible we block in connect(2)
31 * if the max backlog of the listen socket
32 * is been reached. This won't break
33 * old apps and it will avoid huge amount
34 * of socks hashed (this for unix_gc()
35 * performances reasons).
36 * Security fix that limits the max
37 * number of socks to 2*max_files and
38 * the number of skb queueable in the
39 * dgram receiver.
40 * Artur Skawina : Hash function optimizations
41 * Alexey Kuznetsov : Full scale SMP. Lot of bugs are introduced 8)
42 * Malcolm Beattie : Set peercred for socketpair
43 * Michal Ostrowski : Module initialization cleanup.
44 * Arnaldo C. Melo : Remove MOD_{INC,DEC}_USE_COUNT,
45 * the core infrastructure is doing that
46 * for all net proto families now (2.5.69+)
47 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070048 * Known differences from reference BSD that was tested:
49 *
50 * [TO FIX]
51 * ECONNREFUSED is not returned from one end of a connected() socket to the
52 * other the moment one end closes.
53 * fstat() doesn't return st_dev=0, and give the blksize as high water mark
54 * and a fake inode identifier (nor the BSD first socket fstat twice bug).
55 * [NOT TO FIX]
56 * accept() returns a path name even if the connecting socket has closed
57 * in the meantime (BSD loses the path and gives up).
58 * accept() returns 0 length path for an unbound connector. BSD returns 16
59 * and a null first byte in the path (but not for gethost/peername - BSD bug ??)
60 * socketpair(...SOCK_RAW..) doesn't panic the kernel.
61 * BSD af_unix apparently has connect forgetting to block properly.
62 * (need to check this with the POSIX spec in detail)
63 *
64 * Differences from 2.0.0-11-... (ANK)
65 * Bug fixes and improvements.
66 * - client shutdown killed server socket.
67 * - removed all useless cli/sti pairs.
68 *
69 * Semantic changes/extensions.
70 * - generic control message passing.
71 * - SCM_CREDENTIALS control message.
72 * - "Abstract" (not FS based) socket bindings.
73 * Abstract names are sequences of bytes (not zero terminated)
74 * started by 0, so that this name space does not intersect
75 * with BSD names.
76 */
77
wangweidong5cc208b2013-12-06 18:03:36 +080078#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
79
Linus Torvalds1da177e2005-04-16 15:20:36 -070080#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070081#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070082#include <linux/signal.h>
Ingo Molnar3f07c012017-02-08 18:51:30 +010083#include <linux/sched/signal.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070084#include <linux/errno.h>
85#include <linux/string.h>
86#include <linux/stat.h>
87#include <linux/dcache.h>
88#include <linux/namei.h>
89#include <linux/socket.h>
90#include <linux/un.h>
91#include <linux/fcntl.h>
92#include <linux/termios.h>
93#include <linux/sockios.h>
94#include <linux/net.h>
95#include <linux/in.h>
96#include <linux/fs.h>
97#include <linux/slab.h>
Linus Torvalds7c0f6ba2016-12-24 11:46:01 -080098#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070099#include <linux/skbuff.h>
100#include <linux/netdevice.h>
Eric W. Biederman457c4cb2007-09-12 12:01:34 +0200101#include <net/net_namespace.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102#include <net/sock.h>
Arnaldo Carvalho de Meloc752f072005-08-09 20:08:28 -0700103#include <net/tcp_states.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104#include <net/af_unix.h>
105#include <linux/proc_fs.h>
106#include <linux/seq_file.h>
107#include <net/scm.h>
108#include <linux/init.h>
109#include <linux/poll.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110#include <linux/rtnetlink.h>
111#include <linux/mount.h>
112#include <net/checksum.h>
113#include <linux/security.h>
Colin Cross2b15af62013-05-06 23:50:21 +0000114#include <linux/freezer.h>
Andrey Vaginba94f302017-02-01 11:00:45 -0800115#include <linux/file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116
Jens Axboef4e65872019-02-08 09:01:44 -0700117#include "scm.h"
118
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{
Stephen Smalley37a9a8d2015-06-10 08:44:59 -0400141 UNIXCB(skb).secid = scm->secid;
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700142}
143
144static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
145{
Stephen Smalley37a9a8d2015-06-10 08:44:59 -0400146 scm->secid = UNIXCB(skb).secid;
147}
148
149static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
150{
151 return (scm->secid == UNIXCB(skb).secid);
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700152}
153#else
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700154static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700155{ }
156
157static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
158{ }
Stephen Smalley37a9a8d2015-06-10 08:44:59 -0400159
160static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
161{
162 return true;
163}
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700164#endif /* CONFIG_SECURITY_NETWORK */
165
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166/*
167 * SMP locking strategy:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800168 * hash table is protected with spinlock unix_table_lock
Stephen Hemminger663717f2010-02-18 14:12:06 -0800169 * each socket state is protected by separate spin lock.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 */
171
Eric Dumazet95c96172012-04-15 05:58:06 +0000172static inline unsigned int unix_hash_fold(__wsum n)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173{
Anton Blanchard0a134042014-03-05 14:29:58 +1100174 unsigned int hash = (__force unsigned int)csum_fold(n);
Eric Dumazet95c96172012-04-15 05:58:06 +0000175
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 hash ^= hash>>8;
177 return hash&(UNIX_HASH_SIZE-1);
178}
179
180#define unix_peer(sk) (unix_sk(sk)->peer)
181
182static inline int unix_our_peer(struct sock *sk, struct sock *osk)
183{
184 return unix_peer(osk) == sk;
185}
186
187static inline int unix_may_send(struct sock *sk, struct sock *osk)
188{
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800189 return unix_peer(osk) == NULL || unix_our_peer(sk, osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190}
191
Rainer Weikusat3c734192008-06-17 22:28:05 -0700192static inline int unix_recvq_full(struct sock const *sk)
193{
194 return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
195}
196
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000197struct sock *unix_peer_get(struct sock *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198{
199 struct sock *peer;
200
David S. Miller1c92b4e2007-05-31 13:24:26 -0700201 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 peer = unix_peer(s);
203 if (peer)
204 sock_hold(peer);
David S. Miller1c92b4e2007-05-31 13:24:26 -0700205 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 return peer;
207}
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000208EXPORT_SYMBOL_GPL(unix_peer_get);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209
210static inline void unix_release_addr(struct unix_address *addr)
211{
Reshetova, Elena8c9814b2017-06-30 13:08:05 +0300212 if (refcount_dec_and_test(&addr->refcnt))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 kfree(addr);
214}
215
216/*
217 * Check unix socket name:
218 * - should be not zero length.
219 * - if started by not zero, should be NULL terminated (FS object)
220 * - if started by zero, it is abstract name.
221 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900222
Eric Dumazet95c96172012-04-15 05:58:06 +0000223static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned int *hashp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224{
Kyeongdon Kim33c43682018-10-16 14:57:26 +0900225 *hashp = 0;
226
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 if (len <= sizeof(short) || len > sizeof(*sunaddr))
228 return -EINVAL;
229 if (!sunaddr || sunaddr->sun_family != AF_UNIX)
230 return -EINVAL;
231 if (sunaddr->sun_path[0]) {
232 /*
233 * This may look like an off by one error but it is a bit more
234 * subtle. 108 is the longest valid AF_UNIX path for a binding.
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300235 * sun_path[108] doesn't as such exist. However in kernel space
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 * we are guaranteed that it is a valid memory location in our
237 * kernel address buffer.
238 */
Jianjun Konge27dfce2008-11-01 21:38:31 -0700239 ((char *)sunaddr)[len] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 len = strlen(sunaddr->sun_path)+1+sizeof(short);
241 return len;
242 }
243
Joe Perches07f07572008-11-19 15:44:53 -0800244 *hashp = unix_hash_fold(csum_partial(sunaddr, len, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 return len;
246}
247
248static void __unix_remove_socket(struct sock *sk)
249{
250 sk_del_node_init(sk);
251}
252
253static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
254{
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700255 WARN_ON(!sk_unhashed(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 sk_add_node(sk, list);
257}
258
259static inline void unix_remove_socket(struct sock *sk)
260{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800261 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 __unix_remove_socket(sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800263 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264}
265
266static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
267{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800268 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 __unix_insert_socket(list, sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800270 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271}
272
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800273static struct sock *__unix_find_socket_byname(struct net *net,
274 struct sockaddr_un *sunname,
Eric Dumazet95c96172012-04-15 05:58:06 +0000275 int len, int type, unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276{
277 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278
Sasha Levinb67bfe02013-02-27 17:06:00 -0800279 sk_for_each(s, &unix_socket_table[hash ^ type]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 struct unix_sock *u = unix_sk(s);
281
YOSHIFUJI Hideaki878628f2008-03-26 03:57:35 +0900282 if (!net_eq(sock_net(s), net))
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800283 continue;
284
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 if (u->addr->len == len &&
286 !memcmp(u->addr->name, sunname, len))
Vito Caputo262ce0a2019-10-09 20:43:47 -0700287 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 }
Vito Caputo262ce0a2019-10-09 20:43:47 -0700289 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290}
291
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800292static inline struct sock *unix_find_socket_byname(struct net *net,
293 struct sockaddr_un *sunname,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 int len, int type,
Eric Dumazet95c96172012-04-15 05:58:06 +0000295 unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296{
297 struct sock *s;
298
David S. Millerfbe9cc42005-12-13 23:26:29 -0800299 spin_lock(&unix_table_lock);
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800300 s = __unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 if (s)
302 sock_hold(s);
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
Eric W. Biederman6616f782010-06-13 03:35:48 +0000307static struct sock *unix_find_socket_byinode(struct inode *i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308{
309 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310
David S. Millerfbe9cc42005-12-13 23:26:29 -0800311 spin_lock(&unix_table_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800312 sk_for_each(s,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
Al Viro40ffe672012-03-14 21:54:32 -0400314 struct dentry *dentry = unix_sk(s)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315
Miklos Szeredibeef5122016-12-16 11:02:53 +0100316 if (dentry && d_backing_inode(dentry) == i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 sock_hold(s);
318 goto found;
319 }
320 }
321 s = NULL;
322found:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800323 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 return s;
325}
326
Rainer Weikusat7d267272015-11-20 22:07:23 +0000327/* Support code for asymmetrically connected dgram sockets
328 *
329 * If a datagram socket is connected to a socket not itself connected
330 * to the first socket (eg, /dev/log), clients may only enqueue more
331 * messages if the present receive queue of the server socket is not
332 * "too large". This means there's a second writeability condition
333 * poll and sendmsg need to test. The dgram recv code will do a wake
334 * up on the peer_wait wait queue of a socket upon reception of a
335 * datagram which needs to be propagated to sleeping would-be writers
336 * since these might not have sent anything so far. This can't be
337 * accomplished via poll_wait because the lifetime of the server
338 * socket might be less than that of its clients if these break their
339 * association with it or if the server socket is closed while clients
340 * are still connected to it and there's no way to inform "a polling
341 * implementation" that it should let go of a certain wait queue
342 *
Ingo Molnarac6424b2017-06-20 12:06:13 +0200343 * In order to propagate a wake up, a wait_queue_entry_t of the client
Rainer Weikusat7d267272015-11-20 22:07:23 +0000344 * socket is enqueued on the peer_wait queue of the server socket
345 * whose wake function does a wake_up on the ordinary client socket
346 * wait queue. This connection is established whenever a write (or
347 * poll for write) hit the flow control condition and broken when the
348 * association to the server socket is dissolved or after a wake up
349 * was relayed.
350 */
351
Ingo Molnarac6424b2017-06-20 12:06:13 +0200352static int unix_dgram_peer_wake_relay(wait_queue_entry_t *q, unsigned mode, int flags,
Rainer Weikusat7d267272015-11-20 22:07:23 +0000353 void *key)
354{
355 struct unix_sock *u;
356 wait_queue_head_t *u_sleep;
357
358 u = container_of(q, struct unix_sock, peer_wake);
359
360 __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
361 q);
362 u->peer_wake.private = NULL;
363
364 /* relaying can only happen while the wq still exists */
365 u_sleep = sk_sleep(&u->sk);
366 if (u_sleep)
Al Viro3ad6f932017-07-03 20:14:56 -0400367 wake_up_interruptible_poll(u_sleep, key_to_poll(key));
Rainer Weikusat7d267272015-11-20 22:07:23 +0000368
369 return 0;
370}
371
372static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
373{
374 struct unix_sock *u, *u_other;
375 int rc;
376
377 u = unix_sk(sk);
378 u_other = unix_sk(other);
379 rc = 0;
380 spin_lock(&u_other->peer_wait.lock);
381
382 if (!u->peer_wake.private) {
383 u->peer_wake.private = other;
384 __add_wait_queue(&u_other->peer_wait, &u->peer_wake);
385
386 rc = 1;
387 }
388
389 spin_unlock(&u_other->peer_wait.lock);
390 return rc;
391}
392
393static void unix_dgram_peer_wake_disconnect(struct sock *sk,
394 struct sock *other)
395{
396 struct unix_sock *u, *u_other;
397
398 u = unix_sk(sk);
399 u_other = unix_sk(other);
400 spin_lock(&u_other->peer_wait.lock);
401
402 if (u->peer_wake.private == other) {
403 __remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
404 u->peer_wake.private = NULL;
405 }
406
407 spin_unlock(&u_other->peer_wait.lock);
408}
409
410static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
411 struct sock *other)
412{
413 unix_dgram_peer_wake_disconnect(sk, other);
414 wake_up_interruptible_poll(sk_sleep(sk),
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800415 EPOLLOUT |
416 EPOLLWRNORM |
417 EPOLLWRBAND);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000418}
419
420/* preconditions:
421 * - unix_peer(sk) == other
422 * - association is stable
423 */
424static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
425{
426 int connected;
427
428 connected = unix_dgram_peer_wake_connect(sk, other);
429
Jason Baron51f7e952018-08-03 17:24:53 -0400430 /* If other is SOCK_DEAD, we want to make sure we signal
431 * POLLOUT, such that a subsequent write() can get a
432 * -ECONNREFUSED. Otherwise, if we haven't queued any skbs
433 * to other and its full, we will hang waiting for POLLOUT.
434 */
435 if (unix_recvq_full(other) && !sock_flag(other, SOCK_DEAD))
Rainer Weikusat7d267272015-11-20 22:07:23 +0000436 return 1;
437
438 if (connected)
439 unix_dgram_peer_wake_disconnect(sk, other);
440
441 return 0;
442}
443
Eric Dumazet1586a582015-10-23 10:59:16 -0700444static int unix_writable(const struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445{
Eric Dumazet1586a582015-10-23 10:59:16 -0700446 return sk->sk_state != TCP_LISTEN &&
Reshetova, Elena14afee42017-06-30 13:08:00 +0300447 (refcount_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448}
449
450static void unix_write_space(struct sock *sk)
451{
Eric Dumazet43815482010-04-29 11:01:49 +0000452 struct socket_wq *wq;
453
454 rcu_read_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 if (unix_writable(sk)) {
Eric Dumazet43815482010-04-29 11:01:49 +0000456 wq = rcu_dereference(sk->sk_wq);
Herbert Xu1ce0bf52015-11-26 13:55:39 +0800457 if (skwq_has_sleeper(wq))
Eric Dumazet67426b72010-10-29 20:44:44 +0000458 wake_up_interruptible_sync_poll(&wq->wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800459 EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800460 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 }
Eric Dumazet43815482010-04-29 11:01:49 +0000462 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463}
464
465/* When dgram socket disconnects (or changes its peer), we clear its receive
466 * queue of packets arrived from previous peer. First, it allows to do
467 * flow control based only on wmem_alloc; second, sk connected to peer
468 * may receive messages only from that peer. */
469static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
470{
David S. Millerb03efcf2005-07-08 14:57:23 -0700471 if (!skb_queue_empty(&sk->sk_receive_queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 skb_queue_purge(&sk->sk_receive_queue);
473 wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
474
475 /* If one link of bidirectional dgram pipe is disconnected,
476 * we signal error. Messages are lost. Do not make this,
477 * when peer was not connected to us.
478 */
479 if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) {
480 other->sk_err = ECONNRESET;
481 other->sk_error_report(other);
482 }
483 }
484}
485
486static void unix_sock_destructor(struct sock *sk)
487{
488 struct unix_sock *u = unix_sk(sk);
489
490 skb_queue_purge(&sk->sk_receive_queue);
491
Reshetova, Elena14afee42017-06-30 13:08:00 +0300492 WARN_ON(refcount_read(&sk->sk_wmem_alloc));
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700493 WARN_ON(!sk_unhashed(sk));
494 WARN_ON(sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 if (!sock_flag(sk, SOCK_DEAD)) {
wangweidong5cc208b2013-12-06 18:03:36 +0800496 pr_info("Attempt to release alive unix socket: %p\n", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 return;
498 }
499
500 if (u->addr)
501 unix_release_addr(u->addr);
502
Eric Dumazet518de9b2010-10-26 14:22:44 -0700503 atomic_long_dec(&unix_nr_socks);
David S. Miller6f756a82008-11-23 17:34:03 -0800504 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800505 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
David S. Miller6f756a82008-11-23 17:34:03 -0800506 local_bh_enable();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507#ifdef UNIX_REFCNT_DEBUG
wangweidong5cc208b2013-12-06 18:03:36 +0800508 pr_debug("UNIX %p is destroyed, %ld are still alive.\n", sk,
Eric Dumazet518de9b2010-10-26 14:22:44 -0700509 atomic_long_read(&unix_nr_socks));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510#endif
511}
512
Paul Mooreded34e02013-03-25 03:18:33 +0000513static void unix_release_sock(struct sock *sk, int embrion)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514{
515 struct unix_sock *u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400516 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 struct sock *skpair;
518 struct sk_buff *skb;
519 int state;
520
521 unix_remove_socket(sk);
522
523 /* Clear state */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700524 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 sock_orphan(sk);
526 sk->sk_shutdown = SHUTDOWN_MASK;
Al Viro40ffe672012-03-14 21:54:32 -0400527 path = u->path;
528 u->path.dentry = NULL;
529 u->path.mnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 state = sk->sk_state;
531 sk->sk_state = TCP_CLOSE;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700532 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533
534 wake_up_interruptible_all(&u->peer_wait);
535
Jianjun Konge27dfce2008-11-01 21:38:31 -0700536 skpair = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537
Jianjun Konge27dfce2008-11-01 21:38:31 -0700538 if (skpair != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
David S. Miller1c92b4e2007-05-31 13:24:26 -0700540 unix_state_lock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 /* No more writes */
542 skpair->sk_shutdown = SHUTDOWN_MASK;
543 if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
544 skpair->sk_err = ECONNRESET;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700545 unix_state_unlock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 skpair->sk_state_change(skpair);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800547 sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 }
Rainer Weikusat7d267272015-11-20 22:07:23 +0000549
550 unix_dgram_peer_wake_disconnect(sk, skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 sock_put(skpair); /* It may now die */
552 unix_peer(sk) = NULL;
553 }
554
555 /* Try to flush out this socket. Throw out buffers at least */
556
557 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
Jianjun Konge27dfce2008-11-01 21:38:31 -0700558 if (state == TCP_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 unix_release_sock(skb->sk, 1);
560 /* passed fds are erased in the kfree_skb hook */
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +0100561 UNIXCB(skb).consumed = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 kfree_skb(skb);
563 }
564
Al Viro40ffe672012-03-14 21:54:32 -0400565 if (path.dentry)
566 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567
568 sock_put(sk);
569
570 /* ---- Socket is dead now and most probably destroyed ---- */
571
572 /*
Alan Coxe04dae82012-09-17 00:52:41 +0000573 * Fixme: BSD difference: In BSD all sockets connected to us get
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 * ECONNRESET and we die on the spot. In Linux we behave
575 * like files and pipes do and wait for the last
576 * dereference.
577 *
578 * Can't we simply set sock->err?
579 *
580 * What the above comment does talk about? --ANK(980817)
581 */
582
Pavel Emelyanov9305cfa2007-11-10 22:06:01 -0800583 if (unix_tot_inflight)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900584 unix_gc(); /* Garbage collect fds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585}
586
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000587static void init_peercred(struct sock *sk)
588{
589 put_pid(sk->sk_peer_pid);
590 if (sk->sk_peer_cred)
591 put_cred(sk->sk_peer_cred);
592 sk->sk_peer_pid = get_pid(task_tgid(current));
593 sk->sk_peer_cred = get_current_cred();
594}
595
596static void copy_peercred(struct sock *sk, struct sock *peersk)
597{
598 put_pid(sk->sk_peer_pid);
599 if (sk->sk_peer_cred)
600 put_cred(sk->sk_peer_cred);
601 sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
602 sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
603}
604
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605static int unix_listen(struct socket *sock, int backlog)
606{
607 int err;
608 struct sock *sk = sock->sk;
609 struct unix_sock *u = unix_sk(sk);
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000610 struct pid *old_pid = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
612 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800613 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
614 goto out; /* Only stream/seqpacket sockets accept */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 err = -EINVAL;
616 if (!u->addr)
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800617 goto out; /* No listens on an unbound socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700618 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
620 goto out_unlock;
621 if (backlog > sk->sk_max_ack_backlog)
622 wake_up_interruptible_all(&u->peer_wait);
623 sk->sk_max_ack_backlog = backlog;
624 sk->sk_state = TCP_LISTEN;
625 /* set credentials so connect can copy them */
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000626 init_peercred(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 err = 0;
628
629out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -0700630 unix_state_unlock(sk);
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000631 put_pid(old_pid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632out:
633 return err;
634}
635
636static int unix_release(struct socket *);
637static int unix_bind(struct socket *, struct sockaddr *, int);
638static int unix_stream_connect(struct socket *, struct sockaddr *,
639 int addr_len, int flags);
640static int unix_socketpair(struct socket *, struct socket *);
David Howellscdfbabf2017-03-09 08:09:05 +0000641static int unix_accept(struct socket *, struct socket *, int, bool);
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +0100642static int unix_getname(struct socket *, struct sockaddr *, int);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700643static __poll_t unix_poll(struct file *, struct socket *, poll_table *);
644static __poll_t unix_dgram_poll(struct file *, struct socket *,
645 poll_table *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646static int unix_ioctl(struct socket *, unsigned int, unsigned long);
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200647#ifdef CONFIG_COMPAT
648static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
649#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650static int unix_shutdown(struct socket *, int);
Ying Xue1b784142015-03-02 15:37:48 +0800651static int unix_stream_sendmsg(struct socket *, struct msghdr *, size_t);
652static int unix_stream_recvmsg(struct socket *, struct msghdr *, size_t, int);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200653static ssize_t unix_stream_sendpage(struct socket *, struct page *, int offset,
654 size_t size, int flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200655static ssize_t unix_stream_splice_read(struct socket *, loff_t *ppos,
656 struct pipe_inode_info *, size_t size,
657 unsigned int flags);
Ying Xue1b784142015-03-02 15:37:48 +0800658static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t);
659static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660static int unix_dgram_connect(struct socket *, struct sockaddr *,
661 int, int);
Ying Xue1b784142015-03-02 15:37:48 +0800662static int unix_seqpacket_sendmsg(struct socket *, struct msghdr *, size_t);
663static int unix_seqpacket_recvmsg(struct socket *, struct msghdr *, size_t,
664 int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665
Sasha Levin12663bf2013-12-07 17:26:27 -0500666static int unix_set_peek_off(struct sock *sk, int val)
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000667{
668 struct unix_sock *u = unix_sk(sk);
669
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700670 if (mutex_lock_interruptible(&u->iolock))
Sasha Levin12663bf2013-12-07 17:26:27 -0500671 return -EINTR;
672
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000673 sk->sk_peek_off = val;
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700674 mutex_unlock(&u->iolock);
Sasha Levin12663bf2013-12-07 17:26:27 -0500675
676 return 0;
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000677}
678
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300679static void unix_show_fdinfo(struct seq_file *m, struct socket *sock)
680{
681 struct sock *sk = sock->sk;
682 struct unix_sock *u;
683
684 if (sk) {
685 u = unix_sk(sock->sk);
686 seq_printf(m, "scm_fds: %u\n", READ_ONCE(u->scm_stat.nr_fds));
687 }
688}
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000689
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800690static const struct proto_ops unix_stream_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 .family = PF_UNIX,
692 .owner = THIS_MODULE,
693 .release = unix_release,
694 .bind = unix_bind,
695 .connect = unix_stream_connect,
696 .socketpair = unix_socketpair,
697 .accept = unix_accept,
698 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700699 .poll = unix_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200701#ifdef CONFIG_COMPAT
702 .compat_ioctl = unix_compat_ioctl,
703#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704 .listen = unix_listen,
705 .shutdown = unix_shutdown,
706 .setsockopt = sock_no_setsockopt,
707 .getsockopt = sock_no_getsockopt,
708 .sendmsg = unix_stream_sendmsg,
709 .recvmsg = unix_stream_recvmsg,
710 .mmap = sock_no_mmap,
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200711 .sendpage = unix_stream_sendpage,
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200712 .splice_read = unix_stream_splice_read,
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +0000713 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300714 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715};
716
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800717static const struct proto_ops unix_dgram_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 .family = PF_UNIX,
719 .owner = THIS_MODULE,
720 .release = unix_release,
721 .bind = unix_bind,
722 .connect = unix_dgram_connect,
723 .socketpair = unix_socketpair,
724 .accept = sock_no_accept,
725 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700726 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200728#ifdef CONFIG_COMPAT
729 .compat_ioctl = unix_compat_ioctl,
730#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 .listen = sock_no_listen,
732 .shutdown = unix_shutdown,
733 .setsockopt = sock_no_setsockopt,
734 .getsockopt = sock_no_getsockopt,
735 .sendmsg = unix_dgram_sendmsg,
736 .recvmsg = unix_dgram_recvmsg,
737 .mmap = sock_no_mmap,
738 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000739 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300740 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741};
742
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800743static const struct proto_ops unix_seqpacket_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 .family = PF_UNIX,
745 .owner = THIS_MODULE,
746 .release = unix_release,
747 .bind = unix_bind,
748 .connect = unix_stream_connect,
749 .socketpair = unix_socketpair,
750 .accept = unix_accept,
751 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700752 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200754#ifdef CONFIG_COMPAT
755 .compat_ioctl = unix_compat_ioctl,
756#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 .listen = unix_listen,
758 .shutdown = unix_shutdown,
759 .setsockopt = sock_no_setsockopt,
760 .getsockopt = sock_no_getsockopt,
761 .sendmsg = unix_seqpacket_sendmsg,
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +0000762 .recvmsg = unix_seqpacket_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 .mmap = sock_no_mmap,
764 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000765 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300766 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767};
768
769static struct proto unix_proto = {
Eric Dumazet248969a2008-11-17 00:00:30 -0800770 .name = "UNIX",
771 .owner = THIS_MODULE,
Eric Dumazet248969a2008-11-17 00:00:30 -0800772 .obj_size = sizeof(struct unix_sock),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773};
774
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500775static struct sock *unix_create1(struct net *net, struct socket *sock, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776{
777 struct sock *sk = NULL;
778 struct unix_sock *u;
779
Eric Dumazet518de9b2010-10-26 14:22:44 -0700780 atomic_long_inc(&unix_nr_socks);
781 if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 goto out;
783
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500784 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, kern);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 if (!sk)
786 goto out;
787
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800788 sock_init_data(sock, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789
Vladimir Davydov3aa97992016-07-26 15:24:36 -0700790 sk->sk_allocation = GFP_KERNEL_ACCOUNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 sk->sk_write_space = unix_write_space;
Denis V. Luneva0a53c82007-12-11 04:19:17 -0800792 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 sk->sk_destruct = unix_sock_destructor;
794 u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400795 u->path.dentry = NULL;
796 u->path.mnt = NULL;
Benjamin LaHaisefd19f322006-01-03 14:10:46 -0800797 spin_lock_init(&u->lock);
Al Viro516e0cc2008-07-26 00:39:17 -0400798 atomic_long_set(&u->inflight, 0);
Miklos Szeredi1fd05ba2007-07-11 14:22:39 -0700799 INIT_LIST_HEAD(&u->link);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700800 mutex_init(&u->iolock); /* single task reading lock */
801 mutex_init(&u->bindlock); /* single task binding lock */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 init_waitqueue_head(&u->peer_wait);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000803 init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300804 memset(&u->scm_stat, 0, sizeof(struct scm_stat));
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000805 unix_insert_socket(unix_sockets_unbound(sk), sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806out:
Pavel Emelyanov284b3272007-11-10 22:08:30 -0800807 if (sk == NULL)
Eric Dumazet518de9b2010-10-26 14:22:44 -0700808 atomic_long_dec(&unix_nr_socks);
Eric Dumazet920de802008-11-24 00:09:29 -0800809 else {
810 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800811 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
Eric Dumazet920de802008-11-24 00:09:29 -0800812 local_bh_enable();
813 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 return sk;
815}
816
Eric Paris3f378b62009-11-05 22:18:14 -0800817static int unix_create(struct net *net, struct socket *sock, int protocol,
818 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819{
820 if (protocol && protocol != PF_UNIX)
821 return -EPROTONOSUPPORT;
822
823 sock->state = SS_UNCONNECTED;
824
825 switch (sock->type) {
826 case SOCK_STREAM:
827 sock->ops = &unix_stream_ops;
828 break;
829 /*
830 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
831 * nothing uses it.
832 */
833 case SOCK_RAW:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700834 sock->type = SOCK_DGRAM;
Gustavo A. R. Silva110af3a2017-10-20 12:05:30 -0500835 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 case SOCK_DGRAM:
837 sock->ops = &unix_dgram_ops;
838 break;
839 case SOCK_SEQPACKET:
840 sock->ops = &unix_seqpacket_ops;
841 break;
842 default:
843 return -ESOCKTNOSUPPORT;
844 }
845
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500846 return unix_create1(net, sock, kern) ? 0 : -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847}
848
849static int unix_release(struct socket *sock)
850{
851 struct sock *sk = sock->sk;
852
853 if (!sk)
854 return 0;
855
Paul Mooreded34e02013-03-25 03:18:33 +0000856 unix_release_sock(sk, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 sock->sk = NULL;
858
Paul Mooreded34e02013-03-25 03:18:33 +0000859 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860}
861
862static int unix_autobind(struct socket *sock)
863{
864 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900865 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 struct unix_sock *u = unix_sk(sk);
867 static u32 ordernum = 1;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800868 struct unix_address *addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 int err;
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000870 unsigned int retries = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700872 err = mutex_lock_interruptible(&u->bindlock);
Sasha Levin37ab4fa2013-12-13 10:54:22 -0500873 if (err)
874 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
876 err = 0;
877 if (u->addr)
878 goto out;
879
880 err = -ENOMEM;
Panagiotis Issaris0da974f2006-07-21 14:51:30 -0700881 addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 if (!addr)
883 goto out;
884
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 addr->name->sun_family = AF_UNIX;
Reshetova, Elena8c9814b2017-06-30 13:08:05 +0300886 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887
888retry:
889 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
Joe Perches07f07572008-11-19 15:44:53 -0800890 addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891
David S. Millerfbe9cc42005-12-13 23:26:29 -0800892 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 ordernum = (ordernum+1)&0xFFFFF;
894
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800895 if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 addr->hash)) {
David S. Millerfbe9cc42005-12-13 23:26:29 -0800897 spin_unlock(&unix_table_lock);
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000898 /*
899 * __unix_find_socket_byname() may take long time if many names
900 * are already in use.
901 */
902 cond_resched();
903 /* Give up if all names seems to be in use. */
904 if (retries++ == 0xFFFFF) {
905 err = -ENOSPC;
906 kfree(addr);
907 goto out;
908 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 goto retry;
910 }
911 addr->hash ^= sk->sk_type;
912
913 __unix_remove_socket(sk);
Al Viroae3b5642019-02-15 20:09:35 +0000914 smp_store_release(&u->addr, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 __unix_insert_socket(&unix_socket_table[addr->hash], sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800916 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 err = 0;
918
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700919out: mutex_unlock(&u->bindlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 return err;
921}
922
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800923static struct sock *unix_find_other(struct net *net,
924 struct sockaddr_un *sunname, int len,
Eric Dumazet95c96172012-04-15 05:58:06 +0000925 int type, unsigned int hash, int *error)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926{
927 struct sock *u;
Al Viro421748e2008-08-02 01:04:36 -0400928 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 int err = 0;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900930
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 if (sunname->sun_path[0]) {
Al Viro421748e2008-08-02 01:04:36 -0400932 struct inode *inode;
933 err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 if (err)
935 goto fail;
Miklos Szeredibeef5122016-12-16 11:02:53 +0100936 inode = d_backing_inode(path.dentry);
Al Viro421748e2008-08-02 01:04:36 -0400937 err = inode_permission(inode, MAY_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 if (err)
939 goto put_fail;
940
941 err = -ECONNREFUSED;
Al Viro421748e2008-08-02 01:04:36 -0400942 if (!S_ISSOCK(inode->i_mode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 goto put_fail;
Eric W. Biederman6616f782010-06-13 03:35:48 +0000944 u = unix_find_socket_byinode(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 if (!u)
946 goto put_fail;
947
948 if (u->sk_type == type)
Al Viro68ac1232012-03-15 08:21:57 -0400949 touch_atime(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950
Al Viro421748e2008-08-02 01:04:36 -0400951 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952
Jianjun Konge27dfce2008-11-01 21:38:31 -0700953 err = -EPROTOTYPE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 if (u->sk_type != type) {
955 sock_put(u);
956 goto fail;
957 }
958 } else {
959 err = -ECONNREFUSED;
Jianjun Konge27dfce2008-11-01 21:38:31 -0700960 u = unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 if (u) {
962 struct dentry *dentry;
Al Viro40ffe672012-03-14 21:54:32 -0400963 dentry = unix_sk(u)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964 if (dentry)
Al Viro68ac1232012-03-15 08:21:57 -0400965 touch_atime(&unix_sk(u)->path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 } else
967 goto fail;
968 }
969 return u;
970
971put_fail:
Al Viro421748e2008-08-02 01:04:36 -0400972 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973fail:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700974 *error = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 return NULL;
976}
977
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700978static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
Al Virofaf02012012-07-20 02:37:29 +0400979{
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700980 struct dentry *dentry;
981 struct path path;
982 int err = 0;
983 /*
984 * Get the parent directory, calculate the hash for last
985 * component.
986 */
987 dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
988 err = PTR_ERR(dentry);
989 if (IS_ERR(dentry))
990 return err;
Al Virofaf02012012-07-20 02:37:29 +0400991
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700992 /*
993 * All right, let's create it.
994 */
995 err = security_path_mknod(&path, dentry, mode, 0);
Al Virofaf02012012-07-20 02:37:29 +0400996 if (!err) {
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700997 err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0);
Al Virofaf02012012-07-20 02:37:29 +0400998 if (!err) {
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700999 res->mnt = mntget(path.mnt);
Al Virofaf02012012-07-20 02:37:29 +04001000 res->dentry = dget(dentry);
1001 }
1002 }
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001003 done_path_create(&path, dentry);
Al Virofaf02012012-07-20 02:37:29 +04001004 return err;
1005}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006
1007static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1008{
1009 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001010 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 struct unix_sock *u = unix_sk(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001012 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Al Virodae6ad82011-06-26 11:50:15 -04001013 char *sun_path = sunaddr->sun_path;
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001014 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001015 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 struct unix_address *addr;
1017 struct hlist_head *list;
Kees Cook82fe0d22017-04-04 22:12:09 -07001018 struct path path = { };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019
1020 err = -EINVAL;
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001021 if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
1022 sunaddr->sun_family != AF_UNIX)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 goto out;
1024
Jianjun Konge27dfce2008-11-01 21:38:31 -07001025 if (addr_len == sizeof(short)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 err = unix_autobind(sock);
1027 goto out;
1028 }
1029
1030 err = unix_mkname(sunaddr, addr_len, &hash);
1031 if (err < 0)
1032 goto out;
1033 addr_len = err;
1034
WANG Cong0fb44552017-01-23 11:17:35 -08001035 if (sun_path[0]) {
1036 umode_t mode = S_IFSOCK |
1037 (SOCK_INODE(sock)->i_mode & ~current_umask());
1038 err = unix_mknod(sun_path, mode, &path);
1039 if (err) {
1040 if (err == -EEXIST)
1041 err = -EADDRINUSE;
1042 goto out;
1043 }
1044 }
1045
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001046 err = mutex_lock_interruptible(&u->bindlock);
Sasha Levin37ab4fa2013-12-13 10:54:22 -05001047 if (err)
WANG Cong0fb44552017-01-23 11:17:35 -08001048 goto out_put;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
1050 err = -EINVAL;
1051 if (u->addr)
1052 goto out_up;
1053
1054 err = -ENOMEM;
1055 addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
1056 if (!addr)
1057 goto out_up;
1058
1059 memcpy(addr->name, sunaddr, addr_len);
1060 addr->len = addr_len;
1061 addr->hash = hash ^ sk->sk_type;
Reshetova, Elena8c9814b2017-06-30 13:08:05 +03001062 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001064 if (sun_path[0]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 addr->hash = UNIX_HASH_SIZE;
Miklos Szeredibeef5122016-12-16 11:02:53 +01001066 hash = d_backing_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1);
Al Virofaf02012012-07-20 02:37:29 +04001067 spin_lock(&unix_table_lock);
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001068 u->path = path;
Al Virofaf02012012-07-20 02:37:29 +04001069 list = &unix_socket_table[hash];
1070 } else {
1071 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 err = -EADDRINUSE;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001073 if (__unix_find_socket_byname(net, sunaddr, addr_len,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 sk->sk_type, hash)) {
1075 unix_release_addr(addr);
1076 goto out_unlock;
1077 }
1078
1079 list = &unix_socket_table[addr->hash];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 }
1081
1082 err = 0;
1083 __unix_remove_socket(sk);
Al Viroae3b5642019-02-15 20:09:35 +00001084 smp_store_release(&u->addr, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 __unix_insert_socket(list, sk);
1086
1087out_unlock:
David S. Millerfbe9cc42005-12-13 23:26:29 -08001088 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089out_up:
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001090 mutex_unlock(&u->bindlock);
WANG Cong0fb44552017-01-23 11:17:35 -08001091out_put:
1092 if (err)
1093 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094out:
1095 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096}
1097
David S. Miller278a3de2007-05-31 15:19:20 -07001098static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
1099{
1100 if (unlikely(sk1 == sk2) || !sk2) {
1101 unix_state_lock(sk1);
1102 return;
1103 }
1104 if (sk1 < sk2) {
1105 unix_state_lock(sk1);
1106 unix_state_lock_nested(sk2);
1107 } else {
1108 unix_state_lock(sk2);
1109 unix_state_lock_nested(sk1);
1110 }
1111}
1112
1113static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
1114{
1115 if (unlikely(sk1 == sk2) || !sk2) {
1116 unix_state_unlock(sk1);
1117 return;
1118 }
1119 unix_state_unlock(sk1);
1120 unix_state_unlock(sk2);
1121}
1122
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
1124 int alen, int flags)
1125{
1126 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001127 struct net *net = sock_net(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001128 struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 struct sock *other;
Eric Dumazet95c96172012-04-15 05:58:06 +00001130 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 int err;
1132
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001133 err = -EINVAL;
1134 if (alen < offsetofend(struct sockaddr, sa_family))
1135 goto out;
1136
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 if (addr->sa_family != AF_UNSPEC) {
1138 err = unix_mkname(sunaddr, alen, &hash);
1139 if (err < 0)
1140 goto out;
1141 alen = err;
1142
1143 if (test_bit(SOCK_PASSCRED, &sock->flags) &&
1144 !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
1145 goto out;
1146
David S. Miller278a3de2007-05-31 15:19:20 -07001147restart:
Jianjun Konge27dfce2008-11-01 21:38:31 -07001148 other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 if (!other)
1150 goto out;
1151
David S. Miller278a3de2007-05-31 15:19:20 -07001152 unix_state_double_lock(sk, other);
1153
1154 /* Apparently VFS overslept socket death. Retry. */
1155 if (sock_flag(other, SOCK_DEAD)) {
1156 unix_state_double_unlock(sk, other);
1157 sock_put(other);
1158 goto restart;
1159 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160
1161 err = -EPERM;
1162 if (!unix_may_send(sk, other))
1163 goto out_unlock;
1164
1165 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1166 if (err)
1167 goto out_unlock;
1168
1169 } else {
1170 /*
1171 * 1003.1g breaking connected state with AF_UNSPEC
1172 */
1173 other = NULL;
David S. Miller278a3de2007-05-31 15:19:20 -07001174 unix_state_double_lock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 }
1176
1177 /*
1178 * If it was connected, reconnect.
1179 */
1180 if (unix_peer(sk)) {
1181 struct sock *old_peer = unix_peer(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001182 unix_peer(sk) = other;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001183 unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
1184
David S. Miller278a3de2007-05-31 15:19:20 -07001185 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186
1187 if (other != old_peer)
1188 unix_dgram_disconnected(sk, old_peer);
1189 sock_put(old_peer);
1190 } else {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001191 unix_peer(sk) = other;
David S. Miller278a3de2007-05-31 15:19:20 -07001192 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 }
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001194 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195
1196out_unlock:
David S. Miller278a3de2007-05-31 15:19:20 -07001197 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 sock_put(other);
1199out:
1200 return err;
1201}
1202
1203static long unix_wait_for_peer(struct sock *other, long timeo)
1204{
1205 struct unix_sock *u = unix_sk(other);
1206 int sched;
1207 DEFINE_WAIT(wait);
1208
1209 prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
1210
1211 sched = !sock_flag(other, SOCK_DEAD) &&
1212 !(other->sk_shutdown & RCV_SHUTDOWN) &&
Rainer Weikusat3c734192008-06-17 22:28:05 -07001213 unix_recvq_full(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214
David S. Miller1c92b4e2007-05-31 13:24:26 -07001215 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216
1217 if (sched)
1218 timeo = schedule_timeout(timeo);
1219
1220 finish_wait(&u->peer_wait, &wait);
1221 return timeo;
1222}
1223
1224static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
1225 int addr_len, int flags)
1226{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001227 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001229 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 struct unix_sock *u = unix_sk(sk), *newu, *otheru;
1231 struct sock *newsk = NULL;
1232 struct sock *other = NULL;
1233 struct sk_buff *skb = NULL;
Eric Dumazet95c96172012-04-15 05:58:06 +00001234 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 int st;
1236 int err;
1237 long timeo;
1238
1239 err = unix_mkname(sunaddr, addr_len, &hash);
1240 if (err < 0)
1241 goto out;
1242 addr_len = err;
1243
Joe Perchesf64f9e72009-11-29 16:55:45 -08001244 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr &&
1245 (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246 goto out;
1247
1248 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
1249
1250 /* First of all allocate resources.
1251 If we will make it after state is locked,
1252 we will have to recheck all again in any case.
1253 */
1254
1255 err = -ENOMEM;
1256
1257 /* create new sock for complete connection */
Eric W. Biederman11aa9c22015-05-08 21:09:13 -05001258 newsk = unix_create1(sock_net(sk), NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259 if (newsk == NULL)
1260 goto out;
1261
1262 /* Allocate skb for sending to listening sock */
1263 skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL);
1264 if (skb == NULL)
1265 goto out;
1266
1267restart:
1268 /* Find listening sock. */
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001269 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 if (!other)
1271 goto out;
1272
1273 /* Latch state of peer */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001274 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275
1276 /* Apparently VFS overslept socket death. Retry. */
1277 if (sock_flag(other, SOCK_DEAD)) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001278 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 sock_put(other);
1280 goto restart;
1281 }
1282
1283 err = -ECONNREFUSED;
1284 if (other->sk_state != TCP_LISTEN)
1285 goto out_unlock;
Tomoki Sekiyama77238f22009-10-18 23:17:37 -07001286 if (other->sk_shutdown & RCV_SHUTDOWN)
1287 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288
Rainer Weikusat3c734192008-06-17 22:28:05 -07001289 if (unix_recvq_full(other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290 err = -EAGAIN;
1291 if (!timeo)
1292 goto out_unlock;
1293
1294 timeo = unix_wait_for_peer(other, timeo);
1295
1296 err = sock_intr_errno(timeo);
1297 if (signal_pending(current))
1298 goto out;
1299 sock_put(other);
1300 goto restart;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001301 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302
1303 /* Latch our state.
1304
Daniel Balutae5537bf2011-03-14 15:25:33 -07001305 It is tricky place. We need to grab our state lock and cannot
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 drop lock on peer. It is dangerous because deadlock is
1307 possible. Connect to self case and simultaneous
1308 attempt to connect are eliminated by checking socket
1309 state. other is TCP_LISTEN, if sk is TCP_LISTEN we
1310 check this before attempt to grab lock.
1311
1312 Well, and we have to recheck the state after socket locked.
1313 */
1314 st = sk->sk_state;
1315
1316 switch (st) {
1317 case TCP_CLOSE:
1318 /* This is ok... continue with connect */
1319 break;
1320 case TCP_ESTABLISHED:
1321 /* Socket is already connected */
1322 err = -EISCONN;
1323 goto out_unlock;
1324 default:
1325 err = -EINVAL;
1326 goto out_unlock;
1327 }
1328
David S. Miller1c92b4e2007-05-31 13:24:26 -07001329 unix_state_lock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330
1331 if (sk->sk_state != st) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001332 unix_state_unlock(sk);
1333 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 sock_put(other);
1335 goto restart;
1336 }
1337
David S. Miller3610cda2011-01-05 15:38:53 -08001338 err = security_unix_stream_connect(sk, other, newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 if (err) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001340 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 goto out_unlock;
1342 }
1343
1344 /* The way is open! Fastly set all the necessary fields... */
1345
1346 sock_hold(sk);
1347 unix_peer(newsk) = sk;
1348 newsk->sk_state = TCP_ESTABLISHED;
1349 newsk->sk_type = sk->sk_type;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001350 init_peercred(newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 newu = unix_sk(newsk);
Eric Dumazeteaefd1102011-02-18 03:26:36 +00001352 RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 otheru = unix_sk(other);
1354
Al Viroae3b5642019-02-15 20:09:35 +00001355 /* copy address information from listening to new sock
1356 *
1357 * The contents of *(otheru->addr) and otheru->path
1358 * are seen fully set up here, since we have found
1359 * otheru in hash under unix_table_lock. Insertion
1360 * into the hash chain we'd found it in had been done
1361 * in an earlier critical area protected by unix_table_lock,
1362 * the same one where we'd set *(otheru->addr) contents,
1363 * as well as otheru->path and otheru->addr itself.
1364 *
1365 * Using smp_store_release() here to set newu->addr
1366 * is enough to make those stores, as well as stores
1367 * to newu->path visible to anyone who gets newu->addr
1368 * by smp_load_acquire(). IOW, the same warranties
1369 * as for unix_sock instances bound in unix_bind() or
1370 * in unix_autobind().
1371 */
Al Viro40ffe672012-03-14 21:54:32 -04001372 if (otheru->path.dentry) {
1373 path_get(&otheru->path);
1374 newu->path = otheru->path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 }
Al Viroae3b5642019-02-15 20:09:35 +00001376 refcount_inc(&otheru->addr->refcnt);
1377 smp_store_release(&newu->addr, otheru->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378
1379 /* Set credentials */
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001380 copy_peercred(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 sock->state = SS_CONNECTED;
1383 sk->sk_state = TCP_ESTABLISHED;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001384 sock_hold(newsk);
1385
Peter Zijlstra4e857c52014-03-17 18:06:10 +01001386 smp_mb__after_atomic(); /* sock_hold() does an atomic_inc() */
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001387 unix_peer(sk) = newsk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388
David S. Miller1c92b4e2007-05-31 13:24:26 -07001389 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390
1391 /* take ten and and send info to listening sock */
1392 spin_lock(&other->sk_receive_queue.lock);
1393 __skb_queue_tail(&other->sk_receive_queue, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001395 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001396 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 sock_put(other);
1398 return 0;
1399
1400out_unlock:
1401 if (other)
David S. Miller1c92b4e2007-05-31 13:24:26 -07001402 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
1404out:
Wei Yongjun40d44442009-02-25 00:32:45 +00001405 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 if (newsk)
1407 unix_release_sock(newsk, 0);
1408 if (other)
1409 sock_put(other);
1410 return err;
1411}
1412
1413static int unix_socketpair(struct socket *socka, struct socket *sockb)
1414{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001415 struct sock *ska = socka->sk, *skb = sockb->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
1417 /* Join our sockets back to back */
1418 sock_hold(ska);
1419 sock_hold(skb);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001420 unix_peer(ska) = skb;
1421 unix_peer(skb) = ska;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001422 init_peercred(ska);
1423 init_peercred(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424
1425 if (ska->sk_type != SOCK_DGRAM) {
1426 ska->sk_state = TCP_ESTABLISHED;
1427 skb->sk_state = TCP_ESTABLISHED;
1428 socka->state = SS_CONNECTED;
1429 sockb->state = SS_CONNECTED;
1430 }
1431 return 0;
1432}
1433
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001434static void unix_sock_inherit_flags(const struct socket *old,
1435 struct socket *new)
1436{
1437 if (test_bit(SOCK_PASSCRED, &old->flags))
1438 set_bit(SOCK_PASSCRED, &new->flags);
1439 if (test_bit(SOCK_PASSSEC, &old->flags))
1440 set_bit(SOCK_PASSSEC, &new->flags);
1441}
1442
David Howellscdfbabf2017-03-09 08:09:05 +00001443static int unix_accept(struct socket *sock, struct socket *newsock, int flags,
1444 bool kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445{
1446 struct sock *sk = sock->sk;
1447 struct sock *tsk;
1448 struct sk_buff *skb;
1449 int err;
1450
1451 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001452 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 goto out;
1454
1455 err = -EINVAL;
1456 if (sk->sk_state != TCP_LISTEN)
1457 goto out;
1458
1459 /* If socket state is TCP_LISTEN it cannot change (for now...),
1460 * so that no locks are necessary.
1461 */
1462
1463 skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
1464 if (!skb) {
1465 /* This means receive shutdown. */
1466 if (err == 0)
1467 err = -EINVAL;
1468 goto out;
1469 }
1470
1471 tsk = skb->sk;
1472 skb_free_datagram(sk, skb);
1473 wake_up_interruptible(&unix_sk(sk)->peer_wait);
1474
1475 /* attach accepted sock to socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001476 unix_state_lock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 newsock->state = SS_CONNECTED;
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001478 unix_sock_inherit_flags(sock, newsock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479 sock_graft(tsk, newsock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001480 unix_state_unlock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 return 0;
1482
1483out:
1484 return err;
1485}
1486
1487
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001488static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489{
1490 struct sock *sk = sock->sk;
Al Viroae3b5642019-02-15 20:09:35 +00001491 struct unix_address *addr;
Cyrill Gorcunov13cfa972009-11-08 05:51:19 +00001492 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 int err = 0;
1494
1495 if (peer) {
1496 sk = unix_peer_get(sk);
1497
1498 err = -ENOTCONN;
1499 if (!sk)
1500 goto out;
1501 err = 0;
1502 } else {
1503 sock_hold(sk);
1504 }
1505
Al Viroae3b5642019-02-15 20:09:35 +00001506 addr = smp_load_acquire(&unix_sk(sk)->addr);
1507 if (!addr) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 sunaddr->sun_family = AF_UNIX;
1509 sunaddr->sun_path[0] = 0;
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001510 err = sizeof(short);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 } else {
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001512 err = addr->len;
1513 memcpy(sunaddr, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 sock_put(sk);
1516out:
1517 return err;
1518}
1519
David S. Millerf78a5fd2011-09-16 19:34:00 -04001520static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001521{
1522 int err = 0;
Eric Dumazet16e57262011-09-19 05:52:27 +00001523
David S. Millerf78a5fd2011-09-16 19:34:00 -04001524 UNIXCB(skb).pid = get_pid(scm->pid);
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001525 UNIXCB(skb).uid = scm->creds.uid;
1526 UNIXCB(skb).gid = scm->creds.gid;
Eric W. Biederman7361c362010-06-13 03:34:33 +00001527 UNIXCB(skb).fp = NULL;
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04001528 unix_get_secdata(scm, skb);
Eric W. Biederman7361c362010-06-13 03:34:33 +00001529 if (scm->fp && send_fds)
1530 err = unix_attach_fds(scm, skb);
1531
1532 skb->destructor = unix_destruct_scm;
1533 return err;
1534}
1535
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001536static bool unix_passcred_enabled(const struct socket *sock,
1537 const struct sock *other)
1538{
1539 return test_bit(SOCK_PASSCRED, &sock->flags) ||
1540 !other->sk_socket ||
1541 test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
1542}
1543
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544/*
Eric Dumazet16e57262011-09-19 05:52:27 +00001545 * Some apps rely on write() giving SCM_CREDENTIALS
1546 * We include credentials if source or destination socket
1547 * asserted SOCK_PASSCRED.
1548 */
1549static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1550 const struct sock *other)
1551{
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001552 if (UNIXCB(skb).pid)
Eric Dumazet16e57262011-09-19 05:52:27 +00001553 return;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001554 if (unix_passcred_enabled(sock, other)) {
Eric Dumazet16e57262011-09-19 05:52:27 +00001555 UNIXCB(skb).pid = get_pid(task_tgid(current));
David S. Miller6e0895c2013-04-22 20:32:51 -04001556 current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
Eric Dumazet16e57262011-09-19 05:52:27 +00001557 }
1558}
1559
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001560static int maybe_init_creds(struct scm_cookie *scm,
1561 struct socket *socket,
1562 const struct sock *other)
1563{
1564 int err;
1565 struct msghdr msg = { .msg_controllen = 0 };
1566
1567 err = scm_send(socket, &msg, scm, false);
1568 if (err)
1569 return err;
1570
1571 if (unix_passcred_enabled(socket, other)) {
1572 scm->pid = get_pid(task_tgid(current));
1573 current_uid_gid(&scm->creds.uid, &scm->creds.gid);
1574 }
1575 return err;
1576}
1577
1578static bool unix_skb_scm_eq(struct sk_buff *skb,
1579 struct scm_cookie *scm)
1580{
1581 const struct unix_skb_parms *u = &UNIXCB(skb);
1582
1583 return u->pid == scm->pid &&
1584 uid_eq(u->uid, scm->creds.uid) &&
1585 gid_eq(u->gid, scm->creds.gid) &&
1586 unix_secdata_eq(scm, skb);
1587}
1588
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001589static void scm_stat_add(struct sock *sk, struct sk_buff *skb)
1590{
1591 struct scm_fp_list *fp = UNIXCB(skb).fp;
1592 struct unix_sock *u = unix_sk(sk);
1593
1594 lockdep_assert_held(&sk->sk_receive_queue.lock);
1595
1596 if (unlikely(fp && fp->count))
1597 u->scm_stat.nr_fds += fp->count;
1598}
1599
1600static void scm_stat_del(struct sock *sk, struct sk_buff *skb)
1601{
1602 struct scm_fp_list *fp = UNIXCB(skb).fp;
1603 struct unix_sock *u = unix_sk(sk);
1604
1605 lockdep_assert_held(&sk->sk_receive_queue.lock);
1606
1607 if (unlikely(fp && fp->count))
1608 u->scm_stat.nr_fds -= fp->count;
1609}
1610
Eric Dumazet16e57262011-09-19 05:52:27 +00001611/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 * Send AF_UNIX data.
1613 */
1614
Ying Xue1b784142015-03-02 15:37:48 +08001615static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
1616 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001619 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 struct unix_sock *u = unix_sk(sk);
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001621 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 struct sock *other = NULL;
1623 int namelen = 0; /* fake GCC */
1624 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001625 unsigned int hash;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001626 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 long timeo;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001628 struct scm_cookie scm;
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001629 int data_len = 0;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001630 int sk_locked;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631
dann frazier5f23b732008-11-26 15:32:27 -08001632 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001633 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 if (err < 0)
1635 return err;
1636
1637 err = -EOPNOTSUPP;
1638 if (msg->msg_flags&MSG_OOB)
1639 goto out;
1640
1641 if (msg->msg_namelen) {
1642 err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
1643 if (err < 0)
1644 goto out;
1645 namelen = err;
1646 } else {
1647 sunaddr = NULL;
1648 err = -ENOTCONN;
1649 other = unix_peer_get(sk);
1650 if (!other)
1651 goto out;
1652 }
1653
Joe Perchesf64f9e72009-11-29 16:55:45 -08001654 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr
1655 && (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 goto out;
1657
1658 err = -EMSGSIZE;
1659 if (len > sk->sk_sndbuf - 32)
1660 goto out;
1661
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001662 if (len > SKB_MAX_ALLOC) {
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001663 data_len = min_t(size_t,
1664 len - SKB_MAX_ALLOC,
1665 MAX_SKB_FRAGS * PAGE_SIZE);
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001666 data_len = PAGE_ALIGN(data_len);
1667
1668 BUILD_BUG_ON(SKB_MAX_ALLOC < PAGE_SIZE);
1669 }
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001670
1671 skb = sock_alloc_send_pskb(sk, len - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07001672 msg->msg_flags & MSG_DONTWAIT, &err,
1673 PAGE_ALLOC_COSTLY_ORDER);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001674 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 goto out;
1676
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001677 err = unix_scm_to_skb(&scm, skb, true);
Eric Dumazet25888e32010-11-25 04:11:39 +00001678 if (err < 0)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001679 goto out_free;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001680
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001681 skb_put(skb, len - data_len);
1682 skb->data_len = data_len;
1683 skb->len = len;
Al Viroc0371da2014-11-24 10:42:55 -05001684 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 if (err)
1686 goto out_free;
1687
1688 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1689
1690restart:
1691 if (!other) {
1692 err = -ECONNRESET;
1693 if (sunaddr == NULL)
1694 goto out_free;
1695
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001696 other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 hash, &err);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001698 if (other == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 goto out_free;
1700 }
1701
Alban Crequyd6ae3ba2011-01-18 06:39:15 +00001702 if (sk_filter(other, skb) < 0) {
1703 /* Toss the packet but do not return any error to the sender */
1704 err = len;
1705 goto out_free;
1706 }
1707
Rainer Weikusat7d267272015-11-20 22:07:23 +00001708 sk_locked = 0;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001709 unix_state_lock(other);
Rainer Weikusat7d267272015-11-20 22:07:23 +00001710restart_locked:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 err = -EPERM;
1712 if (!unix_may_send(sk, other))
1713 goto out_unlock;
1714
Rainer Weikusat7d267272015-11-20 22:07:23 +00001715 if (unlikely(sock_flag(other, SOCK_DEAD))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 /*
1717 * Check with 1003.1g - what should
1718 * datagram error
1719 */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001720 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 sock_put(other);
1722
Rainer Weikusat7d267272015-11-20 22:07:23 +00001723 if (!sk_locked)
1724 unix_state_lock(sk);
1725
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 if (unix_peer(sk) == other) {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001728 unix_peer(sk) = NULL;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001729 unix_dgram_peer_wake_disconnect_wakeup(sk, other);
1730
David S. Miller1c92b4e2007-05-31 13:24:26 -07001731 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732
1733 unix_dgram_disconnected(sk, other);
1734 sock_put(other);
1735 err = -ECONNREFUSED;
1736 } else {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001737 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 }
1739
1740 other = NULL;
1741 if (err)
1742 goto out_free;
1743 goto restart;
1744 }
1745
1746 err = -EPIPE;
1747 if (other->sk_shutdown & RCV_SHUTDOWN)
1748 goto out_unlock;
1749
1750 if (sk->sk_type != SOCK_SEQPACKET) {
1751 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1752 if (err)
1753 goto out_unlock;
1754 }
1755
Rainer Weikusata5527dd2016-02-11 19:37:27 +00001756 /* other == sk && unix_peer(other) != sk if
1757 * - unix_peer(sk) == NULL, destination address bound to sk
1758 * - unix_peer(sk) == sk by time of get but disconnected before lock
1759 */
1760 if (other != sk &&
1761 unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
Rainer Weikusat7d267272015-11-20 22:07:23 +00001762 if (timeo) {
1763 timeo = unix_wait_for_peer(other, timeo);
1764
1765 err = sock_intr_errno(timeo);
1766 if (signal_pending(current))
1767 goto out_free;
1768
1769 goto restart;
1770 }
1771
1772 if (!sk_locked) {
1773 unix_state_unlock(other);
1774 unix_state_double_lock(sk, other);
1775 }
1776
1777 if (unix_peer(sk) != other ||
1778 unix_dgram_peer_wake_me(sk, other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 err = -EAGAIN;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001780 sk_locked = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 goto out_unlock;
1782 }
1783
Rainer Weikusat7d267272015-11-20 22:07:23 +00001784 if (!sk_locked) {
1785 sk_locked = 1;
1786 goto restart_locked;
1787 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 }
1789
Rainer Weikusat7d267272015-11-20 22:07:23 +00001790 if (unlikely(sk_locked))
1791 unix_state_unlock(sk);
1792
Alban Crequy3f661162010-10-04 08:48:28 +00001793 if (sock_flag(other, SOCK_RCVTSTAMP))
1794 __net_timestamp(skb);
Eric Dumazet16e57262011-09-19 05:52:27 +00001795 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001796 spin_lock(&other->sk_receive_queue.lock);
1797 scm_stat_add(other, skb);
1798 __skb_queue_tail(&other->sk_receive_queue, skb);
1799 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001800 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001801 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001803 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 return len;
1805
1806out_unlock:
Rainer Weikusat7d267272015-11-20 22:07:23 +00001807 if (sk_locked)
1808 unix_state_unlock(sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001809 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810out_free:
1811 kfree_skb(skb);
1812out:
1813 if (other)
1814 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001815 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 return err;
1817}
1818
Eric Dumazete370a722013-08-08 14:37:32 -07001819/* We use paged skbs for stream sockets, and limit occupancy to 32768
Tobias Klauserd4e9a402018-02-13 11:11:30 +01001820 * bytes, and a minimum of a full page.
Eric Dumazete370a722013-08-08 14:37:32 -07001821 */
1822#define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001823
Ying Xue1b784142015-03-02 15:37:48 +08001824static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1825 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 struct sock *sk = sock->sk;
1828 struct sock *other = NULL;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001829 int err, size;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001830 struct sk_buff *skb;
Jianjun Konge27dfce2008-11-01 21:38:31 -07001831 int sent = 0;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001832 struct scm_cookie scm;
Miklos Szeredi8ba69ba2009-09-11 11:31:45 -07001833 bool fds_sent = false;
Eric Dumazete370a722013-08-08 14:37:32 -07001834 int data_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
dann frazier5f23b732008-11-26 15:32:27 -08001836 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001837 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 if (err < 0)
1839 return err;
1840
1841 err = -EOPNOTSUPP;
1842 if (msg->msg_flags&MSG_OOB)
1843 goto out_err;
1844
1845 if (msg->msg_namelen) {
1846 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
1847 goto out_err;
1848 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 err = -ENOTCONN;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001850 other = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 if (!other)
1852 goto out_err;
1853 }
1854
1855 if (sk->sk_shutdown & SEND_SHUTDOWN)
1856 goto pipe_err;
1857
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001858 while (sent < len) {
Eric Dumazete370a722013-08-08 14:37:32 -07001859 size = len - sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
1861 /* Keep two messages in the pipe so it schedules better */
Eric Dumazete370a722013-08-08 14:37:32 -07001862 size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863
Eric Dumazete370a722013-08-08 14:37:32 -07001864 /* allow fallback to order-0 allocations */
1865 size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001866
Eric Dumazete370a722013-08-08 14:37:32 -07001867 data_len = max_t(int, 0, size - SKB_MAX_HEAD(0));
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001868
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001869 data_len = min_t(size_t, size, PAGE_ALIGN(data_len));
1870
Eric Dumazete370a722013-08-08 14:37:32 -07001871 skb = sock_alloc_send_pskb(sk, size - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07001872 msg->msg_flags & MSG_DONTWAIT, &err,
1873 get_order(UNIX_SKB_FRAGS_SZ));
Eric Dumazete370a722013-08-08 14:37:32 -07001874 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 goto out_err;
1876
David S. Millerf78a5fd2011-09-16 19:34:00 -04001877 /* Only send the fds in the first buffer */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001878 err = unix_scm_to_skb(&scm, skb, !fds_sent);
Eric Dumazet25888e32010-11-25 04:11:39 +00001879 if (err < 0) {
Eric W. Biederman7361c362010-06-13 03:34:33 +00001880 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001881 goto out_err;
Miklos Szeredi62093442008-11-09 15:23:57 +01001882 }
Eric W. Biederman7361c362010-06-13 03:34:33 +00001883 fds_sent = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884
Eric Dumazete370a722013-08-08 14:37:32 -07001885 skb_put(skb, size - data_len);
1886 skb->data_len = data_len;
1887 skb->len = size;
Al Viroc0371da2014-11-24 10:42:55 -05001888 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001889 if (err) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001891 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 }
1893
David S. Miller1c92b4e2007-05-31 13:24:26 -07001894 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895
1896 if (sock_flag(other, SOCK_DEAD) ||
1897 (other->sk_shutdown & RCV_SHUTDOWN))
1898 goto pipe_err_free;
1899
Eric Dumazet16e57262011-09-19 05:52:27 +00001900 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001901 spin_lock(&other->sk_receive_queue.lock);
1902 scm_stat_add(other, skb);
1903 __skb_queue_tail(&other->sk_receive_queue, skb);
1904 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001905 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001906 other->sk_data_ready(other);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001907 sent += size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001910 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
1912 return sent;
1913
1914pipe_err_free:
David S. Miller1c92b4e2007-05-31 13:24:26 -07001915 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 kfree_skb(skb);
1917pipe_err:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001918 if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
1919 send_sig(SIGPIPE, current, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 err = -EPIPE;
1921out_err:
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001922 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 return sent ? : err;
1924}
1925
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001926static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
1927 int offset, size_t size, int flags)
1928{
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001929 int err;
1930 bool send_sigpipe = false;
1931 bool init_scm = true;
1932 struct scm_cookie scm;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001933 struct sock *other, *sk = socket->sk;
1934 struct sk_buff *skb, *newskb = NULL, *tail = NULL;
1935
1936 if (flags & MSG_OOB)
1937 return -EOPNOTSUPP;
1938
1939 other = unix_peer(sk);
1940 if (!other || sk->sk_state != TCP_ESTABLISHED)
1941 return -ENOTCONN;
1942
1943 if (false) {
1944alloc_skb:
1945 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001946 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001947 newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
1948 &err, 0);
1949 if (!newskb)
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001950 goto err;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001951 }
1952
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001953 /* we must acquire iolock as we modify already present
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001954 * skbs in the sk_receive_queue and mess with skb->len
1955 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001956 err = mutex_lock_interruptible(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001957 if (err) {
1958 err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001959 goto err;
1960 }
1961
1962 if (sk->sk_shutdown & SEND_SHUTDOWN) {
1963 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001964 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001965 goto err_unlock;
1966 }
1967
1968 unix_state_lock(other);
1969
1970 if (sock_flag(other, SOCK_DEAD) ||
1971 other->sk_shutdown & RCV_SHUTDOWN) {
1972 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001973 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001974 goto err_state_unlock;
1975 }
1976
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001977 if (init_scm) {
1978 err = maybe_init_creds(&scm, socket, other);
1979 if (err)
1980 goto err_state_unlock;
1981 init_scm = false;
1982 }
1983
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001984 skb = skb_peek_tail(&other->sk_receive_queue);
1985 if (tail && tail == skb) {
1986 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001987 } else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
1988 if (newskb) {
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001989 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001990 } else {
1991 tail = skb;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001992 goto alloc_skb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001993 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001994 } else if (newskb) {
1995 /* this is fast path, we don't necessarily need to
1996 * call to kfree_skb even though with newskb == NULL
1997 * this - does no harm
1998 */
1999 consume_skb(newskb);
Hannes Frederic Sowa8844f972015-11-16 16:25:56 +01002000 newskb = NULL;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002001 }
2002
2003 if (skb_append_pagefrags(skb, page, offset, size)) {
2004 tail = skb;
2005 goto alloc_skb;
2006 }
2007
2008 skb->len += size;
2009 skb->data_len += size;
2010 skb->truesize += size;
Reshetova, Elena14afee42017-06-30 13:08:00 +03002011 refcount_add(size, &sk->sk_wmem_alloc);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002012
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002013 if (newskb) {
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002014 err = unix_scm_to_skb(&scm, skb, false);
2015 if (err)
2016 goto err_state_unlock;
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002017 spin_lock(&other->sk_receive_queue.lock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002018 __skb_queue_tail(&other->sk_receive_queue, newskb);
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002019 spin_unlock(&other->sk_receive_queue.lock);
2020 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002021
2022 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002023 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002024
2025 other->sk_data_ready(other);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002026 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002027 return size;
2028
2029err_state_unlock:
2030 unix_state_unlock(other);
2031err_unlock:
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002032 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002033err:
2034 kfree_skb(newskb);
2035 if (send_sigpipe && !(flags & MSG_NOSIGNAL))
2036 send_sig(SIGPIPE, current, 0);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002037 if (!init_scm)
2038 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002039 return err;
2040}
2041
Ying Xue1b784142015-03-02 15:37:48 +08002042static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg,
2043 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044{
2045 int err;
2046 struct sock *sk = sock->sk;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002047
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048 err = sock_error(sk);
2049 if (err)
2050 return err;
2051
2052 if (sk->sk_state != TCP_ESTABLISHED)
2053 return -ENOTCONN;
2054
2055 if (msg->msg_namelen)
2056 msg->msg_namelen = 0;
2057
Ying Xue1b784142015-03-02 15:37:48 +08002058 return unix_dgram_sendmsg(sock, msg, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002059}
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002060
Ying Xue1b784142015-03-02 15:37:48 +08002061static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg,
2062 size_t size, int flags)
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002063{
2064 struct sock *sk = sock->sk;
2065
2066 if (sk->sk_state != TCP_ESTABLISHED)
2067 return -ENOTCONN;
2068
Ying Xue1b784142015-03-02 15:37:48 +08002069 return unix_dgram_recvmsg(sock, msg, size, flags);
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002070}
2071
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
2073{
Al Viroae3b5642019-02-15 20:09:35 +00002074 struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075
Al Viroae3b5642019-02-15 20:09:35 +00002076 if (addr) {
2077 msg->msg_namelen = addr->len;
2078 memcpy(msg->msg_name, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 }
2080}
2081
Ying Xue1b784142015-03-02 15:37:48 +08002082static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
2083 size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002085 struct scm_cookie scm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 struct sock *sk = sock->sk;
2087 struct unix_sock *u = unix_sk(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002088 struct sk_buff *skb, *last;
2089 long timeo;
Paolo Abenifd69c392019-04-08 10:15:59 +02002090 int skip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002091 int err;
2092
2093 err = -EOPNOTSUPP;
2094 if (flags&MSG_OOB)
2095 goto out;
2096
Rainer Weikusat64874282015-12-06 21:11:38 +00002097 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098
Rainer Weikusat64874282015-12-06 21:11:38 +00002099 do {
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002100 mutex_lock(&u->iolock);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002101
Rainer Weikusat64874282015-12-06 21:11:38 +00002102 skip = sk_peek_offset(sk, flags);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002103 skb = __skb_try_recv_datagram(sk, flags, scm_stat_del,
2104 &skip, &err, &last);
Rainer Weikusat64874282015-12-06 21:11:38 +00002105 if (skb)
2106 break;
2107
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002108 mutex_unlock(&u->iolock);
Rainer Weikusat64874282015-12-06 21:11:38 +00002109
2110 if (err != -EAGAIN)
2111 break;
2112 } while (timeo &&
2113 !__skb_wait_for_more_packets(sk, &err, &timeo, last));
2114
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002115 if (!skb) { /* implies iolock unlocked */
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002116 unix_state_lock(sk);
2117 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
2118 if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
2119 (sk->sk_shutdown & RCV_SHUTDOWN))
2120 err = 0;
2121 unix_state_unlock(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002122 goto out;
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002123 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124
Rainer Weikusat77b75f42015-11-26 19:23:15 +00002125 if (wq_has_sleeper(&u->peer_wait))
2126 wake_up_interruptible_sync_poll(&u->peer_wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002127 EPOLLOUT | EPOLLWRNORM |
2128 EPOLLWRBAND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129
2130 if (msg->msg_name)
2131 unix_copy_addr(msg, skb->sk);
2132
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002133 if (size > skb->len - skip)
2134 size = skb->len - skip;
2135 else if (size < skb->len - skip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136 msg->msg_flags |= MSG_TRUNC;
2137
David S. Miller51f3d022014-11-05 16:46:40 -05002138 err = skb_copy_datagram_msg(skb, skip, msg, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139 if (err)
2140 goto out_free;
2141
Alban Crequy3f661162010-10-04 08:48:28 +00002142 if (sock_flag(sk, SOCK_RCVTSTAMP))
2143 __sock_recv_timestamp(msg, sk, skb);
2144
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002145 memset(&scm, 0, sizeof(scm));
2146
2147 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
2148 unix_set_secdata(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002150 if (!(flags & MSG_PEEK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002151 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002152 unix_detach_fds(&scm, skb);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002153
2154 sk_peek_offset_bwd(sk, skb->len);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002155 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 /* It is questionable: on PEEK we could:
2157 - do not return fds - good, but too simple 8)
2158 - return fds, and do not return them on read (old strategy,
2159 apparently wrong)
2160 - clone fds (I chose it for now, it is the most universal
2161 solution)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002162
2163 POSIX 1003.1g does not actually define this clearly
2164 at all. POSIX 1003.1g doesn't define a lot of things
2165 clearly however!
2166
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167 */
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002168
2169 sk_peek_offset_fwd(sk, size);
2170
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002172 scm.fp = scm_fp_dup(UNIXCB(skb).fp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002173 }
Eric Dumazet9f6f9af2012-02-21 23:24:55 +00002174 err = (flags & MSG_TRUNC) ? skb->len - skip : size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002176 scm_recv(sock, msg, &scm, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177
2178out_free:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002179 skb_free_datagram(sk, skb);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002180 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181out:
2182 return err;
2183}
2184
2185/*
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002186 * Sleep until more data has arrived. But check for races..
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187 */
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002188static long unix_stream_data_wait(struct sock *sk, long timeo,
WANG Cong06a77b02016-11-17 15:55:26 -08002189 struct sk_buff *last, unsigned int last_len,
2190 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191{
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002192 struct sk_buff *tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193 DEFINE_WAIT(wait);
2194
David S. Miller1c92b4e2007-05-31 13:24:26 -07002195 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196
2197 for (;;) {
Eric Dumazetaa395142010-04-20 13:03:51 +00002198 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002200 tail = skb_peek_tail(&sk->sk_receive_queue);
2201 if (tail != last ||
2202 (tail && tail->len != last_len) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203 sk->sk_err ||
2204 (sk->sk_shutdown & RCV_SHUTDOWN) ||
2205 signal_pending(current) ||
2206 !timeo)
2207 break;
2208
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002209 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002210 unix_state_unlock(sk);
WANG Cong06a77b02016-11-17 15:55:26 -08002211 if (freezable)
2212 timeo = freezable_schedule_timeout(timeo);
2213 else
2214 timeo = schedule_timeout(timeo);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002215 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002216
2217 if (sock_flag(sk, SOCK_DEAD))
2218 break;
2219
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002220 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221 }
2222
Eric Dumazetaa395142010-04-20 13:03:51 +00002223 finish_wait(sk_sleep(sk), &wait);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002224 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002225 return timeo;
2226}
2227
Eric Dumazete370a722013-08-08 14:37:32 -07002228static unsigned int unix_skb_len(const struct sk_buff *skb)
2229{
2230 return skb->len - UNIXCB(skb).consumed;
2231}
2232
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002233struct unix_stream_read_state {
2234 int (*recv_actor)(struct sk_buff *, int, int,
2235 struct unix_stream_read_state *);
2236 struct socket *socket;
2237 struct msghdr *msg;
2238 struct pipe_inode_info *pipe;
2239 size_t size;
2240 int flags;
2241 unsigned int splice_flags;
2242};
2243
WANG Cong06a77b02016-11-17 15:55:26 -08002244static int unix_stream_read_generic(struct unix_stream_read_state *state,
2245 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002247 struct scm_cookie scm;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002248 struct socket *sock = state->socket;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249 struct sock *sk = sock->sk;
2250 struct unix_sock *u = unix_sk(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251 int copied = 0;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002252 int flags = state->flags;
Eric Dumazetde144392014-03-25 18:42:27 -07002253 int noblock = flags & MSG_DONTWAIT;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002254 bool check_creds = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 int target;
2256 int err = 0;
2257 long timeo;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002258 int skip;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002259 size_t size = state->size;
2260 unsigned int last_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002262 if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
2263 err = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002265 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002267 if (unlikely(flags & MSG_OOB)) {
2268 err = -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002270 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002272 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
Eric Dumazetde144392014-03-25 18:42:27 -07002273 timeo = sock_rcvtimeo(sk, noblock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002275 memset(&scm, 0, sizeof(scm));
2276
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277 /* Lock the socket to prevent queue disordering
2278 * while sleeps in memcpy_tomsg
2279 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002280 mutex_lock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281
Matthew Dawsona0917e02017-08-18 15:04:54 -04002282 skip = max(sk_peek_offset(sk, flags), 0);
Andrey Vagine9193d62015-10-02 00:05:36 +03002283
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002284 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285 int chunk;
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002286 bool drop_skb;
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002287 struct sk_buff *skb, *last;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002289redo:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002290 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002291 if (sock_flag(sk, SOCK_DEAD)) {
2292 err = -ECONNRESET;
2293 goto unlock;
2294 }
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002295 last = skb = skb_peek(&sk->sk_receive_queue);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002296 last_len = last ? last->len : 0;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002297again:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002298 if (skb == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299 if (copied >= target)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002300 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002301
2302 /*
2303 * POSIX 1003.1g mandates this order.
2304 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002305
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002306 err = sock_error(sk);
2307 if (err)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002308 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309 if (sk->sk_shutdown & RCV_SHUTDOWN)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002310 goto unlock;
2311
2312 unix_state_unlock(sk);
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002313 if (!timeo) {
2314 err = -EAGAIN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 break;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002316 }
2317
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002318 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002320 timeo = unix_stream_data_wait(sk, timeo, last,
WANG Cong06a77b02016-11-17 15:55:26 -08002321 last_len, freezable);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322
Rainer Weikusat3822b5c2015-12-16 20:09:25 +00002323 if (signal_pending(current)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 err = sock_intr_errno(timeo);
Eric Dumazetfa0dc042016-01-24 13:53:50 -08002325 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 goto out;
2327 }
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00002328
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002329 mutex_lock(&u->iolock);
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002330 goto redo;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002331unlock:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002332 unix_state_unlock(sk);
2333 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002334 }
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002335
Eric Dumazete370a722013-08-08 14:37:32 -07002336 while (skip >= unix_skb_len(skb)) {
2337 skip -= unix_skb_len(skb);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002338 last = skb;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002339 last_len = skb->len;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002340 skb = skb_peek_next(skb, &sk->sk_receive_queue);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002341 if (!skb)
2342 goto again;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002343 }
2344
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002345 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346
2347 if (check_creds) {
2348 /* Never glue messages from different writers */
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002349 if (!unix_skb_scm_eq(skb, &scm))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350 break;
Eric W. Biederman0e82e7f6d2013-04-03 16:14:47 +00002351 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352 /* Copy credentials */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002353 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04002354 unix_set_secdata(&scm, skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002355 check_creds = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002356 }
2357
2358 /* Copy address just once */
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002359 if (state->msg && state->msg->msg_name) {
2360 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr,
2361 state->msg->msg_name);
2362 unix_copy_addr(state->msg, skb->sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363 sunaddr = NULL;
2364 }
2365
Eric Dumazete370a722013-08-08 14:37:32 -07002366 chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002367 skb_get(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002368 chunk = state->recv_actor(skb, skip, chunk, state);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002369 drop_skb = !unix_skb_len(skb);
2370 /* skb is only safe to use if !drop_skb */
2371 consume_skb(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002372 if (chunk < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002373 if (copied == 0)
2374 copied = -EFAULT;
2375 break;
2376 }
2377 copied += chunk;
2378 size -= chunk;
2379
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002380 if (drop_skb) {
2381 /* the skb was touched by a concurrent reader;
2382 * we should not expect anything from this skb
2383 * anymore and assume it invalid - we can be
2384 * sure it was dropped from the socket queue
2385 *
2386 * let's report a short read
2387 */
2388 err = 0;
2389 break;
2390 }
2391
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392 /* Mark read part of skb as used */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002393 if (!(flags & MSG_PEEK)) {
Eric Dumazete370a722013-08-08 14:37:32 -07002394 UNIXCB(skb).consumed += chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002396 sk_peek_offset_bwd(sk, chunk);
2397
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002398 if (UNIXCB(skb).fp) {
2399 spin_lock(&sk->sk_receive_queue.lock);
2400 scm_stat_del(sk, skb);
2401 spin_unlock(&sk->sk_receive_queue.lock);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002402 unix_detach_fds(&scm, skb);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002403 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404
Eric Dumazete370a722013-08-08 14:37:32 -07002405 if (unix_skb_len(skb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407
Eric Dumazet6f01fd62012-01-28 16:11:03 +00002408 skb_unlink(skb, &sk->sk_receive_queue);
Neil Horman70d4bf62010-07-20 06:45:56 +00002409 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002411 if (scm.fp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002413 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 /* It is questionable, see note in unix_dgram_recvmsg.
2415 */
2416 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002417 scm.fp = scm_fp_dup(UNIXCB(skb).fp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418
Andrey Vagine9193d62015-10-02 00:05:36 +03002419 sk_peek_offset_fwd(sk, chunk);
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002420
Aaron Conole9f389e32015-09-26 18:50:43 -04002421 if (UNIXCB(skb).fp)
2422 break;
2423
Andrey Vagine9193d62015-10-02 00:05:36 +03002424 skip = 0;
Aaron Conole9f389e32015-09-26 18:50:43 -04002425 last = skb;
2426 last_len = skb->len;
2427 unix_state_lock(sk);
2428 skb = skb_peek_next(skb, &sk->sk_receive_queue);
2429 if (skb)
2430 goto again;
2431 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002432 break;
2433 }
2434 } while (size);
2435
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002436 mutex_unlock(&u->iolock);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002437 if (state->msg)
2438 scm_recv(sock, state->msg, &scm, flags);
2439 else
2440 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441out:
2442 return copied ? : err;
2443}
2444
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002445static int unix_stream_read_actor(struct sk_buff *skb,
2446 int skip, int chunk,
2447 struct unix_stream_read_state *state)
2448{
2449 int ret;
2450
2451 ret = skb_copy_datagram_msg(skb, UNIXCB(skb).consumed + skip,
2452 state->msg, chunk);
2453 return ret ?: chunk;
2454}
2455
2456static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
2457 size_t size, int flags)
2458{
2459 struct unix_stream_read_state state = {
2460 .recv_actor = unix_stream_read_actor,
2461 .socket = sock,
2462 .msg = msg,
2463 .size = size,
2464 .flags = flags
2465 };
2466
WANG Cong06a77b02016-11-17 15:55:26 -08002467 return unix_stream_read_generic(&state, true);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002468}
2469
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002470static int unix_stream_splice_actor(struct sk_buff *skb,
2471 int skip, int chunk,
2472 struct unix_stream_read_state *state)
2473{
2474 return skb_splice_bits(skb, state->socket->sk,
2475 UNIXCB(skb).consumed + skip,
Al Viro25869262016-09-17 21:02:10 -04002476 state->pipe, chunk, state->splice_flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002477}
2478
2479static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos,
2480 struct pipe_inode_info *pipe,
2481 size_t size, unsigned int flags)
2482{
2483 struct unix_stream_read_state state = {
2484 .recv_actor = unix_stream_splice_actor,
2485 .socket = sock,
2486 .pipe = pipe,
2487 .size = size,
2488 .splice_flags = flags,
2489 };
2490
2491 if (unlikely(*ppos))
2492 return -ESPIPE;
2493
2494 if (sock->file->f_flags & O_NONBLOCK ||
2495 flags & SPLICE_F_NONBLOCK)
2496 state.flags = MSG_DONTWAIT;
2497
WANG Cong06a77b02016-11-17 15:55:26 -08002498 return unix_stream_read_generic(&state, false);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002499}
2500
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501static int unix_shutdown(struct socket *sock, int mode)
2502{
2503 struct sock *sk = sock->sk;
2504 struct sock *other;
2505
Xi Wangfc61b922012-08-26 16:47:13 +00002506 if (mode < SHUT_RD || mode > SHUT_RDWR)
2507 return -EINVAL;
2508 /* This maps:
2509 * SHUT_RD (0) -> RCV_SHUTDOWN (1)
2510 * SHUT_WR (1) -> SEND_SHUTDOWN (2)
2511 * SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
2512 */
2513 ++mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514
Alban Crequy7180a032011-01-19 04:56:36 +00002515 unix_state_lock(sk);
2516 sk->sk_shutdown |= mode;
2517 other = unix_peer(sk);
2518 if (other)
2519 sock_hold(other);
2520 unix_state_unlock(sk);
2521 sk->sk_state_change(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522
Alban Crequy7180a032011-01-19 04:56:36 +00002523 if (other &&
2524 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525
Alban Crequy7180a032011-01-19 04:56:36 +00002526 int peer_mode = 0;
2527
2528 if (mode&RCV_SHUTDOWN)
2529 peer_mode |= SEND_SHUTDOWN;
2530 if (mode&SEND_SHUTDOWN)
2531 peer_mode |= RCV_SHUTDOWN;
2532 unix_state_lock(other);
2533 other->sk_shutdown |= peer_mode;
2534 unix_state_unlock(other);
2535 other->sk_state_change(other);
2536 if (peer_mode == SHUTDOWN_MASK)
2537 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
2538 else if (peer_mode & RCV_SHUTDOWN)
2539 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540 }
Alban Crequy7180a032011-01-19 04:56:36 +00002541 if (other)
2542 sock_put(other);
2543
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 return 0;
2545}
2546
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002547long unix_inq_len(struct sock *sk)
2548{
2549 struct sk_buff *skb;
2550 long amount = 0;
2551
2552 if (sk->sk_state == TCP_LISTEN)
2553 return -EINVAL;
2554
2555 spin_lock(&sk->sk_receive_queue.lock);
2556 if (sk->sk_type == SOCK_STREAM ||
2557 sk->sk_type == SOCK_SEQPACKET) {
2558 skb_queue_walk(&sk->sk_receive_queue, skb)
Eric Dumazete370a722013-08-08 14:37:32 -07002559 amount += unix_skb_len(skb);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002560 } else {
2561 skb = skb_peek(&sk->sk_receive_queue);
2562 if (skb)
2563 amount = skb->len;
2564 }
2565 spin_unlock(&sk->sk_receive_queue.lock);
2566
2567 return amount;
2568}
2569EXPORT_SYMBOL_GPL(unix_inq_len);
2570
2571long unix_outq_len(struct sock *sk)
2572{
2573 return sk_wmem_alloc_get(sk);
2574}
2575EXPORT_SYMBOL_GPL(unix_outq_len);
2576
Andrey Vaginba94f302017-02-01 11:00:45 -08002577static int unix_open_file(struct sock *sk)
2578{
2579 struct path path;
2580 struct file *f;
2581 int fd;
2582
2583 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
2584 return -EPERM;
2585
Al Viroae3b5642019-02-15 20:09:35 +00002586 if (!smp_load_acquire(&unix_sk(sk)->addr))
Andrey Vaginba94f302017-02-01 11:00:45 -08002587 return -ENOENT;
Al Viroae3b5642019-02-15 20:09:35 +00002588
2589 path = unix_sk(sk)->path;
2590 if (!path.dentry)
2591 return -ENOENT;
Andrey Vaginba94f302017-02-01 11:00:45 -08002592
2593 path_get(&path);
Andrey Vaginba94f302017-02-01 11:00:45 -08002594
2595 fd = get_unused_fd_flags(O_CLOEXEC);
2596 if (fd < 0)
2597 goto out;
2598
2599 f = dentry_open(&path, O_PATH, current_cred());
2600 if (IS_ERR(f)) {
2601 put_unused_fd(fd);
2602 fd = PTR_ERR(f);
2603 goto out;
2604 }
2605
2606 fd_install(fd, f);
2607out:
2608 path_put(&path);
2609
2610 return fd;
2611}
2612
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2614{
2615 struct sock *sk = sock->sk;
Jianjun Konge27dfce2008-11-01 21:38:31 -07002616 long amount = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617 int err;
2618
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002619 switch (cmd) {
2620 case SIOCOUTQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002621 amount = unix_outq_len(sk);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002622 err = put_user(amount, (int __user *)arg);
2623 break;
2624 case SIOCINQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002625 amount = unix_inq_len(sk);
2626 if (amount < 0)
2627 err = amount;
2628 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629 err = put_user(amount, (int __user *)arg);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002630 break;
Andrey Vaginba94f302017-02-01 11:00:45 -08002631 case SIOCUNIXFILE:
2632 err = unix_open_file(sk);
2633 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002634 default:
2635 err = -ENOIOCTLCMD;
2636 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637 }
2638 return err;
2639}
2640
Arnd Bergmann5f6beb92019-06-03 22:03:44 +02002641#ifdef CONFIG_COMPAT
2642static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2643{
2644 return unix_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
2645}
2646#endif
2647
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002648static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649{
2650 struct sock *sk = sock->sk;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002651 __poll_t mask;
2652
Karsten Graul89ab0662018-10-23 13:40:39 +02002653 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002654 mask = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655
2656 /* exceptional events? */
2657 if (sk->sk_err)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002658 mask |= EPOLLERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002660 mask |= EPOLLHUP;
Davide Libenzif348d702006-03-25 03:07:39 -08002661 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002662 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663
2664 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002665 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002666 mask |= EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667
2668 /* Connection-based need to check for termination and startup */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002669 if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
2670 sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002671 mask |= EPOLLHUP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672
2673 /*
2674 * we set writable also when the other side has shut down the
2675 * connection. This prevents stuck sockets.
2676 */
2677 if (unix_writable(sk))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002678 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679
2680 return mask;
2681}
2682
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002683static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
2684 poll_table *wait)
Rainer Weikusat3c734192008-06-17 22:28:05 -07002685{
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002686 struct sock *sk = sock->sk, *other;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002687 unsigned int writable;
2688 __poll_t mask;
2689
Karsten Graul89ab0662018-10-23 13:40:39 +02002690 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002691 mask = 0;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002692
2693 /* exceptional events? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002694 if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002695 mask |= EPOLLERR |
2696 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +00002697
Rainer Weikusat3c734192008-06-17 22:28:05 -07002698 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002699 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002700 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002701 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002702
2703 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002704 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002705 mask |= EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002706
2707 /* Connection-based need to check for termination and startup */
2708 if (sk->sk_type == SOCK_SEQPACKET) {
2709 if (sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002710 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002711 /* connection hasn't started yet? */
2712 if (sk->sk_state == TCP_SYN_SENT)
2713 return mask;
2714 }
2715
Eric Dumazet973a34a2010-10-31 05:38:25 +00002716 /* No write status requested, avoid expensive OUT tests. */
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002717 if (!(poll_requested_events(wait) & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT)))
Eric Dumazet973a34a2010-10-31 05:38:25 +00002718 return mask;
2719
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002720 writable = unix_writable(sk);
Rainer Weikusat7d267272015-11-20 22:07:23 +00002721 if (writable) {
2722 unix_state_lock(sk);
2723
2724 other = unix_peer(sk);
2725 if (other && unix_peer(other) != sk &&
2726 unix_recvq_full(other) &&
2727 unix_dgram_peer_wake_me(sk, other))
2728 writable = 0;
2729
2730 unix_state_unlock(sk);
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002731 }
2732
2733 if (writable)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002734 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002735 else
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002736 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
Rainer Weikusat3c734192008-06-17 22:28:05 -07002737
Rainer Weikusat3c734192008-06-17 22:28:05 -07002738 return mask;
2739}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740
2741#ifdef CONFIG_PROC_FS
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002742
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002743#define BUCKET_SPACE (BITS_PER_LONG - (UNIX_HASH_BITS + 1) - 1)
2744
2745#define get_bucket(x) ((x) >> BUCKET_SPACE)
2746#define get_offset(x) ((x) & ((1L << BUCKET_SPACE) - 1))
2747#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002748
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002749static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750{
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002751 unsigned long offset = get_offset(*pos);
2752 unsigned long bucket = get_bucket(*pos);
2753 struct sock *sk;
2754 unsigned long count = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002756 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
2757 if (sock_net(sk) != seq_file_net(seq))
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002758 continue;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002759 if (++count == offset)
2760 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002761 }
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002762
2763 return sk;
2764}
2765
2766static struct sock *unix_next_socket(struct seq_file *seq,
2767 struct sock *sk,
2768 loff_t *pos)
2769{
2770 unsigned long bucket;
2771
2772 while (sk > (struct sock *)SEQ_START_TOKEN) {
2773 sk = sk_next(sk);
2774 if (!sk)
2775 goto next_bucket;
2776 if (sock_net(sk) == seq_file_net(seq))
2777 return sk;
2778 }
2779
2780 do {
2781 sk = unix_from_bucket(seq, pos);
2782 if (sk)
2783 return sk;
2784
2785next_bucket:
2786 bucket = get_bucket(*pos) + 1;
2787 *pos = set_bucket_offset(bucket, 1);
2788 } while (bucket < ARRAY_SIZE(unix_socket_table));
2789
Linus Torvalds1da177e2005-04-16 15:20:36 -07002790 return NULL;
2791}
2792
Linus Torvalds1da177e2005-04-16 15:20:36 -07002793static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002794 __acquires(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002796 spin_lock(&unix_table_lock);
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002797
2798 if (!*pos)
2799 return SEQ_START_TOKEN;
2800
2801 if (get_bucket(*pos) >= ARRAY_SIZE(unix_socket_table))
2802 return NULL;
2803
2804 return unix_next_socket(seq, NULL, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805}
2806
2807static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2808{
2809 ++*pos;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002810 return unix_next_socket(seq, v, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811}
2812
2813static void unix_seq_stop(struct seq_file *seq, void *v)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002814 __releases(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002816 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817}
2818
2819static int unix_seq_show(struct seq_file *seq, void *v)
2820{
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002821
Joe Perchesb9f31242008-04-12 19:04:38 -07002822 if (v == SEQ_START_TOKEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823 seq_puts(seq, "Num RefCount Protocol Flags Type St "
2824 "Inode Path\n");
2825 else {
2826 struct sock *s = v;
2827 struct unix_sock *u = unix_sk(s);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002828 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829
Dan Rosenberg71338aa2011-05-23 12:17:35 +00002830 seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831 s,
Reshetova, Elena41c6d652017-06-30 13:08:01 +03002832 refcount_read(&s->sk_refcnt),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 0,
2834 s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
2835 s->sk_type,
2836 s->sk_socket ?
2837 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
2838 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
2839 sock_i_ino(s));
2840
Al Viroae3b5642019-02-15 20:09:35 +00002841 if (u->addr) { // under unix_table_lock here
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842 int i, len;
2843 seq_putc(seq, ' ');
2844
2845 i = 0;
2846 len = u->addr->len - sizeof(short);
2847 if (!UNIX_ABSTRACT(s))
2848 len--;
2849 else {
2850 seq_putc(seq, '@');
2851 i++;
2852 }
2853 for ( ; i < len; i++)
Isaac Boukrise7947ea2016-11-01 02:41:35 +02002854 seq_putc(seq, u->addr->name->sun_path[i] ?:
2855 '@');
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07002857 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 seq_putc(seq, '\n');
2859 }
2860
2861 return 0;
2862}
2863
Philippe De Muyter56b3d972007-07-10 23:07:31 -07002864static const struct seq_operations unix_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 .start = unix_seq_start,
2866 .next = unix_seq_next,
2867 .stop = unix_seq_stop,
2868 .show = unix_seq_show,
2869};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870#endif
2871
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00002872static const struct net_proto_family unix_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873 .family = PF_UNIX,
2874 .create = unix_create,
2875 .owner = THIS_MODULE,
2876};
2877
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002878
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002879static int __net_init unix_net_init(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002880{
2881 int error = -ENOMEM;
2882
Denis V. Luneva0a53c82007-12-11 04:19:17 -08002883 net->unx.sysctl_max_dgram_qlen = 10;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002884 if (unix_sysctl_register(net))
2885 goto out;
Pavel Emelyanovd392e492007-12-01 23:44:15 +11002886
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002887#ifdef CONFIG_PROC_FS
Christoph Hellwigc3506372018-04-10 19:42:55 +02002888 if (!proc_create_net("unix", 0, net->proc_net, &unix_seq_ops,
2889 sizeof(struct seq_net_private))) {
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002890 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002891 goto out;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002892 }
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002893#endif
2894 error = 0;
2895out:
Jianjun Kong48dcc33e2008-11-01 21:37:27 -07002896 return error;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002897}
2898
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002899static void __net_exit unix_net_exit(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002900{
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002901 unix_sysctl_unregister(net);
Gao fengece31ff2013-02-18 01:34:56 +00002902 remove_proc_entry("unix", net->proc_net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002903}
2904
2905static struct pernet_operations unix_net_ops = {
2906 .init = unix_net_init,
2907 .exit = unix_net_exit,
2908};
2909
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910static int __init af_unix_init(void)
2911{
2912 int rc = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913
YOSHIFUJI Hideaki / 吉藤英明b4fff5f2013-01-09 07:20:07 +00002914 BUILD_BUG_ON(sizeof(struct unix_skb_parms) > FIELD_SIZEOF(struct sk_buff, cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915
2916 rc = proto_register(&unix_proto, 1);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002917 if (rc != 0) {
wangweidong5cc208b2013-12-06 18:03:36 +08002918 pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919 goto out;
2920 }
2921
2922 sock_register(&unix_family_ops);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002923 register_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924out:
2925 return rc;
2926}
2927
2928static void __exit af_unix_exit(void)
2929{
2930 sock_unregister(PF_UNIX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931 proto_unregister(&unix_proto);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002932 unregister_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933}
2934
David Woodhouse3d366962008-04-24 00:59:25 -07002935/* Earlier than device_initcall() so that other drivers invoking
2936 request_module() don't end up in a loop when modprobe tries
2937 to use a UNIX socket. But later than subsys_initcall() because
2938 we depend on stuff initialised there */
2939fs_initcall(af_unix_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940module_exit(af_unix_exit);
2941
2942MODULE_LICENSE("GPL");
2943MODULE_ALIAS_NETPROTO(PF_UNIX);