blob: 23c92ad15c61e948c89f4896e5775b6ab070cc4c [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
Al Viro185ab882021-06-19 03:50:26 +0000265static void __unix_set_addr(struct sock *sk, struct unix_address *addr,
266 unsigned hash)
267{
268 __unix_remove_socket(sk);
269 smp_store_release(&unix_sk(sk)->addr, addr);
270 __unix_insert_socket(&unix_socket_table[hash], sk);
271}
272
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273static inline void unix_remove_socket(struct sock *sk)
274{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800275 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 __unix_remove_socket(sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800277 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278}
279
280static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
281{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800282 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 __unix_insert_socket(list, sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800284 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285}
286
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800287static struct sock *__unix_find_socket_byname(struct net *net,
288 struct sockaddr_un *sunname,
Al Virobe752282021-06-19 03:50:33 +0000289 int len, unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290{
291 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292
Al Virobe752282021-06-19 03:50:33 +0000293 sk_for_each(s, &unix_socket_table[hash]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 struct unix_sock *u = unix_sk(s);
295
YOSHIFUJI Hideaki878628f2008-03-26 03:57:35 +0900296 if (!net_eq(sock_net(s), net))
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800297 continue;
298
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 if (u->addr->len == len &&
300 !memcmp(u->addr->name, sunname, len))
Vito Caputo262ce0a2019-10-09 20:43:47 -0700301 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 }
Vito Caputo262ce0a2019-10-09 20:43:47 -0700303 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304}
305
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800306static inline struct sock *unix_find_socket_byname(struct net *net,
307 struct sockaddr_un *sunname,
Al Virobe752282021-06-19 03:50:33 +0000308 int len, unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309{
310 struct sock *s;
311
David S. Millerfbe9cc42005-12-13 23:26:29 -0800312 spin_lock(&unix_table_lock);
Al Virobe752282021-06-19 03:50:33 +0000313 s = __unix_find_socket_byname(net, sunname, len, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 if (s)
315 sock_hold(s);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800316 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 return s;
318}
319
Eric W. Biederman6616f782010-06-13 03:35:48 +0000320static struct sock *unix_find_socket_byinode(struct inode *i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321{
322 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323
David S. Millerfbe9cc42005-12-13 23:26:29 -0800324 spin_lock(&unix_table_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800325 sk_for_each(s,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
Al Viro40ffe672012-03-14 21:54:32 -0400327 struct dentry *dentry = unix_sk(s)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328
Miklos Szeredibeef5122016-12-16 11:02:53 +0100329 if (dentry && d_backing_inode(dentry) == i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 sock_hold(s);
331 goto found;
332 }
333 }
334 s = NULL;
335found:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800336 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 return s;
338}
339
Rainer Weikusat7d267272015-11-20 22:07:23 +0000340/* Support code for asymmetrically connected dgram sockets
341 *
342 * If a datagram socket is connected to a socket not itself connected
343 * to the first socket (eg, /dev/log), clients may only enqueue more
344 * messages if the present receive queue of the server socket is not
345 * "too large". This means there's a second writeability condition
346 * poll and sendmsg need to test. The dgram recv code will do a wake
347 * up on the peer_wait wait queue of a socket upon reception of a
348 * datagram which needs to be propagated to sleeping would-be writers
349 * since these might not have sent anything so far. This can't be
350 * accomplished via poll_wait because the lifetime of the server
351 * socket might be less than that of its clients if these break their
352 * association with it or if the server socket is closed while clients
353 * are still connected to it and there's no way to inform "a polling
354 * implementation" that it should let go of a certain wait queue
355 *
Ingo Molnarac6424b2017-06-20 12:06:13 +0200356 * In order to propagate a wake up, a wait_queue_entry_t of the client
Rainer Weikusat7d267272015-11-20 22:07:23 +0000357 * socket is enqueued on the peer_wait queue of the server socket
358 * whose wake function does a wake_up on the ordinary client socket
359 * wait queue. This connection is established whenever a write (or
360 * poll for write) hit the flow control condition and broken when the
361 * association to the server socket is dissolved or after a wake up
362 * was relayed.
363 */
364
Ingo Molnarac6424b2017-06-20 12:06:13 +0200365static int unix_dgram_peer_wake_relay(wait_queue_entry_t *q, unsigned mode, int flags,
Rainer Weikusat7d267272015-11-20 22:07:23 +0000366 void *key)
367{
368 struct unix_sock *u;
369 wait_queue_head_t *u_sleep;
370
371 u = container_of(q, struct unix_sock, peer_wake);
372
373 __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
374 q);
375 u->peer_wake.private = NULL;
376
377 /* relaying can only happen while the wq still exists */
378 u_sleep = sk_sleep(&u->sk);
379 if (u_sleep)
Al Viro3ad6f932017-07-03 20:14:56 -0400380 wake_up_interruptible_poll(u_sleep, key_to_poll(key));
Rainer Weikusat7d267272015-11-20 22:07:23 +0000381
382 return 0;
383}
384
385static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
386{
387 struct unix_sock *u, *u_other;
388 int rc;
389
390 u = unix_sk(sk);
391 u_other = unix_sk(other);
392 rc = 0;
393 spin_lock(&u_other->peer_wait.lock);
394
395 if (!u->peer_wake.private) {
396 u->peer_wake.private = other;
397 __add_wait_queue(&u_other->peer_wait, &u->peer_wake);
398
399 rc = 1;
400 }
401
402 spin_unlock(&u_other->peer_wait.lock);
403 return rc;
404}
405
406static void unix_dgram_peer_wake_disconnect(struct sock *sk,
407 struct sock *other)
408{
409 struct unix_sock *u, *u_other;
410
411 u = unix_sk(sk);
412 u_other = unix_sk(other);
413 spin_lock(&u_other->peer_wait.lock);
414
415 if (u->peer_wake.private == other) {
416 __remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
417 u->peer_wake.private = NULL;
418 }
419
420 spin_unlock(&u_other->peer_wait.lock);
421}
422
423static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
424 struct sock *other)
425{
426 unix_dgram_peer_wake_disconnect(sk, other);
427 wake_up_interruptible_poll(sk_sleep(sk),
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800428 EPOLLOUT |
429 EPOLLWRNORM |
430 EPOLLWRBAND);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000431}
432
433/* preconditions:
434 * - unix_peer(sk) == other
435 * - association is stable
436 */
437static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
438{
439 int connected;
440
441 connected = unix_dgram_peer_wake_connect(sk, other);
442
Jason Baron51f7e952018-08-03 17:24:53 -0400443 /* If other is SOCK_DEAD, we want to make sure we signal
444 * POLLOUT, such that a subsequent write() can get a
445 * -ECONNREFUSED. Otherwise, if we haven't queued any skbs
446 * to other and its full, we will hang waiting for POLLOUT.
447 */
448 if (unix_recvq_full(other) && !sock_flag(other, SOCK_DEAD))
Rainer Weikusat7d267272015-11-20 22:07:23 +0000449 return 1;
450
451 if (connected)
452 unix_dgram_peer_wake_disconnect(sk, other);
453
454 return 0;
455}
456
Eric Dumazet1586a582015-10-23 10:59:16 -0700457static int unix_writable(const struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458{
Eric Dumazet1586a582015-10-23 10:59:16 -0700459 return sk->sk_state != TCP_LISTEN &&
Reshetova, Elena14afee42017-06-30 13:08:00 +0300460 (refcount_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461}
462
463static void unix_write_space(struct sock *sk)
464{
Eric Dumazet43815482010-04-29 11:01:49 +0000465 struct socket_wq *wq;
466
467 rcu_read_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 if (unix_writable(sk)) {
Eric Dumazet43815482010-04-29 11:01:49 +0000469 wq = rcu_dereference(sk->sk_wq);
Herbert Xu1ce0bf52015-11-26 13:55:39 +0800470 if (skwq_has_sleeper(wq))
Eric Dumazet67426b72010-10-29 20:44:44 +0000471 wake_up_interruptible_sync_poll(&wq->wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800472 EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800473 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 }
Eric Dumazet43815482010-04-29 11:01:49 +0000475 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476}
477
478/* When dgram socket disconnects (or changes its peer), we clear its receive
479 * queue of packets arrived from previous peer. First, it allows to do
480 * flow control based only on wmem_alloc; second, sk connected to peer
481 * may receive messages only from that peer. */
482static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
483{
David S. Millerb03efcf2005-07-08 14:57:23 -0700484 if (!skb_queue_empty(&sk->sk_receive_queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 skb_queue_purge(&sk->sk_receive_queue);
486 wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
487
488 /* If one link of bidirectional dgram pipe is disconnected,
489 * we signal error. Messages are lost. Do not make this,
490 * when peer was not connected to us.
491 */
492 if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) {
493 other->sk_err = ECONNRESET;
Alexander Aringe3ae2362021-06-27 18:48:21 -0400494 sk_error_report(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 }
496 }
497}
498
499static void unix_sock_destructor(struct sock *sk)
500{
501 struct unix_sock *u = unix_sk(sk);
502
503 skb_queue_purge(&sk->sk_receive_queue);
504
Reshetova, Elena14afee42017-06-30 13:08:00 +0300505 WARN_ON(refcount_read(&sk->sk_wmem_alloc));
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700506 WARN_ON(!sk_unhashed(sk));
507 WARN_ON(sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 if (!sock_flag(sk, SOCK_DEAD)) {
wangweidong5cc208b2013-12-06 18:03:36 +0800509 pr_info("Attempt to release alive unix socket: %p\n", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 return;
511 }
512
513 if (u->addr)
514 unix_release_addr(u->addr);
515
Eric Dumazet518de9b2010-10-26 14:22:44 -0700516 atomic_long_dec(&unix_nr_socks);
David S. Miller6f756a82008-11-23 17:34:03 -0800517 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800518 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
David S. Miller6f756a82008-11-23 17:34:03 -0800519 local_bh_enable();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520#ifdef UNIX_REFCNT_DEBUG
wangweidong5cc208b2013-12-06 18:03:36 +0800521 pr_debug("UNIX %p is destroyed, %ld are still alive.\n", sk,
Eric Dumazet518de9b2010-10-26 14:22:44 -0700522 atomic_long_read(&unix_nr_socks));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523#endif
524}
525
Paul Mooreded34e02013-03-25 03:18:33 +0000526static void unix_release_sock(struct sock *sk, int embrion)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527{
528 struct unix_sock *u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400529 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 struct sock *skpair;
531 struct sk_buff *skb;
532 int state;
533
534 unix_remove_socket(sk);
535
536 /* Clear state */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700537 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 sock_orphan(sk);
539 sk->sk_shutdown = SHUTDOWN_MASK;
Al Viro40ffe672012-03-14 21:54:32 -0400540 path = u->path;
541 u->path.dentry = NULL;
542 u->path.mnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 state = sk->sk_state;
544 sk->sk_state = TCP_CLOSE;
Eric Dumazeta494bd62021-06-16 07:47:15 -0700545
546 skpair = unix_peer(sk);
547 unix_peer(sk) = NULL;
548
David S. Miller1c92b4e2007-05-31 13:24:26 -0700549 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550
551 wake_up_interruptible_all(&u->peer_wait);
552
Jianjun Konge27dfce2008-11-01 21:38:31 -0700553 if (skpair != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
David S. Miller1c92b4e2007-05-31 13:24:26 -0700555 unix_state_lock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 /* No more writes */
557 skpair->sk_shutdown = SHUTDOWN_MASK;
558 if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
559 skpair->sk_err = ECONNRESET;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700560 unix_state_unlock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 skpair->sk_state_change(skpair);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800562 sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 }
Rainer Weikusat7d267272015-11-20 22:07:23 +0000564
565 unix_dgram_peer_wake_disconnect(sk, skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 sock_put(skpair); /* It may now die */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 }
568
569 /* Try to flush out this socket. Throw out buffers at least */
570
571 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
Jianjun Konge27dfce2008-11-01 21:38:31 -0700572 if (state == TCP_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 unix_release_sock(skb->sk, 1);
574 /* passed fds are erased in the kfree_skb hook */
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +0100575 UNIXCB(skb).consumed = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 kfree_skb(skb);
577 }
578
Al Viro40ffe672012-03-14 21:54:32 -0400579 if (path.dentry)
580 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581
582 sock_put(sk);
583
584 /* ---- Socket is dead now and most probably destroyed ---- */
585
586 /*
Alan Coxe04dae82012-09-17 00:52:41 +0000587 * Fixme: BSD difference: In BSD all sockets connected to us get
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 * ECONNRESET and we die on the spot. In Linux we behave
589 * like files and pipes do and wait for the last
590 * dereference.
591 *
592 * Can't we simply set sock->err?
593 *
594 * What the above comment does talk about? --ANK(980817)
595 */
596
Pavel Emelyanov9305cfa2007-11-10 22:06:01 -0800597 if (unix_tot_inflight)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900598 unix_gc(); /* Garbage collect fds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599}
600
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000601static void init_peercred(struct sock *sk)
602{
603 put_pid(sk->sk_peer_pid);
604 if (sk->sk_peer_cred)
605 put_cred(sk->sk_peer_cred);
606 sk->sk_peer_pid = get_pid(task_tgid(current));
607 sk->sk_peer_cred = get_current_cred();
608}
609
610static void copy_peercred(struct sock *sk, struct sock *peersk)
611{
612 put_pid(sk->sk_peer_pid);
613 if (sk->sk_peer_cred)
614 put_cred(sk->sk_peer_cred);
615 sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
616 sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
617}
618
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619static int unix_listen(struct socket *sock, int backlog)
620{
621 int err;
622 struct sock *sk = sock->sk;
623 struct unix_sock *u = unix_sk(sk);
624
625 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800626 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
627 goto out; /* Only stream/seqpacket sockets accept */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 err = -EINVAL;
629 if (!u->addr)
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800630 goto out; /* No listens on an unbound socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700631 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
633 goto out_unlock;
634 if (backlog > sk->sk_max_ack_backlog)
635 wake_up_interruptible_all(&u->peer_wait);
636 sk->sk_max_ack_backlog = backlog;
637 sk->sk_state = TCP_LISTEN;
638 /* set credentials so connect can copy them */
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000639 init_peercred(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 err = 0;
641
642out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -0700643 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644out:
645 return err;
646}
647
648static int unix_release(struct socket *);
649static int unix_bind(struct socket *, struct sockaddr *, int);
650static int unix_stream_connect(struct socket *, struct sockaddr *,
651 int addr_len, int flags);
652static int unix_socketpair(struct socket *, struct socket *);
David Howellscdfbabf2017-03-09 08:09:05 +0000653static int unix_accept(struct socket *, struct socket *, int, bool);
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +0100654static int unix_getname(struct socket *, struct sockaddr *, int);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700655static __poll_t unix_poll(struct file *, struct socket *, poll_table *);
656static __poll_t unix_dgram_poll(struct file *, struct socket *,
657 poll_table *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658static int unix_ioctl(struct socket *, unsigned int, unsigned long);
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200659#ifdef CONFIG_COMPAT
660static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
661#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662static int unix_shutdown(struct socket *, int);
Ying Xue1b784142015-03-02 15:37:48 +0800663static int unix_stream_sendmsg(struct socket *, struct msghdr *, size_t);
664static int unix_stream_recvmsg(struct socket *, struct msghdr *, size_t, int);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200665static ssize_t unix_stream_sendpage(struct socket *, struct page *, int offset,
666 size_t size, int flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200667static ssize_t unix_stream_splice_read(struct socket *, loff_t *ppos,
668 struct pipe_inode_info *, size_t size,
669 unsigned int flags);
Ying Xue1b784142015-03-02 15:37:48 +0800670static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t);
671static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672static int unix_dgram_connect(struct socket *, struct sockaddr *,
673 int, int);
Ying Xue1b784142015-03-02 15:37:48 +0800674static int unix_seqpacket_sendmsg(struct socket *, struct msghdr *, size_t);
675static int unix_seqpacket_recvmsg(struct socket *, struct msghdr *, size_t,
676 int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677
Sasha Levin12663bf2013-12-07 17:26:27 -0500678static int unix_set_peek_off(struct sock *sk, int val)
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000679{
680 struct unix_sock *u = unix_sk(sk);
681
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700682 if (mutex_lock_interruptible(&u->iolock))
Sasha Levin12663bf2013-12-07 17:26:27 -0500683 return -EINTR;
684
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000685 sk->sk_peek_off = val;
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700686 mutex_unlock(&u->iolock);
Sasha Levin12663bf2013-12-07 17:26:27 -0500687
688 return 0;
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000689}
690
David S. Miller5c05a162020-02-27 11:52:35 -0800691#ifdef CONFIG_PROC_FS
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300692static void unix_show_fdinfo(struct seq_file *m, struct socket *sock)
693{
694 struct sock *sk = sock->sk;
695 struct unix_sock *u;
696
697 if (sk) {
698 u = unix_sk(sock->sk);
Paolo Abeni77820402020-02-28 14:45:21 +0100699 seq_printf(m, "scm_fds: %u\n",
700 atomic_read(&u->scm_stat.nr_fds));
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300701 }
702}
Tobias Klauser3a125002020-02-26 18:29:53 +0100703#else
704#define unix_show_fdinfo NULL
705#endif
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000706
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800707static const struct proto_ops unix_stream_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 .family = PF_UNIX,
709 .owner = THIS_MODULE,
710 .release = unix_release,
711 .bind = unix_bind,
712 .connect = unix_stream_connect,
713 .socketpair = unix_socketpair,
714 .accept = unix_accept,
715 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700716 .poll = unix_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200718#ifdef CONFIG_COMPAT
719 .compat_ioctl = unix_compat_ioctl,
720#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 .listen = unix_listen,
722 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 .sendmsg = unix_stream_sendmsg,
724 .recvmsg = unix_stream_recvmsg,
725 .mmap = sock_no_mmap,
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200726 .sendpage = unix_stream_sendpage,
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200727 .splice_read = unix_stream_splice_read,
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +0000728 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300729 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730};
731
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800732static const struct proto_ops unix_dgram_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 .family = PF_UNIX,
734 .owner = THIS_MODULE,
735 .release = unix_release,
736 .bind = unix_bind,
737 .connect = unix_dgram_connect,
738 .socketpair = unix_socketpair,
739 .accept = sock_no_accept,
740 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700741 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200743#ifdef CONFIG_COMPAT
744 .compat_ioctl = unix_compat_ioctl,
745#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 .listen = sock_no_listen,
747 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 .sendmsg = unix_dgram_sendmsg,
749 .recvmsg = unix_dgram_recvmsg,
750 .mmap = sock_no_mmap,
751 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000752 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300753 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754};
755
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800756static const struct proto_ops unix_seqpacket_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 .family = PF_UNIX,
758 .owner = THIS_MODULE,
759 .release = unix_release,
760 .bind = unix_bind,
761 .connect = unix_stream_connect,
762 .socketpair = unix_socketpair,
763 .accept = unix_accept,
764 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700765 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200767#ifdef CONFIG_COMPAT
768 .compat_ioctl = unix_compat_ioctl,
769#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 .listen = unix_listen,
771 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 .sendmsg = unix_seqpacket_sendmsg,
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +0000773 .recvmsg = unix_seqpacket_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 .mmap = sock_no_mmap,
775 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000776 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300777 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778};
779
780static struct proto unix_proto = {
Eric Dumazet248969a2008-11-17 00:00:30 -0800781 .name = "UNIX",
782 .owner = THIS_MODULE,
Eric Dumazet248969a2008-11-17 00:00:30 -0800783 .obj_size = sizeof(struct unix_sock),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784};
785
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500786static struct sock *unix_create1(struct net *net, struct socket *sock, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787{
788 struct sock *sk = NULL;
789 struct unix_sock *u;
790
Eric Dumazet518de9b2010-10-26 14:22:44 -0700791 atomic_long_inc(&unix_nr_socks);
792 if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 goto out;
794
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500795 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, kern);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 if (!sk)
797 goto out;
798
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800799 sock_init_data(sock, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
Vladimir Davydov3aa97992016-07-26 15:24:36 -0700801 sk->sk_allocation = GFP_KERNEL_ACCOUNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 sk->sk_write_space = unix_write_space;
Denis V. Luneva0a53c82007-12-11 04:19:17 -0800803 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 sk->sk_destruct = unix_sock_destructor;
805 u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400806 u->path.dentry = NULL;
807 u->path.mnt = NULL;
Benjamin LaHaisefd19f322006-01-03 14:10:46 -0800808 spin_lock_init(&u->lock);
Al Viro516e0cc2008-07-26 00:39:17 -0400809 atomic_long_set(&u->inflight, 0);
Miklos Szeredi1fd05ba2007-07-11 14:22:39 -0700810 INIT_LIST_HEAD(&u->link);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700811 mutex_init(&u->iolock); /* single task reading lock */
812 mutex_init(&u->bindlock); /* single task binding lock */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 init_waitqueue_head(&u->peer_wait);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000814 init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300815 memset(&u->scm_stat, 0, sizeof(struct scm_stat));
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000816 unix_insert_socket(unix_sockets_unbound(sk), sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817out:
Pavel Emelyanov284b3272007-11-10 22:08:30 -0800818 if (sk == NULL)
Eric Dumazet518de9b2010-10-26 14:22:44 -0700819 atomic_long_dec(&unix_nr_socks);
Eric Dumazet920de802008-11-24 00:09:29 -0800820 else {
821 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800822 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
Eric Dumazet920de802008-11-24 00:09:29 -0800823 local_bh_enable();
824 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 return sk;
826}
827
Eric Paris3f378b62009-11-05 22:18:14 -0800828static int unix_create(struct net *net, struct socket *sock, int protocol,
829 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830{
831 if (protocol && protocol != PF_UNIX)
832 return -EPROTONOSUPPORT;
833
834 sock->state = SS_UNCONNECTED;
835
836 switch (sock->type) {
837 case SOCK_STREAM:
838 sock->ops = &unix_stream_ops;
839 break;
840 /*
841 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
842 * nothing uses it.
843 */
844 case SOCK_RAW:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700845 sock->type = SOCK_DGRAM;
Gustavo A. R. Silvadf561f662020-08-23 17:36:59 -0500846 fallthrough;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 case SOCK_DGRAM:
848 sock->ops = &unix_dgram_ops;
849 break;
850 case SOCK_SEQPACKET:
851 sock->ops = &unix_seqpacket_ops;
852 break;
853 default:
854 return -ESOCKTNOSUPPORT;
855 }
856
Eric W. Biederman11aa9c22015-05-08 21:09:13 -0500857 return unix_create1(net, sock, kern) ? 0 : -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858}
859
860static int unix_release(struct socket *sock)
861{
862 struct sock *sk = sock->sk;
863
864 if (!sk)
865 return 0;
866
Paul Mooreded34e02013-03-25 03:18:33 +0000867 unix_release_sock(sk, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868 sock->sk = NULL;
869
Paul Mooreded34e02013-03-25 03:18:33 +0000870 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871}
872
873static int unix_autobind(struct socket *sock)
874{
875 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900876 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 struct unix_sock *u = unix_sk(sk);
878 static u32 ordernum = 1;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800879 struct unix_address *addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 int err;
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000881 unsigned int retries = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700883 err = mutex_lock_interruptible(&u->bindlock);
Sasha Levin37ab4fa2013-12-13 10:54:22 -0500884 if (err)
885 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 if (u->addr)
888 goto out;
889
890 err = -ENOMEM;
Panagiotis Issaris0da974f2006-07-21 14:51:30 -0700891 addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 if (!addr)
893 goto out;
894
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895 addr->name->sun_family = AF_UNIX;
Reshetova, Elena8c9814b2017-06-30 13:08:05 +0300896 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897
898retry:
899 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
Joe Perches07f07572008-11-19 15:44:53 -0800900 addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
Al Virobe752282021-06-19 03:50:33 +0000901 addr->hash ^= sk->sk_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902
David S. Millerfbe9cc42005-12-13 23:26:29 -0800903 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 ordernum = (ordernum+1)&0xFFFFF;
905
Al Virobe752282021-06-19 03:50:33 +0000906 if (__unix_find_socket_byname(net, addr->name, addr->len, addr->hash)) {
David S. Millerfbe9cc42005-12-13 23:26:29 -0800907 spin_unlock(&unix_table_lock);
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000908 /*
909 * __unix_find_socket_byname() may take long time if many names
910 * are already in use.
911 */
912 cond_resched();
913 /* Give up if all names seems to be in use. */
914 if (retries++ == 0xFFFFF) {
915 err = -ENOSPC;
916 kfree(addr);
917 goto out;
918 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 goto retry;
920 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921
Al Viro185ab882021-06-19 03:50:26 +0000922 __unix_set_addr(sk, addr, addr->hash);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800923 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 err = 0;
925
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700926out: mutex_unlock(&u->bindlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 return err;
928}
929
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800930static struct sock *unix_find_other(struct net *net,
931 struct sockaddr_un *sunname, int len,
Eric Dumazet95c96172012-04-15 05:58:06 +0000932 int type, unsigned int hash, int *error)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933{
934 struct sock *u;
Al Viro421748e2008-08-02 01:04:36 -0400935 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 int err = 0;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900937
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 if (sunname->sun_path[0]) {
Al Viro421748e2008-08-02 01:04:36 -0400939 struct inode *inode;
940 err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941 if (err)
942 goto fail;
Miklos Szeredibeef5122016-12-16 11:02:53 +0100943 inode = d_backing_inode(path.dentry);
Christian Brauner02f92b32021-01-21 14:19:22 +0100944 err = path_permission(&path, MAY_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 if (err)
946 goto put_fail;
947
948 err = -ECONNREFUSED;
Al Viro421748e2008-08-02 01:04:36 -0400949 if (!S_ISSOCK(inode->i_mode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 goto put_fail;
Eric W. Biederman6616f782010-06-13 03:35:48 +0000951 u = unix_find_socket_byinode(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 if (!u)
953 goto put_fail;
954
955 if (u->sk_type == type)
Al Viro68ac1232012-03-15 08:21:57 -0400956 touch_atime(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957
Al Viro421748e2008-08-02 01:04:36 -0400958 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
Jianjun Konge27dfce2008-11-01 21:38:31 -0700960 err = -EPROTOTYPE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 if (u->sk_type != type) {
962 sock_put(u);
963 goto fail;
964 }
965 } else {
966 err = -ECONNREFUSED;
Al Virobe752282021-06-19 03:50:33 +0000967 u = unix_find_socket_byname(net, sunname, len, type ^ hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968 if (u) {
969 struct dentry *dentry;
Al Viro40ffe672012-03-14 21:54:32 -0400970 dentry = unix_sk(u)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 if (dentry)
Al Viro68ac1232012-03-15 08:21:57 -0400972 touch_atime(&unix_sk(u)->path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 } else
974 goto fail;
975 }
976 return u;
977
978put_fail:
Al Viro421748e2008-08-02 01:04:36 -0400979 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980fail:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700981 *error = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 return NULL;
983}
984
Al Viro71e6be62021-06-19 03:50:30 +0000985static int unix_bind_bsd(struct sock *sk, struct unix_address *addr)
Al Virofaf02012012-07-20 02:37:29 +0400986{
Al Viro71e6be62021-06-19 03:50:30 +0000987 struct unix_sock *u = unix_sk(sk);
988 umode_t mode = S_IFSOCK |
989 (SOCK_INODE(sk->sk_socket)->i_mode & ~current_umask());
Al Viro71e6be62021-06-19 03:50:30 +0000990 struct user_namespace *ns; // barf...
Al Viro56c17312021-06-19 03:50:31 +0000991 struct path parent;
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700992 struct dentry *dentry;
Al Viro71e6be62021-06-19 03:50:30 +0000993 unsigned int hash;
994 int err;
995
Linus Torvalds38f7bd942016-09-01 14:56:49 -0700996 /*
997 * Get the parent directory, calculate the hash for last
998 * component.
999 */
Al Viro71e6be62021-06-19 03:50:30 +00001000 dentry = kern_path_create(AT_FDCWD, addr->name->sun_path, &parent, 0);
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001001 if (IS_ERR(dentry))
Al Viro71e6be62021-06-19 03:50:30 +00001002 return PTR_ERR(dentry);
1003 ns = mnt_user_ns(parent.mnt);
Al Virofaf02012012-07-20 02:37:29 +04001004
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001005 /*
1006 * All right, let's create it.
1007 */
Al Viro71e6be62021-06-19 03:50:30 +00001008 err = security_path_mknod(&parent, dentry, mode, 0);
Al Viro56c17312021-06-19 03:50:31 +00001009 if (!err)
Al Viro71e6be62021-06-19 03:50:30 +00001010 err = vfs_mknod(ns, d_inode(parent.dentry), dentry, mode, 0);
Al Viroc0c3b8d2021-06-19 03:50:32 +00001011 if (err)
1012 goto out;
Al Virofa42d912021-06-19 03:50:29 +00001013 err = mutex_lock_interruptible(&u->bindlock);
Al Viroc0c3b8d2021-06-19 03:50:32 +00001014 if (err)
1015 goto out_unlink;
1016 if (u->addr)
1017 goto out_unlock;
Al Virofa42d912021-06-19 03:50:29 +00001018
1019 addr->hash = UNIX_HASH_SIZE;
Al Viro56c17312021-06-19 03:50:31 +00001020 hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
Al Virofa42d912021-06-19 03:50:29 +00001021 spin_lock(&unix_table_lock);
Al Viro56c17312021-06-19 03:50:31 +00001022 u->path.mnt = mntget(parent.mnt);
1023 u->path.dentry = dget(dentry);
Al Virofa42d912021-06-19 03:50:29 +00001024 __unix_set_addr(sk, addr, hash);
1025 spin_unlock(&unix_table_lock);
1026 mutex_unlock(&u->bindlock);
Al Viro56c17312021-06-19 03:50:31 +00001027 done_path_create(&parent, dentry);
Al Virofa42d912021-06-19 03:50:29 +00001028 return 0;
Al Viroc0c3b8d2021-06-19 03:50:32 +00001029
1030out_unlock:
1031 mutex_unlock(&u->bindlock);
1032 err = -EINVAL;
1033out_unlink:
1034 /* failed after successful mknod? unlink what we'd created... */
1035 vfs_unlink(ns, d_inode(parent.dentry), dentry, NULL);
1036out:
1037 done_path_create(&parent, dentry);
1038 return err;
Al Virofa42d912021-06-19 03:50:29 +00001039}
1040
Al Virobe752282021-06-19 03:50:33 +00001041static int unix_bind_abstract(struct sock *sk, struct unix_address *addr)
Al Virofa42d912021-06-19 03:50:29 +00001042{
1043 struct unix_sock *u = unix_sk(sk);
1044 int err;
1045
1046 err = mutex_lock_interruptible(&u->bindlock);
1047 if (err)
1048 return err;
1049
1050 if (u->addr) {
1051 mutex_unlock(&u->bindlock);
1052 return -EINVAL;
1053 }
1054
1055 spin_lock(&unix_table_lock);
1056 if (__unix_find_socket_byname(sock_net(sk), addr->name, addr->len,
Al Virobe752282021-06-19 03:50:33 +00001057 addr->hash)) {
Al Virofa42d912021-06-19 03:50:29 +00001058 spin_unlock(&unix_table_lock);
1059 mutex_unlock(&u->bindlock);
1060 return -EADDRINUSE;
1061 }
1062 __unix_set_addr(sk, addr, addr->hash);
1063 spin_unlock(&unix_table_lock);
1064 mutex_unlock(&u->bindlock);
1065 return 0;
1066}
1067
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1069{
1070 struct sock *sk = sock->sk;
Jianjun Konge27dfce2008-11-01 21:38:31 -07001071 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Al Virodae6ad82011-06-26 11:50:15 -04001072 char *sun_path = sunaddr->sun_path;
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001073 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001074 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 struct unix_address *addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001077 if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
1078 sunaddr->sun_family != AF_UNIX)
Al Virofa42d912021-06-19 03:50:29 +00001079 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080
Al Virofa42d912021-06-19 03:50:29 +00001081 if (addr_len == sizeof(short))
1082 return unix_autobind(sock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083
1084 err = unix_mkname(sunaddr, addr_len, &hash);
1085 if (err < 0)
Al Virofa42d912021-06-19 03:50:29 +00001086 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 addr_len = err;
Al Viroc34d4582021-06-19 03:50:27 +00001088 addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
1089 if (!addr)
Al Virofa42d912021-06-19 03:50:29 +00001090 return -ENOMEM;
Al Viroc34d4582021-06-19 03:50:27 +00001091
1092 memcpy(addr->name, sunaddr, addr_len);
1093 addr->len = addr_len;
1094 addr->hash = hash ^ sk->sk_type;
1095 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
Al Virofa42d912021-06-19 03:50:29 +00001097 if (sun_path[0])
1098 err = unix_bind_bsd(sk, addr);
1099 else
Al Virobe752282021-06-19 03:50:33 +00001100 err = unix_bind_abstract(sk, addr);
Al Virofa42d912021-06-19 03:50:29 +00001101 if (err)
Al Viroc34d4582021-06-19 03:50:27 +00001102 unix_release_addr(addr);
Al Virofa42d912021-06-19 03:50:29 +00001103 return err == -EEXIST ? -EADDRINUSE : err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104}
1105
David S. Miller278a3de2007-05-31 15:19:20 -07001106static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
1107{
1108 if (unlikely(sk1 == sk2) || !sk2) {
1109 unix_state_lock(sk1);
1110 return;
1111 }
1112 if (sk1 < sk2) {
1113 unix_state_lock(sk1);
1114 unix_state_lock_nested(sk2);
1115 } else {
1116 unix_state_lock(sk2);
1117 unix_state_lock_nested(sk1);
1118 }
1119}
1120
1121static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
1122{
1123 if (unlikely(sk1 == sk2) || !sk2) {
1124 unix_state_unlock(sk1);
1125 return;
1126 }
1127 unix_state_unlock(sk1);
1128 unix_state_unlock(sk2);
1129}
1130
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
1132 int alen, int flags)
1133{
1134 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001135 struct net *net = sock_net(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001136 struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 struct sock *other;
Eric Dumazet95c96172012-04-15 05:58:06 +00001138 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 int err;
1140
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001141 err = -EINVAL;
1142 if (alen < offsetofend(struct sockaddr, sa_family))
1143 goto out;
1144
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 if (addr->sa_family != AF_UNSPEC) {
1146 err = unix_mkname(sunaddr, alen, &hash);
1147 if (err < 0)
1148 goto out;
1149 alen = err;
1150
1151 if (test_bit(SOCK_PASSCRED, &sock->flags) &&
1152 !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
1153 goto out;
1154
David S. Miller278a3de2007-05-31 15:19:20 -07001155restart:
Jianjun Konge27dfce2008-11-01 21:38:31 -07001156 other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 if (!other)
1158 goto out;
1159
David S. Miller278a3de2007-05-31 15:19:20 -07001160 unix_state_double_lock(sk, other);
1161
1162 /* Apparently VFS overslept socket death. Retry. */
1163 if (sock_flag(other, SOCK_DEAD)) {
1164 unix_state_double_unlock(sk, other);
1165 sock_put(other);
1166 goto restart;
1167 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
1169 err = -EPERM;
1170 if (!unix_may_send(sk, other))
1171 goto out_unlock;
1172
1173 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1174 if (err)
1175 goto out_unlock;
1176
1177 } else {
1178 /*
1179 * 1003.1g breaking connected state with AF_UNSPEC
1180 */
1181 other = NULL;
David S. Miller278a3de2007-05-31 15:19:20 -07001182 unix_state_double_lock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 }
1184
1185 /*
1186 * If it was connected, reconnect.
1187 */
1188 if (unix_peer(sk)) {
1189 struct sock *old_peer = unix_peer(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001190 unix_peer(sk) = other;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001191 unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
1192
David S. Miller278a3de2007-05-31 15:19:20 -07001193 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194
1195 if (other != old_peer)
1196 unix_dgram_disconnected(sk, old_peer);
1197 sock_put(old_peer);
1198 } else {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001199 unix_peer(sk) = other;
David S. Miller278a3de2007-05-31 15:19:20 -07001200 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 }
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001202 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
1204out_unlock:
David S. Miller278a3de2007-05-31 15:19:20 -07001205 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 sock_put(other);
1207out:
1208 return err;
1209}
1210
1211static long unix_wait_for_peer(struct sock *other, long timeo)
Jules Irenge48851e92020-02-23 23:16:56 +00001212 __releases(&unix_sk(other)->lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213{
1214 struct unix_sock *u = unix_sk(other);
1215 int sched;
1216 DEFINE_WAIT(wait);
1217
1218 prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
1219
1220 sched = !sock_flag(other, SOCK_DEAD) &&
1221 !(other->sk_shutdown & RCV_SHUTDOWN) &&
Rainer Weikusat3c734192008-06-17 22:28:05 -07001222 unix_recvq_full(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223
David S. Miller1c92b4e2007-05-31 13:24:26 -07001224 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225
1226 if (sched)
1227 timeo = schedule_timeout(timeo);
1228
1229 finish_wait(&u->peer_wait, &wait);
1230 return timeo;
1231}
1232
1233static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
1234 int addr_len, int flags)
1235{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001236 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001238 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 struct unix_sock *u = unix_sk(sk), *newu, *otheru;
1240 struct sock *newsk = NULL;
1241 struct sock *other = NULL;
1242 struct sk_buff *skb = NULL;
Eric Dumazet95c96172012-04-15 05:58:06 +00001243 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 int st;
1245 int err;
1246 long timeo;
1247
1248 err = unix_mkname(sunaddr, addr_len, &hash);
1249 if (err < 0)
1250 goto out;
1251 addr_len = err;
1252
Joe Perchesf64f9e72009-11-29 16:55:45 -08001253 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr &&
1254 (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 goto out;
1256
1257 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
1258
1259 /* First of all allocate resources.
1260 If we will make it after state is locked,
1261 we will have to recheck all again in any case.
1262 */
1263
1264 err = -ENOMEM;
1265
1266 /* create new sock for complete connection */
Eric W. Biederman11aa9c22015-05-08 21:09:13 -05001267 newsk = unix_create1(sock_net(sk), NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268 if (newsk == NULL)
1269 goto out;
1270
1271 /* Allocate skb for sending to listening sock */
1272 skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL);
1273 if (skb == NULL)
1274 goto out;
1275
1276restart:
1277 /* Find listening sock. */
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001278 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 if (!other)
1280 goto out;
1281
1282 /* Latch state of peer */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001283 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284
1285 /* Apparently VFS overslept socket death. Retry. */
1286 if (sock_flag(other, SOCK_DEAD)) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001287 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 sock_put(other);
1289 goto restart;
1290 }
1291
1292 err = -ECONNREFUSED;
1293 if (other->sk_state != TCP_LISTEN)
1294 goto out_unlock;
Tomoki Sekiyama77238f22009-10-18 23:17:37 -07001295 if (other->sk_shutdown & RCV_SHUTDOWN)
1296 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297
Rainer Weikusat3c734192008-06-17 22:28:05 -07001298 if (unix_recvq_full(other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 err = -EAGAIN;
1300 if (!timeo)
1301 goto out_unlock;
1302
1303 timeo = unix_wait_for_peer(other, timeo);
1304
1305 err = sock_intr_errno(timeo);
1306 if (signal_pending(current))
1307 goto out;
1308 sock_put(other);
1309 goto restart;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001310 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311
1312 /* Latch our state.
1313
Daniel Balutae5537bf2011-03-14 15:25:33 -07001314 It is tricky place. We need to grab our state lock and cannot
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 drop lock on peer. It is dangerous because deadlock is
1316 possible. Connect to self case and simultaneous
1317 attempt to connect are eliminated by checking socket
1318 state. other is TCP_LISTEN, if sk is TCP_LISTEN we
1319 check this before attempt to grab lock.
1320
1321 Well, and we have to recheck the state after socket locked.
1322 */
1323 st = sk->sk_state;
1324
1325 switch (st) {
1326 case TCP_CLOSE:
1327 /* This is ok... continue with connect */
1328 break;
1329 case TCP_ESTABLISHED:
1330 /* Socket is already connected */
1331 err = -EISCONN;
1332 goto out_unlock;
1333 default:
1334 err = -EINVAL;
1335 goto out_unlock;
1336 }
1337
David S. Miller1c92b4e2007-05-31 13:24:26 -07001338 unix_state_lock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339
1340 if (sk->sk_state != st) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001341 unix_state_unlock(sk);
1342 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 sock_put(other);
1344 goto restart;
1345 }
1346
David S. Miller3610cda2011-01-05 15:38:53 -08001347 err = security_unix_stream_connect(sk, other, newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348 if (err) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001349 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 goto out_unlock;
1351 }
1352
1353 /* The way is open! Fastly set all the necessary fields... */
1354
1355 sock_hold(sk);
1356 unix_peer(newsk) = sk;
1357 newsk->sk_state = TCP_ESTABLISHED;
1358 newsk->sk_type = sk->sk_type;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001359 init_peercred(newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360 newu = unix_sk(newsk);
Eric Dumazeteaefd1102011-02-18 03:26:36 +00001361 RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362 otheru = unix_sk(other);
1363
Al Viroae3b5642019-02-15 20:09:35 +00001364 /* copy address information from listening to new sock
1365 *
1366 * The contents of *(otheru->addr) and otheru->path
1367 * are seen fully set up here, since we have found
1368 * otheru in hash under unix_table_lock. Insertion
1369 * into the hash chain we'd found it in had been done
1370 * in an earlier critical area protected by unix_table_lock,
1371 * the same one where we'd set *(otheru->addr) contents,
1372 * as well as otheru->path and otheru->addr itself.
1373 *
1374 * Using smp_store_release() here to set newu->addr
1375 * is enough to make those stores, as well as stores
1376 * to newu->path visible to anyone who gets newu->addr
1377 * by smp_load_acquire(). IOW, the same warranties
1378 * as for unix_sock instances bound in unix_bind() or
1379 * in unix_autobind().
1380 */
Al Viro40ffe672012-03-14 21:54:32 -04001381 if (otheru->path.dentry) {
1382 path_get(&otheru->path);
1383 newu->path = otheru->path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 }
Al Viroae3b5642019-02-15 20:09:35 +00001385 refcount_inc(&otheru->addr->refcnt);
1386 smp_store_release(&newu->addr, otheru->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387
1388 /* Set credentials */
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001389 copy_peercred(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 sock->state = SS_CONNECTED;
1392 sk->sk_state = TCP_ESTABLISHED;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001393 sock_hold(newsk);
1394
Peter Zijlstra4e857c52014-03-17 18:06:10 +01001395 smp_mb__after_atomic(); /* sock_hold() does an atomic_inc() */
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001396 unix_peer(sk) = newsk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397
David S. Miller1c92b4e2007-05-31 13:24:26 -07001398 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399
gushengxian4e03d072021-06-09 20:09:35 -07001400 /* take ten and send info to listening sock */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 spin_lock(&other->sk_receive_queue.lock);
1402 __skb_queue_tail(&other->sk_receive_queue, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001404 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001405 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 sock_put(other);
1407 return 0;
1408
1409out_unlock:
1410 if (other)
David S. Miller1c92b4e2007-05-31 13:24:26 -07001411 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412
1413out:
Wei Yongjun40d44442009-02-25 00:32:45 +00001414 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 if (newsk)
1416 unix_release_sock(newsk, 0);
1417 if (other)
1418 sock_put(other);
1419 return err;
1420}
1421
1422static int unix_socketpair(struct socket *socka, struct socket *sockb)
1423{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001424 struct sock *ska = socka->sk, *skb = sockb->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425
1426 /* Join our sockets back to back */
1427 sock_hold(ska);
1428 sock_hold(skb);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001429 unix_peer(ska) = skb;
1430 unix_peer(skb) = ska;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001431 init_peercred(ska);
1432 init_peercred(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433
1434 if (ska->sk_type != SOCK_DGRAM) {
1435 ska->sk_state = TCP_ESTABLISHED;
1436 skb->sk_state = TCP_ESTABLISHED;
1437 socka->state = SS_CONNECTED;
1438 sockb->state = SS_CONNECTED;
1439 }
1440 return 0;
1441}
1442
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001443static void unix_sock_inherit_flags(const struct socket *old,
1444 struct socket *new)
1445{
1446 if (test_bit(SOCK_PASSCRED, &old->flags))
1447 set_bit(SOCK_PASSCRED, &new->flags);
1448 if (test_bit(SOCK_PASSSEC, &old->flags))
1449 set_bit(SOCK_PASSSEC, &new->flags);
1450}
1451
David Howellscdfbabf2017-03-09 08:09:05 +00001452static int unix_accept(struct socket *sock, struct socket *newsock, int flags,
1453 bool kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454{
1455 struct sock *sk = sock->sk;
1456 struct sock *tsk;
1457 struct sk_buff *skb;
1458 int err;
1459
1460 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001461 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 goto out;
1463
1464 err = -EINVAL;
1465 if (sk->sk_state != TCP_LISTEN)
1466 goto out;
1467
1468 /* If socket state is TCP_LISTEN it cannot change (for now...),
1469 * so that no locks are necessary.
1470 */
1471
1472 skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
1473 if (!skb) {
1474 /* This means receive shutdown. */
1475 if (err == 0)
1476 err = -EINVAL;
1477 goto out;
1478 }
1479
1480 tsk = skb->sk;
1481 skb_free_datagram(sk, skb);
1482 wake_up_interruptible(&unix_sk(sk)->peer_wait);
1483
1484 /* attach accepted sock to socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001485 unix_state_lock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 newsock->state = SS_CONNECTED;
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001487 unix_sock_inherit_flags(sock, newsock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 sock_graft(tsk, newsock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001489 unix_state_unlock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 return 0;
1491
1492out:
1493 return err;
1494}
1495
1496
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001497static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498{
1499 struct sock *sk = sock->sk;
Al Viroae3b5642019-02-15 20:09:35 +00001500 struct unix_address *addr;
Cyrill Gorcunov13cfa972009-11-08 05:51:19 +00001501 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 int err = 0;
1503
1504 if (peer) {
1505 sk = unix_peer_get(sk);
1506
1507 err = -ENOTCONN;
1508 if (!sk)
1509 goto out;
1510 err = 0;
1511 } else {
1512 sock_hold(sk);
1513 }
1514
Al Viroae3b5642019-02-15 20:09:35 +00001515 addr = smp_load_acquire(&unix_sk(sk)->addr);
1516 if (!addr) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 sunaddr->sun_family = AF_UNIX;
1518 sunaddr->sun_path[0] = 0;
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001519 err = sizeof(short);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 } else {
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001521 err = addr->len;
1522 memcpy(sunaddr, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 sock_put(sk);
1525out:
1526 return err;
1527}
1528
David S. Millerf78a5fd2011-09-16 19:34:00 -04001529static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001530{
1531 int err = 0;
Eric Dumazet16e57262011-09-19 05:52:27 +00001532
David S. Millerf78a5fd2011-09-16 19:34:00 -04001533 UNIXCB(skb).pid = get_pid(scm->pid);
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001534 UNIXCB(skb).uid = scm->creds.uid;
1535 UNIXCB(skb).gid = scm->creds.gid;
Eric W. Biederman7361c362010-06-13 03:34:33 +00001536 UNIXCB(skb).fp = NULL;
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04001537 unix_get_secdata(scm, skb);
Eric W. Biederman7361c362010-06-13 03:34:33 +00001538 if (scm->fp && send_fds)
1539 err = unix_attach_fds(scm, skb);
1540
1541 skb->destructor = unix_destruct_scm;
1542 return err;
1543}
1544
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001545static bool unix_passcred_enabled(const struct socket *sock,
1546 const struct sock *other)
1547{
1548 return test_bit(SOCK_PASSCRED, &sock->flags) ||
1549 !other->sk_socket ||
1550 test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
1551}
1552
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553/*
Eric Dumazet16e57262011-09-19 05:52:27 +00001554 * Some apps rely on write() giving SCM_CREDENTIALS
1555 * We include credentials if source or destination socket
1556 * asserted SOCK_PASSCRED.
1557 */
1558static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1559 const struct sock *other)
1560{
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001561 if (UNIXCB(skb).pid)
Eric Dumazet16e57262011-09-19 05:52:27 +00001562 return;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001563 if (unix_passcred_enabled(sock, other)) {
Eric Dumazet16e57262011-09-19 05:52:27 +00001564 UNIXCB(skb).pid = get_pid(task_tgid(current));
David S. Miller6e0895c2013-04-22 20:32:51 -04001565 current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
Eric Dumazet16e57262011-09-19 05:52:27 +00001566 }
1567}
1568
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001569static int maybe_init_creds(struct scm_cookie *scm,
1570 struct socket *socket,
1571 const struct sock *other)
1572{
1573 int err;
1574 struct msghdr msg = { .msg_controllen = 0 };
1575
1576 err = scm_send(socket, &msg, scm, false);
1577 if (err)
1578 return err;
1579
1580 if (unix_passcred_enabled(socket, other)) {
1581 scm->pid = get_pid(task_tgid(current));
1582 current_uid_gid(&scm->creds.uid, &scm->creds.gid);
1583 }
1584 return err;
1585}
1586
1587static bool unix_skb_scm_eq(struct sk_buff *skb,
1588 struct scm_cookie *scm)
1589{
1590 const struct unix_skb_parms *u = &UNIXCB(skb);
1591
1592 return u->pid == scm->pid &&
1593 uid_eq(u->uid, scm->creds.uid) &&
1594 gid_eq(u->gid, scm->creds.gid) &&
1595 unix_secdata_eq(scm, skb);
1596}
1597
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001598static void scm_stat_add(struct sock *sk, struct sk_buff *skb)
1599{
1600 struct scm_fp_list *fp = UNIXCB(skb).fp;
1601 struct unix_sock *u = unix_sk(sk);
1602
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001603 if (unlikely(fp && fp->count))
Paolo Abeni77820402020-02-28 14:45:21 +01001604 atomic_add(fp->count, &u->scm_stat.nr_fds);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001605}
1606
1607static void scm_stat_del(struct sock *sk, struct sk_buff *skb)
1608{
1609 struct scm_fp_list *fp = UNIXCB(skb).fp;
1610 struct unix_sock *u = unix_sk(sk);
1611
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001612 if (unlikely(fp && fp->count))
Paolo Abeni77820402020-02-28 14:45:21 +01001613 atomic_sub(fp->count, &u->scm_stat.nr_fds);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001614}
1615
Eric Dumazet16e57262011-09-19 05:52:27 +00001616/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 * Send AF_UNIX data.
1618 */
1619
Ying Xue1b784142015-03-02 15:37:48 +08001620static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
1621 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001624 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 struct unix_sock *u = unix_sk(sk);
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001626 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 struct sock *other = NULL;
1628 int namelen = 0; /* fake GCC */
1629 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001630 unsigned int hash;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001631 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 long timeo;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001633 struct scm_cookie scm;
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001634 int data_len = 0;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001635 int sk_locked;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636
dann frazier5f23b732008-11-26 15:32:27 -08001637 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001638 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 if (err < 0)
1640 return err;
1641
1642 err = -EOPNOTSUPP;
1643 if (msg->msg_flags&MSG_OOB)
1644 goto out;
1645
1646 if (msg->msg_namelen) {
1647 err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
1648 if (err < 0)
1649 goto out;
1650 namelen = err;
1651 } else {
1652 sunaddr = NULL;
1653 err = -ENOTCONN;
1654 other = unix_peer_get(sk);
1655 if (!other)
1656 goto out;
1657 }
1658
Joe Perchesf64f9e72009-11-29 16:55:45 -08001659 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr
1660 && (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 goto out;
1662
1663 err = -EMSGSIZE;
1664 if (len > sk->sk_sndbuf - 32)
1665 goto out;
1666
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001667 if (len > SKB_MAX_ALLOC) {
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001668 data_len = min_t(size_t,
1669 len - SKB_MAX_ALLOC,
1670 MAX_SKB_FRAGS * PAGE_SIZE);
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001671 data_len = PAGE_ALIGN(data_len);
1672
1673 BUILD_BUG_ON(SKB_MAX_ALLOC < PAGE_SIZE);
1674 }
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001675
1676 skb = sock_alloc_send_pskb(sk, len - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07001677 msg->msg_flags & MSG_DONTWAIT, &err,
1678 PAGE_ALLOC_COSTLY_ORDER);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001679 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 goto out;
1681
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001682 err = unix_scm_to_skb(&scm, skb, true);
Eric Dumazet25888e32010-11-25 04:11:39 +00001683 if (err < 0)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001684 goto out_free;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001685
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001686 skb_put(skb, len - data_len);
1687 skb->data_len = data_len;
1688 skb->len = len;
Al Viroc0371da2014-11-24 10:42:55 -05001689 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 if (err)
1691 goto out_free;
1692
1693 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1694
1695restart:
1696 if (!other) {
1697 err = -ECONNRESET;
1698 if (sunaddr == NULL)
1699 goto out_free;
1700
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001701 other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 hash, &err);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001703 if (other == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 goto out_free;
1705 }
1706
Alban Crequyd6ae3ba2011-01-18 06:39:15 +00001707 if (sk_filter(other, skb) < 0) {
1708 /* Toss the packet but do not return any error to the sender */
1709 err = len;
1710 goto out_free;
1711 }
1712
Rainer Weikusat7d267272015-11-20 22:07:23 +00001713 sk_locked = 0;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001714 unix_state_lock(other);
Rainer Weikusat7d267272015-11-20 22:07:23 +00001715restart_locked:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 err = -EPERM;
1717 if (!unix_may_send(sk, other))
1718 goto out_unlock;
1719
Rainer Weikusat7d267272015-11-20 22:07:23 +00001720 if (unlikely(sock_flag(other, SOCK_DEAD))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 /*
1722 * Check with 1003.1g - what should
1723 * datagram error
1724 */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001725 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 sock_put(other);
1727
Rainer Weikusat7d267272015-11-20 22:07:23 +00001728 if (!sk_locked)
1729 unix_state_lock(sk);
1730
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 if (unix_peer(sk) == other) {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001733 unix_peer(sk) = NULL;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001734 unix_dgram_peer_wake_disconnect_wakeup(sk, other);
1735
David S. Miller1c92b4e2007-05-31 13:24:26 -07001736 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
1738 unix_dgram_disconnected(sk, other);
1739 sock_put(other);
1740 err = -ECONNREFUSED;
1741 } else {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001742 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 }
1744
1745 other = NULL;
1746 if (err)
1747 goto out_free;
1748 goto restart;
1749 }
1750
1751 err = -EPIPE;
1752 if (other->sk_shutdown & RCV_SHUTDOWN)
1753 goto out_unlock;
1754
1755 if (sk->sk_type != SOCK_SEQPACKET) {
1756 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1757 if (err)
1758 goto out_unlock;
1759 }
1760
Rainer Weikusata5527dd2016-02-11 19:37:27 +00001761 /* other == sk && unix_peer(other) != sk if
1762 * - unix_peer(sk) == NULL, destination address bound to sk
1763 * - unix_peer(sk) == sk by time of get but disconnected before lock
1764 */
1765 if (other != sk &&
Qian Cai86b18aa2020-02-04 13:40:29 -05001766 unlikely(unix_peer(other) != sk &&
1767 unix_recvq_full_lockless(other))) {
Rainer Weikusat7d267272015-11-20 22:07:23 +00001768 if (timeo) {
1769 timeo = unix_wait_for_peer(other, timeo);
1770
1771 err = sock_intr_errno(timeo);
1772 if (signal_pending(current))
1773 goto out_free;
1774
1775 goto restart;
1776 }
1777
1778 if (!sk_locked) {
1779 unix_state_unlock(other);
1780 unix_state_double_lock(sk, other);
1781 }
1782
1783 if (unix_peer(sk) != other ||
1784 unix_dgram_peer_wake_me(sk, other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 err = -EAGAIN;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001786 sk_locked = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 goto out_unlock;
1788 }
1789
Rainer Weikusat7d267272015-11-20 22:07:23 +00001790 if (!sk_locked) {
1791 sk_locked = 1;
1792 goto restart_locked;
1793 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 }
1795
Rainer Weikusat7d267272015-11-20 22:07:23 +00001796 if (unlikely(sk_locked))
1797 unix_state_unlock(sk);
1798
Alban Crequy3f661162010-10-04 08:48:28 +00001799 if (sock_flag(other, SOCK_RCVTSTAMP))
1800 __net_timestamp(skb);
Eric Dumazet16e57262011-09-19 05:52:27 +00001801 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001802 scm_stat_add(other, skb);
Paolo Abeni77820402020-02-28 14:45:21 +01001803 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001804 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001805 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001807 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 return len;
1809
1810out_unlock:
Rainer Weikusat7d267272015-11-20 22:07:23 +00001811 if (sk_locked)
1812 unix_state_unlock(sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001813 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814out_free:
1815 kfree_skb(skb);
1816out:
1817 if (other)
1818 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001819 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 return err;
1821}
1822
Eric Dumazete370a722013-08-08 14:37:32 -07001823/* We use paged skbs for stream sockets, and limit occupancy to 32768
Tobias Klauserd4e9a402018-02-13 11:11:30 +01001824 * bytes, and a minimum of a full page.
Eric Dumazete370a722013-08-08 14:37:32 -07001825 */
1826#define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001827
Ying Xue1b784142015-03-02 15:37:48 +08001828static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1829 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 struct sock *sk = sock->sk;
1832 struct sock *other = NULL;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001833 int err, size;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001834 struct sk_buff *skb;
Jianjun Konge27dfce2008-11-01 21:38:31 -07001835 int sent = 0;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001836 struct scm_cookie scm;
Miklos Szeredi8ba69ba2009-09-11 11:31:45 -07001837 bool fds_sent = false;
Eric Dumazete370a722013-08-08 14:37:32 -07001838 int data_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839
dann frazier5f23b732008-11-26 15:32:27 -08001840 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001841 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 if (err < 0)
1843 return err;
1844
1845 err = -EOPNOTSUPP;
1846 if (msg->msg_flags&MSG_OOB)
1847 goto out_err;
1848
1849 if (msg->msg_namelen) {
1850 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
1851 goto out_err;
1852 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 err = -ENOTCONN;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001854 other = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 if (!other)
1856 goto out_err;
1857 }
1858
1859 if (sk->sk_shutdown & SEND_SHUTDOWN)
1860 goto pipe_err;
1861
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001862 while (sent < len) {
Eric Dumazete370a722013-08-08 14:37:32 -07001863 size = len - sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864
1865 /* Keep two messages in the pipe so it schedules better */
Eric Dumazete370a722013-08-08 14:37:32 -07001866 size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
Eric Dumazete370a722013-08-08 14:37:32 -07001868 /* allow fallback to order-0 allocations */
1869 size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001870
Eric Dumazete370a722013-08-08 14:37:32 -07001871 data_len = max_t(int, 0, size - SKB_MAX_HEAD(0));
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001872
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001873 data_len = min_t(size_t, size, PAGE_ALIGN(data_len));
1874
Eric Dumazete370a722013-08-08 14:37:32 -07001875 skb = sock_alloc_send_pskb(sk, size - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07001876 msg->msg_flags & MSG_DONTWAIT, &err,
1877 get_order(UNIX_SKB_FRAGS_SZ));
Eric Dumazete370a722013-08-08 14:37:32 -07001878 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 goto out_err;
1880
David S. Millerf78a5fd2011-09-16 19:34:00 -04001881 /* Only send the fds in the first buffer */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001882 err = unix_scm_to_skb(&scm, skb, !fds_sent);
Eric Dumazet25888e32010-11-25 04:11:39 +00001883 if (err < 0) {
Eric W. Biederman7361c362010-06-13 03:34:33 +00001884 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001885 goto out_err;
Miklos Szeredi62093442008-11-09 15:23:57 +01001886 }
Eric W. Biederman7361c362010-06-13 03:34:33 +00001887 fds_sent = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888
Eric Dumazete370a722013-08-08 14:37:32 -07001889 skb_put(skb, size - data_len);
1890 skb->data_len = data_len;
1891 skb->len = size;
Al Viroc0371da2014-11-24 10:42:55 -05001892 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001893 if (err) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04001895 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 }
1897
David S. Miller1c92b4e2007-05-31 13:24:26 -07001898 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899
1900 if (sock_flag(other, SOCK_DEAD) ||
1901 (other->sk_shutdown & RCV_SHUTDOWN))
1902 goto pipe_err_free;
1903
Eric Dumazet16e57262011-09-19 05:52:27 +00001904 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001905 scm_stat_add(other, skb);
Paolo Abeni77820402020-02-28 14:45:21 +01001906 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001907 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001908 other->sk_data_ready(other);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001909 sent += size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001912 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913
1914 return sent;
1915
1916pipe_err_free:
David S. Miller1c92b4e2007-05-31 13:24:26 -07001917 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 kfree_skb(skb);
1919pipe_err:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001920 if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
1921 send_sig(SIGPIPE, current, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 err = -EPIPE;
1923out_err:
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001924 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 return sent ? : err;
1926}
1927
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001928static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
1929 int offset, size_t size, int flags)
1930{
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001931 int err;
1932 bool send_sigpipe = false;
1933 bool init_scm = true;
1934 struct scm_cookie scm;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001935 struct sock *other, *sk = socket->sk;
1936 struct sk_buff *skb, *newskb = NULL, *tail = NULL;
1937
1938 if (flags & MSG_OOB)
1939 return -EOPNOTSUPP;
1940
1941 other = unix_peer(sk);
1942 if (!other || sk->sk_state != TCP_ESTABLISHED)
1943 return -ENOTCONN;
1944
1945 if (false) {
1946alloc_skb:
1947 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001948 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001949 newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
1950 &err, 0);
1951 if (!newskb)
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001952 goto err;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001953 }
1954
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001955 /* we must acquire iolock as we modify already present
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001956 * skbs in the sk_receive_queue and mess with skb->len
1957 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001958 err = mutex_lock_interruptible(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001959 if (err) {
1960 err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001961 goto err;
1962 }
1963
1964 if (sk->sk_shutdown & SEND_SHUTDOWN) {
1965 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001966 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001967 goto err_unlock;
1968 }
1969
1970 unix_state_lock(other);
1971
1972 if (sock_flag(other, SOCK_DEAD) ||
1973 other->sk_shutdown & RCV_SHUTDOWN) {
1974 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001975 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001976 goto err_state_unlock;
1977 }
1978
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001979 if (init_scm) {
1980 err = maybe_init_creds(&scm, socket, other);
1981 if (err)
1982 goto err_state_unlock;
1983 init_scm = false;
1984 }
1985
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001986 skb = skb_peek_tail(&other->sk_receive_queue);
1987 if (tail && tail == skb) {
1988 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001989 } else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
1990 if (newskb) {
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001991 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001992 } else {
1993 tail = skb;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001994 goto alloc_skb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001995 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02001996 } else if (newskb) {
1997 /* this is fast path, we don't necessarily need to
1998 * call to kfree_skb even though with newskb == NULL
1999 * this - does no harm
2000 */
2001 consume_skb(newskb);
Hannes Frederic Sowa8844f972015-11-16 16:25:56 +01002002 newskb = NULL;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002003 }
2004
2005 if (skb_append_pagefrags(skb, page, offset, size)) {
2006 tail = skb;
2007 goto alloc_skb;
2008 }
2009
2010 skb->len += size;
2011 skb->data_len += size;
2012 skb->truesize += size;
Reshetova, Elena14afee42017-06-30 13:08:00 +03002013 refcount_add(size, &sk->sk_wmem_alloc);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002014
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002015 if (newskb) {
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002016 err = unix_scm_to_skb(&scm, skb, false);
2017 if (err)
2018 goto err_state_unlock;
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002019 spin_lock(&other->sk_receive_queue.lock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002020 __skb_queue_tail(&other->sk_receive_queue, newskb);
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002021 spin_unlock(&other->sk_receive_queue.lock);
2022 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002023
2024 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002025 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002026
2027 other->sk_data_ready(other);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002028 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002029 return size;
2030
2031err_state_unlock:
2032 unix_state_unlock(other);
2033err_unlock:
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002034 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002035err:
2036 kfree_skb(newskb);
2037 if (send_sigpipe && !(flags & MSG_NOSIGNAL))
2038 send_sig(SIGPIPE, current, 0);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002039 if (!init_scm)
2040 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002041 return err;
2042}
2043
Ying Xue1b784142015-03-02 15:37:48 +08002044static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg,
2045 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046{
2047 int err;
2048 struct sock *sk = sock->sk;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002049
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 err = sock_error(sk);
2051 if (err)
2052 return err;
2053
2054 if (sk->sk_state != TCP_ESTABLISHED)
2055 return -ENOTCONN;
2056
2057 if (msg->msg_namelen)
2058 msg->msg_namelen = 0;
2059
Ying Xue1b784142015-03-02 15:37:48 +08002060 return unix_dgram_sendmsg(sock, msg, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061}
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002062
Ying Xue1b784142015-03-02 15:37:48 +08002063static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg,
2064 size_t size, int flags)
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002065{
2066 struct sock *sk = sock->sk;
2067
2068 if (sk->sk_state != TCP_ESTABLISHED)
2069 return -ENOTCONN;
2070
Ying Xue1b784142015-03-02 15:37:48 +08002071 return unix_dgram_recvmsg(sock, msg, size, flags);
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002072}
2073
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
2075{
Al Viroae3b5642019-02-15 20:09:35 +00002076 struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077
Al Viroae3b5642019-02-15 20:09:35 +00002078 if (addr) {
2079 msg->msg_namelen = addr->len;
2080 memcpy(msg->msg_name, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081 }
2082}
2083
Ying Xue1b784142015-03-02 15:37:48 +08002084static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
2085 size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002087 struct scm_cookie scm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088 struct sock *sk = sock->sk;
2089 struct unix_sock *u = unix_sk(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002090 struct sk_buff *skb, *last;
2091 long timeo;
Paolo Abenifd69c392019-04-08 10:15:59 +02002092 int skip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093 int err;
2094
2095 err = -EOPNOTSUPP;
2096 if (flags&MSG_OOB)
2097 goto out;
2098
Rainer Weikusat64874282015-12-06 21:11:38 +00002099 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100
Rainer Weikusat64874282015-12-06 21:11:38 +00002101 do {
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002102 mutex_lock(&u->iolock);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002103
Rainer Weikusat64874282015-12-06 21:11:38 +00002104 skip = sk_peek_offset(sk, flags);
Sabrina Dubrocab50b0582019-11-25 14:48:57 +01002105 skb = __skb_try_recv_datagram(sk, &sk->sk_receive_queue, flags,
Paolo Abenie427cad2020-02-28 14:45:22 +01002106 &skip, &err, &last);
2107 if (skb) {
2108 if (!(flags & MSG_PEEK))
2109 scm_stat_del(sk, skb);
Rainer Weikusat64874282015-12-06 21:11:38 +00002110 break;
Paolo Abenie427cad2020-02-28 14:45:22 +01002111 }
Rainer Weikusat64874282015-12-06 21:11:38 +00002112
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002113 mutex_unlock(&u->iolock);
Rainer Weikusat64874282015-12-06 21:11:38 +00002114
2115 if (err != -EAGAIN)
2116 break;
2117 } while (timeo &&
Sabrina Dubrocab50b0582019-11-25 14:48:57 +01002118 !__skb_wait_for_more_packets(sk, &sk->sk_receive_queue,
2119 &err, &timeo, last));
Rainer Weikusat64874282015-12-06 21:11:38 +00002120
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002121 if (!skb) { /* implies iolock unlocked */
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002122 unix_state_lock(sk);
2123 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
2124 if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
2125 (sk->sk_shutdown & RCV_SHUTDOWN))
2126 err = 0;
2127 unix_state_unlock(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002128 goto out;
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002129 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130
Rainer Weikusat77b75f42015-11-26 19:23:15 +00002131 if (wq_has_sleeper(&u->peer_wait))
2132 wake_up_interruptible_sync_poll(&u->peer_wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002133 EPOLLOUT | EPOLLWRNORM |
2134 EPOLLWRBAND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135
2136 if (msg->msg_name)
2137 unix_copy_addr(msg, skb->sk);
2138
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002139 if (size > skb->len - skip)
2140 size = skb->len - skip;
2141 else if (size < skb->len - skip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142 msg->msg_flags |= MSG_TRUNC;
2143
David S. Miller51f3d022014-11-05 16:46:40 -05002144 err = skb_copy_datagram_msg(skb, skip, msg, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 if (err)
2146 goto out_free;
2147
Alban Crequy3f661162010-10-04 08:48:28 +00002148 if (sock_flag(sk, SOCK_RCVTSTAMP))
2149 __sock_recv_timestamp(msg, sk, skb);
2150
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002151 memset(&scm, 0, sizeof(scm));
2152
2153 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
2154 unix_set_secdata(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002156 if (!(flags & MSG_PEEK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002158 unix_detach_fds(&scm, skb);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002159
2160 sk_peek_offset_bwd(sk, skb->len);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002161 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002162 /* It is questionable: on PEEK we could:
2163 - do not return fds - good, but too simple 8)
2164 - return fds, and do not return them on read (old strategy,
2165 apparently wrong)
2166 - clone fds (I chose it for now, it is the most universal
2167 solution)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002168
2169 POSIX 1003.1g does not actually define this clearly
2170 at all. POSIX 1003.1g doesn't define a lot of things
2171 clearly however!
2172
Linus Torvalds1da177e2005-04-16 15:20:36 -07002173 */
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002174
2175 sk_peek_offset_fwd(sk, size);
2176
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002178 scm.fp = scm_fp_dup(UNIXCB(skb).fp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179 }
Eric Dumazet9f6f9af2012-02-21 23:24:55 +00002180 err = (flags & MSG_TRUNC) ? skb->len - skip : size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002182 scm_recv(sock, msg, &scm, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183
2184out_free:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002185 skb_free_datagram(sk, skb);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002186 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187out:
2188 return err;
2189}
2190
2191/*
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002192 * Sleep until more data has arrived. But check for races..
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193 */
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002194static long unix_stream_data_wait(struct sock *sk, long timeo,
WANG Cong06a77b02016-11-17 15:55:26 -08002195 struct sk_buff *last, unsigned int last_len,
2196 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197{
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002198 struct sk_buff *tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 DEFINE_WAIT(wait);
2200
David S. Miller1c92b4e2007-05-31 13:24:26 -07002201 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202
2203 for (;;) {
Eric Dumazetaa395142010-04-20 13:03:51 +00002204 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002206 tail = skb_peek_tail(&sk->sk_receive_queue);
2207 if (tail != last ||
2208 (tail && tail->len != last_len) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 sk->sk_err ||
2210 (sk->sk_shutdown & RCV_SHUTDOWN) ||
2211 signal_pending(current) ||
2212 !timeo)
2213 break;
2214
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002215 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002216 unix_state_unlock(sk);
WANG Cong06a77b02016-11-17 15:55:26 -08002217 if (freezable)
2218 timeo = freezable_schedule_timeout(timeo);
2219 else
2220 timeo = schedule_timeout(timeo);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002221 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002222
2223 if (sock_flag(sk, SOCK_DEAD))
2224 break;
2225
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002226 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 }
2228
Eric Dumazetaa395142010-04-20 13:03:51 +00002229 finish_wait(sk_sleep(sk), &wait);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002230 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 return timeo;
2232}
2233
Eric Dumazete370a722013-08-08 14:37:32 -07002234static unsigned int unix_skb_len(const struct sk_buff *skb)
2235{
2236 return skb->len - UNIXCB(skb).consumed;
2237}
2238
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002239struct unix_stream_read_state {
2240 int (*recv_actor)(struct sk_buff *, int, int,
2241 struct unix_stream_read_state *);
2242 struct socket *socket;
2243 struct msghdr *msg;
2244 struct pipe_inode_info *pipe;
2245 size_t size;
2246 int flags;
2247 unsigned int splice_flags;
2248};
2249
WANG Cong06a77b02016-11-17 15:55:26 -08002250static int unix_stream_read_generic(struct unix_stream_read_state *state,
2251 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002253 struct scm_cookie scm;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002254 struct socket *sock = state->socket;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 struct sock *sk = sock->sk;
2256 struct unix_sock *u = unix_sk(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 int copied = 0;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002258 int flags = state->flags;
Eric Dumazetde144392014-03-25 18:42:27 -07002259 int noblock = flags & MSG_DONTWAIT;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002260 bool check_creds = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 int target;
2262 int err = 0;
2263 long timeo;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002264 int skip;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002265 size_t size = state->size;
2266 unsigned int last_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002268 if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
2269 err = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002271 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002273 if (unlikely(flags & MSG_OOB)) {
2274 err = -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002275 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002276 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002278 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
Eric Dumazetde144392014-03-25 18:42:27 -07002279 timeo = sock_rcvtimeo(sk, noblock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002281 memset(&scm, 0, sizeof(scm));
2282
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283 /* Lock the socket to prevent queue disordering
2284 * while sleeps in memcpy_tomsg
2285 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002286 mutex_lock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287
Matthew Dawsona0917e02017-08-18 15:04:54 -04002288 skip = max(sk_peek_offset(sk, flags), 0);
Andrey Vagine9193d62015-10-02 00:05:36 +03002289
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002290 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291 int chunk;
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002292 bool drop_skb;
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002293 struct sk_buff *skb, *last;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002295redo:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002296 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002297 if (sock_flag(sk, SOCK_DEAD)) {
2298 err = -ECONNRESET;
2299 goto unlock;
2300 }
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002301 last = skb = skb_peek(&sk->sk_receive_queue);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002302 last_len = last ? last->len : 0;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002303again:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002304 if (skb == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305 if (copied >= target)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002306 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307
2308 /*
2309 * POSIX 1003.1g mandates this order.
2310 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002311
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002312 err = sock_error(sk);
2313 if (err)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002314 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 if (sk->sk_shutdown & RCV_SHUTDOWN)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002316 goto unlock;
2317
2318 unix_state_unlock(sk);
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002319 if (!timeo) {
2320 err = -EAGAIN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321 break;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002322 }
2323
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002324 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002326 timeo = unix_stream_data_wait(sk, timeo, last,
WANG Cong06a77b02016-11-17 15:55:26 -08002327 last_len, freezable);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328
Rainer Weikusat3822b5c2015-12-16 20:09:25 +00002329 if (signal_pending(current)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002330 err = sock_intr_errno(timeo);
Eric Dumazetfa0dc042016-01-24 13:53:50 -08002331 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332 goto out;
2333 }
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00002334
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002335 mutex_lock(&u->iolock);
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002336 goto redo;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002337unlock:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002338 unix_state_unlock(sk);
2339 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340 }
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002341
Eric Dumazete370a722013-08-08 14:37:32 -07002342 while (skip >= unix_skb_len(skb)) {
2343 skip -= unix_skb_len(skb);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002344 last = skb;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002345 last_len = skb->len;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002346 skb = skb_peek_next(skb, &sk->sk_receive_queue);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002347 if (!skb)
2348 goto again;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002349 }
2350
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002351 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352
2353 if (check_creds) {
2354 /* Never glue messages from different writers */
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002355 if (!unix_skb_scm_eq(skb, &scm))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002356 break;
Eric W. Biederman0e82e7f6d2013-04-03 16:14:47 +00002357 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358 /* Copy credentials */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002359 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04002360 unix_set_secdata(&scm, skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002361 check_creds = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362 }
2363
2364 /* Copy address just once */
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002365 if (state->msg && state->msg->msg_name) {
2366 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr,
2367 state->msg->msg_name);
2368 unix_copy_addr(state->msg, skb->sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002369 sunaddr = NULL;
2370 }
2371
Eric Dumazete370a722013-08-08 14:37:32 -07002372 chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002373 skb_get(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002374 chunk = state->recv_actor(skb, skip, chunk, state);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002375 drop_skb = !unix_skb_len(skb);
2376 /* skb is only safe to use if !drop_skb */
2377 consume_skb(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002378 if (chunk < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 if (copied == 0)
2380 copied = -EFAULT;
2381 break;
2382 }
2383 copied += chunk;
2384 size -= chunk;
2385
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002386 if (drop_skb) {
2387 /* the skb was touched by a concurrent reader;
2388 * we should not expect anything from this skb
2389 * anymore and assume it invalid - we can be
2390 * sure it was dropped from the socket queue
2391 *
2392 * let's report a short read
2393 */
2394 err = 0;
2395 break;
2396 }
2397
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398 /* Mark read part of skb as used */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002399 if (!(flags & MSG_PEEK)) {
Eric Dumazete370a722013-08-08 14:37:32 -07002400 UNIXCB(skb).consumed += chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002402 sk_peek_offset_bwd(sk, chunk);
2403
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002404 if (UNIXCB(skb).fp) {
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002405 scm_stat_del(sk, skb);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002406 unix_detach_fds(&scm, skb);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002407 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408
Eric Dumazete370a722013-08-08 14:37:32 -07002409 if (unix_skb_len(skb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411
Eric Dumazet6f01fd62012-01-28 16:11:03 +00002412 skb_unlink(skb, &sk->sk_receive_queue);
Neil Horman70d4bf62010-07-20 06:45:56 +00002413 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002415 if (scm.fp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002417 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418 /* It is questionable, see note in unix_dgram_recvmsg.
2419 */
2420 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002421 scm.fp = scm_fp_dup(UNIXCB(skb).fp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422
Andrey Vagine9193d62015-10-02 00:05:36 +03002423 sk_peek_offset_fwd(sk, chunk);
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002424
Aaron Conole9f389e32015-09-26 18:50:43 -04002425 if (UNIXCB(skb).fp)
2426 break;
2427
Andrey Vagine9193d62015-10-02 00:05:36 +03002428 skip = 0;
Aaron Conole9f389e32015-09-26 18:50:43 -04002429 last = skb;
2430 last_len = skb->len;
2431 unix_state_lock(sk);
2432 skb = skb_peek_next(skb, &sk->sk_receive_queue);
2433 if (skb)
2434 goto again;
2435 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436 break;
2437 }
2438 } while (size);
2439
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002440 mutex_unlock(&u->iolock);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002441 if (state->msg)
2442 scm_recv(sock, state->msg, &scm, flags);
2443 else
2444 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445out:
2446 return copied ? : err;
2447}
2448
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002449static int unix_stream_read_actor(struct sk_buff *skb,
2450 int skip, int chunk,
2451 struct unix_stream_read_state *state)
2452{
2453 int ret;
2454
2455 ret = skb_copy_datagram_msg(skb, UNIXCB(skb).consumed + skip,
2456 state->msg, chunk);
2457 return ret ?: chunk;
2458}
2459
2460static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
2461 size_t size, int flags)
2462{
2463 struct unix_stream_read_state state = {
2464 .recv_actor = unix_stream_read_actor,
2465 .socket = sock,
2466 .msg = msg,
2467 .size = size,
2468 .flags = flags
2469 };
2470
WANG Cong06a77b02016-11-17 15:55:26 -08002471 return unix_stream_read_generic(&state, true);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002472}
2473
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002474static int unix_stream_splice_actor(struct sk_buff *skb,
2475 int skip, int chunk,
2476 struct unix_stream_read_state *state)
2477{
2478 return skb_splice_bits(skb, state->socket->sk,
2479 UNIXCB(skb).consumed + skip,
Al Viro25869262016-09-17 21:02:10 -04002480 state->pipe, chunk, state->splice_flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002481}
2482
2483static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos,
2484 struct pipe_inode_info *pipe,
2485 size_t size, unsigned int flags)
2486{
2487 struct unix_stream_read_state state = {
2488 .recv_actor = unix_stream_splice_actor,
2489 .socket = sock,
2490 .pipe = pipe,
2491 .size = size,
2492 .splice_flags = flags,
2493 };
2494
2495 if (unlikely(*ppos))
2496 return -ESPIPE;
2497
2498 if (sock->file->f_flags & O_NONBLOCK ||
2499 flags & SPLICE_F_NONBLOCK)
2500 state.flags = MSG_DONTWAIT;
2501
WANG Cong06a77b02016-11-17 15:55:26 -08002502 return unix_stream_read_generic(&state, false);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002503}
2504
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505static int unix_shutdown(struct socket *sock, int mode)
2506{
2507 struct sock *sk = sock->sk;
2508 struct sock *other;
2509
Xi Wangfc61b922012-08-26 16:47:13 +00002510 if (mode < SHUT_RD || mode > SHUT_RDWR)
2511 return -EINVAL;
2512 /* This maps:
2513 * SHUT_RD (0) -> RCV_SHUTDOWN (1)
2514 * SHUT_WR (1) -> SEND_SHUTDOWN (2)
2515 * SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
2516 */
2517 ++mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518
Alban Crequy7180a032011-01-19 04:56:36 +00002519 unix_state_lock(sk);
2520 sk->sk_shutdown |= mode;
2521 other = unix_peer(sk);
2522 if (other)
2523 sock_hold(other);
2524 unix_state_unlock(sk);
2525 sk->sk_state_change(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526
Alban Crequy7180a032011-01-19 04:56:36 +00002527 if (other &&
2528 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529
Alban Crequy7180a032011-01-19 04:56:36 +00002530 int peer_mode = 0;
2531
2532 if (mode&RCV_SHUTDOWN)
2533 peer_mode |= SEND_SHUTDOWN;
2534 if (mode&SEND_SHUTDOWN)
2535 peer_mode |= RCV_SHUTDOWN;
2536 unix_state_lock(other);
2537 other->sk_shutdown |= peer_mode;
2538 unix_state_unlock(other);
2539 other->sk_state_change(other);
2540 if (peer_mode == SHUTDOWN_MASK)
2541 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
2542 else if (peer_mode & RCV_SHUTDOWN)
2543 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 }
Alban Crequy7180a032011-01-19 04:56:36 +00002545 if (other)
2546 sock_put(other);
2547
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548 return 0;
2549}
2550
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002551long unix_inq_len(struct sock *sk)
2552{
2553 struct sk_buff *skb;
2554 long amount = 0;
2555
2556 if (sk->sk_state == TCP_LISTEN)
2557 return -EINVAL;
2558
2559 spin_lock(&sk->sk_receive_queue.lock);
2560 if (sk->sk_type == SOCK_STREAM ||
2561 sk->sk_type == SOCK_SEQPACKET) {
2562 skb_queue_walk(&sk->sk_receive_queue, skb)
Eric Dumazete370a722013-08-08 14:37:32 -07002563 amount += unix_skb_len(skb);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002564 } else {
2565 skb = skb_peek(&sk->sk_receive_queue);
2566 if (skb)
2567 amount = skb->len;
2568 }
2569 spin_unlock(&sk->sk_receive_queue.lock);
2570
2571 return amount;
2572}
2573EXPORT_SYMBOL_GPL(unix_inq_len);
2574
2575long unix_outq_len(struct sock *sk)
2576{
2577 return sk_wmem_alloc_get(sk);
2578}
2579EXPORT_SYMBOL_GPL(unix_outq_len);
2580
Andrey Vaginba94f302017-02-01 11:00:45 -08002581static int unix_open_file(struct sock *sk)
2582{
2583 struct path path;
2584 struct file *f;
2585 int fd;
2586
2587 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
2588 return -EPERM;
2589
Al Viroae3b5642019-02-15 20:09:35 +00002590 if (!smp_load_acquire(&unix_sk(sk)->addr))
Andrey Vaginba94f302017-02-01 11:00:45 -08002591 return -ENOENT;
Al Viroae3b5642019-02-15 20:09:35 +00002592
2593 path = unix_sk(sk)->path;
2594 if (!path.dentry)
2595 return -ENOENT;
Andrey Vaginba94f302017-02-01 11:00:45 -08002596
2597 path_get(&path);
Andrey Vaginba94f302017-02-01 11:00:45 -08002598
2599 fd = get_unused_fd_flags(O_CLOEXEC);
2600 if (fd < 0)
2601 goto out;
2602
2603 f = dentry_open(&path, O_PATH, current_cred());
2604 if (IS_ERR(f)) {
2605 put_unused_fd(fd);
2606 fd = PTR_ERR(f);
2607 goto out;
2608 }
2609
2610 fd_install(fd, f);
2611out:
2612 path_put(&path);
2613
2614 return fd;
2615}
2616
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2618{
2619 struct sock *sk = sock->sk;
Jianjun Konge27dfce2008-11-01 21:38:31 -07002620 long amount = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002621 int err;
2622
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002623 switch (cmd) {
2624 case SIOCOUTQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002625 amount = unix_outq_len(sk);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002626 err = put_user(amount, (int __user *)arg);
2627 break;
2628 case SIOCINQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002629 amount = unix_inq_len(sk);
2630 if (amount < 0)
2631 err = amount;
2632 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633 err = put_user(amount, (int __user *)arg);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002634 break;
Andrey Vaginba94f302017-02-01 11:00:45 -08002635 case SIOCUNIXFILE:
2636 err = unix_open_file(sk);
2637 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002638 default:
2639 err = -ENOIOCTLCMD;
2640 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641 }
2642 return err;
2643}
2644
Arnd Bergmann5f6beb92019-06-03 22:03:44 +02002645#ifdef CONFIG_COMPAT
2646static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2647{
2648 return unix_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
2649}
2650#endif
2651
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002652static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653{
2654 struct sock *sk = sock->sk;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002655 __poll_t mask;
2656
Karsten Graul89ab0662018-10-23 13:40:39 +02002657 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002658 mask = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659
2660 /* exceptional events? */
2661 if (sk->sk_err)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002662 mask |= EPOLLERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002664 mask |= EPOLLHUP;
Davide Libenzif348d702006-03-25 03:07:39 -08002665 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002666 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667
2668 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002669 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002670 mask |= EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671
2672 /* Connection-based need to check for termination and startup */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002673 if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
2674 sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002675 mask |= EPOLLHUP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002676
2677 /*
2678 * we set writable also when the other side has shut down the
2679 * connection. This prevents stuck sockets.
2680 */
2681 if (unix_writable(sk))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002682 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683
2684 return mask;
2685}
2686
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002687static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
2688 poll_table *wait)
Rainer Weikusat3c734192008-06-17 22:28:05 -07002689{
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002690 struct sock *sk = sock->sk, *other;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002691 unsigned int writable;
2692 __poll_t mask;
2693
Karsten Graul89ab0662018-10-23 13:40:39 +02002694 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002695 mask = 0;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002696
2697 /* exceptional events? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002698 if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002699 mask |= EPOLLERR |
2700 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +00002701
Rainer Weikusat3c734192008-06-17 22:28:05 -07002702 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002703 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002704 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002705 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002706
2707 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07002708 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002709 mask |= EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002710
2711 /* Connection-based need to check for termination and startup */
2712 if (sk->sk_type == SOCK_SEQPACKET) {
2713 if (sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002714 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002715 /* connection hasn't started yet? */
2716 if (sk->sk_state == TCP_SYN_SENT)
2717 return mask;
2718 }
2719
Eric Dumazet973a34a2010-10-31 05:38:25 +00002720 /* No write status requested, avoid expensive OUT tests. */
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002721 if (!(poll_requested_events(wait) & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT)))
Eric Dumazet973a34a2010-10-31 05:38:25 +00002722 return mask;
2723
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002724 writable = unix_writable(sk);
Rainer Weikusat7d267272015-11-20 22:07:23 +00002725 if (writable) {
2726 unix_state_lock(sk);
2727
2728 other = unix_peer(sk);
2729 if (other && unix_peer(other) != sk &&
2730 unix_recvq_full(other) &&
2731 unix_dgram_peer_wake_me(sk, other))
2732 writable = 0;
2733
2734 unix_state_unlock(sk);
Rainer Weikusatec0d2152008-06-27 19:34:18 -07002735 }
2736
2737 if (writable)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002738 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Rainer Weikusat3c734192008-06-17 22:28:05 -07002739 else
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002740 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
Rainer Weikusat3c734192008-06-17 22:28:05 -07002741
Rainer Weikusat3c734192008-06-17 22:28:05 -07002742 return mask;
2743}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744
2745#ifdef CONFIG_PROC_FS
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002746
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002747#define BUCKET_SPACE (BITS_PER_LONG - (UNIX_HASH_BITS + 1) - 1)
2748
2749#define get_bucket(x) ((x) >> BUCKET_SPACE)
2750#define get_offset(x) ((x) & ((1L << BUCKET_SPACE) - 1))
2751#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08002752
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002753static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754{
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002755 unsigned long offset = get_offset(*pos);
2756 unsigned long bucket = get_bucket(*pos);
2757 struct sock *sk;
2758 unsigned long count = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002760 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
2761 if (sock_net(sk) != seq_file_net(seq))
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002762 continue;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002763 if (++count == offset)
2764 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765 }
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002766
2767 return sk;
2768}
2769
2770static struct sock *unix_next_socket(struct seq_file *seq,
2771 struct sock *sk,
2772 loff_t *pos)
2773{
2774 unsigned long bucket;
2775
2776 while (sk > (struct sock *)SEQ_START_TOKEN) {
2777 sk = sk_next(sk);
2778 if (!sk)
2779 goto next_bucket;
2780 if (sock_net(sk) == seq_file_net(seq))
2781 return sk;
2782 }
2783
2784 do {
2785 sk = unix_from_bucket(seq, pos);
2786 if (sk)
2787 return sk;
2788
2789next_bucket:
2790 bucket = get_bucket(*pos) + 1;
2791 *pos = set_bucket_offset(bucket, 1);
2792 } while (bucket < ARRAY_SIZE(unix_socket_table));
2793
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 return NULL;
2795}
2796
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002798 __acquires(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002800 spin_lock(&unix_table_lock);
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002801
2802 if (!*pos)
2803 return SEQ_START_TOKEN;
2804
2805 if (get_bucket(*pos) >= ARRAY_SIZE(unix_socket_table))
2806 return NULL;
2807
2808 return unix_next_socket(seq, NULL, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002809}
2810
2811static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2812{
2813 ++*pos;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00002814 return unix_next_socket(seq, v, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815}
2816
2817static void unix_seq_stop(struct seq_file *seq, void *v)
Eric Dumazet9a429c42008-01-01 21:58:02 -08002818 __releases(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819{
David S. Millerfbe9cc42005-12-13 23:26:29 -08002820 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821}
2822
2823static int unix_seq_show(struct seq_file *seq, void *v)
2824{
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002825
Joe Perchesb9f31242008-04-12 19:04:38 -07002826 if (v == SEQ_START_TOKEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 seq_puts(seq, "Num RefCount Protocol Flags Type St "
2828 "Inode Path\n");
2829 else {
2830 struct sock *s = v;
2831 struct unix_sock *u = unix_sk(s);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002832 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833
Dan Rosenberg71338aa2011-05-23 12:17:35 +00002834 seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835 s,
Reshetova, Elena41c6d652017-06-30 13:08:01 +03002836 refcount_read(&s->sk_refcnt),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837 0,
2838 s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
2839 s->sk_type,
2840 s->sk_socket ?
2841 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
2842 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
2843 sock_i_ino(s));
2844
Al Viroae3b5642019-02-15 20:09:35 +00002845 if (u->addr) { // under unix_table_lock here
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846 int i, len;
2847 seq_putc(seq, ' ');
2848
2849 i = 0;
2850 len = u->addr->len - sizeof(short);
2851 if (!UNIX_ABSTRACT(s))
2852 len--;
2853 else {
2854 seq_putc(seq, '@');
2855 i++;
2856 }
2857 for ( ; i < len; i++)
Isaac Boukrise7947ea2016-11-01 02:41:35 +02002858 seq_putc(seq, u->addr->name->sun_path[i] ?:
2859 '@');
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07002861 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862 seq_putc(seq, '\n');
2863 }
2864
2865 return 0;
2866}
2867
Philippe De Muyter56b3d972007-07-10 23:07:31 -07002868static const struct seq_operations unix_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 .start = unix_seq_start,
2870 .next = unix_seq_next,
2871 .stop = unix_seq_stop,
2872 .show = unix_seq_show,
2873};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874#endif
2875
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00002876static const struct net_proto_family unix_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877 .family = PF_UNIX,
2878 .create = unix_create,
2879 .owner = THIS_MODULE,
2880};
2881
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002882
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002883static int __net_init unix_net_init(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002884{
2885 int error = -ENOMEM;
2886
Denis V. Luneva0a53c82007-12-11 04:19:17 -08002887 net->unx.sysctl_max_dgram_qlen = 10;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002888 if (unix_sysctl_register(net))
2889 goto out;
Pavel Emelyanovd392e492007-12-01 23:44:15 +11002890
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002891#ifdef CONFIG_PROC_FS
Christoph Hellwigc3506372018-04-10 19:42:55 +02002892 if (!proc_create_net("unix", 0, net->proc_net, &unix_seq_ops,
2893 sizeof(struct seq_net_private))) {
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002894 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002895 goto out;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002896 }
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002897#endif
2898 error = 0;
2899out:
Jianjun Kong48dcc33e2008-11-01 21:37:27 -07002900 return error;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002901}
2902
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00002903static void __net_exit unix_net_exit(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002904{
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11002905 unix_sysctl_unregister(net);
Gao fengece31ff2013-02-18 01:34:56 +00002906 remove_proc_entry("unix", net->proc_net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002907}
2908
2909static struct pernet_operations unix_net_ops = {
2910 .init = unix_net_init,
2911 .exit = unix_net_exit,
2912};
2913
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914static int __init af_unix_init(void)
2915{
2916 int rc = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917
Pankaj Bharadiyac5936422019-12-09 10:31:43 -08002918 BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof_field(struct sk_buff, cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919
2920 rc = proto_register(&unix_proto, 1);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002921 if (rc != 0) {
wangweidong5cc208b2013-12-06 18:03:36 +08002922 pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 goto out;
2924 }
2925
2926 sock_register(&unix_family_ops);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002927 register_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928out:
2929 return rc;
2930}
2931
2932static void __exit af_unix_exit(void)
2933{
2934 sock_unregister(PF_UNIX);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 proto_unregister(&unix_proto);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08002936 unregister_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937}
2938
David Woodhouse3d366962008-04-24 00:59:25 -07002939/* Earlier than device_initcall() so that other drivers invoking
2940 request_module() don't end up in a loop when modprobe tries
2941 to use a UNIX socket. But later than subsys_initcall() because
2942 we depend on stuff initialised there */
2943fs_initcall(af_unix_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944module_exit(af_unix_exit);
2945
2946MODULE_LICENSE("GPL");
2947MODULE_ALIAS_NETPROTO(PF_UNIX);