blob: 181ea6fb56a617e722d9bf617c127fbc3ef73ddd [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,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 .sendmsg = unix_stream_sendmsg,
718 .recvmsg = unix_stream_recvmsg,
719 .mmap = sock_no_mmap,
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200720 .sendpage = unix_stream_sendpage,
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200721 .splice_read = unix_stream_splice_read,
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +0000722 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300723 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724};
725
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800726static const struct proto_ops unix_dgram_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 .family = PF_UNIX,
728 .owner = THIS_MODULE,
729 .release = unix_release,
730 .bind = unix_bind,
731 .connect = unix_dgram_connect,
732 .socketpair = unix_socketpair,
733 .accept = sock_no_accept,
734 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700735 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200737#ifdef CONFIG_COMPAT
738 .compat_ioctl = unix_compat_ioctl,
739#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 .listen = sock_no_listen,
741 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 .sendmsg = unix_dgram_sendmsg,
743 .recvmsg = unix_dgram_recvmsg,
744 .mmap = sock_no_mmap,
745 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000746 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300747 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748};
749
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800750static const struct proto_ops unix_seqpacket_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 .family = PF_UNIX,
752 .owner = THIS_MODULE,
753 .release = unix_release,
754 .bind = unix_bind,
755 .connect = unix_stream_connect,
756 .socketpair = unix_socketpair,
757 .accept = unix_accept,
758 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700759 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200761#ifdef CONFIG_COMPAT
762 .compat_ioctl = unix_compat_ioctl,
763#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 .listen = unix_listen,
765 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 .sendmsg = unix_seqpacket_sendmsg,
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +0000767 .recvmsg = unix_seqpacket_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 .mmap = sock_no_mmap,
769 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000770 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300771 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772};
773
774static struct proto unix_proto = {
Eric Dumazet248969a2008-11-17 00:00:30 -0800775 .name = "UNIX",
776 .owner = THIS_MODULE,
Eric Dumazet248969a2008-11-17 00:00:30 -0800777 .obj_size = sizeof(struct unix_sock),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778};
779
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500780static struct sock *unix_create1(struct net *net, struct socket *sock, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781{
782 struct sock *sk = NULL;
783 struct unix_sock *u;
784
Eric Dumazet518de9b2010-10-26 14:22:44 -0700785 atomic_long_inc(&unix_nr_socks);
786 if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 goto out;
788
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500789 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, kern);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 if (!sk)
791 goto out;
792
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800793 sock_init_data(sock, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794
Vladimir Davydov3aa97992016-07-26 15:24:36 -0700795 sk->sk_allocation = GFP_KERNEL_ACCOUNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 sk->sk_write_space = unix_write_space;
Denis V. Luneva0a53c82007-12-11 04:19:17 -0800797 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 sk->sk_destruct = unix_sock_destructor;
799 u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400800 u->path.dentry = NULL;
801 u->path.mnt = NULL;
Benjamin LaHaisefd19f322006-01-03 14:10:46 -0800802 spin_lock_init(&u->lock);
Al Viro516e0cc2008-07-26 00:39:17 -0400803 atomic_long_set(&u->inflight, 0);
Miklos Szeredi1fd05ba2007-07-11 14:22:39 -0700804 INIT_LIST_HEAD(&u->link);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700805 mutex_init(&u->iolock); /* single task reading lock */
806 mutex_init(&u->bindlock); /* single task binding lock */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 init_waitqueue_head(&u->peer_wait);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000808 init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300809 memset(&u->scm_stat, 0, sizeof(struct scm_stat));
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000810 unix_insert_socket(unix_sockets_unbound(sk), sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811out:
Pavel Emelyanov284b3272007-11-10 22:08:30 -0800812 if (sk == NULL)
Eric Dumazet518de9b2010-10-26 14:22:44 -0700813 atomic_long_dec(&unix_nr_socks);
Eric Dumazet920de802008-11-24 00:09:29 -0800814 else {
815 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800816 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
Eric Dumazet920de802008-11-24 00:09:29 -0800817 local_bh_enable();
818 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 return sk;
820}
821
Eric Paris3f378b62009-11-05 22:18:14 -0800822static int unix_create(struct net *net, struct socket *sock, int protocol,
823 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824{
825 if (protocol && protocol != PF_UNIX)
826 return -EPROTONOSUPPORT;
827
828 sock->state = SS_UNCONNECTED;
829
830 switch (sock->type) {
831 case SOCK_STREAM:
832 sock->ops = &unix_stream_ops;
833 break;
834 /*
835 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
836 * nothing uses it.
837 */
838 case SOCK_RAW:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700839 sock->type = SOCK_DGRAM;
Gustavo A. R. Silva110af3a2017-10-20 12:05:30 -0500840 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 case SOCK_DGRAM:
842 sock->ops = &unix_dgram_ops;
843 break;
844 case SOCK_SEQPACKET:
845 sock->ops = &unix_seqpacket_ops;
846 break;
847 default:
848 return -ESOCKTNOSUPPORT;
849 }
850
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500851 return unix_create1(net, sock, kern) ? 0 : -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852}
853
854static int unix_release(struct socket *sock)
855{
856 struct sock *sk = sock->sk;
857
858 if (!sk)
859 return 0;
860
Paul Mooreded34e02013-03-25 03:18:33 +0000861 unix_release_sock(sk, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 sock->sk = NULL;
863
Paul Mooreded34e02013-03-25 03:18:33 +0000864 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865}
866
867static int unix_autobind(struct socket *sock)
868{
869 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900870 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 struct unix_sock *u = unix_sk(sk);
872 static u32 ordernum = 1;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800873 struct unix_address *addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 int err;
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000875 unsigned int retries = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700877 err = mutex_lock_interruptible(&u->bindlock);
Sasha Levin37ab4fa2013-12-13 10:54:22 -0500878 if (err)
879 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880
881 err = 0;
882 if (u->addr)
883 goto out;
884
885 err = -ENOMEM;
Panagiotis Issaris0da974f2006-07-21 14:51:30 -0700886 addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 if (!addr)
888 goto out;
889
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 addr->name->sun_family = AF_UNIX;
Reshetova, Elena8c9814b2017-06-30 13:08:05 +0300891 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892
893retry:
894 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
Joe Perches07f07572008-11-19 15:44:53 -0800895 addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896
David S. Millerfbe9cc42005-12-13 23:26:29 -0800897 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 ordernum = (ordernum+1)&0xFFFFF;
899
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800900 if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 addr->hash)) {
David S. Millerfbe9cc42005-12-13 23:26:29 -0800902 spin_unlock(&unix_table_lock);
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000903 /*
904 * __unix_find_socket_byname() may take long time if many names
905 * are already in use.
906 */
907 cond_resched();
908 /* Give up if all names seems to be in use. */
909 if (retries++ == 0xFFFFF) {
910 err = -ENOSPC;
911 kfree(addr);
912 goto out;
913 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 goto retry;
915 }
916 addr->hash ^= sk->sk_type;
917
918 __unix_remove_socket(sk);
Al Viroae3b5642019-02-15 20:09:35 +0000919 smp_store_release(&u->addr, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 __unix_insert_socket(&unix_socket_table[addr->hash], sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800921 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 err = 0;
923
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700924out: mutex_unlock(&u->bindlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 return err;
926}
927
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800928static struct sock *unix_find_other(struct net *net,
929 struct sockaddr_un *sunname, int len,
Eric Dumazet95c96172012-04-15 05:58:06 +0000930 int type, unsigned int hash, int *error)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931{
932 struct sock *u;
Al Viro421748e2008-08-02 01:04:36 -0400933 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 int err = 0;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900935
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 if (sunname->sun_path[0]) {
Al Viro421748e2008-08-02 01:04:36 -0400937 struct inode *inode;
938 err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 if (err)
940 goto fail;
Miklos Szeredibeef5122016-12-16 11:02:53 +0100941 inode = d_backing_inode(path.dentry);
Al Viro421748e2008-08-02 01:04:36 -0400942 err = inode_permission(inode, MAY_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 if (err)
944 goto put_fail;
945
946 err = -ECONNREFUSED;
Al Viro421748e2008-08-02 01:04:36 -0400947 if (!S_ISSOCK(inode->i_mode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948 goto put_fail;
Eric W. Biederman6616f782010-06-13 03:35:48 +0000949 u = unix_find_socket_byinode(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 if (!u)
951 goto put_fail;
952
953 if (u->sk_type == type)
Al Viro68ac1232012-03-15 08:21:57 -0400954 touch_atime(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955
Al Viro421748e2008-08-02 01:04:36 -0400956 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957
Jianjun Konge27dfce2008-11-01 21:38:31 -0700958 err = -EPROTOTYPE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959 if (u->sk_type != type) {
960 sock_put(u);
961 goto fail;
962 }
963 } else {
964 err = -ECONNREFUSED;
Jianjun Konge27dfce2008-11-01 21:38:31 -0700965 u = unix_find_socket_byname(net, sunname, len, type, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 if (u) {
967 struct dentry *dentry;
Al Viro40ffe672012-03-14 21:54:32 -0400968 dentry = unix_sk(u)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 if (dentry)
Al Viro68ac1232012-03-15 08:21:57 -0400970 touch_atime(&unix_sk(u)->path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 } else
972 goto fail;
973 }
974 return u;
975
976put_fail:
Al Viro421748e2008-08-02 01:04:36 -0400977 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978fail:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700979 *error = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980 return NULL;
981}
982
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700983static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
Al Virofaf02012012-07-20 02:37:29 +0400984{
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700985 struct dentry *dentry;
986 struct path path;
987 int err = 0;
988 /*
989 * Get the parent directory, calculate the hash for last
990 * component.
991 */
992 dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
993 err = PTR_ERR(dentry);
994 if (IS_ERR(dentry))
995 return err;
Al Virofaf02012012-07-20 02:37:29 +0400996
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700997 /*
998 * All right, let's create it.
999 */
1000 err = security_path_mknod(&path, dentry, mode, 0);
Al Virofaf02012012-07-20 02:37:29 +04001001 if (!err) {
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001002 err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0);
Al Virofaf02012012-07-20 02:37:29 +04001003 if (!err) {
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001004 res->mnt = mntget(path.mnt);
Al Virofaf02012012-07-20 02:37:29 +04001005 res->dentry = dget(dentry);
1006 }
1007 }
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001008 done_path_create(&path, dentry);
Al Virofaf02012012-07-20 02:37:29 +04001009 return err;
1010}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011
1012static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1013{
1014 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001015 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 struct unix_sock *u = unix_sk(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001017 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Al Virodae6ad82011-06-26 11:50:15 -04001018 char *sun_path = sunaddr->sun_path;
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001019 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001020 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 struct unix_address *addr;
1022 struct hlist_head *list;
Kees Cook82fe0d22017-04-04 22:12:09 -07001023 struct path path = { };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024
1025 err = -EINVAL;
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001026 if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
1027 sunaddr->sun_family != AF_UNIX)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 goto out;
1029
Jianjun Konge27dfce2008-11-01 21:38:31 -07001030 if (addr_len == sizeof(short)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 err = unix_autobind(sock);
1032 goto out;
1033 }
1034
1035 err = unix_mkname(sunaddr, addr_len, &hash);
1036 if (err < 0)
1037 goto out;
1038 addr_len = err;
1039
WANG Cong0fb44552017-01-23 11:17:35 -08001040 if (sun_path[0]) {
1041 umode_t mode = S_IFSOCK |
1042 (SOCK_INODE(sock)->i_mode & ~current_umask());
1043 err = unix_mknod(sun_path, mode, &path);
1044 if (err) {
1045 if (err == -EEXIST)
1046 err = -EADDRINUSE;
1047 goto out;
1048 }
1049 }
1050
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001051 err = mutex_lock_interruptible(&u->bindlock);
Sasha Levin37ab4fa2013-12-13 10:54:22 -05001052 if (err)
WANG Cong0fb44552017-01-23 11:17:35 -08001053 goto out_put;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
1055 err = -EINVAL;
1056 if (u->addr)
1057 goto out_up;
1058
1059 err = -ENOMEM;
1060 addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
1061 if (!addr)
1062 goto out_up;
1063
1064 memcpy(addr->name, sunaddr, addr_len);
1065 addr->len = addr_len;
1066 addr->hash = hash ^ sk->sk_type;
Reshetova, Elena8c9814b2017-06-30 13:08:05 +03001067 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001069 if (sun_path[0]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 addr->hash = UNIX_HASH_SIZE;
Miklos Szeredibeef5122016-12-16 11:02:53 +01001071 hash = d_backing_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1);
Al Virofaf02012012-07-20 02:37:29 +04001072 spin_lock(&unix_table_lock);
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001073 u->path = path;
Al Virofaf02012012-07-20 02:37:29 +04001074 list = &unix_socket_table[hash];
1075 } else {
1076 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 err = -EADDRINUSE;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001078 if (__unix_find_socket_byname(net, sunaddr, addr_len,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 sk->sk_type, hash)) {
1080 unix_release_addr(addr);
1081 goto out_unlock;
1082 }
1083
1084 list = &unix_socket_table[addr->hash];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 }
1086
1087 err = 0;
1088 __unix_remove_socket(sk);
Al Viroae3b5642019-02-15 20:09:35 +00001089 smp_store_release(&u->addr, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 __unix_insert_socket(list, sk);
1091
1092out_unlock:
David S. Millerfbe9cc42005-12-13 23:26:29 -08001093 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094out_up:
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001095 mutex_unlock(&u->bindlock);
WANG Cong0fb44552017-01-23 11:17:35 -08001096out_put:
1097 if (err)
1098 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099out:
1100 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101}
1102
David S. Miller278a3de2007-05-31 15:19:20 -07001103static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
1104{
1105 if (unlikely(sk1 == sk2) || !sk2) {
1106 unix_state_lock(sk1);
1107 return;
1108 }
1109 if (sk1 < sk2) {
1110 unix_state_lock(sk1);
1111 unix_state_lock_nested(sk2);
1112 } else {
1113 unix_state_lock(sk2);
1114 unix_state_lock_nested(sk1);
1115 }
1116}
1117
1118static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
1119{
1120 if (unlikely(sk1 == sk2) || !sk2) {
1121 unix_state_unlock(sk1);
1122 return;
1123 }
1124 unix_state_unlock(sk1);
1125 unix_state_unlock(sk2);
1126}
1127
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
1129 int alen, int flags)
1130{
1131 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001132 struct net *net = sock_net(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001133 struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 struct sock *other;
Eric Dumazet95c96172012-04-15 05:58:06 +00001135 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 int err;
1137
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001138 err = -EINVAL;
1139 if (alen < offsetofend(struct sockaddr, sa_family))
1140 goto out;
1141
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 if (addr->sa_family != AF_UNSPEC) {
1143 err = unix_mkname(sunaddr, alen, &hash);
1144 if (err < 0)
1145 goto out;
1146 alen = err;
1147
1148 if (test_bit(SOCK_PASSCRED, &sock->flags) &&
1149 !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
1150 goto out;
1151
David S. Miller278a3de2007-05-31 15:19:20 -07001152restart:
Jianjun Konge27dfce2008-11-01 21:38:31 -07001153 other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 if (!other)
1155 goto out;
1156
David S. Miller278a3de2007-05-31 15:19:20 -07001157 unix_state_double_lock(sk, other);
1158
1159 /* Apparently VFS overslept socket death. Retry. */
1160 if (sock_flag(other, SOCK_DEAD)) {
1161 unix_state_double_unlock(sk, other);
1162 sock_put(other);
1163 goto restart;
1164 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165
1166 err = -EPERM;
1167 if (!unix_may_send(sk, other))
1168 goto out_unlock;
1169
1170 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1171 if (err)
1172 goto out_unlock;
1173
1174 } else {
1175 /*
1176 * 1003.1g breaking connected state with AF_UNSPEC
1177 */
1178 other = NULL;
David S. Miller278a3de2007-05-31 15:19:20 -07001179 unix_state_double_lock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 }
1181
1182 /*
1183 * If it was connected, reconnect.
1184 */
1185 if (unix_peer(sk)) {
1186 struct sock *old_peer = unix_peer(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001187 unix_peer(sk) = other;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001188 unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
1189
David S. Miller278a3de2007-05-31 15:19:20 -07001190 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191
1192 if (other != old_peer)
1193 unix_dgram_disconnected(sk, old_peer);
1194 sock_put(old_peer);
1195 } else {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001196 unix_peer(sk) = other;
David S. Miller278a3de2007-05-31 15:19:20 -07001197 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 }
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001199 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
1201out_unlock:
David S. Miller278a3de2007-05-31 15:19:20 -07001202 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 sock_put(other);
1204out:
1205 return err;
1206}
1207
1208static long unix_wait_for_peer(struct sock *other, long timeo)
Jules Irenge48851e92020-02-23 23:16:56 +00001209 __releases(&unix_sk(other)->lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210{
1211 struct unix_sock *u = unix_sk(other);
1212 int sched;
1213 DEFINE_WAIT(wait);
1214
1215 prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
1216
1217 sched = !sock_flag(other, SOCK_DEAD) &&
1218 !(other->sk_shutdown & RCV_SHUTDOWN) &&
Rainer Weikusat3c734192008-06-17 22:28:05 -07001219 unix_recvq_full(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220
David S. Miller1c92b4e2007-05-31 13:24:26 -07001221 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222
1223 if (sched)
1224 timeo = schedule_timeout(timeo);
1225
1226 finish_wait(&u->peer_wait, &wait);
1227 return timeo;
1228}
1229
1230static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
1231 int addr_len, int flags)
1232{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001233 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001235 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 struct unix_sock *u = unix_sk(sk), *newu, *otheru;
1237 struct sock *newsk = NULL;
1238 struct sock *other = NULL;
1239 struct sk_buff *skb = NULL;
Eric Dumazet95c96172012-04-15 05:58:06 +00001240 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 int st;
1242 int err;
1243 long timeo;
1244
1245 err = unix_mkname(sunaddr, addr_len, &hash);
1246 if (err < 0)
1247 goto out;
1248 addr_len = err;
1249
Joe Perchesf64f9e72009-11-29 16:55:45 -08001250 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr &&
1251 (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 goto out;
1253
1254 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
1255
1256 /* First of all allocate resources.
1257 If we will make it after state is locked,
1258 we will have to recheck all again in any case.
1259 */
1260
1261 err = -ENOMEM;
1262
1263 /* create new sock for complete connection */
Eric W. Biederman11aa9c22015-05-08 21:09:13 -05001264 newsk = unix_create1(sock_net(sk), NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265 if (newsk == NULL)
1266 goto out;
1267
1268 /* Allocate skb for sending to listening sock */
1269 skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL);
1270 if (skb == NULL)
1271 goto out;
1272
1273restart:
1274 /* Find listening sock. */
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001275 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 if (!other)
1277 goto out;
1278
1279 /* Latch state of peer */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001280 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281
1282 /* Apparently VFS overslept socket death. Retry. */
1283 if (sock_flag(other, SOCK_DEAD)) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001284 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 sock_put(other);
1286 goto restart;
1287 }
1288
1289 err = -ECONNREFUSED;
1290 if (other->sk_state != TCP_LISTEN)
1291 goto out_unlock;
Tomoki Sekiyama77238f22009-10-18 23:17:37 -07001292 if (other->sk_shutdown & RCV_SHUTDOWN)
1293 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294
Rainer Weikusat3c734192008-06-17 22:28:05 -07001295 if (unix_recvq_full(other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296 err = -EAGAIN;
1297 if (!timeo)
1298 goto out_unlock;
1299
1300 timeo = unix_wait_for_peer(other, timeo);
1301
1302 err = sock_intr_errno(timeo);
1303 if (signal_pending(current))
1304 goto out;
1305 sock_put(other);
1306 goto restart;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001307 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308
1309 /* Latch our state.
1310
Daniel Balutae5537bf2011-03-14 15:25:33 -07001311 It is tricky place. We need to grab our state lock and cannot
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 drop lock on peer. It is dangerous because deadlock is
1313 possible. Connect to self case and simultaneous
1314 attempt to connect are eliminated by checking socket
1315 state. other is TCP_LISTEN, if sk is TCP_LISTEN we
1316 check this before attempt to grab lock.
1317
1318 Well, and we have to recheck the state after socket locked.
1319 */
1320 st = sk->sk_state;
1321
1322 switch (st) {
1323 case TCP_CLOSE:
1324 /* This is ok... continue with connect */
1325 break;
1326 case TCP_ESTABLISHED:
1327 /* Socket is already connected */
1328 err = -EISCONN;
1329 goto out_unlock;
1330 default:
1331 err = -EINVAL;
1332 goto out_unlock;
1333 }
1334
David S. Miller1c92b4e2007-05-31 13:24:26 -07001335 unix_state_lock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336
1337 if (sk->sk_state != st) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001338 unix_state_unlock(sk);
1339 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 sock_put(other);
1341 goto restart;
1342 }
1343
David S. Miller3610cda2011-01-05 15:38:53 -08001344 err = security_unix_stream_connect(sk, other, newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 if (err) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001346 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 goto out_unlock;
1348 }
1349
1350 /* The way is open! Fastly set all the necessary fields... */
1351
1352 sock_hold(sk);
1353 unix_peer(newsk) = sk;
1354 newsk->sk_state = TCP_ESTABLISHED;
1355 newsk->sk_type = sk->sk_type;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001356 init_peercred(newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 newu = unix_sk(newsk);
Eric Dumazeteaefd1102011-02-18 03:26:36 +00001358 RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 otheru = unix_sk(other);
1360
Al Viroae3b5642019-02-15 20:09:35 +00001361 /* copy address information from listening to new sock
1362 *
1363 * The contents of *(otheru->addr) and otheru->path
1364 * are seen fully set up here, since we have found
1365 * otheru in hash under unix_table_lock. Insertion
1366 * into the hash chain we'd found it in had been done
1367 * in an earlier critical area protected by unix_table_lock,
1368 * the same one where we'd set *(otheru->addr) contents,
1369 * as well as otheru->path and otheru->addr itself.
1370 *
1371 * Using smp_store_release() here to set newu->addr
1372 * is enough to make those stores, as well as stores
1373 * to newu->path visible to anyone who gets newu->addr
1374 * by smp_load_acquire(). IOW, the same warranties
1375 * as for unix_sock instances bound in unix_bind() or
1376 * in unix_autobind().
1377 */
Al Viro40ffe672012-03-14 21:54:32 -04001378 if (otheru->path.dentry) {
1379 path_get(&otheru->path);
1380 newu->path = otheru->path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 }
Al Viroae3b5642019-02-15 20:09:35 +00001382 refcount_inc(&otheru->addr->refcnt);
1383 smp_store_release(&newu->addr, otheru->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384
1385 /* Set credentials */
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001386 copy_peercred(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388 sock->state = SS_CONNECTED;
1389 sk->sk_state = TCP_ESTABLISHED;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001390 sock_hold(newsk);
1391
Peter Zijlstra4e857c52014-03-17 18:06:10 +01001392 smp_mb__after_atomic(); /* sock_hold() does an atomic_inc() */
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001393 unix_peer(sk) = newsk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394
David S. Miller1c92b4e2007-05-31 13:24:26 -07001395 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396
1397 /* take ten and and send info to listening sock */
1398 spin_lock(&other->sk_receive_queue.lock);
1399 __skb_queue_tail(&other->sk_receive_queue, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001401 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001402 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 sock_put(other);
1404 return 0;
1405
1406out_unlock:
1407 if (other)
David S. Miller1c92b4e2007-05-31 13:24:26 -07001408 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409
1410out:
Wei Yongjun40d44442009-02-25 00:32:45 +00001411 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 if (newsk)
1413 unix_release_sock(newsk, 0);
1414 if (other)
1415 sock_put(other);
1416 return err;
1417}
1418
1419static int unix_socketpair(struct socket *socka, struct socket *sockb)
1420{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001421 struct sock *ska = socka->sk, *skb = sockb->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422
1423 /* Join our sockets back to back */
1424 sock_hold(ska);
1425 sock_hold(skb);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001426 unix_peer(ska) = skb;
1427 unix_peer(skb) = ska;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001428 init_peercred(ska);
1429 init_peercred(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430
1431 if (ska->sk_type != SOCK_DGRAM) {
1432 ska->sk_state = TCP_ESTABLISHED;
1433 skb->sk_state = TCP_ESTABLISHED;
1434 socka->state = SS_CONNECTED;
1435 sockb->state = SS_CONNECTED;
1436 }
1437 return 0;
1438}
1439
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001440static void unix_sock_inherit_flags(const struct socket *old,
1441 struct socket *new)
1442{
1443 if (test_bit(SOCK_PASSCRED, &old->flags))
1444 set_bit(SOCK_PASSCRED, &new->flags);
1445 if (test_bit(SOCK_PASSSEC, &old->flags))
1446 set_bit(SOCK_PASSSEC, &new->flags);
1447}
1448
David Howellscdfbabf2017-03-09 08:09:05 +00001449static int unix_accept(struct socket *sock, struct socket *newsock, int flags,
1450 bool kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451{
1452 struct sock *sk = sock->sk;
1453 struct sock *tsk;
1454 struct sk_buff *skb;
1455 int err;
1456
1457 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001458 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 goto out;
1460
1461 err = -EINVAL;
1462 if (sk->sk_state != TCP_LISTEN)
1463 goto out;
1464
1465 /* If socket state is TCP_LISTEN it cannot change (for now...),
1466 * so that no locks are necessary.
1467 */
1468
1469 skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
1470 if (!skb) {
1471 /* This means receive shutdown. */
1472 if (err == 0)
1473 err = -EINVAL;
1474 goto out;
1475 }
1476
1477 tsk = skb->sk;
1478 skb_free_datagram(sk, skb);
1479 wake_up_interruptible(&unix_sk(sk)->peer_wait);
1480
1481 /* attach accepted sock to socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001482 unix_state_lock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 newsock->state = SS_CONNECTED;
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001484 unix_sock_inherit_flags(sock, newsock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 sock_graft(tsk, newsock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001486 unix_state_unlock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 return 0;
1488
1489out:
1490 return err;
1491}
1492
1493
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001494static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495{
1496 struct sock *sk = sock->sk;
Al Viroae3b5642019-02-15 20:09:35 +00001497 struct unix_address *addr;
Cyrill Gorcunov13cfa972009-11-08 05:51:19 +00001498 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 int err = 0;
1500
1501 if (peer) {
1502 sk = unix_peer_get(sk);
1503
1504 err = -ENOTCONN;
1505 if (!sk)
1506 goto out;
1507 err = 0;
1508 } else {
1509 sock_hold(sk);
1510 }
1511
Al Viroae3b5642019-02-15 20:09:35 +00001512 addr = smp_load_acquire(&unix_sk(sk)->addr);
1513 if (!addr) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 sunaddr->sun_family = AF_UNIX;
1515 sunaddr->sun_path[0] = 0;
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001516 err = sizeof(short);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 } else {
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001518 err = addr->len;
1519 memcpy(sunaddr, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 sock_put(sk);
1522out:
1523 return err;
1524}
1525
David S. Millerf78a5fd2011-09-16 19:34:00 -04001526static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001527{
1528 int err = 0;
Eric Dumazet16e57262011-09-19 05:52:27 +00001529
David S. Millerf78a5fd2011-09-16 19:34:00 -04001530 UNIXCB(skb).pid = get_pid(scm->pid);
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001531 UNIXCB(skb).uid = scm->creds.uid;
1532 UNIXCB(skb).gid = scm->creds.gid;
Eric W. Biederman7361c362010-06-13 03:34:33 +00001533 UNIXCB(skb).fp = NULL;
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04001534 unix_get_secdata(scm, skb);
Eric W. Biederman7361c362010-06-13 03:34:33 +00001535 if (scm->fp && send_fds)
1536 err = unix_attach_fds(scm, skb);
1537
1538 skb->destructor = unix_destruct_scm;
1539 return err;
1540}
1541
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001542static bool unix_passcred_enabled(const struct socket *sock,
1543 const struct sock *other)
1544{
1545 return test_bit(SOCK_PASSCRED, &sock->flags) ||
1546 !other->sk_socket ||
1547 test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
1548}
1549
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550/*
Eric Dumazet16e57262011-09-19 05:52:27 +00001551 * Some apps rely on write() giving SCM_CREDENTIALS
1552 * We include credentials if source or destination socket
1553 * asserted SOCK_PASSCRED.
1554 */
1555static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1556 const struct sock *other)
1557{
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001558 if (UNIXCB(skb).pid)
Eric Dumazet16e57262011-09-19 05:52:27 +00001559 return;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001560 if (unix_passcred_enabled(sock, other)) {
Eric Dumazet16e57262011-09-19 05:52:27 +00001561 UNIXCB(skb).pid = get_pid(task_tgid(current));
David S. Miller6e0895c2013-04-22 20:32:51 -04001562 current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
Eric Dumazet16e57262011-09-19 05:52:27 +00001563 }
1564}
1565
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001566static int maybe_init_creds(struct scm_cookie *scm,
1567 struct socket *socket,
1568 const struct sock *other)
1569{
1570 int err;
1571 struct msghdr msg = { .msg_controllen = 0 };
1572
1573 err = scm_send(socket, &msg, scm, false);
1574 if (err)
1575 return err;
1576
1577 if (unix_passcred_enabled(socket, other)) {
1578 scm->pid = get_pid(task_tgid(current));
1579 current_uid_gid(&scm->creds.uid, &scm->creds.gid);
1580 }
1581 return err;
1582}
1583
1584static bool unix_skb_scm_eq(struct sk_buff *skb,
1585 struct scm_cookie *scm)
1586{
1587 const struct unix_skb_parms *u = &UNIXCB(skb);
1588
1589 return u->pid == scm->pid &&
1590 uid_eq(u->uid, scm->creds.uid) &&
1591 gid_eq(u->gid, scm->creds.gid) &&
1592 unix_secdata_eq(scm, skb);
1593}
1594
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001595static void scm_stat_add(struct sock *sk, struct sk_buff *skb)
1596{
1597 struct scm_fp_list *fp = UNIXCB(skb).fp;
1598 struct unix_sock *u = unix_sk(sk);
1599
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001600 if (unlikely(fp && fp->count))
Paolo Abeni77820402020-02-28 14:45:21 +01001601 atomic_add(fp->count, &u->scm_stat.nr_fds);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001602}
1603
1604static void scm_stat_del(struct sock *sk, struct sk_buff *skb)
1605{
1606 struct scm_fp_list *fp = UNIXCB(skb).fp;
1607 struct unix_sock *u = unix_sk(sk);
1608
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001609 if (unlikely(fp && fp->count))
Paolo Abeni77820402020-02-28 14:45:21 +01001610 atomic_sub(fp->count, &u->scm_stat.nr_fds);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001611}
1612
Eric Dumazet16e57262011-09-19 05:52:27 +00001613/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 * Send AF_UNIX data.
1615 */
1616
Ying Xue1b784142015-03-02 15:37:48 +08001617static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
1618 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001621 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 struct unix_sock *u = unix_sk(sk);
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001623 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 struct sock *other = NULL;
1625 int namelen = 0; /* fake GCC */
1626 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001627 unsigned int hash;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001628 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 long timeo;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001630 struct scm_cookie scm;
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001631 int data_len = 0;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001632 int sk_locked;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633
dann frazier5f23b732008-11-26 15:32:27 -08001634 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001635 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 if (err < 0)
1637 return err;
1638
1639 err = -EOPNOTSUPP;
1640 if (msg->msg_flags&MSG_OOB)
1641 goto out;
1642
1643 if (msg->msg_namelen) {
1644 err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
1645 if (err < 0)
1646 goto out;
1647 namelen = err;
1648 } else {
1649 sunaddr = NULL;
1650 err = -ENOTCONN;
1651 other = unix_peer_get(sk);
1652 if (!other)
1653 goto out;
1654 }
1655
Joe Perchesf64f9e72009-11-29 16:55:45 -08001656 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr
1657 && (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 goto out;
1659
1660 err = -EMSGSIZE;
1661 if (len > sk->sk_sndbuf - 32)
1662 goto out;
1663
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001664 if (len > SKB_MAX_ALLOC) {
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001665 data_len = min_t(size_t,
1666 len - SKB_MAX_ALLOC,
1667 MAX_SKB_FRAGS * PAGE_SIZE);
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001668 data_len = PAGE_ALIGN(data_len);
1669
1670 BUILD_BUG_ON(SKB_MAX_ALLOC < PAGE_SIZE);
1671 }
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001672
1673 skb = sock_alloc_send_pskb(sk, len - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07001674 msg->msg_flags & MSG_DONTWAIT, &err,
1675 PAGE_ALLOC_COSTLY_ORDER);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001676 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 goto out;
1678
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001679 err = unix_scm_to_skb(&scm, skb, true);
Eric Dumazet25888e32010-11-25 04:11:39 +00001680 if (err < 0)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001681 goto out_free;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001682
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001683 skb_put(skb, len - data_len);
1684 skb->data_len = data_len;
1685 skb->len = len;
Al Viroc0371da2014-11-24 10:42:55 -05001686 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 if (err)
1688 goto out_free;
1689
1690 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1691
1692restart:
1693 if (!other) {
1694 err = -ECONNRESET;
1695 if (sunaddr == NULL)
1696 goto out_free;
1697
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001698 other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 hash, &err);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001700 if (other == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 goto out_free;
1702 }
1703
Alban Crequyd6ae3ba2011-01-18 06:39:15 +00001704 if (sk_filter(other, skb) < 0) {
1705 /* Toss the packet but do not return any error to the sender */
1706 err = len;
1707 goto out_free;
1708 }
1709
Rainer Weikusat7d267272015-11-20 22:07:23 +00001710 sk_locked = 0;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001711 unix_state_lock(other);
Rainer Weikusat7d267272015-11-20 22:07:23 +00001712restart_locked:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 err = -EPERM;
1714 if (!unix_may_send(sk, other))
1715 goto out_unlock;
1716
Rainer Weikusat7d267272015-11-20 22:07:23 +00001717 if (unlikely(sock_flag(other, SOCK_DEAD))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 /*
1719 * Check with 1003.1g - what should
1720 * datagram error
1721 */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001722 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 sock_put(other);
1724
Rainer Weikusat7d267272015-11-20 22:07:23 +00001725 if (!sk_locked)
1726 unix_state_lock(sk);
1727
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 if (unix_peer(sk) == other) {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001730 unix_peer(sk) = NULL;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001731 unix_dgram_peer_wake_disconnect_wakeup(sk, other);
1732
David S. Miller1c92b4e2007-05-31 13:24:26 -07001733 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
1735 unix_dgram_disconnected(sk, other);
1736 sock_put(other);
1737 err = -ECONNREFUSED;
1738 } else {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001739 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 }
1741
1742 other = NULL;
1743 if (err)
1744 goto out_free;
1745 goto restart;
1746 }
1747
1748 err = -EPIPE;
1749 if (other->sk_shutdown & RCV_SHUTDOWN)
1750 goto out_unlock;
1751
1752 if (sk->sk_type != SOCK_SEQPACKET) {
1753 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1754 if (err)
1755 goto out_unlock;
1756 }
1757
Rainer Weikusata5527dd2016-02-11 19:37:27 +00001758 /* other == sk && unix_peer(other) != sk if
1759 * - unix_peer(sk) == NULL, destination address bound to sk
1760 * - unix_peer(sk) == sk by time of get but disconnected before lock
1761 */
1762 if (other != sk &&
Qian Cai86b18aa2020-02-04 13:40:29 -05001763 unlikely(unix_peer(other) != sk &&
1764 unix_recvq_full_lockless(other))) {
Rainer Weikusat7d267272015-11-20 22:07:23 +00001765 if (timeo) {
1766 timeo = unix_wait_for_peer(other, timeo);
1767
1768 err = sock_intr_errno(timeo);
1769 if (signal_pending(current))
1770 goto out_free;
1771
1772 goto restart;
1773 }
1774
1775 if (!sk_locked) {
1776 unix_state_unlock(other);
1777 unix_state_double_lock(sk, other);
1778 }
1779
1780 if (unix_peer(sk) != other ||
1781 unix_dgram_peer_wake_me(sk, other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 err = -EAGAIN;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001783 sk_locked = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 goto out_unlock;
1785 }
1786
Rainer Weikusat7d267272015-11-20 22:07:23 +00001787 if (!sk_locked) {
1788 sk_locked = 1;
1789 goto restart_locked;
1790 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 }
1792
Rainer Weikusat7d267272015-11-20 22:07:23 +00001793 if (unlikely(sk_locked))
1794 unix_state_unlock(sk);
1795
Alban Crequy3f661162010-10-04 08:48:28 +00001796 if (sock_flag(other, SOCK_RCVTSTAMP))
1797 __net_timestamp(skb);
Eric Dumazet16e57262011-09-19 05:52:27 +00001798 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001799 scm_stat_add(other, skb);
Paolo Abeni77820402020-02-28 14:45:21 +01001800 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001801 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001802 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001804 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 return len;
1806
1807out_unlock:
Rainer Weikusat7d267272015-11-20 22:07:23 +00001808 if (sk_locked)
1809 unix_state_unlock(sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001810 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811out_free:
1812 kfree_skb(skb);
1813out:
1814 if (other)
1815 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001816 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 return err;
1818}
1819
Eric Dumazete370a722013-08-08 14:37:32 -07001820/* We use paged skbs for stream sockets, and limit occupancy to 32768
Tobias Klauserd4e9a402018-02-13 11:11:30 +01001821 * bytes, and a minimum of a full page.
Eric Dumazete370a722013-08-08 14:37:32 -07001822 */
1823#define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001824
Ying Xue1b784142015-03-02 15:37:48 +08001825static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1826 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 struct sock *sk = sock->sk;
1829 struct sock *other = NULL;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001830 int err, size;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001831 struct sk_buff *skb;
Jianjun Konge27dfce2008-11-01 21:38:31 -07001832 int sent = 0;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001833 struct scm_cookie scm;
Miklos Szeredi8ba69ba2009-09-11 11:31:45 -07001834 bool fds_sent = false;
Eric Dumazete370a722013-08-08 14:37:32 -07001835 int data_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836
dann frazier5f23b732008-11-26 15:32:27 -08001837 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001838 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839 if (err < 0)
1840 return err;
1841
1842 err = -EOPNOTSUPP;
1843 if (msg->msg_flags&MSG_OOB)
1844 goto out_err;
1845
1846 if (msg->msg_namelen) {
1847 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
1848 goto out_err;
1849 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 err = -ENOTCONN;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001851 other = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 if (!other)
1853 goto out_err;
1854 }
1855
1856 if (sk->sk_shutdown & SEND_SHUTDOWN)
1857 goto pipe_err;
1858
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001859 while (sent < len) {
Eric Dumazete370a722013-08-08 14:37:32 -07001860 size = len - sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861
1862 /* Keep two messages in the pipe so it schedules better */
Eric Dumazete370a722013-08-08 14:37:32 -07001863 size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864
Eric Dumazete370a722013-08-08 14:37:32 -07001865 /* allow fallback to order-0 allocations */
1866 size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001867
Eric Dumazete370a722013-08-08 14:37:32 -07001868 data_len = max_t(int, 0, size - SKB_MAX_HEAD(0));
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001869
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001870 data_len = min_t(size_t, size, PAGE_ALIGN(data_len));
1871
Eric Dumazete370a722013-08-08 14:37:32 -07001872 skb = sock_alloc_send_pskb(sk, size - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07001873 msg->msg_flags & MSG_DONTWAIT, &err,
1874 get_order(UNIX_SKB_FRAGS_SZ));
Eric Dumazete370a722013-08-08 14:37:32 -07001875 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 goto out_err;
1877
David S. Millerf78a5fd2011-09-16 19:34:00 -04001878 /* Only send the fds in the first buffer */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001879 err = unix_scm_to_skb(&scm, skb, !fds_sent);
Eric Dumazet25888e32010-11-25 04:11:39 +00001880 if (err < 0) {
Eric W. Biederman7361c362010-06-13 03:34:33 +00001881 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001882 goto out_err;
Miklos Szeredi62093442008-11-09 15:23:57 +01001883 }
Eric W. Biederman7361c362010-06-13 03:34:33 +00001884 fds_sent = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885
Eric Dumazete370a722013-08-08 14:37:32 -07001886 skb_put(skb, size - data_len);
1887 skb->data_len = data_len;
1888 skb->len = size;
Al Viroc0371da2014-11-24 10:42:55 -05001889 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001890 if (err) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001892 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 }
1894
David S. Miller1c92b4e2007-05-31 13:24:26 -07001895 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896
1897 if (sock_flag(other, SOCK_DEAD) ||
1898 (other->sk_shutdown & RCV_SHUTDOWN))
1899 goto pipe_err_free;
1900
Eric Dumazet16e57262011-09-19 05:52:27 +00001901 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001902 scm_stat_add(other, skb);
Paolo Abeni77820402020-02-28 14:45:21 +01001903 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001904 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001905 other->sk_data_ready(other);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001906 sent += size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001909 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
1911 return sent;
1912
1913pipe_err_free:
David S. Miller1c92b4e2007-05-31 13:24:26 -07001914 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 kfree_skb(skb);
1916pipe_err:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001917 if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
1918 send_sig(SIGPIPE, current, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 err = -EPIPE;
1920out_err:
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001921 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 return sent ? : err;
1923}
1924
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001925static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
1926 int offset, size_t size, int flags)
1927{
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001928 int err;
1929 bool send_sigpipe = false;
1930 bool init_scm = true;
1931 struct scm_cookie scm;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001932 struct sock *other, *sk = socket->sk;
1933 struct sk_buff *skb, *newskb = NULL, *tail = NULL;
1934
1935 if (flags & MSG_OOB)
1936 return -EOPNOTSUPP;
1937
1938 other = unix_peer(sk);
1939 if (!other || sk->sk_state != TCP_ESTABLISHED)
1940 return -ENOTCONN;
1941
1942 if (false) {
1943alloc_skb:
1944 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001945 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001946 newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
1947 &err, 0);
1948 if (!newskb)
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001949 goto err;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001950 }
1951
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001952 /* we must acquire iolock as we modify already present
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001953 * skbs in the sk_receive_queue and mess with skb->len
1954 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001955 err = mutex_lock_interruptible(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001956 if (err) {
1957 err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001958 goto err;
1959 }
1960
1961 if (sk->sk_shutdown & SEND_SHUTDOWN) {
1962 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001963 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001964 goto err_unlock;
1965 }
1966
1967 unix_state_lock(other);
1968
1969 if (sock_flag(other, SOCK_DEAD) ||
1970 other->sk_shutdown & RCV_SHUTDOWN) {
1971 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001972 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001973 goto err_state_unlock;
1974 }
1975
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001976 if (init_scm) {
1977 err = maybe_init_creds(&scm, socket, other);
1978 if (err)
1979 goto err_state_unlock;
1980 init_scm = false;
1981 }
1982
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001983 skb = skb_peek_tail(&other->sk_receive_queue);
1984 if (tail && tail == skb) {
1985 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001986 } else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
1987 if (newskb) {
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001988 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001989 } else {
1990 tail = skb;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001991 goto alloc_skb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001992 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001993 } else if (newskb) {
1994 /* this is fast path, we don't necessarily need to
1995 * call to kfree_skb even though with newskb == NULL
1996 * this - does no harm
1997 */
1998 consume_skb(newskb);
Hannes Frederic Sowa8844f972015-11-16 16:25:56 +01001999 newskb = NULL;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002000 }
2001
2002 if (skb_append_pagefrags(skb, page, offset, size)) {
2003 tail = skb;
2004 goto alloc_skb;
2005 }
2006
2007 skb->len += size;
2008 skb->data_len += size;
2009 skb->truesize += size;
Reshetova, Elena14afee42017-06-30 13:08:00 +03002010 refcount_add(size, &sk->sk_wmem_alloc);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002011
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002012 if (newskb) {
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002013 err = unix_scm_to_skb(&scm, skb, false);
2014 if (err)
2015 goto err_state_unlock;
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002016 spin_lock(&other->sk_receive_queue.lock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002017 __skb_queue_tail(&other->sk_receive_queue, newskb);
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002018 spin_unlock(&other->sk_receive_queue.lock);
2019 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002020
2021 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002022 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002023
2024 other->sk_data_ready(other);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002025 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002026 return size;
2027
2028err_state_unlock:
2029 unix_state_unlock(other);
2030err_unlock:
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002031 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002032err:
2033 kfree_skb(newskb);
2034 if (send_sigpipe && !(flags & MSG_NOSIGNAL))
2035 send_sig(SIGPIPE, current, 0);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002036 if (!init_scm)
2037 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002038 return err;
2039}
2040
Ying Xue1b784142015-03-02 15:37:48 +08002041static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg,
2042 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043{
2044 int err;
2045 struct sock *sk = sock->sk;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002046
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 err = sock_error(sk);
2048 if (err)
2049 return err;
2050
2051 if (sk->sk_state != TCP_ESTABLISHED)
2052 return -ENOTCONN;
2053
2054 if (msg->msg_namelen)
2055 msg->msg_namelen = 0;
2056
Ying Xue1b784142015-03-02 15:37:48 +08002057 return unix_dgram_sendmsg(sock, msg, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058}
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002059
Ying Xue1b784142015-03-02 15:37:48 +08002060static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg,
2061 size_t size, int flags)
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002062{
2063 struct sock *sk = sock->sk;
2064
2065 if (sk->sk_state != TCP_ESTABLISHED)
2066 return -ENOTCONN;
2067
Ying Xue1b784142015-03-02 15:37:48 +08002068 return unix_dgram_recvmsg(sock, msg, size, flags);
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002069}
2070
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
2072{
Al Viroae3b5642019-02-15 20:09:35 +00002073 struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074
Al Viroae3b5642019-02-15 20:09:35 +00002075 if (addr) {
2076 msg->msg_namelen = addr->len;
2077 memcpy(msg->msg_name, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078 }
2079}
2080
Ying Xue1b784142015-03-02 15:37:48 +08002081static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
2082 size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002084 struct scm_cookie scm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 struct sock *sk = sock->sk;
2086 struct unix_sock *u = unix_sk(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002087 struct sk_buff *skb, *last;
2088 long timeo;
Paolo Abenifd69c392019-04-08 10:15:59 +02002089 int skip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 int err;
2091
2092 err = -EOPNOTSUPP;
2093 if (flags&MSG_OOB)
2094 goto out;
2095
Rainer Weikusat64874282015-12-06 21:11:38 +00002096 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097
Rainer Weikusat64874282015-12-06 21:11:38 +00002098 do {
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002099 mutex_lock(&u->iolock);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002100
Rainer Weikusat64874282015-12-06 21:11:38 +00002101 skip = sk_peek_offset(sk, flags);
Sabrina Dubrocab50b0582019-11-25 14:48:57 +01002102 skb = __skb_try_recv_datagram(sk, &sk->sk_receive_queue, flags,
Paolo Abenie427cad2020-02-28 14:45:22 +01002103 &skip, &err, &last);
2104 if (skb) {
2105 if (!(flags & MSG_PEEK))
2106 scm_stat_del(sk, skb);
Rainer Weikusat64874282015-12-06 21:11:38 +00002107 break;
Paolo Abenie427cad2020-02-28 14:45:22 +01002108 }
Rainer Weikusat64874282015-12-06 21:11:38 +00002109
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002110 mutex_unlock(&u->iolock);
Rainer Weikusat64874282015-12-06 21:11:38 +00002111
2112 if (err != -EAGAIN)
2113 break;
2114 } while (timeo &&
Sabrina Dubrocab50b0582019-11-25 14:48:57 +01002115 !__skb_wait_for_more_packets(sk, &sk->sk_receive_queue,
2116 &err, &timeo, last));
Rainer Weikusat64874282015-12-06 21:11:38 +00002117
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002118 if (!skb) { /* implies iolock unlocked */
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002119 unix_state_lock(sk);
2120 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
2121 if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
2122 (sk->sk_shutdown & RCV_SHUTDOWN))
2123 err = 0;
2124 unix_state_unlock(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002125 goto out;
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002126 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127
Rainer Weikusat77b75f42015-11-26 19:23:15 +00002128 if (wq_has_sleeper(&u->peer_wait))
2129 wake_up_interruptible_sync_poll(&u->peer_wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002130 EPOLLOUT | EPOLLWRNORM |
2131 EPOLLWRBAND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132
2133 if (msg->msg_name)
2134 unix_copy_addr(msg, skb->sk);
2135
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002136 if (size > skb->len - skip)
2137 size = skb->len - skip;
2138 else if (size < skb->len - skip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139 msg->msg_flags |= MSG_TRUNC;
2140
David S. Miller51f3d022014-11-05 16:46:40 -05002141 err = skb_copy_datagram_msg(skb, skip, msg, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142 if (err)
2143 goto out_free;
2144
Alban Crequy3f661162010-10-04 08:48:28 +00002145 if (sock_flag(sk, SOCK_RCVTSTAMP))
2146 __sock_recv_timestamp(msg, sk, skb);
2147
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002148 memset(&scm, 0, sizeof(scm));
2149
2150 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
2151 unix_set_secdata(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002152
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002153 if (!(flags & MSG_PEEK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002155 unix_detach_fds(&scm, skb);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002156
2157 sk_peek_offset_bwd(sk, skb->len);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002158 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159 /* It is questionable: on PEEK we could:
2160 - do not return fds - good, but too simple 8)
2161 - return fds, and do not return them on read (old strategy,
2162 apparently wrong)
2163 - clone fds (I chose it for now, it is the most universal
2164 solution)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002165
2166 POSIX 1003.1g does not actually define this clearly
2167 at all. POSIX 1003.1g doesn't define a lot of things
2168 clearly however!
2169
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170 */
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002171
2172 sk_peek_offset_fwd(sk, size);
2173
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002175 scm.fp = scm_fp_dup(UNIXCB(skb).fp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176 }
Eric Dumazet9f6f9af2012-02-21 23:24:55 +00002177 err = (flags & MSG_TRUNC) ? skb->len - skip : size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002179 scm_recv(sock, msg, &scm, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180
2181out_free:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002182 skb_free_datagram(sk, skb);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002183 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184out:
2185 return err;
2186}
2187
2188/*
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002189 * Sleep until more data has arrived. But check for races..
Linus Torvalds1da177e2005-04-16 15:20:36 -07002190 */
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002191static long unix_stream_data_wait(struct sock *sk, long timeo,
WANG Cong06a77b02016-11-17 15:55:26 -08002192 struct sk_buff *last, unsigned int last_len,
2193 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194{
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002195 struct sk_buff *tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196 DEFINE_WAIT(wait);
2197
David S. Miller1c92b4e2007-05-31 13:24:26 -07002198 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199
2200 for (;;) {
Eric Dumazetaa395142010-04-20 13:03:51 +00002201 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002203 tail = skb_peek_tail(&sk->sk_receive_queue);
2204 if (tail != last ||
2205 (tail && tail->len != last_len) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206 sk->sk_err ||
2207 (sk->sk_shutdown & RCV_SHUTDOWN) ||
2208 signal_pending(current) ||
2209 !timeo)
2210 break;
2211
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002212 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002213 unix_state_unlock(sk);
WANG Cong06a77b02016-11-17 15:55:26 -08002214 if (freezable)
2215 timeo = freezable_schedule_timeout(timeo);
2216 else
2217 timeo = schedule_timeout(timeo);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002218 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002219
2220 if (sock_flag(sk, SOCK_DEAD))
2221 break;
2222
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002223 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224 }
2225
Eric Dumazetaa395142010-04-20 13:03:51 +00002226 finish_wait(sk_sleep(sk), &wait);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002227 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228 return timeo;
2229}
2230
Eric Dumazete370a722013-08-08 14:37:32 -07002231static unsigned int unix_skb_len(const struct sk_buff *skb)
2232{
2233 return skb->len - UNIXCB(skb).consumed;
2234}
2235
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002236struct unix_stream_read_state {
2237 int (*recv_actor)(struct sk_buff *, int, int,
2238 struct unix_stream_read_state *);
2239 struct socket *socket;
2240 struct msghdr *msg;
2241 struct pipe_inode_info *pipe;
2242 size_t size;
2243 int flags;
2244 unsigned int splice_flags;
2245};
2246
WANG Cong06a77b02016-11-17 15:55:26 -08002247static int unix_stream_read_generic(struct unix_stream_read_state *state,
2248 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002250 struct scm_cookie scm;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002251 struct socket *sock = state->socket;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252 struct sock *sk = sock->sk;
2253 struct unix_sock *u = unix_sk(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254 int copied = 0;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002255 int flags = state->flags;
Eric Dumazetde144392014-03-25 18:42:27 -07002256 int noblock = flags & MSG_DONTWAIT;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002257 bool check_creds = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258 int target;
2259 int err = 0;
2260 long timeo;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002261 int skip;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002262 size_t size = state->size;
2263 unsigned int last_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002265 if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
2266 err = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002268 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002270 if (unlikely(flags & MSG_OOB)) {
2271 err = -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002273 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002275 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
Eric Dumazetde144392014-03-25 18:42:27 -07002276 timeo = sock_rcvtimeo(sk, noblock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002278 memset(&scm, 0, sizeof(scm));
2279
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280 /* Lock the socket to prevent queue disordering
2281 * while sleeps in memcpy_tomsg
2282 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002283 mutex_lock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284
Matthew Dawsona0917e02017-08-18 15:04:54 -04002285 skip = max(sk_peek_offset(sk, flags), 0);
Andrey Vagine9193d62015-10-02 00:05:36 +03002286
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002287 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 int chunk;
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002289 bool drop_skb;
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002290 struct sk_buff *skb, *last;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002292redo:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002293 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002294 if (sock_flag(sk, SOCK_DEAD)) {
2295 err = -ECONNRESET;
2296 goto unlock;
2297 }
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002298 last = skb = skb_peek(&sk->sk_receive_queue);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002299 last_len = last ? last->len : 0;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002300again:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002301 if (skb == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302 if (copied >= target)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002303 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304
2305 /*
2306 * POSIX 1003.1g mandates this order.
2307 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002308
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002309 err = sock_error(sk);
2310 if (err)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002311 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312 if (sk->sk_shutdown & RCV_SHUTDOWN)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002313 goto unlock;
2314
2315 unix_state_unlock(sk);
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002316 if (!timeo) {
2317 err = -EAGAIN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318 break;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002319 }
2320
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002321 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002323 timeo = unix_stream_data_wait(sk, timeo, last,
WANG Cong06a77b02016-11-17 15:55:26 -08002324 last_len, freezable);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325
Rainer Weikusat3822b5c2015-12-16 20:09:25 +00002326 if (signal_pending(current)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327 err = sock_intr_errno(timeo);
Eric Dumazetfa0dc042016-01-24 13:53:50 -08002328 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 goto out;
2330 }
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00002331
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002332 mutex_lock(&u->iolock);
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002333 goto redo;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002334unlock:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002335 unix_state_unlock(sk);
2336 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337 }
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002338
Eric Dumazete370a722013-08-08 14:37:32 -07002339 while (skip >= unix_skb_len(skb)) {
2340 skip -= unix_skb_len(skb);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002341 last = skb;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002342 last_len = skb->len;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002343 skb = skb_peek_next(skb, &sk->sk_receive_queue);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002344 if (!skb)
2345 goto again;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002346 }
2347
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002348 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349
2350 if (check_creds) {
2351 /* Never glue messages from different writers */
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002352 if (!unix_skb_scm_eq(skb, &scm))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353 break;
Eric W. Biederman0e82e7f6d2013-04-03 16:14:47 +00002354 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355 /* Copy credentials */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002356 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04002357 unix_set_secdata(&scm, skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002358 check_creds = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359 }
2360
2361 /* Copy address just once */
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002362 if (state->msg && state->msg->msg_name) {
2363 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr,
2364 state->msg->msg_name);
2365 unix_copy_addr(state->msg, skb->sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366 sunaddr = NULL;
2367 }
2368
Eric Dumazete370a722013-08-08 14:37:32 -07002369 chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002370 skb_get(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002371 chunk = state->recv_actor(skb, skip, chunk, state);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002372 drop_skb = !unix_skb_len(skb);
2373 /* skb is only safe to use if !drop_skb */
2374 consume_skb(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002375 if (chunk < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376 if (copied == 0)
2377 copied = -EFAULT;
2378 break;
2379 }
2380 copied += chunk;
2381 size -= chunk;
2382
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002383 if (drop_skb) {
2384 /* the skb was touched by a concurrent reader;
2385 * we should not expect anything from this skb
2386 * anymore and assume it invalid - we can be
2387 * sure it was dropped from the socket queue
2388 *
2389 * let's report a short read
2390 */
2391 err = 0;
2392 break;
2393 }
2394
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395 /* Mark read part of skb as used */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002396 if (!(flags & MSG_PEEK)) {
Eric Dumazete370a722013-08-08 14:37:32 -07002397 UNIXCB(skb).consumed += chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002399 sk_peek_offset_bwd(sk, chunk);
2400
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002401 if (UNIXCB(skb).fp) {
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002402 scm_stat_del(sk, skb);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002403 unix_detach_fds(&scm, skb);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002404 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405
Eric Dumazete370a722013-08-08 14:37:32 -07002406 if (unix_skb_len(skb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408
Eric Dumazet6f01fd62012-01-28 16:11:03 +00002409 skb_unlink(skb, &sk->sk_receive_queue);
Neil Horman70d4bf62010-07-20 06:45:56 +00002410 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002412 if (scm.fp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002414 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415 /* It is questionable, see note in unix_dgram_recvmsg.
2416 */
2417 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002418 scm.fp = scm_fp_dup(UNIXCB(skb).fp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419
Andrey Vagine9193d62015-10-02 00:05:36 +03002420 sk_peek_offset_fwd(sk, chunk);
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002421
Aaron Conole9f389e32015-09-26 18:50:43 -04002422 if (UNIXCB(skb).fp)
2423 break;
2424
Andrey Vagine9193d62015-10-02 00:05:36 +03002425 skip = 0;
Aaron Conole9f389e32015-09-26 18:50:43 -04002426 last = skb;
2427 last_len = skb->len;
2428 unix_state_lock(sk);
2429 skb = skb_peek_next(skb, &sk->sk_receive_queue);
2430 if (skb)
2431 goto again;
2432 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433 break;
2434 }
2435 } while (size);
2436
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002437 mutex_unlock(&u->iolock);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002438 if (state->msg)
2439 scm_recv(sock, state->msg, &scm, flags);
2440 else
2441 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442out:
2443 return copied ? : err;
2444}
2445
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002446static int unix_stream_read_actor(struct sk_buff *skb,
2447 int skip, int chunk,
2448 struct unix_stream_read_state *state)
2449{
2450 int ret;
2451
2452 ret = skb_copy_datagram_msg(skb, UNIXCB(skb).consumed + skip,
2453 state->msg, chunk);
2454 return ret ?: chunk;
2455}
2456
2457static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
2458 size_t size, int flags)
2459{
2460 struct unix_stream_read_state state = {
2461 .recv_actor = unix_stream_read_actor,
2462 .socket = sock,
2463 .msg = msg,
2464 .size = size,
2465 .flags = flags
2466 };
2467
WANG Cong06a77b02016-11-17 15:55:26 -08002468 return unix_stream_read_generic(&state, true);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002469}
2470
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002471static int unix_stream_splice_actor(struct sk_buff *skb,
2472 int skip, int chunk,
2473 struct unix_stream_read_state *state)
2474{
2475 return skb_splice_bits(skb, state->socket->sk,
2476 UNIXCB(skb).consumed + skip,
Al Viro25869262016-09-17 21:02:10 -04002477 state->pipe, chunk, state->splice_flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002478}
2479
2480static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos,
2481 struct pipe_inode_info *pipe,
2482 size_t size, unsigned int flags)
2483{
2484 struct unix_stream_read_state state = {
2485 .recv_actor = unix_stream_splice_actor,
2486 .socket = sock,
2487 .pipe = pipe,
2488 .size = size,
2489 .splice_flags = flags,
2490 };
2491
2492 if (unlikely(*ppos))
2493 return -ESPIPE;
2494
2495 if (sock->file->f_flags & O_NONBLOCK ||
2496 flags & SPLICE_F_NONBLOCK)
2497 state.flags = MSG_DONTWAIT;
2498
WANG Cong06a77b02016-11-17 15:55:26 -08002499 return unix_stream_read_generic(&state, false);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002500}
2501
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502static int unix_shutdown(struct socket *sock, int mode)
2503{
2504 struct sock *sk = sock->sk;
2505 struct sock *other;
2506
Xi Wangfc61b922012-08-26 16:47:13 +00002507 if (mode < SHUT_RD || mode > SHUT_RDWR)
2508 return -EINVAL;
2509 /* This maps:
2510 * SHUT_RD (0) -> RCV_SHUTDOWN (1)
2511 * SHUT_WR (1) -> SEND_SHUTDOWN (2)
2512 * SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
2513 */
2514 ++mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515
Alban Crequy7180a032011-01-19 04:56:36 +00002516 unix_state_lock(sk);
2517 sk->sk_shutdown |= mode;
2518 other = unix_peer(sk);
2519 if (other)
2520 sock_hold(other);
2521 unix_state_unlock(sk);
2522 sk->sk_state_change(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523
Alban Crequy7180a032011-01-19 04:56:36 +00002524 if (other &&
2525 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526
Alban Crequy7180a032011-01-19 04:56:36 +00002527 int peer_mode = 0;
2528
2529 if (mode&RCV_SHUTDOWN)
2530 peer_mode |= SEND_SHUTDOWN;
2531 if (mode&SEND_SHUTDOWN)
2532 peer_mode |= RCV_SHUTDOWN;
2533 unix_state_lock(other);
2534 other->sk_shutdown |= peer_mode;
2535 unix_state_unlock(other);
2536 other->sk_state_change(other);
2537 if (peer_mode == SHUTDOWN_MASK)
2538 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
2539 else if (peer_mode & RCV_SHUTDOWN)
2540 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541 }
Alban Crequy7180a032011-01-19 04:56:36 +00002542 if (other)
2543 sock_put(other);
2544
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545 return 0;
2546}
2547
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002548long unix_inq_len(struct sock *sk)
2549{
2550 struct sk_buff *skb;
2551 long amount = 0;
2552
2553 if (sk->sk_state == TCP_LISTEN)
2554 return -EINVAL;
2555
2556 spin_lock(&sk->sk_receive_queue.lock);
2557 if (sk->sk_type == SOCK_STREAM ||
2558 sk->sk_type == SOCK_SEQPACKET) {
2559 skb_queue_walk(&sk->sk_receive_queue, skb)
Eric Dumazete370a722013-08-08 14:37:32 -07002560 amount += unix_skb_len(skb);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002561 } else {
2562 skb = skb_peek(&sk->sk_receive_queue);
2563 if (skb)
2564 amount = skb->len;
2565 }
2566 spin_unlock(&sk->sk_receive_queue.lock);
2567
2568 return amount;
2569}
2570EXPORT_SYMBOL_GPL(unix_inq_len);
2571
2572long unix_outq_len(struct sock *sk)
2573{
2574 return sk_wmem_alloc_get(sk);
2575}
2576EXPORT_SYMBOL_GPL(unix_outq_len);
2577
Andrey Vaginba94f302017-02-01 11:00:45 -08002578static int unix_open_file(struct sock *sk)
2579{
2580 struct path path;
2581 struct file *f;
2582 int fd;
2583
2584 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
2585 return -EPERM;
2586
Al Viroae3b5642019-02-15 20:09:35 +00002587 if (!smp_load_acquire(&unix_sk(sk)->addr))
Andrey Vaginba94f302017-02-01 11:00:45 -08002588 return -ENOENT;
Al Viroae3b5642019-02-15 20:09:35 +00002589
2590 path = unix_sk(sk)->path;
2591 if (!path.dentry)
2592 return -ENOENT;
Andrey Vaginba94f302017-02-01 11:00:45 -08002593
2594 path_get(&path);
Andrey Vaginba94f302017-02-01 11:00:45 -08002595
2596 fd = get_unused_fd_flags(O_CLOEXEC);
2597 if (fd < 0)
2598 goto out;
2599
2600 f = dentry_open(&path, O_PATH, current_cred());
2601 if (IS_ERR(f)) {
2602 put_unused_fd(fd);
2603 fd = PTR_ERR(f);
2604 goto out;
2605 }
2606
2607 fd_install(fd, f);
2608out:
2609 path_put(&path);
2610
2611 return fd;
2612}
2613
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2615{
2616 struct sock *sk = sock->sk;
Jianjun Konge27dfce2008-11-01 21:38:31 -07002617 long amount = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618 int err;
2619
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002620 switch (cmd) {
2621 case SIOCOUTQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002622 amount = unix_outq_len(sk);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002623 err = put_user(amount, (int __user *)arg);
2624 break;
2625 case SIOCINQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002626 amount = unix_inq_len(sk);
2627 if (amount < 0)
2628 err = amount;
2629 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630 err = put_user(amount, (int __user *)arg);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002631 break;
Andrey Vaginba94f302017-02-01 11:00:45 -08002632 case SIOCUNIXFILE:
2633 err = unix_open_file(sk);
2634 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002635 default:
2636 err = -ENOIOCTLCMD;
2637 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638 }
2639 return err;
2640}
2641
Arnd Bergmann5f6beb92019-06-03 22:03:44 +02002642#ifdef CONFIG_COMPAT
2643static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2644{
2645 return unix_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
2646}
2647#endif
2648
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002649static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650{
2651 struct sock *sk = sock->sk;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002652 __poll_t mask;
2653
Karsten Graul89ab0662018-10-23 13:40:39 +02002654 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002655 mask = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656
2657 /* exceptional events? */
2658 if (sk->sk_err)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002659 mask |= EPOLLERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002661 mask |= EPOLLHUP;
Davide Libenzif348d702006-03-25 03:07:39 -08002662 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002663 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002664
2665 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002666 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002667 mask |= EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668
2669 /* Connection-based need to check for termination and startup */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002670 if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
2671 sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002672 mask |= EPOLLHUP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673
2674 /*
2675 * we set writable also when the other side has shut down the
2676 * connection. This prevents stuck sockets.
2677 */
2678 if (unix_writable(sk))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002679 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002680
2681 return mask;
2682}
2683
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002684static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
2685 poll_table *wait)
Rainer Weikusat3c734192008-06-17 22:28:05 -07002686{
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002687 struct sock *sk = sock->sk, *other;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002688 unsigned int writable;
2689 __poll_t mask;
2690
Karsten Graul89ab0662018-10-23 13:40:39 +02002691 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002692 mask = 0;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002693
2694 /* exceptional events? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002695 if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002696 mask |= EPOLLERR |
2697 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +00002698
Rainer Weikusat3c734192008-06-17 22:28:05 -07002699 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002700 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002701 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002702 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002703
2704 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002705 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002706 mask |= EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002707
2708 /* Connection-based need to check for termination and startup */
2709 if (sk->sk_type == SOCK_SEQPACKET) {
2710 if (sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002711 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002712 /* connection hasn't started yet? */
2713 if (sk->sk_state == TCP_SYN_SENT)
2714 return mask;
2715 }
2716
Eric Dumazet973a34a2010-10-31 05:38:25 +00002717 /* No write status requested, avoid expensive OUT tests. */
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002718 if (!(poll_requested_events(wait) & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT)))
Eric Dumazet973a34a2010-10-31 05:38:25 +00002719 return mask;
2720
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002721 writable = unix_writable(sk);
Rainer Weikusat7d267272015-11-20 22:07:23 +00002722 if (writable) {
2723 unix_state_lock(sk);
2724
2725 other = unix_peer(sk);
2726 if (other && unix_peer(other) != sk &&
2727 unix_recvq_full(other) &&
2728 unix_dgram_peer_wake_me(sk, other))
2729 writable = 0;
2730
2731 unix_state_unlock(sk);
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002732 }
2733
2734 if (writable)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002735 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002736 else
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002737 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
Rainer Weikusat3c734192008-06-17 22:28:05 -07002738
Rainer Weikusat3c734192008-06-17 22:28:05 -07002739 return mask;
2740}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741
2742#ifdef CONFIG_PROC_FS
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002743
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002744#define BUCKET_SPACE (BITS_PER_LONG - (UNIX_HASH_BITS + 1) - 1)
2745
2746#define get_bucket(x) ((x) >> BUCKET_SPACE)
2747#define get_offset(x) ((x) & ((1L << BUCKET_SPACE) - 1))
2748#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002749
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002750static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751{
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002752 unsigned long offset = get_offset(*pos);
2753 unsigned long bucket = get_bucket(*pos);
2754 struct sock *sk;
2755 unsigned long count = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002757 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
2758 if (sock_net(sk) != seq_file_net(seq))
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002759 continue;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002760 if (++count == offset)
2761 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762 }
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002763
2764 return sk;
2765}
2766
2767static struct sock *unix_next_socket(struct seq_file *seq,
2768 struct sock *sk,
2769 loff_t *pos)
2770{
2771 unsigned long bucket;
2772
2773 while (sk > (struct sock *)SEQ_START_TOKEN) {
2774 sk = sk_next(sk);
2775 if (!sk)
2776 goto next_bucket;
2777 if (sock_net(sk) == seq_file_net(seq))
2778 return sk;
2779 }
2780
2781 do {
2782 sk = unix_from_bucket(seq, pos);
2783 if (sk)
2784 return sk;
2785
2786next_bucket:
2787 bucket = get_bucket(*pos) + 1;
2788 *pos = set_bucket_offset(bucket, 1);
2789 } while (bucket < ARRAY_SIZE(unix_socket_table));
2790
Linus Torvalds1da177e2005-04-16 15:20:36 -07002791 return NULL;
2792}
2793
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002795 __acquires(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002797 spin_lock(&unix_table_lock);
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002798
2799 if (!*pos)
2800 return SEQ_START_TOKEN;
2801
2802 if (get_bucket(*pos) >= ARRAY_SIZE(unix_socket_table))
2803 return NULL;
2804
2805 return unix_next_socket(seq, NULL, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002806}
2807
2808static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2809{
2810 ++*pos;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002811 return unix_next_socket(seq, v, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812}
2813
2814static void unix_seq_stop(struct seq_file *seq, void *v)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002815 __releases(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002817 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818}
2819
2820static int unix_seq_show(struct seq_file *seq, void *v)
2821{
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002822
Joe Perchesb9f31242008-04-12 19:04:38 -07002823 if (v == SEQ_START_TOKEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 seq_puts(seq, "Num RefCount Protocol Flags Type St "
2825 "Inode Path\n");
2826 else {
2827 struct sock *s = v;
2828 struct unix_sock *u = unix_sk(s);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002829 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830
Dan Rosenberg71338aa2011-05-23 12:17:35 +00002831 seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 s,
Reshetova, Elena41c6d652017-06-30 13:08:01 +03002833 refcount_read(&s->sk_refcnt),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 0,
2835 s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
2836 s->sk_type,
2837 s->sk_socket ?
2838 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
2839 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
2840 sock_i_ino(s));
2841
Al Viroae3b5642019-02-15 20:09:35 +00002842 if (u->addr) { // under unix_table_lock here
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843 int i, len;
2844 seq_putc(seq, ' ');
2845
2846 i = 0;
2847 len = u->addr->len - sizeof(short);
2848 if (!UNIX_ABSTRACT(s))
2849 len--;
2850 else {
2851 seq_putc(seq, '@');
2852 i++;
2853 }
2854 for ( ; i < len; i++)
Isaac Boukrise7947ea2016-11-01 02:41:35 +02002855 seq_putc(seq, u->addr->name->sun_path[i] ?:
2856 '@');
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07002858 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 seq_putc(seq, '\n');
2860 }
2861
2862 return 0;
2863}
2864
Philippe De Muyter56b3d972007-07-10 23:07:31 -07002865static const struct seq_operations unix_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 .start = unix_seq_start,
2867 .next = unix_seq_next,
2868 .stop = unix_seq_stop,
2869 .show = unix_seq_show,
2870};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871#endif
2872
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00002873static const struct net_proto_family unix_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874 .family = PF_UNIX,
2875 .create = unix_create,
2876 .owner = THIS_MODULE,
2877};
2878
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002879
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002880static int __net_init unix_net_init(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002881{
2882 int error = -ENOMEM;
2883
Denis V. Luneva0a53c82007-12-11 04:19:17 -08002884 net->unx.sysctl_max_dgram_qlen = 10;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002885 if (unix_sysctl_register(net))
2886 goto out;
Pavel Emelyanovd392e492007-12-01 23:44:15 +11002887
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002888#ifdef CONFIG_PROC_FS
Christoph Hellwigc3506372018-04-10 19:42:55 +02002889 if (!proc_create_net("unix", 0, net->proc_net, &unix_seq_ops,
2890 sizeof(struct seq_net_private))) {
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002891 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002892 goto out;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002893 }
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002894#endif
2895 error = 0;
2896out:
Jianjun Kong48dcc33e2008-11-01 21:37:27 -07002897 return error;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002898}
2899
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002900static void __net_exit unix_net_exit(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002901{
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002902 unix_sysctl_unregister(net);
Gao fengece31ff2013-02-18 01:34:56 +00002903 remove_proc_entry("unix", net->proc_net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002904}
2905
2906static struct pernet_operations unix_net_ops = {
2907 .init = unix_net_init,
2908 .exit = unix_net_exit,
2909};
2910
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911static int __init af_unix_init(void)
2912{
2913 int rc = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914
Pankaj Bharadiyac5936422019-12-09 10:31:43 -08002915 BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof_field(struct sk_buff, cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916
2917 rc = proto_register(&unix_proto, 1);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002918 if (rc != 0) {
wangweidong5cc208b2013-12-06 18:03:36 +08002919 pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920 goto out;
2921 }
2922
2923 sock_register(&unix_family_ops);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002924 register_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925out:
2926 return rc;
2927}
2928
2929static void __exit af_unix_exit(void)
2930{
2931 sock_unregister(PF_UNIX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 proto_unregister(&unix_proto);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002933 unregister_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934}
2935
David Woodhouse3d366962008-04-24 00:59:25 -07002936/* Earlier than device_initcall() so that other drivers invoking
2937 request_module() don't end up in a loop when modprobe tries
2938 to use a UNIX socket. But later than subsys_initcall() because
2939 we depend on stuff initialised there */
2940fs_initcall(af_unix_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941module_exit(af_unix_exit);
2942
2943MODULE_LICENSE("GPL");
2944MODULE_ALIAS_NETPROTO(PF_UNIX);