blob: 3385a7a0b231339f758cddd7cb1f4cb5ed2c3117 [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
Qian Cai86b18aa2020-02-04 13:40:29 -0500192static inline int unix_recvq_full(const struct sock *sk)
Rainer Weikusat3c734192008-06-17 22:28:05 -0700193{
194 return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
195}
196
Qian Cai86b18aa2020-02-04 13:40:29 -0500197static inline int unix_recvq_full_lockless(const struct sock *sk)
198{
199 return skb_queue_len_lockless(&sk->sk_receive_queue) >
200 READ_ONCE(sk->sk_max_ack_backlog);
201}
202
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000203struct sock *unix_peer_get(struct sock *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204{
205 struct sock *peer;
206
David S. Miller1c92b4e2007-05-31 13:24:26 -0700207 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 peer = unix_peer(s);
209 if (peer)
210 sock_hold(peer);
David S. Miller1c92b4e2007-05-31 13:24:26 -0700211 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212 return peer;
213}
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000214EXPORT_SYMBOL_GPL(unix_peer_get);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
216static inline void unix_release_addr(struct unix_address *addr)
217{
Reshetova, Elena8c9814b2017-06-30 13:08:05 +0300218 if (refcount_dec_and_test(&addr->refcnt))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 kfree(addr);
220}
221
222/*
223 * Check unix socket name:
224 * - should be not zero length.
225 * - if started by not zero, should be NULL terminated (FS object)
226 * - if started by zero, it is abstract name.
227 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900228
Eric Dumazet95c96172012-04-15 05:58:06 +0000229static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned int *hashp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230{
Kyeongdon Kim33c43682018-10-16 14:57:26 +0900231 *hashp = 0;
232
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 if (len <= sizeof(short) || len > sizeof(*sunaddr))
234 return -EINVAL;
235 if (!sunaddr || sunaddr->sun_family != AF_UNIX)
236 return -EINVAL;
237 if (sunaddr->sun_path[0]) {
238 /*
239 * This may look like an off by one error but it is a bit more
240 * subtle. 108 is the longest valid AF_UNIX path for a binding.
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300241 * sun_path[108] doesn't as such exist. However in kernel space
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242 * we are guaranteed that it is a valid memory location in our
243 * kernel address buffer.
244 */
Jianjun Konge27dfce2008-11-01 21:38:31 -0700245 ((char *)sunaddr)[len] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 len = strlen(sunaddr->sun_path)+1+sizeof(short);
247 return len;
248 }
249
Joe Perches07f07572008-11-19 15:44:53 -0800250 *hashp = unix_hash_fold(csum_partial(sunaddr, len, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 return len;
252}
253
254static void __unix_remove_socket(struct sock *sk)
255{
256 sk_del_node_init(sk);
257}
258
259static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
260{
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700261 WARN_ON(!sk_unhashed(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 sk_add_node(sk, list);
263}
264
265static inline void unix_remove_socket(struct sock *sk)
266{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800267 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 __unix_remove_socket(sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800269 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270}
271
272static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
273{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800274 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 __unix_insert_socket(list, sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800276 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277}
278
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800279static struct sock *__unix_find_socket_byname(struct net *net,
280 struct sockaddr_un *sunname,
Eric Dumazet95c96172012-04-15 05:58:06 +0000281 int len, int type, unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282{
283 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284
Sasha Levinb67bfe02013-02-27 17:06:00 -0800285 sk_for_each(s, &unix_socket_table[hash ^ type]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 struct unix_sock *u = unix_sk(s);
287
YOSHIFUJI Hideaki878628f2008-03-26 03:57:35 +0900288 if (!net_eq(sock_net(s), net))
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800289 continue;
290
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 if (u->addr->len == len &&
292 !memcmp(u->addr->name, sunname, len))
Vito Caputo262ce0a2019-10-09 20:43:47 -0700293 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 }
Vito Caputo262ce0a2019-10-09 20:43:47 -0700295 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296}
297
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800298static inline struct sock *unix_find_socket_byname(struct net *net,
299 struct sockaddr_un *sunname,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 int len, int type,
Eric Dumazet95c96172012-04-15 05:58:06 +0000301 unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302{
303 struct sock *s;
304
David S. Millerfbe9cc42005-12-13 23:26:29 -0800305 spin_lock(&unix_table_lock);
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800306 s = __unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 if (s)
308 sock_hold(s);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800309 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 return s;
311}
312
Eric W. Biederman6616f782010-06-13 03:35:48 +0000313static struct sock *unix_find_socket_byinode(struct inode *i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314{
315 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316
David S. Millerfbe9cc42005-12-13 23:26:29 -0800317 spin_lock(&unix_table_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800318 sk_for_each(s,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
Al Viro40ffe672012-03-14 21:54:32 -0400320 struct dentry *dentry = unix_sk(s)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321
Miklos Szeredibeef5122016-12-16 11:02:53 +0100322 if (dentry && d_backing_inode(dentry) == i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 sock_hold(s);
324 goto found;
325 }
326 }
327 s = NULL;
328found:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800329 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 return s;
331}
332
Rainer Weikusat7d267272015-11-20 22:07:23 +0000333/* Support code for asymmetrically connected dgram sockets
334 *
335 * If a datagram socket is connected to a socket not itself connected
336 * to the first socket (eg, /dev/log), clients may only enqueue more
337 * messages if the present receive queue of the server socket is not
338 * "too large". This means there's a second writeability condition
339 * poll and sendmsg need to test. The dgram recv code will do a wake
340 * up on the peer_wait wait queue of a socket upon reception of a
341 * datagram which needs to be propagated to sleeping would-be writers
342 * since these might not have sent anything so far. This can't be
343 * accomplished via poll_wait because the lifetime of the server
344 * socket might be less than that of its clients if these break their
345 * association with it or if the server socket is closed while clients
346 * are still connected to it and there's no way to inform "a polling
347 * implementation" that it should let go of a certain wait queue
348 *
Ingo Molnarac6424b2017-06-20 12:06:13 +0200349 * In order to propagate a wake up, a wait_queue_entry_t of the client
Rainer Weikusat7d267272015-11-20 22:07:23 +0000350 * socket is enqueued on the peer_wait queue of the server socket
351 * whose wake function does a wake_up on the ordinary client socket
352 * wait queue. This connection is established whenever a write (or
353 * poll for write) hit the flow control condition and broken when the
354 * association to the server socket is dissolved or after a wake up
355 * was relayed.
356 */
357
Ingo Molnarac6424b2017-06-20 12:06:13 +0200358static int unix_dgram_peer_wake_relay(wait_queue_entry_t *q, unsigned mode, int flags,
Rainer Weikusat7d267272015-11-20 22:07:23 +0000359 void *key)
360{
361 struct unix_sock *u;
362 wait_queue_head_t *u_sleep;
363
364 u = container_of(q, struct unix_sock, peer_wake);
365
366 __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
367 q);
368 u->peer_wake.private = NULL;
369
370 /* relaying can only happen while the wq still exists */
371 u_sleep = sk_sleep(&u->sk);
372 if (u_sleep)
Al Viro3ad6f932017-07-03 20:14:56 -0400373 wake_up_interruptible_poll(u_sleep, key_to_poll(key));
Rainer Weikusat7d267272015-11-20 22:07:23 +0000374
375 return 0;
376}
377
378static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
379{
380 struct unix_sock *u, *u_other;
381 int rc;
382
383 u = unix_sk(sk);
384 u_other = unix_sk(other);
385 rc = 0;
386 spin_lock(&u_other->peer_wait.lock);
387
388 if (!u->peer_wake.private) {
389 u->peer_wake.private = other;
390 __add_wait_queue(&u_other->peer_wait, &u->peer_wake);
391
392 rc = 1;
393 }
394
395 spin_unlock(&u_other->peer_wait.lock);
396 return rc;
397}
398
399static void unix_dgram_peer_wake_disconnect(struct sock *sk,
400 struct sock *other)
401{
402 struct unix_sock *u, *u_other;
403
404 u = unix_sk(sk);
405 u_other = unix_sk(other);
406 spin_lock(&u_other->peer_wait.lock);
407
408 if (u->peer_wake.private == other) {
409 __remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
410 u->peer_wake.private = NULL;
411 }
412
413 spin_unlock(&u_other->peer_wait.lock);
414}
415
416static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
417 struct sock *other)
418{
419 unix_dgram_peer_wake_disconnect(sk, other);
420 wake_up_interruptible_poll(sk_sleep(sk),
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800421 EPOLLOUT |
422 EPOLLWRNORM |
423 EPOLLWRBAND);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000424}
425
426/* preconditions:
427 * - unix_peer(sk) == other
428 * - association is stable
429 */
430static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
431{
432 int connected;
433
434 connected = unix_dgram_peer_wake_connect(sk, other);
435
Jason Baron51f7e952018-08-03 17:24:53 -0400436 /* If other is SOCK_DEAD, we want to make sure we signal
437 * POLLOUT, such that a subsequent write() can get a
438 * -ECONNREFUSED. Otherwise, if we haven't queued any skbs
439 * to other and its full, we will hang waiting for POLLOUT.
440 */
441 if (unix_recvq_full(other) && !sock_flag(other, SOCK_DEAD))
Rainer Weikusat7d267272015-11-20 22:07:23 +0000442 return 1;
443
444 if (connected)
445 unix_dgram_peer_wake_disconnect(sk, other);
446
447 return 0;
448}
449
Eric Dumazet1586a582015-10-23 10:59:16 -0700450static int unix_writable(const struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451{
Eric Dumazet1586a582015-10-23 10:59:16 -0700452 return sk->sk_state != TCP_LISTEN &&
Reshetova, Elena14afee42017-06-30 13:08:00 +0300453 (refcount_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454}
455
456static void unix_write_space(struct sock *sk)
457{
Eric Dumazet43815482010-04-29 11:01:49 +0000458 struct socket_wq *wq;
459
460 rcu_read_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 if (unix_writable(sk)) {
Eric Dumazet43815482010-04-29 11:01:49 +0000462 wq = rcu_dereference(sk->sk_wq);
Herbert Xu1ce0bf52015-11-26 13:55:39 +0800463 if (skwq_has_sleeper(wq))
Eric Dumazet67426b72010-10-29 20:44:44 +0000464 wake_up_interruptible_sync_poll(&wq->wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800465 EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800466 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 }
Eric Dumazet43815482010-04-29 11:01:49 +0000468 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469}
470
471/* When dgram socket disconnects (or changes its peer), we clear its receive
472 * queue of packets arrived from previous peer. First, it allows to do
473 * flow control based only on wmem_alloc; second, sk connected to peer
474 * may receive messages only from that peer. */
475static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
476{
David S. Millerb03efcf2005-07-08 14:57:23 -0700477 if (!skb_queue_empty(&sk->sk_receive_queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 skb_queue_purge(&sk->sk_receive_queue);
479 wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
480
481 /* If one link of bidirectional dgram pipe is disconnected,
482 * we signal error. Messages are lost. Do not make this,
483 * when peer was not connected to us.
484 */
485 if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) {
486 other->sk_err = ECONNRESET;
487 other->sk_error_report(other);
488 }
489 }
490}
491
492static void unix_sock_destructor(struct sock *sk)
493{
494 struct unix_sock *u = unix_sk(sk);
495
496 skb_queue_purge(&sk->sk_receive_queue);
497
Reshetova, Elena14afee42017-06-30 13:08:00 +0300498 WARN_ON(refcount_read(&sk->sk_wmem_alloc));
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700499 WARN_ON(!sk_unhashed(sk));
500 WARN_ON(sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 if (!sock_flag(sk, SOCK_DEAD)) {
wangweidong5cc208b2013-12-06 18:03:36 +0800502 pr_info("Attempt to release alive unix socket: %p\n", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 return;
504 }
505
506 if (u->addr)
507 unix_release_addr(u->addr);
508
Eric Dumazet518de9b2010-10-26 14:22:44 -0700509 atomic_long_dec(&unix_nr_socks);
David S. Miller6f756a82008-11-23 17:34:03 -0800510 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800511 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
David S. Miller6f756a82008-11-23 17:34:03 -0800512 local_bh_enable();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513#ifdef UNIX_REFCNT_DEBUG
wangweidong5cc208b2013-12-06 18:03:36 +0800514 pr_debug("UNIX %p is destroyed, %ld are still alive.\n", sk,
Eric Dumazet518de9b2010-10-26 14:22:44 -0700515 atomic_long_read(&unix_nr_socks));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516#endif
517}
518
Paul Mooreded34e02013-03-25 03:18:33 +0000519static void unix_release_sock(struct sock *sk, int embrion)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520{
521 struct unix_sock *u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400522 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 struct sock *skpair;
524 struct sk_buff *skb;
525 int state;
526
527 unix_remove_socket(sk);
528
529 /* Clear state */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700530 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 sock_orphan(sk);
532 sk->sk_shutdown = SHUTDOWN_MASK;
Al Viro40ffe672012-03-14 21:54:32 -0400533 path = u->path;
534 u->path.dentry = NULL;
535 u->path.mnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 state = sk->sk_state;
537 sk->sk_state = TCP_CLOSE;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700538 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539
540 wake_up_interruptible_all(&u->peer_wait);
541
Jianjun Konge27dfce2008-11-01 21:38:31 -0700542 skpair = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543
Jianjun Konge27dfce2008-11-01 21:38:31 -0700544 if (skpair != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
David S. Miller1c92b4e2007-05-31 13:24:26 -0700546 unix_state_lock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 /* No more writes */
548 skpair->sk_shutdown = SHUTDOWN_MASK;
549 if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
550 skpair->sk_err = ECONNRESET;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700551 unix_state_unlock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 skpair->sk_state_change(skpair);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800553 sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 }
Rainer Weikusat7d267272015-11-20 22:07:23 +0000555
556 unix_dgram_peer_wake_disconnect(sk, skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 sock_put(skpair); /* It may now die */
558 unix_peer(sk) = NULL;
559 }
560
561 /* Try to flush out this socket. Throw out buffers at least */
562
563 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
Jianjun Konge27dfce2008-11-01 21:38:31 -0700564 if (state == TCP_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565 unix_release_sock(skb->sk, 1);
566 /* passed fds are erased in the kfree_skb hook */
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +0100567 UNIXCB(skb).consumed = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 kfree_skb(skb);
569 }
570
Al Viro40ffe672012-03-14 21:54:32 -0400571 if (path.dentry)
572 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573
574 sock_put(sk);
575
576 /* ---- Socket is dead now and most probably destroyed ---- */
577
578 /*
Alan Coxe04dae82012-09-17 00:52:41 +0000579 * Fixme: BSD difference: In BSD all sockets connected to us get
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 * ECONNRESET and we die on the spot. In Linux we behave
581 * like files and pipes do and wait for the last
582 * dereference.
583 *
584 * Can't we simply set sock->err?
585 *
586 * What the above comment does talk about? --ANK(980817)
587 */
588
Pavel Emelyanov9305cfa2007-11-10 22:06:01 -0800589 if (unix_tot_inflight)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900590 unix_gc(); /* Garbage collect fds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591}
592
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000593static void init_peercred(struct sock *sk)
594{
595 put_pid(sk->sk_peer_pid);
596 if (sk->sk_peer_cred)
597 put_cred(sk->sk_peer_cred);
598 sk->sk_peer_pid = get_pid(task_tgid(current));
599 sk->sk_peer_cred = get_current_cred();
600}
601
602static void copy_peercred(struct sock *sk, struct sock *peersk)
603{
604 put_pid(sk->sk_peer_pid);
605 if (sk->sk_peer_cred)
606 put_cred(sk->sk_peer_cred);
607 sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
608 sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
609}
610
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611static int unix_listen(struct socket *sock, int backlog)
612{
613 int err;
614 struct sock *sk = sock->sk;
615 struct unix_sock *u = unix_sk(sk);
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000616 struct pid *old_pid = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617
618 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800619 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
620 goto out; /* Only stream/seqpacket sockets accept */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 err = -EINVAL;
622 if (!u->addr)
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800623 goto out; /* No listens on an unbound socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700624 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
626 goto out_unlock;
627 if (backlog > sk->sk_max_ack_backlog)
628 wake_up_interruptible_all(&u->peer_wait);
629 sk->sk_max_ack_backlog = backlog;
630 sk->sk_state = TCP_LISTEN;
631 /* set credentials so connect can copy them */
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000632 init_peercred(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 err = 0;
634
635out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -0700636 unix_state_unlock(sk);
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000637 put_pid(old_pid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638out:
639 return err;
640}
641
642static int unix_release(struct socket *);
643static int unix_bind(struct socket *, struct sockaddr *, int);
644static int unix_stream_connect(struct socket *, struct sockaddr *,
645 int addr_len, int flags);
646static int unix_socketpair(struct socket *, struct socket *);
David Howellscdfbabf2017-03-09 08:09:05 +0000647static int unix_accept(struct socket *, struct socket *, int, bool);
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +0100648static int unix_getname(struct socket *, struct sockaddr *, int);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700649static __poll_t unix_poll(struct file *, struct socket *, poll_table *);
650static __poll_t unix_dgram_poll(struct file *, struct socket *,
651 poll_table *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652static int unix_ioctl(struct socket *, unsigned int, unsigned long);
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200653#ifdef CONFIG_COMPAT
654static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
655#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656static int unix_shutdown(struct socket *, int);
Ying Xue1b784142015-03-02 15:37:48 +0800657static int unix_stream_sendmsg(struct socket *, struct msghdr *, size_t);
658static int unix_stream_recvmsg(struct socket *, struct msghdr *, size_t, int);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200659static ssize_t unix_stream_sendpage(struct socket *, struct page *, int offset,
660 size_t size, int flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200661static ssize_t unix_stream_splice_read(struct socket *, loff_t *ppos,
662 struct pipe_inode_info *, size_t size,
663 unsigned int flags);
Ying Xue1b784142015-03-02 15:37:48 +0800664static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t);
665static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666static int unix_dgram_connect(struct socket *, struct sockaddr *,
667 int, int);
Ying Xue1b784142015-03-02 15:37:48 +0800668static int unix_seqpacket_sendmsg(struct socket *, struct msghdr *, size_t);
669static int unix_seqpacket_recvmsg(struct socket *, struct msghdr *, size_t,
670 int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671
Sasha Levin12663bf2013-12-07 17:26:27 -0500672static int unix_set_peek_off(struct sock *sk, int val)
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000673{
674 struct unix_sock *u = unix_sk(sk);
675
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700676 if (mutex_lock_interruptible(&u->iolock))
Sasha Levin12663bf2013-12-07 17:26:27 -0500677 return -EINTR;
678
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000679 sk->sk_peek_off = val;
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700680 mutex_unlock(&u->iolock);
Sasha Levin12663bf2013-12-07 17:26:27 -0500681
682 return 0;
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000683}
684
David S. Miller5c05a162020-02-27 11:52:35 -0800685#ifdef CONFIG_PROC_FS
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300686static void unix_show_fdinfo(struct seq_file *m, struct socket *sock)
687{
688 struct sock *sk = sock->sk;
689 struct unix_sock *u;
690
691 if (sk) {
692 u = unix_sk(sock->sk);
Paolo Abeni77820402020-02-28 14:45:21 +0100693 seq_printf(m, "scm_fds: %u\n",
694 atomic_read(&u->scm_stat.nr_fds));
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300695 }
696}
Tobias Klauser3a125002020-02-26 18:29:53 +0100697#else
698#define unix_show_fdinfo NULL
699#endif
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000700
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800701static const struct proto_ops unix_stream_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 .family = PF_UNIX,
703 .owner = THIS_MODULE,
704 .release = unix_release,
705 .bind = unix_bind,
706 .connect = unix_stream_connect,
707 .socketpair = unix_socketpair,
708 .accept = unix_accept,
709 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700710 .poll = unix_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200712#ifdef CONFIG_COMPAT
713 .compat_ioctl = unix_compat_ioctl,
714#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 .listen = unix_listen,
716 .shutdown = unix_shutdown,
717 .setsockopt = sock_no_setsockopt,
718 .getsockopt = sock_no_getsockopt,
719 .sendmsg = unix_stream_sendmsg,
720 .recvmsg = unix_stream_recvmsg,
721 .mmap = sock_no_mmap,
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200722 .sendpage = unix_stream_sendpage,
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200723 .splice_read = unix_stream_splice_read,
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +0000724 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300725 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726};
727
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800728static const struct proto_ops unix_dgram_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 .family = PF_UNIX,
730 .owner = THIS_MODULE,
731 .release = unix_release,
732 .bind = unix_bind,
733 .connect = unix_dgram_connect,
734 .socketpair = unix_socketpair,
735 .accept = sock_no_accept,
736 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700737 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200739#ifdef CONFIG_COMPAT
740 .compat_ioctl = unix_compat_ioctl,
741#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 .listen = sock_no_listen,
743 .shutdown = unix_shutdown,
744 .setsockopt = sock_no_setsockopt,
745 .getsockopt = sock_no_getsockopt,
746 .sendmsg = unix_dgram_sendmsg,
747 .recvmsg = unix_dgram_recvmsg,
748 .mmap = sock_no_mmap,
749 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000750 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300751 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752};
753
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800754static const struct proto_ops unix_seqpacket_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 .family = PF_UNIX,
756 .owner = THIS_MODULE,
757 .release = unix_release,
758 .bind = unix_bind,
759 .connect = unix_stream_connect,
760 .socketpair = unix_socketpair,
761 .accept = unix_accept,
762 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700763 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200765#ifdef CONFIG_COMPAT
766 .compat_ioctl = unix_compat_ioctl,
767#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 .listen = unix_listen,
769 .shutdown = unix_shutdown,
770 .setsockopt = sock_no_setsockopt,
771 .getsockopt = sock_no_getsockopt,
772 .sendmsg = unix_seqpacket_sendmsg,
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +0000773 .recvmsg = unix_seqpacket_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 .mmap = sock_no_mmap,
775 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000776 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300777 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778};
779
780static struct proto unix_proto = {
Eric Dumazet248969a2008-11-17 00:00:30 -0800781 .name = "UNIX",
782 .owner = THIS_MODULE,
Eric Dumazet248969a2008-11-17 00:00:30 -0800783 .obj_size = sizeof(struct unix_sock),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784};
785
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500786static struct sock *unix_create1(struct net *net, struct socket *sock, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787{
788 struct sock *sk = NULL;
789 struct unix_sock *u;
790
Eric Dumazet518de9b2010-10-26 14:22:44 -0700791 atomic_long_inc(&unix_nr_socks);
792 if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 goto out;
794
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500795 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, kern);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 if (!sk)
797 goto out;
798
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800799 sock_init_data(sock, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
Vladimir Davydov3aa97992016-07-26 15:24:36 -0700801 sk->sk_allocation = GFP_KERNEL_ACCOUNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 sk->sk_write_space = unix_write_space;
Denis V. Luneva0a53c82007-12-11 04:19:17 -0800803 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 sk->sk_destruct = unix_sock_destructor;
805 u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400806 u->path.dentry = NULL;
807 u->path.mnt = NULL;
Benjamin LaHaisefd19f322006-01-03 14:10:46 -0800808 spin_lock_init(&u->lock);
Al Viro516e0cc2008-07-26 00:39:17 -0400809 atomic_long_set(&u->inflight, 0);
Miklos Szeredi1fd05ba2007-07-11 14:22:39 -0700810 INIT_LIST_HEAD(&u->link);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700811 mutex_init(&u->iolock); /* single task reading lock */
812 mutex_init(&u->bindlock); /* single task binding lock */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 init_waitqueue_head(&u->peer_wait);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000814 init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300815 memset(&u->scm_stat, 0, sizeof(struct scm_stat));
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000816 unix_insert_socket(unix_sockets_unbound(sk), sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817out:
Pavel Emelyanov284b3272007-11-10 22:08:30 -0800818 if (sk == NULL)
Eric Dumazet518de9b2010-10-26 14:22:44 -0700819 atomic_long_dec(&unix_nr_socks);
Eric Dumazet920de802008-11-24 00:09:29 -0800820 else {
821 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800822 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
Eric Dumazet920de802008-11-24 00:09:29 -0800823 local_bh_enable();
824 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 return sk;
826}
827
Eric Paris3f378b62009-11-05 22:18:14 -0800828static int unix_create(struct net *net, struct socket *sock, int protocol,
829 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830{
831 if (protocol && protocol != PF_UNIX)
832 return -EPROTONOSUPPORT;
833
834 sock->state = SS_UNCONNECTED;
835
836 switch (sock->type) {
837 case SOCK_STREAM:
838 sock->ops = &unix_stream_ops;
839 break;
840 /*
841 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
842 * nothing uses it.
843 */
844 case SOCK_RAW:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700845 sock->type = SOCK_DGRAM;
Gustavo A. R. Silva110af3a2017-10-20 12:05:30 -0500846 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 case SOCK_DGRAM:
848 sock->ops = &unix_dgram_ops;
849 break;
850 case SOCK_SEQPACKET:
851 sock->ops = &unix_seqpacket_ops;
852 break;
853 default:
854 return -ESOCKTNOSUPPORT;
855 }
856
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500857 return unix_create1(net, sock, kern) ? 0 : -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858}
859
860static int unix_release(struct socket *sock)
861{
862 struct sock *sk = sock->sk;
863
864 if (!sk)
865 return 0;
866
Paul Mooreded34e02013-03-25 03:18:33 +0000867 unix_release_sock(sk, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868 sock->sk = NULL;
869
Paul Mooreded34e02013-03-25 03:18:33 +0000870 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871}
872
873static int unix_autobind(struct socket *sock)
874{
875 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900876 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 struct unix_sock *u = unix_sk(sk);
878 static u32 ordernum = 1;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800879 struct unix_address *addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 int err;
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000881 unsigned int retries = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700883 err = mutex_lock_interruptible(&u->bindlock);
Sasha Levin37ab4fa2013-12-13 10:54:22 -0500884 if (err)
885 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887 err = 0;
888 if (u->addr)
889 goto out;
890
891 err = -ENOMEM;
Panagiotis Issaris0da974f2006-07-21 14:51:30 -0700892 addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 if (!addr)
894 goto out;
895
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 addr->name->sun_family = AF_UNIX;
Reshetova, Elena8c9814b2017-06-30 13:08:05 +0300897 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898
899retry:
900 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
Joe Perches07f07572008-11-19 15:44:53 -0800901 addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902
David S. Millerfbe9cc42005-12-13 23:26:29 -0800903 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 ordernum = (ordernum+1)&0xFFFFF;
905
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800906 if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 addr->hash)) {
David S. Millerfbe9cc42005-12-13 23:26:29 -0800908 spin_unlock(&unix_table_lock);
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000909 /*
910 * __unix_find_socket_byname() may take long time if many names
911 * are already in use.
912 */
913 cond_resched();
914 /* Give up if all names seems to be in use. */
915 if (retries++ == 0xFFFFF) {
916 err = -ENOSPC;
917 kfree(addr);
918 goto out;
919 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 goto retry;
921 }
922 addr->hash ^= sk->sk_type;
923
924 __unix_remove_socket(sk);
Al Viroae3b5642019-02-15 20:09:35 +0000925 smp_store_release(&u->addr, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 __unix_insert_socket(&unix_socket_table[addr->hash], sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800927 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 err = 0;
929
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700930out: mutex_unlock(&u->bindlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 return err;
932}
933
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800934static struct sock *unix_find_other(struct net *net,
935 struct sockaddr_un *sunname, int len,
Eric Dumazet95c96172012-04-15 05:58:06 +0000936 int type, unsigned int hash, int *error)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937{
938 struct sock *u;
Al Viro421748e2008-08-02 01:04:36 -0400939 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 int err = 0;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900941
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 if (sunname->sun_path[0]) {
Al Viro421748e2008-08-02 01:04:36 -0400943 struct inode *inode;
944 err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 if (err)
946 goto fail;
Miklos Szeredibeef5122016-12-16 11:02:53 +0100947 inode = d_backing_inode(path.dentry);
Al Viro421748e2008-08-02 01:04:36 -0400948 err = inode_permission(inode, MAY_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 if (err)
950 goto put_fail;
951
952 err = -ECONNREFUSED;
Al Viro421748e2008-08-02 01:04:36 -0400953 if (!S_ISSOCK(inode->i_mode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 goto put_fail;
Eric W. Biederman6616f782010-06-13 03:35:48 +0000955 u = unix_find_socket_byinode(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 if (!u)
957 goto put_fail;
958
959 if (u->sk_type == type)
Al Viro68ac1232012-03-15 08:21:57 -0400960 touch_atime(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961
Al Viro421748e2008-08-02 01:04:36 -0400962 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963
Jianjun Konge27dfce2008-11-01 21:38:31 -0700964 err = -EPROTOTYPE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 if (u->sk_type != type) {
966 sock_put(u);
967 goto fail;
968 }
969 } else {
970 err = -ECONNREFUSED;
Jianjun Konge27dfce2008-11-01 21:38:31 -0700971 u = unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 if (u) {
973 struct dentry *dentry;
Al Viro40ffe672012-03-14 21:54:32 -0400974 dentry = unix_sk(u)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 if (dentry)
Al Viro68ac1232012-03-15 08:21:57 -0400976 touch_atime(&unix_sk(u)->path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 } else
978 goto fail;
979 }
980 return u;
981
982put_fail:
Al Viro421748e2008-08-02 01:04:36 -0400983 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984fail:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700985 *error = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986 return NULL;
987}
988
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700989static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
Al Virofaf02012012-07-20 02:37:29 +0400990{
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700991 struct dentry *dentry;
992 struct path path;
993 int err = 0;
994 /*
995 * Get the parent directory, calculate the hash for last
996 * component.
997 */
998 dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
999 err = PTR_ERR(dentry);
1000 if (IS_ERR(dentry))
1001 return err;
Al Virofaf02012012-07-20 02:37:29 +04001002
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001003 /*
1004 * All right, let's create it.
1005 */
1006 err = security_path_mknod(&path, dentry, mode, 0);
Al Virofaf02012012-07-20 02:37:29 +04001007 if (!err) {
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001008 err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0);
Al Virofaf02012012-07-20 02:37:29 +04001009 if (!err) {
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001010 res->mnt = mntget(path.mnt);
Al Virofaf02012012-07-20 02:37:29 +04001011 res->dentry = dget(dentry);
1012 }
1013 }
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001014 done_path_create(&path, dentry);
Al Virofaf02012012-07-20 02:37:29 +04001015 return err;
1016}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017
1018static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1019{
1020 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001021 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 struct unix_sock *u = unix_sk(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001023 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Al Virodae6ad82011-06-26 11:50:15 -04001024 char *sun_path = sunaddr->sun_path;
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001025 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001026 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 struct unix_address *addr;
1028 struct hlist_head *list;
Kees Cook82fe0d22017-04-04 22:12:09 -07001029 struct path path = { };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030
1031 err = -EINVAL;
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001032 if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
1033 sunaddr->sun_family != AF_UNIX)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 goto out;
1035
Jianjun Konge27dfce2008-11-01 21:38:31 -07001036 if (addr_len == sizeof(short)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037 err = unix_autobind(sock);
1038 goto out;
1039 }
1040
1041 err = unix_mkname(sunaddr, addr_len, &hash);
1042 if (err < 0)
1043 goto out;
1044 addr_len = err;
1045
WANG Cong0fb44552017-01-23 11:17:35 -08001046 if (sun_path[0]) {
1047 umode_t mode = S_IFSOCK |
1048 (SOCK_INODE(sock)->i_mode & ~current_umask());
1049 err = unix_mknod(sun_path, mode, &path);
1050 if (err) {
1051 if (err == -EEXIST)
1052 err = -EADDRINUSE;
1053 goto out;
1054 }
1055 }
1056
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001057 err = mutex_lock_interruptible(&u->bindlock);
Sasha Levin37ab4fa2013-12-13 10:54:22 -05001058 if (err)
WANG Cong0fb44552017-01-23 11:17:35 -08001059 goto out_put;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
1061 err = -EINVAL;
1062 if (u->addr)
1063 goto out_up;
1064
1065 err = -ENOMEM;
1066 addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
1067 if (!addr)
1068 goto out_up;
1069
1070 memcpy(addr->name, sunaddr, addr_len);
1071 addr->len = addr_len;
1072 addr->hash = hash ^ sk->sk_type;
Reshetova, Elena8c9814b2017-06-30 13:08:05 +03001073 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001075 if (sun_path[0]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 addr->hash = UNIX_HASH_SIZE;
Miklos Szeredibeef5122016-12-16 11:02:53 +01001077 hash = d_backing_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1);
Al Virofaf02012012-07-20 02:37:29 +04001078 spin_lock(&unix_table_lock);
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001079 u->path = path;
Al Virofaf02012012-07-20 02:37:29 +04001080 list = &unix_socket_table[hash];
1081 } else {
1082 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 err = -EADDRINUSE;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001084 if (__unix_find_socket_byname(net, sunaddr, addr_len,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 sk->sk_type, hash)) {
1086 unix_release_addr(addr);
1087 goto out_unlock;
1088 }
1089
1090 list = &unix_socket_table[addr->hash];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 }
1092
1093 err = 0;
1094 __unix_remove_socket(sk);
Al Viroae3b5642019-02-15 20:09:35 +00001095 smp_store_release(&u->addr, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 __unix_insert_socket(list, sk);
1097
1098out_unlock:
David S. Millerfbe9cc42005-12-13 23:26:29 -08001099 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100out_up:
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001101 mutex_unlock(&u->bindlock);
WANG Cong0fb44552017-01-23 11:17:35 -08001102out_put:
1103 if (err)
1104 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105out:
1106 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107}
1108
David S. Miller278a3de2007-05-31 15:19:20 -07001109static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
1110{
1111 if (unlikely(sk1 == sk2) || !sk2) {
1112 unix_state_lock(sk1);
1113 return;
1114 }
1115 if (sk1 < sk2) {
1116 unix_state_lock(sk1);
1117 unix_state_lock_nested(sk2);
1118 } else {
1119 unix_state_lock(sk2);
1120 unix_state_lock_nested(sk1);
1121 }
1122}
1123
1124static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
1125{
1126 if (unlikely(sk1 == sk2) || !sk2) {
1127 unix_state_unlock(sk1);
1128 return;
1129 }
1130 unix_state_unlock(sk1);
1131 unix_state_unlock(sk2);
1132}
1133
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
1135 int alen, int flags)
1136{
1137 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001138 struct net *net = sock_net(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001139 struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 struct sock *other;
Eric Dumazet95c96172012-04-15 05:58:06 +00001141 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 int err;
1143
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001144 err = -EINVAL;
1145 if (alen < offsetofend(struct sockaddr, sa_family))
1146 goto out;
1147
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 if (addr->sa_family != AF_UNSPEC) {
1149 err = unix_mkname(sunaddr, alen, &hash);
1150 if (err < 0)
1151 goto out;
1152 alen = err;
1153
1154 if (test_bit(SOCK_PASSCRED, &sock->flags) &&
1155 !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
1156 goto out;
1157
David S. Miller278a3de2007-05-31 15:19:20 -07001158restart:
Jianjun Konge27dfce2008-11-01 21:38:31 -07001159 other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 if (!other)
1161 goto out;
1162
David S. Miller278a3de2007-05-31 15:19:20 -07001163 unix_state_double_lock(sk, other);
1164
1165 /* Apparently VFS overslept socket death. Retry. */
1166 if (sock_flag(other, SOCK_DEAD)) {
1167 unix_state_double_unlock(sk, other);
1168 sock_put(other);
1169 goto restart;
1170 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171
1172 err = -EPERM;
1173 if (!unix_may_send(sk, other))
1174 goto out_unlock;
1175
1176 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1177 if (err)
1178 goto out_unlock;
1179
1180 } else {
1181 /*
1182 * 1003.1g breaking connected state with AF_UNSPEC
1183 */
1184 other = NULL;
David S. Miller278a3de2007-05-31 15:19:20 -07001185 unix_state_double_lock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 }
1187
1188 /*
1189 * If it was connected, reconnect.
1190 */
1191 if (unix_peer(sk)) {
1192 struct sock *old_peer = unix_peer(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001193 unix_peer(sk) = other;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001194 unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
1195
David S. Miller278a3de2007-05-31 15:19:20 -07001196 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197
1198 if (other != old_peer)
1199 unix_dgram_disconnected(sk, old_peer);
1200 sock_put(old_peer);
1201 } else {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001202 unix_peer(sk) = other;
David S. Miller278a3de2007-05-31 15:19:20 -07001203 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 }
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001205 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206
1207out_unlock:
David S. Miller278a3de2007-05-31 15:19:20 -07001208 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 sock_put(other);
1210out:
1211 return err;
1212}
1213
1214static long unix_wait_for_peer(struct sock *other, long timeo)
Jules Irenge48851e92020-02-23 23:16:56 +00001215 __releases(&unix_sk(other)->lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216{
1217 struct unix_sock *u = unix_sk(other);
1218 int sched;
1219 DEFINE_WAIT(wait);
1220
1221 prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
1222
1223 sched = !sock_flag(other, SOCK_DEAD) &&
1224 !(other->sk_shutdown & RCV_SHUTDOWN) &&
Rainer Weikusat3c734192008-06-17 22:28:05 -07001225 unix_recvq_full(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226
David S. Miller1c92b4e2007-05-31 13:24:26 -07001227 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228
1229 if (sched)
1230 timeo = schedule_timeout(timeo);
1231
1232 finish_wait(&u->peer_wait, &wait);
1233 return timeo;
1234}
1235
1236static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
1237 int addr_len, int flags)
1238{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001239 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001241 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 struct unix_sock *u = unix_sk(sk), *newu, *otheru;
1243 struct sock *newsk = NULL;
1244 struct sock *other = NULL;
1245 struct sk_buff *skb = NULL;
Eric Dumazet95c96172012-04-15 05:58:06 +00001246 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 int st;
1248 int err;
1249 long timeo;
1250
1251 err = unix_mkname(sunaddr, addr_len, &hash);
1252 if (err < 0)
1253 goto out;
1254 addr_len = err;
1255
Joe Perchesf64f9e72009-11-29 16:55:45 -08001256 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr &&
1257 (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258 goto out;
1259
1260 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
1261
1262 /* First of all allocate resources.
1263 If we will make it after state is locked,
1264 we will have to recheck all again in any case.
1265 */
1266
1267 err = -ENOMEM;
1268
1269 /* create new sock for complete connection */
Eric W. Biederman11aa9c22015-05-08 21:09:13 -05001270 newsk = unix_create1(sock_net(sk), NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 if (newsk == NULL)
1272 goto out;
1273
1274 /* Allocate skb for sending to listening sock */
1275 skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL);
1276 if (skb == NULL)
1277 goto out;
1278
1279restart:
1280 /* Find listening sock. */
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001281 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 if (!other)
1283 goto out;
1284
1285 /* Latch state of peer */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001286 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287
1288 /* Apparently VFS overslept socket death. Retry. */
1289 if (sock_flag(other, SOCK_DEAD)) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001290 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291 sock_put(other);
1292 goto restart;
1293 }
1294
1295 err = -ECONNREFUSED;
1296 if (other->sk_state != TCP_LISTEN)
1297 goto out_unlock;
Tomoki Sekiyama77238f22009-10-18 23:17:37 -07001298 if (other->sk_shutdown & RCV_SHUTDOWN)
1299 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300
Rainer Weikusat3c734192008-06-17 22:28:05 -07001301 if (unix_recvq_full(other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302 err = -EAGAIN;
1303 if (!timeo)
1304 goto out_unlock;
1305
1306 timeo = unix_wait_for_peer(other, timeo);
1307
1308 err = sock_intr_errno(timeo);
1309 if (signal_pending(current))
1310 goto out;
1311 sock_put(other);
1312 goto restart;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001313 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314
1315 /* Latch our state.
1316
Daniel Balutae5537bf2011-03-14 15:25:33 -07001317 It is tricky place. We need to grab our state lock and cannot
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 drop lock on peer. It is dangerous because deadlock is
1319 possible. Connect to self case and simultaneous
1320 attempt to connect are eliminated by checking socket
1321 state. other is TCP_LISTEN, if sk is TCP_LISTEN we
1322 check this before attempt to grab lock.
1323
1324 Well, and we have to recheck the state after socket locked.
1325 */
1326 st = sk->sk_state;
1327
1328 switch (st) {
1329 case TCP_CLOSE:
1330 /* This is ok... continue with connect */
1331 break;
1332 case TCP_ESTABLISHED:
1333 /* Socket is already connected */
1334 err = -EISCONN;
1335 goto out_unlock;
1336 default:
1337 err = -EINVAL;
1338 goto out_unlock;
1339 }
1340
David S. Miller1c92b4e2007-05-31 13:24:26 -07001341 unix_state_lock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342
1343 if (sk->sk_state != st) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001344 unix_state_unlock(sk);
1345 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 sock_put(other);
1347 goto restart;
1348 }
1349
David S. Miller3610cda2011-01-05 15:38:53 -08001350 err = security_unix_stream_connect(sk, other, newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 if (err) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001352 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 goto out_unlock;
1354 }
1355
1356 /* The way is open! Fastly set all the necessary fields... */
1357
1358 sock_hold(sk);
1359 unix_peer(newsk) = sk;
1360 newsk->sk_state = TCP_ESTABLISHED;
1361 newsk->sk_type = sk->sk_type;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001362 init_peercred(newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 newu = unix_sk(newsk);
Eric Dumazeteaefd1102011-02-18 03:26:36 +00001364 RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 otheru = unix_sk(other);
1366
Al Viroae3b5642019-02-15 20:09:35 +00001367 /* copy address information from listening to new sock
1368 *
1369 * The contents of *(otheru->addr) and otheru->path
1370 * are seen fully set up here, since we have found
1371 * otheru in hash under unix_table_lock. Insertion
1372 * into the hash chain we'd found it in had been done
1373 * in an earlier critical area protected by unix_table_lock,
1374 * the same one where we'd set *(otheru->addr) contents,
1375 * as well as otheru->path and otheru->addr itself.
1376 *
1377 * Using smp_store_release() here to set newu->addr
1378 * is enough to make those stores, as well as stores
1379 * to newu->path visible to anyone who gets newu->addr
1380 * by smp_load_acquire(). IOW, the same warranties
1381 * as for unix_sock instances bound in unix_bind() or
1382 * in unix_autobind().
1383 */
Al Viro40ffe672012-03-14 21:54:32 -04001384 if (otheru->path.dentry) {
1385 path_get(&otheru->path);
1386 newu->path = otheru->path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 }
Al Viroae3b5642019-02-15 20:09:35 +00001388 refcount_inc(&otheru->addr->refcnt);
1389 smp_store_release(&newu->addr, otheru->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390
1391 /* Set credentials */
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001392 copy_peercred(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 sock->state = SS_CONNECTED;
1395 sk->sk_state = TCP_ESTABLISHED;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001396 sock_hold(newsk);
1397
Peter Zijlstra4e857c52014-03-17 18:06:10 +01001398 smp_mb__after_atomic(); /* sock_hold() does an atomic_inc() */
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001399 unix_peer(sk) = newsk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400
David S. Miller1c92b4e2007-05-31 13:24:26 -07001401 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402
1403 /* take ten and and send info to listening sock */
1404 spin_lock(&other->sk_receive_queue.lock);
1405 __skb_queue_tail(&other->sk_receive_queue, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001407 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001408 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 sock_put(other);
1410 return 0;
1411
1412out_unlock:
1413 if (other)
David S. Miller1c92b4e2007-05-31 13:24:26 -07001414 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415
1416out:
Wei Yongjun40d44442009-02-25 00:32:45 +00001417 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 if (newsk)
1419 unix_release_sock(newsk, 0);
1420 if (other)
1421 sock_put(other);
1422 return err;
1423}
1424
1425static int unix_socketpair(struct socket *socka, struct socket *sockb)
1426{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001427 struct sock *ska = socka->sk, *skb = sockb->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
1429 /* Join our sockets back to back */
1430 sock_hold(ska);
1431 sock_hold(skb);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001432 unix_peer(ska) = skb;
1433 unix_peer(skb) = ska;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001434 init_peercred(ska);
1435 init_peercred(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436
1437 if (ska->sk_type != SOCK_DGRAM) {
1438 ska->sk_state = TCP_ESTABLISHED;
1439 skb->sk_state = TCP_ESTABLISHED;
1440 socka->state = SS_CONNECTED;
1441 sockb->state = SS_CONNECTED;
1442 }
1443 return 0;
1444}
1445
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001446static void unix_sock_inherit_flags(const struct socket *old,
1447 struct socket *new)
1448{
1449 if (test_bit(SOCK_PASSCRED, &old->flags))
1450 set_bit(SOCK_PASSCRED, &new->flags);
1451 if (test_bit(SOCK_PASSSEC, &old->flags))
1452 set_bit(SOCK_PASSSEC, &new->flags);
1453}
1454
David Howellscdfbabf2017-03-09 08:09:05 +00001455static int unix_accept(struct socket *sock, struct socket *newsock, int flags,
1456 bool kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457{
1458 struct sock *sk = sock->sk;
1459 struct sock *tsk;
1460 struct sk_buff *skb;
1461 int err;
1462
1463 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001464 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 goto out;
1466
1467 err = -EINVAL;
1468 if (sk->sk_state != TCP_LISTEN)
1469 goto out;
1470
1471 /* If socket state is TCP_LISTEN it cannot change (for now...),
1472 * so that no locks are necessary.
1473 */
1474
1475 skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
1476 if (!skb) {
1477 /* This means receive shutdown. */
1478 if (err == 0)
1479 err = -EINVAL;
1480 goto out;
1481 }
1482
1483 tsk = skb->sk;
1484 skb_free_datagram(sk, skb);
1485 wake_up_interruptible(&unix_sk(sk)->peer_wait);
1486
1487 /* attach accepted sock to socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001488 unix_state_lock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 newsock->state = SS_CONNECTED;
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001490 unix_sock_inherit_flags(sock, newsock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 sock_graft(tsk, newsock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001492 unix_state_unlock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 return 0;
1494
1495out:
1496 return err;
1497}
1498
1499
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001500static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501{
1502 struct sock *sk = sock->sk;
Al Viroae3b5642019-02-15 20:09:35 +00001503 struct unix_address *addr;
Cyrill Gorcunov13cfa972009-11-08 05:51:19 +00001504 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505 int err = 0;
1506
1507 if (peer) {
1508 sk = unix_peer_get(sk);
1509
1510 err = -ENOTCONN;
1511 if (!sk)
1512 goto out;
1513 err = 0;
1514 } else {
1515 sock_hold(sk);
1516 }
1517
Al Viroae3b5642019-02-15 20:09:35 +00001518 addr = smp_load_acquire(&unix_sk(sk)->addr);
1519 if (!addr) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 sunaddr->sun_family = AF_UNIX;
1521 sunaddr->sun_path[0] = 0;
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001522 err = sizeof(short);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 } else {
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001524 err = addr->len;
1525 memcpy(sunaddr, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 sock_put(sk);
1528out:
1529 return err;
1530}
1531
David S. Millerf78a5fd2011-09-16 19:34:00 -04001532static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001533{
1534 int err = 0;
Eric Dumazet16e57262011-09-19 05:52:27 +00001535
David S. Millerf78a5fd2011-09-16 19:34:00 -04001536 UNIXCB(skb).pid = get_pid(scm->pid);
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001537 UNIXCB(skb).uid = scm->creds.uid;
1538 UNIXCB(skb).gid = scm->creds.gid;
Eric W. Biederman7361c362010-06-13 03:34:33 +00001539 UNIXCB(skb).fp = NULL;
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04001540 unix_get_secdata(scm, skb);
Eric W. Biederman7361c362010-06-13 03:34:33 +00001541 if (scm->fp && send_fds)
1542 err = unix_attach_fds(scm, skb);
1543
1544 skb->destructor = unix_destruct_scm;
1545 return err;
1546}
1547
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001548static bool unix_passcred_enabled(const struct socket *sock,
1549 const struct sock *other)
1550{
1551 return test_bit(SOCK_PASSCRED, &sock->flags) ||
1552 !other->sk_socket ||
1553 test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
1554}
1555
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556/*
Eric Dumazet16e57262011-09-19 05:52:27 +00001557 * Some apps rely on write() giving SCM_CREDENTIALS
1558 * We include credentials if source or destination socket
1559 * asserted SOCK_PASSCRED.
1560 */
1561static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1562 const struct sock *other)
1563{
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001564 if (UNIXCB(skb).pid)
Eric Dumazet16e57262011-09-19 05:52:27 +00001565 return;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001566 if (unix_passcred_enabled(sock, other)) {
Eric Dumazet16e57262011-09-19 05:52:27 +00001567 UNIXCB(skb).pid = get_pid(task_tgid(current));
David S. Miller6e0895c2013-04-22 20:32:51 -04001568 current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
Eric Dumazet16e57262011-09-19 05:52:27 +00001569 }
1570}
1571
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001572static int maybe_init_creds(struct scm_cookie *scm,
1573 struct socket *socket,
1574 const struct sock *other)
1575{
1576 int err;
1577 struct msghdr msg = { .msg_controllen = 0 };
1578
1579 err = scm_send(socket, &msg, scm, false);
1580 if (err)
1581 return err;
1582
1583 if (unix_passcred_enabled(socket, other)) {
1584 scm->pid = get_pid(task_tgid(current));
1585 current_uid_gid(&scm->creds.uid, &scm->creds.gid);
1586 }
1587 return err;
1588}
1589
1590static bool unix_skb_scm_eq(struct sk_buff *skb,
1591 struct scm_cookie *scm)
1592{
1593 const struct unix_skb_parms *u = &UNIXCB(skb);
1594
1595 return u->pid == scm->pid &&
1596 uid_eq(u->uid, scm->creds.uid) &&
1597 gid_eq(u->gid, scm->creds.gid) &&
1598 unix_secdata_eq(scm, skb);
1599}
1600
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001601static void scm_stat_add(struct sock *sk, struct sk_buff *skb)
1602{
1603 struct scm_fp_list *fp = UNIXCB(skb).fp;
1604 struct unix_sock *u = unix_sk(sk);
1605
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001606 if (unlikely(fp && fp->count))
Paolo Abeni77820402020-02-28 14:45:21 +01001607 atomic_add(fp->count, &u->scm_stat.nr_fds);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001608}
1609
1610static void scm_stat_del(struct sock *sk, struct sk_buff *skb)
1611{
1612 struct scm_fp_list *fp = UNIXCB(skb).fp;
1613 struct unix_sock *u = unix_sk(sk);
1614
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001615 if (unlikely(fp && fp->count))
Paolo Abeni77820402020-02-28 14:45:21 +01001616 atomic_sub(fp->count, &u->scm_stat.nr_fds);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001617}
1618
Eric Dumazet16e57262011-09-19 05:52:27 +00001619/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 * Send AF_UNIX data.
1621 */
1622
Ying Xue1b784142015-03-02 15:37:48 +08001623static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
1624 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001627 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628 struct unix_sock *u = unix_sk(sk);
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001629 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 struct sock *other = NULL;
1631 int namelen = 0; /* fake GCC */
1632 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001633 unsigned int hash;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001634 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635 long timeo;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001636 struct scm_cookie scm;
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001637 int data_len = 0;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001638 int sk_locked;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
dann frazier5f23b732008-11-26 15:32:27 -08001640 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001641 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642 if (err < 0)
1643 return err;
1644
1645 err = -EOPNOTSUPP;
1646 if (msg->msg_flags&MSG_OOB)
1647 goto out;
1648
1649 if (msg->msg_namelen) {
1650 err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
1651 if (err < 0)
1652 goto out;
1653 namelen = err;
1654 } else {
1655 sunaddr = NULL;
1656 err = -ENOTCONN;
1657 other = unix_peer_get(sk);
1658 if (!other)
1659 goto out;
1660 }
1661
Joe Perchesf64f9e72009-11-29 16:55:45 -08001662 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr
1663 && (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 goto out;
1665
1666 err = -EMSGSIZE;
1667 if (len > sk->sk_sndbuf - 32)
1668 goto out;
1669
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001670 if (len > SKB_MAX_ALLOC) {
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001671 data_len = min_t(size_t,
1672 len - SKB_MAX_ALLOC,
1673 MAX_SKB_FRAGS * PAGE_SIZE);
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001674 data_len = PAGE_ALIGN(data_len);
1675
1676 BUILD_BUG_ON(SKB_MAX_ALLOC < PAGE_SIZE);
1677 }
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001678
1679 skb = sock_alloc_send_pskb(sk, len - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07001680 msg->msg_flags & MSG_DONTWAIT, &err,
1681 PAGE_ALLOC_COSTLY_ORDER);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001682 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 goto out;
1684
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001685 err = unix_scm_to_skb(&scm, skb, true);
Eric Dumazet25888e32010-11-25 04:11:39 +00001686 if (err < 0)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001687 goto out_free;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001688
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001689 skb_put(skb, len - data_len);
1690 skb->data_len = data_len;
1691 skb->len = len;
Al Viroc0371da2014-11-24 10:42:55 -05001692 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 if (err)
1694 goto out_free;
1695
1696 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1697
1698restart:
1699 if (!other) {
1700 err = -ECONNRESET;
1701 if (sunaddr == NULL)
1702 goto out_free;
1703
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001704 other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 hash, &err);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001706 if (other == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 goto out_free;
1708 }
1709
Alban Crequyd6ae3ba2011-01-18 06:39:15 +00001710 if (sk_filter(other, skb) < 0) {
1711 /* Toss the packet but do not return any error to the sender */
1712 err = len;
1713 goto out_free;
1714 }
1715
Rainer Weikusat7d267272015-11-20 22:07:23 +00001716 sk_locked = 0;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001717 unix_state_lock(other);
Rainer Weikusat7d267272015-11-20 22:07:23 +00001718restart_locked:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 err = -EPERM;
1720 if (!unix_may_send(sk, other))
1721 goto out_unlock;
1722
Rainer Weikusat7d267272015-11-20 22:07:23 +00001723 if (unlikely(sock_flag(other, SOCK_DEAD))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 /*
1725 * Check with 1003.1g - what should
1726 * datagram error
1727 */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001728 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 sock_put(other);
1730
Rainer Weikusat7d267272015-11-20 22:07:23 +00001731 if (!sk_locked)
1732 unix_state_lock(sk);
1733
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 if (unix_peer(sk) == other) {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001736 unix_peer(sk) = NULL;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001737 unix_dgram_peer_wake_disconnect_wakeup(sk, other);
1738
David S. Miller1c92b4e2007-05-31 13:24:26 -07001739 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
1741 unix_dgram_disconnected(sk, other);
1742 sock_put(other);
1743 err = -ECONNREFUSED;
1744 } else {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001745 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 }
1747
1748 other = NULL;
1749 if (err)
1750 goto out_free;
1751 goto restart;
1752 }
1753
1754 err = -EPIPE;
1755 if (other->sk_shutdown & RCV_SHUTDOWN)
1756 goto out_unlock;
1757
1758 if (sk->sk_type != SOCK_SEQPACKET) {
1759 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1760 if (err)
1761 goto out_unlock;
1762 }
1763
Rainer Weikusata5527dd2016-02-11 19:37:27 +00001764 /* other == sk && unix_peer(other) != sk if
1765 * - unix_peer(sk) == NULL, destination address bound to sk
1766 * - unix_peer(sk) == sk by time of get but disconnected before lock
1767 */
1768 if (other != sk &&
Qian Cai86b18aa2020-02-04 13:40:29 -05001769 unlikely(unix_peer(other) != sk &&
1770 unix_recvq_full_lockless(other))) {
Rainer Weikusat7d267272015-11-20 22:07:23 +00001771 if (timeo) {
1772 timeo = unix_wait_for_peer(other, timeo);
1773
1774 err = sock_intr_errno(timeo);
1775 if (signal_pending(current))
1776 goto out_free;
1777
1778 goto restart;
1779 }
1780
1781 if (!sk_locked) {
1782 unix_state_unlock(other);
1783 unix_state_double_lock(sk, other);
1784 }
1785
1786 if (unix_peer(sk) != other ||
1787 unix_dgram_peer_wake_me(sk, other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 err = -EAGAIN;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001789 sk_locked = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 goto out_unlock;
1791 }
1792
Rainer Weikusat7d267272015-11-20 22:07:23 +00001793 if (!sk_locked) {
1794 sk_locked = 1;
1795 goto restart_locked;
1796 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 }
1798
Rainer Weikusat7d267272015-11-20 22:07:23 +00001799 if (unlikely(sk_locked))
1800 unix_state_unlock(sk);
1801
Alban Crequy3f661162010-10-04 08:48:28 +00001802 if (sock_flag(other, SOCK_RCVTSTAMP))
1803 __net_timestamp(skb);
Eric Dumazet16e57262011-09-19 05:52:27 +00001804 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001805 scm_stat_add(other, skb);
Paolo Abeni77820402020-02-28 14:45:21 +01001806 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001807 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001808 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001810 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 return len;
1812
1813out_unlock:
Rainer Weikusat7d267272015-11-20 22:07:23 +00001814 if (sk_locked)
1815 unix_state_unlock(sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001816 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817out_free:
1818 kfree_skb(skb);
1819out:
1820 if (other)
1821 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001822 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 return err;
1824}
1825
Eric Dumazete370a722013-08-08 14:37:32 -07001826/* We use paged skbs for stream sockets, and limit occupancy to 32768
Tobias Klauserd4e9a402018-02-13 11:11:30 +01001827 * bytes, and a minimum of a full page.
Eric Dumazete370a722013-08-08 14:37:32 -07001828 */
1829#define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001830
Ying Xue1b784142015-03-02 15:37:48 +08001831static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1832 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 struct sock *sk = sock->sk;
1835 struct sock *other = NULL;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001836 int err, size;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001837 struct sk_buff *skb;
Jianjun Konge27dfce2008-11-01 21:38:31 -07001838 int sent = 0;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001839 struct scm_cookie scm;
Miklos Szeredi8ba69ba2009-09-11 11:31:45 -07001840 bool fds_sent = false;
Eric Dumazete370a722013-08-08 14:37:32 -07001841 int data_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842
dann frazier5f23b732008-11-26 15:32:27 -08001843 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001844 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 if (err < 0)
1846 return err;
1847
1848 err = -EOPNOTSUPP;
1849 if (msg->msg_flags&MSG_OOB)
1850 goto out_err;
1851
1852 if (msg->msg_namelen) {
1853 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
1854 goto out_err;
1855 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 err = -ENOTCONN;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001857 other = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 if (!other)
1859 goto out_err;
1860 }
1861
1862 if (sk->sk_shutdown & SEND_SHUTDOWN)
1863 goto pipe_err;
1864
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001865 while (sent < len) {
Eric Dumazete370a722013-08-08 14:37:32 -07001866 size = len - sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
1868 /* Keep two messages in the pipe so it schedules better */
Eric Dumazete370a722013-08-08 14:37:32 -07001869 size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870
Eric Dumazete370a722013-08-08 14:37:32 -07001871 /* allow fallback to order-0 allocations */
1872 size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001873
Eric Dumazete370a722013-08-08 14:37:32 -07001874 data_len = max_t(int, 0, size - SKB_MAX_HEAD(0));
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001875
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001876 data_len = min_t(size_t, size, PAGE_ALIGN(data_len));
1877
Eric Dumazete370a722013-08-08 14:37:32 -07001878 skb = sock_alloc_send_pskb(sk, size - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07001879 msg->msg_flags & MSG_DONTWAIT, &err,
1880 get_order(UNIX_SKB_FRAGS_SZ));
Eric Dumazete370a722013-08-08 14:37:32 -07001881 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 goto out_err;
1883
David S. Millerf78a5fd2011-09-16 19:34:00 -04001884 /* Only send the fds in the first buffer */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001885 err = unix_scm_to_skb(&scm, skb, !fds_sent);
Eric Dumazet25888e32010-11-25 04:11:39 +00001886 if (err < 0) {
Eric W. Biederman7361c362010-06-13 03:34:33 +00001887 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001888 goto out_err;
Miklos Szeredi62093442008-11-09 15:23:57 +01001889 }
Eric W. Biederman7361c362010-06-13 03:34:33 +00001890 fds_sent = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891
Eric Dumazete370a722013-08-08 14:37:32 -07001892 skb_put(skb, size - data_len);
1893 skb->data_len = data_len;
1894 skb->len = size;
Al Viroc0371da2014-11-24 10:42:55 -05001895 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001896 if (err) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001898 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 }
1900
David S. Miller1c92b4e2007-05-31 13:24:26 -07001901 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902
1903 if (sock_flag(other, SOCK_DEAD) ||
1904 (other->sk_shutdown & RCV_SHUTDOWN))
1905 goto pipe_err_free;
1906
Eric Dumazet16e57262011-09-19 05:52:27 +00001907 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001908 scm_stat_add(other, skb);
Paolo Abeni77820402020-02-28 14:45:21 +01001909 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001910 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001911 other->sk_data_ready(other);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001912 sent += size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001915 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916
1917 return sent;
1918
1919pipe_err_free:
David S. Miller1c92b4e2007-05-31 13:24:26 -07001920 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 kfree_skb(skb);
1922pipe_err:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001923 if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
1924 send_sig(SIGPIPE, current, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 err = -EPIPE;
1926out_err:
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001927 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 return sent ? : err;
1929}
1930
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001931static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
1932 int offset, size_t size, int flags)
1933{
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001934 int err;
1935 bool send_sigpipe = false;
1936 bool init_scm = true;
1937 struct scm_cookie scm;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001938 struct sock *other, *sk = socket->sk;
1939 struct sk_buff *skb, *newskb = NULL, *tail = NULL;
1940
1941 if (flags & MSG_OOB)
1942 return -EOPNOTSUPP;
1943
1944 other = unix_peer(sk);
1945 if (!other || sk->sk_state != TCP_ESTABLISHED)
1946 return -ENOTCONN;
1947
1948 if (false) {
1949alloc_skb:
1950 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001951 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001952 newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
1953 &err, 0);
1954 if (!newskb)
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001955 goto err;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001956 }
1957
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001958 /* we must acquire iolock as we modify already present
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001959 * skbs in the sk_receive_queue and mess with skb->len
1960 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001961 err = mutex_lock_interruptible(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001962 if (err) {
1963 err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001964 goto err;
1965 }
1966
1967 if (sk->sk_shutdown & SEND_SHUTDOWN) {
1968 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001969 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001970 goto err_unlock;
1971 }
1972
1973 unix_state_lock(other);
1974
1975 if (sock_flag(other, SOCK_DEAD) ||
1976 other->sk_shutdown & RCV_SHUTDOWN) {
1977 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001978 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001979 goto err_state_unlock;
1980 }
1981
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001982 if (init_scm) {
1983 err = maybe_init_creds(&scm, socket, other);
1984 if (err)
1985 goto err_state_unlock;
1986 init_scm = false;
1987 }
1988
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001989 skb = skb_peek_tail(&other->sk_receive_queue);
1990 if (tail && tail == skb) {
1991 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001992 } else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
1993 if (newskb) {
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001994 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001995 } else {
1996 tail = skb;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001997 goto alloc_skb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001998 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001999 } else if (newskb) {
2000 /* this is fast path, we don't necessarily need to
2001 * call to kfree_skb even though with newskb == NULL
2002 * this - does no harm
2003 */
2004 consume_skb(newskb);
Hannes Frederic Sowa8844f972015-11-16 16:25:56 +01002005 newskb = NULL;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002006 }
2007
2008 if (skb_append_pagefrags(skb, page, offset, size)) {
2009 tail = skb;
2010 goto alloc_skb;
2011 }
2012
2013 skb->len += size;
2014 skb->data_len += size;
2015 skb->truesize += size;
Reshetova, Elena14afee42017-06-30 13:08:00 +03002016 refcount_add(size, &sk->sk_wmem_alloc);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002017
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002018 if (newskb) {
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002019 err = unix_scm_to_skb(&scm, skb, false);
2020 if (err)
2021 goto err_state_unlock;
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002022 spin_lock(&other->sk_receive_queue.lock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002023 __skb_queue_tail(&other->sk_receive_queue, newskb);
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002024 spin_unlock(&other->sk_receive_queue.lock);
2025 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002026
2027 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002028 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002029
2030 other->sk_data_ready(other);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002031 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002032 return size;
2033
2034err_state_unlock:
2035 unix_state_unlock(other);
2036err_unlock:
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002037 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002038err:
2039 kfree_skb(newskb);
2040 if (send_sigpipe && !(flags & MSG_NOSIGNAL))
2041 send_sig(SIGPIPE, current, 0);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002042 if (!init_scm)
2043 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002044 return err;
2045}
2046
Ying Xue1b784142015-03-02 15:37:48 +08002047static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg,
2048 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049{
2050 int err;
2051 struct sock *sk = sock->sk;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002052
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053 err = sock_error(sk);
2054 if (err)
2055 return err;
2056
2057 if (sk->sk_state != TCP_ESTABLISHED)
2058 return -ENOTCONN;
2059
2060 if (msg->msg_namelen)
2061 msg->msg_namelen = 0;
2062
Ying Xue1b784142015-03-02 15:37:48 +08002063 return unix_dgram_sendmsg(sock, msg, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064}
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002065
Ying Xue1b784142015-03-02 15:37:48 +08002066static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg,
2067 size_t size, int flags)
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002068{
2069 struct sock *sk = sock->sk;
2070
2071 if (sk->sk_state != TCP_ESTABLISHED)
2072 return -ENOTCONN;
2073
Ying Xue1b784142015-03-02 15:37:48 +08002074 return unix_dgram_recvmsg(sock, msg, size, flags);
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002075}
2076
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
2078{
Al Viroae3b5642019-02-15 20:09:35 +00002079 struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080
Al Viroae3b5642019-02-15 20:09:35 +00002081 if (addr) {
2082 msg->msg_namelen = addr->len;
2083 memcpy(msg->msg_name, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084 }
2085}
2086
Ying Xue1b784142015-03-02 15:37:48 +08002087static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
2088 size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002089{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002090 struct scm_cookie scm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002091 struct sock *sk = sock->sk;
2092 struct unix_sock *u = unix_sk(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002093 struct sk_buff *skb, *last;
2094 long timeo;
Paolo Abenifd69c392019-04-08 10:15:59 +02002095 int skip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096 int err;
2097
2098 err = -EOPNOTSUPP;
2099 if (flags&MSG_OOB)
2100 goto out;
2101
Rainer Weikusat64874282015-12-06 21:11:38 +00002102 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103
Rainer Weikusat64874282015-12-06 21:11:38 +00002104 do {
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002105 mutex_lock(&u->iolock);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002106
Rainer Weikusat64874282015-12-06 21:11:38 +00002107 skip = sk_peek_offset(sk, flags);
Sabrina Dubrocab50b0582019-11-25 14:48:57 +01002108 skb = __skb_try_recv_datagram(sk, &sk->sk_receive_queue, flags,
Paolo Abenie427cad2020-02-28 14:45:22 +01002109 &skip, &err, &last);
2110 if (skb) {
2111 if (!(flags & MSG_PEEK))
2112 scm_stat_del(sk, skb);
Rainer Weikusat64874282015-12-06 21:11:38 +00002113 break;
Paolo Abenie427cad2020-02-28 14:45:22 +01002114 }
Rainer Weikusat64874282015-12-06 21:11:38 +00002115
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002116 mutex_unlock(&u->iolock);
Rainer Weikusat64874282015-12-06 21:11:38 +00002117
2118 if (err != -EAGAIN)
2119 break;
2120 } while (timeo &&
Sabrina Dubrocab50b0582019-11-25 14:48:57 +01002121 !__skb_wait_for_more_packets(sk, &sk->sk_receive_queue,
2122 &err, &timeo, last));
Rainer Weikusat64874282015-12-06 21:11:38 +00002123
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002124 if (!skb) { /* implies iolock unlocked */
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002125 unix_state_lock(sk);
2126 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
2127 if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
2128 (sk->sk_shutdown & RCV_SHUTDOWN))
2129 err = 0;
2130 unix_state_unlock(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002131 goto out;
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002132 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133
Rainer Weikusat77b75f42015-11-26 19:23:15 +00002134 if (wq_has_sleeper(&u->peer_wait))
2135 wake_up_interruptible_sync_poll(&u->peer_wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002136 EPOLLOUT | EPOLLWRNORM |
2137 EPOLLWRBAND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138
2139 if (msg->msg_name)
2140 unix_copy_addr(msg, skb->sk);
2141
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002142 if (size > skb->len - skip)
2143 size = skb->len - skip;
2144 else if (size < skb->len - skip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 msg->msg_flags |= MSG_TRUNC;
2146
David S. Miller51f3d022014-11-05 16:46:40 -05002147 err = skb_copy_datagram_msg(skb, skip, msg, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 if (err)
2149 goto out_free;
2150
Alban Crequy3f661162010-10-04 08:48:28 +00002151 if (sock_flag(sk, SOCK_RCVTSTAMP))
2152 __sock_recv_timestamp(msg, sk, skb);
2153
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002154 memset(&scm, 0, sizeof(scm));
2155
2156 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
2157 unix_set_secdata(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002159 if (!(flags & MSG_PEEK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002160 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002161 unix_detach_fds(&scm, skb);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002162
2163 sk_peek_offset_bwd(sk, skb->len);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002164 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165 /* It is questionable: on PEEK we could:
2166 - do not return fds - good, but too simple 8)
2167 - return fds, and do not return them on read (old strategy,
2168 apparently wrong)
2169 - clone fds (I chose it for now, it is the most universal
2170 solution)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002171
2172 POSIX 1003.1g does not actually define this clearly
2173 at all. POSIX 1003.1g doesn't define a lot of things
2174 clearly however!
2175
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176 */
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002177
2178 sk_peek_offset_fwd(sk, size);
2179
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002181 scm.fp = scm_fp_dup(UNIXCB(skb).fp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182 }
Eric Dumazet9f6f9af2012-02-21 23:24:55 +00002183 err = (flags & MSG_TRUNC) ? skb->len - skip : size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002185 scm_recv(sock, msg, &scm, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186
2187out_free:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002188 skb_free_datagram(sk, skb);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002189 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002190out:
2191 return err;
2192}
2193
2194/*
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002195 * Sleep until more data has arrived. But check for races..
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196 */
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002197static long unix_stream_data_wait(struct sock *sk, long timeo,
WANG Cong06a77b02016-11-17 15:55:26 -08002198 struct sk_buff *last, unsigned int last_len,
2199 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002200{
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002201 struct sk_buff *tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202 DEFINE_WAIT(wait);
2203
David S. Miller1c92b4e2007-05-31 13:24:26 -07002204 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205
2206 for (;;) {
Eric Dumazetaa395142010-04-20 13:03:51 +00002207 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002209 tail = skb_peek_tail(&sk->sk_receive_queue);
2210 if (tail != last ||
2211 (tail && tail->len != last_len) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212 sk->sk_err ||
2213 (sk->sk_shutdown & RCV_SHUTDOWN) ||
2214 signal_pending(current) ||
2215 !timeo)
2216 break;
2217
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002218 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002219 unix_state_unlock(sk);
WANG Cong06a77b02016-11-17 15:55:26 -08002220 if (freezable)
2221 timeo = freezable_schedule_timeout(timeo);
2222 else
2223 timeo = schedule_timeout(timeo);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002224 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002225
2226 if (sock_flag(sk, SOCK_DEAD))
2227 break;
2228
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002229 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230 }
2231
Eric Dumazetaa395142010-04-20 13:03:51 +00002232 finish_wait(sk_sleep(sk), &wait);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002233 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 return timeo;
2235}
2236
Eric Dumazete370a722013-08-08 14:37:32 -07002237static unsigned int unix_skb_len(const struct sk_buff *skb)
2238{
2239 return skb->len - UNIXCB(skb).consumed;
2240}
2241
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002242struct unix_stream_read_state {
2243 int (*recv_actor)(struct sk_buff *, int, int,
2244 struct unix_stream_read_state *);
2245 struct socket *socket;
2246 struct msghdr *msg;
2247 struct pipe_inode_info *pipe;
2248 size_t size;
2249 int flags;
2250 unsigned int splice_flags;
2251};
2252
WANG Cong06a77b02016-11-17 15:55:26 -08002253static int unix_stream_read_generic(struct unix_stream_read_state *state,
2254 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002256 struct scm_cookie scm;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002257 struct socket *sock = state->socket;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258 struct sock *sk = sock->sk;
2259 struct unix_sock *u = unix_sk(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 int copied = 0;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002261 int flags = state->flags;
Eric Dumazetde144392014-03-25 18:42:27 -07002262 int noblock = flags & MSG_DONTWAIT;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002263 bool check_creds = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264 int target;
2265 int err = 0;
2266 long timeo;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002267 int skip;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002268 size_t size = state->size;
2269 unsigned int last_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002271 if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
2272 err = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002273 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002274 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002275
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002276 if (unlikely(flags & MSG_OOB)) {
2277 err = -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002279 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002281 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
Eric Dumazetde144392014-03-25 18:42:27 -07002282 timeo = sock_rcvtimeo(sk, noblock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002284 memset(&scm, 0, sizeof(scm));
2285
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286 /* Lock the socket to prevent queue disordering
2287 * while sleeps in memcpy_tomsg
2288 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002289 mutex_lock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290
Matthew Dawsona0917e02017-08-18 15:04:54 -04002291 skip = max(sk_peek_offset(sk, flags), 0);
Andrey Vagine9193d62015-10-02 00:05:36 +03002292
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002293 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294 int chunk;
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002295 bool drop_skb;
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002296 struct sk_buff *skb, *last;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002298redo:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002299 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002300 if (sock_flag(sk, SOCK_DEAD)) {
2301 err = -ECONNRESET;
2302 goto unlock;
2303 }
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002304 last = skb = skb_peek(&sk->sk_receive_queue);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002305 last_len = last ? last->len : 0;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002306again:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002307 if (skb == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 if (copied >= target)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002309 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310
2311 /*
2312 * POSIX 1003.1g mandates this order.
2313 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002314
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002315 err = sock_error(sk);
2316 if (err)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002317 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318 if (sk->sk_shutdown & RCV_SHUTDOWN)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002319 goto unlock;
2320
2321 unix_state_unlock(sk);
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002322 if (!timeo) {
2323 err = -EAGAIN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 break;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002325 }
2326
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002327 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002329 timeo = unix_stream_data_wait(sk, timeo, last,
WANG Cong06a77b02016-11-17 15:55:26 -08002330 last_len, freezable);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331
Rainer Weikusat3822b5c2015-12-16 20:09:25 +00002332 if (signal_pending(current)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333 err = sock_intr_errno(timeo);
Eric Dumazetfa0dc042016-01-24 13:53:50 -08002334 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335 goto out;
2336 }
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00002337
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002338 mutex_lock(&u->iolock);
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002339 goto redo;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002340unlock:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002341 unix_state_unlock(sk);
2342 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002343 }
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002344
Eric Dumazete370a722013-08-08 14:37:32 -07002345 while (skip >= unix_skb_len(skb)) {
2346 skip -= unix_skb_len(skb);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002347 last = skb;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002348 last_len = skb->len;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002349 skb = skb_peek_next(skb, &sk->sk_receive_queue);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002350 if (!skb)
2351 goto again;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002352 }
2353
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002354 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355
2356 if (check_creds) {
2357 /* Never glue messages from different writers */
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002358 if (!unix_skb_scm_eq(skb, &scm))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359 break;
Eric W. Biederman0e82e7f6d2013-04-03 16:14:47 +00002360 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 /* Copy credentials */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002362 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04002363 unix_set_secdata(&scm, skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002364 check_creds = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365 }
2366
2367 /* Copy address just once */
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002368 if (state->msg && state->msg->msg_name) {
2369 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr,
2370 state->msg->msg_name);
2371 unix_copy_addr(state->msg, skb->sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372 sunaddr = NULL;
2373 }
2374
Eric Dumazete370a722013-08-08 14:37:32 -07002375 chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002376 skb_get(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002377 chunk = state->recv_actor(skb, skip, chunk, state);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002378 drop_skb = !unix_skb_len(skb);
2379 /* skb is only safe to use if !drop_skb */
2380 consume_skb(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002381 if (chunk < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382 if (copied == 0)
2383 copied = -EFAULT;
2384 break;
2385 }
2386 copied += chunk;
2387 size -= chunk;
2388
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002389 if (drop_skb) {
2390 /* the skb was touched by a concurrent reader;
2391 * we should not expect anything from this skb
2392 * anymore and assume it invalid - we can be
2393 * sure it was dropped from the socket queue
2394 *
2395 * let's report a short read
2396 */
2397 err = 0;
2398 break;
2399 }
2400
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 /* Mark read part of skb as used */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002402 if (!(flags & MSG_PEEK)) {
Eric Dumazete370a722013-08-08 14:37:32 -07002403 UNIXCB(skb).consumed += chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002405 sk_peek_offset_bwd(sk, chunk);
2406
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002407 if (UNIXCB(skb).fp) {
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002408 scm_stat_del(sk, skb);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002409 unix_detach_fds(&scm, skb);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002410 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411
Eric Dumazete370a722013-08-08 14:37:32 -07002412 if (unix_skb_len(skb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414
Eric Dumazet6f01fd62012-01-28 16:11:03 +00002415 skb_unlink(skb, &sk->sk_receive_queue);
Neil Horman70d4bf62010-07-20 06:45:56 +00002416 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002418 if (scm.fp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002420 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421 /* It is questionable, see note in unix_dgram_recvmsg.
2422 */
2423 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002424 scm.fp = scm_fp_dup(UNIXCB(skb).fp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425
Andrey Vagine9193d62015-10-02 00:05:36 +03002426 sk_peek_offset_fwd(sk, chunk);
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002427
Aaron Conole9f389e32015-09-26 18:50:43 -04002428 if (UNIXCB(skb).fp)
2429 break;
2430
Andrey Vagine9193d62015-10-02 00:05:36 +03002431 skip = 0;
Aaron Conole9f389e32015-09-26 18:50:43 -04002432 last = skb;
2433 last_len = skb->len;
2434 unix_state_lock(sk);
2435 skb = skb_peek_next(skb, &sk->sk_receive_queue);
2436 if (skb)
2437 goto again;
2438 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439 break;
2440 }
2441 } while (size);
2442
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002443 mutex_unlock(&u->iolock);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002444 if (state->msg)
2445 scm_recv(sock, state->msg, &scm, flags);
2446 else
2447 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448out:
2449 return copied ? : err;
2450}
2451
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002452static int unix_stream_read_actor(struct sk_buff *skb,
2453 int skip, int chunk,
2454 struct unix_stream_read_state *state)
2455{
2456 int ret;
2457
2458 ret = skb_copy_datagram_msg(skb, UNIXCB(skb).consumed + skip,
2459 state->msg, chunk);
2460 return ret ?: chunk;
2461}
2462
2463static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
2464 size_t size, int flags)
2465{
2466 struct unix_stream_read_state state = {
2467 .recv_actor = unix_stream_read_actor,
2468 .socket = sock,
2469 .msg = msg,
2470 .size = size,
2471 .flags = flags
2472 };
2473
WANG Cong06a77b02016-11-17 15:55:26 -08002474 return unix_stream_read_generic(&state, true);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002475}
2476
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002477static int unix_stream_splice_actor(struct sk_buff *skb,
2478 int skip, int chunk,
2479 struct unix_stream_read_state *state)
2480{
2481 return skb_splice_bits(skb, state->socket->sk,
2482 UNIXCB(skb).consumed + skip,
Al Viro25869262016-09-17 21:02:10 -04002483 state->pipe, chunk, state->splice_flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002484}
2485
2486static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos,
2487 struct pipe_inode_info *pipe,
2488 size_t size, unsigned int flags)
2489{
2490 struct unix_stream_read_state state = {
2491 .recv_actor = unix_stream_splice_actor,
2492 .socket = sock,
2493 .pipe = pipe,
2494 .size = size,
2495 .splice_flags = flags,
2496 };
2497
2498 if (unlikely(*ppos))
2499 return -ESPIPE;
2500
2501 if (sock->file->f_flags & O_NONBLOCK ||
2502 flags & SPLICE_F_NONBLOCK)
2503 state.flags = MSG_DONTWAIT;
2504
WANG Cong06a77b02016-11-17 15:55:26 -08002505 return unix_stream_read_generic(&state, false);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002506}
2507
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508static int unix_shutdown(struct socket *sock, int mode)
2509{
2510 struct sock *sk = sock->sk;
2511 struct sock *other;
2512
Xi Wangfc61b922012-08-26 16:47:13 +00002513 if (mode < SHUT_RD || mode > SHUT_RDWR)
2514 return -EINVAL;
2515 /* This maps:
2516 * SHUT_RD (0) -> RCV_SHUTDOWN (1)
2517 * SHUT_WR (1) -> SEND_SHUTDOWN (2)
2518 * SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
2519 */
2520 ++mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521
Alban Crequy7180a032011-01-19 04:56:36 +00002522 unix_state_lock(sk);
2523 sk->sk_shutdown |= mode;
2524 other = unix_peer(sk);
2525 if (other)
2526 sock_hold(other);
2527 unix_state_unlock(sk);
2528 sk->sk_state_change(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529
Alban Crequy7180a032011-01-19 04:56:36 +00002530 if (other &&
2531 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532
Alban Crequy7180a032011-01-19 04:56:36 +00002533 int peer_mode = 0;
2534
2535 if (mode&RCV_SHUTDOWN)
2536 peer_mode |= SEND_SHUTDOWN;
2537 if (mode&SEND_SHUTDOWN)
2538 peer_mode |= RCV_SHUTDOWN;
2539 unix_state_lock(other);
2540 other->sk_shutdown |= peer_mode;
2541 unix_state_unlock(other);
2542 other->sk_state_change(other);
2543 if (peer_mode == SHUTDOWN_MASK)
2544 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
2545 else if (peer_mode & RCV_SHUTDOWN)
2546 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547 }
Alban Crequy7180a032011-01-19 04:56:36 +00002548 if (other)
2549 sock_put(other);
2550
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 return 0;
2552}
2553
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002554long unix_inq_len(struct sock *sk)
2555{
2556 struct sk_buff *skb;
2557 long amount = 0;
2558
2559 if (sk->sk_state == TCP_LISTEN)
2560 return -EINVAL;
2561
2562 spin_lock(&sk->sk_receive_queue.lock);
2563 if (sk->sk_type == SOCK_STREAM ||
2564 sk->sk_type == SOCK_SEQPACKET) {
2565 skb_queue_walk(&sk->sk_receive_queue, skb)
Eric Dumazete370a722013-08-08 14:37:32 -07002566 amount += unix_skb_len(skb);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002567 } else {
2568 skb = skb_peek(&sk->sk_receive_queue);
2569 if (skb)
2570 amount = skb->len;
2571 }
2572 spin_unlock(&sk->sk_receive_queue.lock);
2573
2574 return amount;
2575}
2576EXPORT_SYMBOL_GPL(unix_inq_len);
2577
2578long unix_outq_len(struct sock *sk)
2579{
2580 return sk_wmem_alloc_get(sk);
2581}
2582EXPORT_SYMBOL_GPL(unix_outq_len);
2583
Andrey Vaginba94f302017-02-01 11:00:45 -08002584static int unix_open_file(struct sock *sk)
2585{
2586 struct path path;
2587 struct file *f;
2588 int fd;
2589
2590 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
2591 return -EPERM;
2592
Al Viroae3b5642019-02-15 20:09:35 +00002593 if (!smp_load_acquire(&unix_sk(sk)->addr))
Andrey Vaginba94f302017-02-01 11:00:45 -08002594 return -ENOENT;
Al Viroae3b5642019-02-15 20:09:35 +00002595
2596 path = unix_sk(sk)->path;
2597 if (!path.dentry)
2598 return -ENOENT;
Andrey Vaginba94f302017-02-01 11:00:45 -08002599
2600 path_get(&path);
Andrey Vaginba94f302017-02-01 11:00:45 -08002601
2602 fd = get_unused_fd_flags(O_CLOEXEC);
2603 if (fd < 0)
2604 goto out;
2605
2606 f = dentry_open(&path, O_PATH, current_cred());
2607 if (IS_ERR(f)) {
2608 put_unused_fd(fd);
2609 fd = PTR_ERR(f);
2610 goto out;
2611 }
2612
2613 fd_install(fd, f);
2614out:
2615 path_put(&path);
2616
2617 return fd;
2618}
2619
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2621{
2622 struct sock *sk = sock->sk;
Jianjun Konge27dfce2008-11-01 21:38:31 -07002623 long amount = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624 int err;
2625
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002626 switch (cmd) {
2627 case SIOCOUTQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002628 amount = unix_outq_len(sk);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002629 err = put_user(amount, (int __user *)arg);
2630 break;
2631 case SIOCINQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002632 amount = unix_inq_len(sk);
2633 if (amount < 0)
2634 err = amount;
2635 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 err = put_user(amount, (int __user *)arg);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002637 break;
Andrey Vaginba94f302017-02-01 11:00:45 -08002638 case SIOCUNIXFILE:
2639 err = unix_open_file(sk);
2640 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002641 default:
2642 err = -ENOIOCTLCMD;
2643 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644 }
2645 return err;
2646}
2647
Arnd Bergmann5f6beb92019-06-03 22:03:44 +02002648#ifdef CONFIG_COMPAT
2649static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2650{
2651 return unix_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
2652}
2653#endif
2654
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002655static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656{
2657 struct sock *sk = sock->sk;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002658 __poll_t mask;
2659
Karsten Graul89ab0662018-10-23 13:40:39 +02002660 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002661 mask = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662
2663 /* exceptional events? */
2664 if (sk->sk_err)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002665 mask |= EPOLLERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002667 mask |= EPOLLHUP;
Davide Libenzif348d702006-03-25 03:07:39 -08002668 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002669 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670
2671 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002672 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002673 mask |= EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674
2675 /* Connection-based need to check for termination and startup */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002676 if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
2677 sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002678 mask |= EPOLLHUP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679
2680 /*
2681 * we set writable also when the other side has shut down the
2682 * connection. This prevents stuck sockets.
2683 */
2684 if (unix_writable(sk))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002685 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686
2687 return mask;
2688}
2689
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002690static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
2691 poll_table *wait)
Rainer Weikusat3c734192008-06-17 22:28:05 -07002692{
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002693 struct sock *sk = sock->sk, *other;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002694 unsigned int writable;
2695 __poll_t mask;
2696
Karsten Graul89ab0662018-10-23 13:40:39 +02002697 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002698 mask = 0;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002699
2700 /* exceptional events? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002701 if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002702 mask |= EPOLLERR |
2703 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +00002704
Rainer Weikusat3c734192008-06-17 22:28:05 -07002705 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002706 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002707 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002708 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002709
2710 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002711 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002712 mask |= EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002713
2714 /* Connection-based need to check for termination and startup */
2715 if (sk->sk_type == SOCK_SEQPACKET) {
2716 if (sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002717 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002718 /* connection hasn't started yet? */
2719 if (sk->sk_state == TCP_SYN_SENT)
2720 return mask;
2721 }
2722
Eric Dumazet973a34a2010-10-31 05:38:25 +00002723 /* No write status requested, avoid expensive OUT tests. */
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002724 if (!(poll_requested_events(wait) & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT)))
Eric Dumazet973a34a2010-10-31 05:38:25 +00002725 return mask;
2726
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002727 writable = unix_writable(sk);
Rainer Weikusat7d267272015-11-20 22:07:23 +00002728 if (writable) {
2729 unix_state_lock(sk);
2730
2731 other = unix_peer(sk);
2732 if (other && unix_peer(other) != sk &&
2733 unix_recvq_full(other) &&
2734 unix_dgram_peer_wake_me(sk, other))
2735 writable = 0;
2736
2737 unix_state_unlock(sk);
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002738 }
2739
2740 if (writable)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002741 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002742 else
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002743 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
Rainer Weikusat3c734192008-06-17 22:28:05 -07002744
Rainer Weikusat3c734192008-06-17 22:28:05 -07002745 return mask;
2746}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747
2748#ifdef CONFIG_PROC_FS
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002749
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002750#define BUCKET_SPACE (BITS_PER_LONG - (UNIX_HASH_BITS + 1) - 1)
2751
2752#define get_bucket(x) ((x) >> BUCKET_SPACE)
2753#define get_offset(x) ((x) & ((1L << BUCKET_SPACE) - 1))
2754#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002755
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002756static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757{
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002758 unsigned long offset = get_offset(*pos);
2759 unsigned long bucket = get_bucket(*pos);
2760 struct sock *sk;
2761 unsigned long count = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002763 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
2764 if (sock_net(sk) != seq_file_net(seq))
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002765 continue;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002766 if (++count == offset)
2767 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768 }
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002769
2770 return sk;
2771}
2772
2773static struct sock *unix_next_socket(struct seq_file *seq,
2774 struct sock *sk,
2775 loff_t *pos)
2776{
2777 unsigned long bucket;
2778
2779 while (sk > (struct sock *)SEQ_START_TOKEN) {
2780 sk = sk_next(sk);
2781 if (!sk)
2782 goto next_bucket;
2783 if (sock_net(sk) == seq_file_net(seq))
2784 return sk;
2785 }
2786
2787 do {
2788 sk = unix_from_bucket(seq, pos);
2789 if (sk)
2790 return sk;
2791
2792next_bucket:
2793 bucket = get_bucket(*pos) + 1;
2794 *pos = set_bucket_offset(bucket, 1);
2795 } while (bucket < ARRAY_SIZE(unix_socket_table));
2796
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797 return NULL;
2798}
2799
Linus Torvalds1da177e2005-04-16 15:20:36 -07002800static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002801 __acquires(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002802{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002803 spin_lock(&unix_table_lock);
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002804
2805 if (!*pos)
2806 return SEQ_START_TOKEN;
2807
2808 if (get_bucket(*pos) >= ARRAY_SIZE(unix_socket_table))
2809 return NULL;
2810
2811 return unix_next_socket(seq, NULL, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812}
2813
2814static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2815{
2816 ++*pos;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002817 return unix_next_socket(seq, v, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818}
2819
2820static void unix_seq_stop(struct seq_file *seq, void *v)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002821 __releases(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002822{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002823 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824}
2825
2826static int unix_seq_show(struct seq_file *seq, void *v)
2827{
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002828
Joe Perchesb9f31242008-04-12 19:04:38 -07002829 if (v == SEQ_START_TOKEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 seq_puts(seq, "Num RefCount Protocol Flags Type St "
2831 "Inode Path\n");
2832 else {
2833 struct sock *s = v;
2834 struct unix_sock *u = unix_sk(s);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002835 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836
Dan Rosenberg71338aa2011-05-23 12:17:35 +00002837 seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838 s,
Reshetova, Elena41c6d652017-06-30 13:08:01 +03002839 refcount_read(&s->sk_refcnt),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840 0,
2841 s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
2842 s->sk_type,
2843 s->sk_socket ?
2844 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
2845 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
2846 sock_i_ino(s));
2847
Al Viroae3b5642019-02-15 20:09:35 +00002848 if (u->addr) { // under unix_table_lock here
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849 int i, len;
2850 seq_putc(seq, ' ');
2851
2852 i = 0;
2853 len = u->addr->len - sizeof(short);
2854 if (!UNIX_ABSTRACT(s))
2855 len--;
2856 else {
2857 seq_putc(seq, '@');
2858 i++;
2859 }
2860 for ( ; i < len; i++)
Isaac Boukrise7947ea2016-11-01 02:41:35 +02002861 seq_putc(seq, u->addr->name->sun_path[i] ?:
2862 '@');
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07002864 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 seq_putc(seq, '\n');
2866 }
2867
2868 return 0;
2869}
2870
Philippe De Muyter56b3d972007-07-10 23:07:31 -07002871static const struct seq_operations unix_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872 .start = unix_seq_start,
2873 .next = unix_seq_next,
2874 .stop = unix_seq_stop,
2875 .show = unix_seq_show,
2876};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877#endif
2878
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00002879static const struct net_proto_family unix_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 .family = PF_UNIX,
2881 .create = unix_create,
2882 .owner = THIS_MODULE,
2883};
2884
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002885
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002886static int __net_init unix_net_init(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002887{
2888 int error = -ENOMEM;
2889
Denis V. Luneva0a53c82007-12-11 04:19:17 -08002890 net->unx.sysctl_max_dgram_qlen = 10;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002891 if (unix_sysctl_register(net))
2892 goto out;
Pavel Emelyanovd392e492007-12-01 23:44:15 +11002893
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002894#ifdef CONFIG_PROC_FS
Christoph Hellwigc3506372018-04-10 19:42:55 +02002895 if (!proc_create_net("unix", 0, net->proc_net, &unix_seq_ops,
2896 sizeof(struct seq_net_private))) {
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002897 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002898 goto out;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002899 }
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002900#endif
2901 error = 0;
2902out:
Jianjun Kong48dcc33e2008-11-01 21:37:27 -07002903 return error;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002904}
2905
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002906static void __net_exit unix_net_exit(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002907{
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002908 unix_sysctl_unregister(net);
Gao fengece31ff2013-02-18 01:34:56 +00002909 remove_proc_entry("unix", net->proc_net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002910}
2911
2912static struct pernet_operations unix_net_ops = {
2913 .init = unix_net_init,
2914 .exit = unix_net_exit,
2915};
2916
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917static int __init af_unix_init(void)
2918{
2919 int rc = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920
Pankaj Bharadiyac5936422019-12-09 10:31:43 -08002921 BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof_field(struct sk_buff, cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922
2923 rc = proto_register(&unix_proto, 1);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002924 if (rc != 0) {
wangweidong5cc208b2013-12-06 18:03:36 +08002925 pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 goto out;
2927 }
2928
2929 sock_register(&unix_family_ops);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002930 register_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931out:
2932 return rc;
2933}
2934
2935static void __exit af_unix_exit(void)
2936{
2937 sock_unregister(PF_UNIX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938 proto_unregister(&unix_proto);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002939 unregister_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940}
2941
David Woodhouse3d366962008-04-24 00:59:25 -07002942/* Earlier than device_initcall() so that other drivers invoking
2943 request_module() don't end up in a loop when modprobe tries
2944 to use a UNIX socket. But later than subsys_initcall() because
2945 we depend on stuff initialised there */
2946fs_initcall(af_unix_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947module_exit(af_unix_exit);
2948
2949MODULE_LICENSE("GPL");
2950MODULE_ALIAS_NETPROTO(PF_UNIX);