blob: 92345c9bb60cc3b469e7cf50effe122b81c7bb89 [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>
Kuniyuki Iwashima2c860a42021-08-14 10:57:15 +0900116#include <linux/btf_ids.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117
Jens Axboef4e65872019-02-08 09:01:44 -0700118#include "scm.h"
119
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000120struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000121EXPORT_SYMBOL_GPL(unix_socket_table);
122DEFINE_SPINLOCK(unix_table_lock);
123EXPORT_SYMBOL_GPL(unix_table_lock);
Eric Dumazet518de9b2010-10-26 14:22:44 -0700124static atomic_long_t unix_nr_socks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000127static struct hlist_head *unix_sockets_unbound(void *addr)
128{
129 unsigned long hash = (unsigned long)addr;
130
131 hash ^= hash >> 16;
132 hash ^= hash >> 8;
133 hash %= UNIX_HASH_SIZE;
134 return &unix_socket_table[UNIX_HASH_SIZE + hash];
135}
136
137#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash < UNIX_HASH_SIZE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700139#ifdef CONFIG_SECURITY_NETWORK
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700140static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700141{
Stephen Smalley37a9a8d2015-06-10 08:44:59 -0400142 UNIXCB(skb).secid = scm->secid;
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700143}
144
145static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
146{
Stephen Smalley37a9a8d2015-06-10 08:44:59 -0400147 scm->secid = UNIXCB(skb).secid;
148}
149
150static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
151{
152 return (scm->secid == UNIXCB(skb).secid);
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700153}
154#else
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700155static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700156{ }
157
158static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
159{ }
Stephen Smalley37a9a8d2015-06-10 08:44:59 -0400160
161static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
162{
163 return true;
164}
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700165#endif /* CONFIG_SECURITY_NETWORK */
166
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167/*
168 * SMP locking strategy:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800169 * hash table is protected with spinlock unix_table_lock
Stephen Hemminger663717f2010-02-18 14:12:06 -0800170 * each socket state is protected by separate spin lock.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 */
172
Eric Dumazet95c96172012-04-15 05:58:06 +0000173static inline unsigned int unix_hash_fold(__wsum n)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174{
Anton Blanchard0a134042014-03-05 14:29:58 +1100175 unsigned int hash = (__force unsigned int)csum_fold(n);
Eric Dumazet95c96172012-04-15 05:58:06 +0000176
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 hash ^= hash>>8;
178 return hash&(UNIX_HASH_SIZE-1);
179}
180
181#define unix_peer(sk) (unix_sk(sk)->peer)
182
183static inline int unix_our_peer(struct sock *sk, struct sock *osk)
184{
185 return unix_peer(osk) == sk;
186}
187
188static inline int unix_may_send(struct sock *sk, struct sock *osk)
189{
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800190 return unix_peer(osk) == NULL || unix_our_peer(sk, osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191}
192
Qian Cai86b18aa2020-02-04 13:40:29 -0500193static inline int unix_recvq_full(const struct sock *sk)
Rainer Weikusat3c734192008-06-17 22:28:05 -0700194{
195 return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
196}
197
Qian Cai86b18aa2020-02-04 13:40:29 -0500198static inline int unix_recvq_full_lockless(const struct sock *sk)
199{
200 return skb_queue_len_lockless(&sk->sk_receive_queue) >
201 READ_ONCE(sk->sk_max_ack_backlog);
202}
203
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000204struct sock *unix_peer_get(struct sock *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205{
206 struct sock *peer;
207
David S. Miller1c92b4e2007-05-31 13:24:26 -0700208 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 peer = unix_peer(s);
210 if (peer)
211 sock_hold(peer);
David S. Miller1c92b4e2007-05-31 13:24:26 -0700212 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 return peer;
214}
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000215EXPORT_SYMBOL_GPL(unix_peer_get);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216
217static inline void unix_release_addr(struct unix_address *addr)
218{
Reshetova, Elena8c9814b2017-06-30 13:08:05 +0300219 if (refcount_dec_and_test(&addr->refcnt))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 kfree(addr);
221}
222
223/*
224 * Check unix socket name:
225 * - should be not zero length.
226 * - if started by not zero, should be NULL terminated (FS object)
227 * - if started by zero, it is abstract name.
228 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900229
Eric Dumazet95c96172012-04-15 05:58:06 +0000230static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned int *hashp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231{
Kyeongdon Kim33c43682018-10-16 14:57:26 +0900232 *hashp = 0;
233
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 if (len <= sizeof(short) || len > sizeof(*sunaddr))
235 return -EINVAL;
236 if (!sunaddr || sunaddr->sun_family != AF_UNIX)
237 return -EINVAL;
238 if (sunaddr->sun_path[0]) {
239 /*
240 * This may look like an off by one error but it is a bit more
241 * subtle. 108 is the longest valid AF_UNIX path for a binding.
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300242 * sun_path[108] doesn't as such exist. However in kernel space
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 * we are guaranteed that it is a valid memory location in our
244 * kernel address buffer.
245 */
Jianjun Konge27dfce2008-11-01 21:38:31 -0700246 ((char *)sunaddr)[len] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 len = strlen(sunaddr->sun_path)+1+sizeof(short);
248 return len;
249 }
250
Joe Perches07f07572008-11-19 15:44:53 -0800251 *hashp = unix_hash_fold(csum_partial(sunaddr, len, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 return len;
253}
254
255static void __unix_remove_socket(struct sock *sk)
256{
257 sk_del_node_init(sk);
258}
259
260static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
261{
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700262 WARN_ON(!sk_unhashed(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 sk_add_node(sk, list);
264}
265
Al Viro185ab882021-06-19 03:50:26 +0000266static void __unix_set_addr(struct sock *sk, struct unix_address *addr,
267 unsigned hash)
268{
269 __unix_remove_socket(sk);
270 smp_store_release(&unix_sk(sk)->addr, addr);
271 __unix_insert_socket(&unix_socket_table[hash], sk);
272}
273
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274static inline void unix_remove_socket(struct sock *sk)
275{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800276 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 __unix_remove_socket(sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800278 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279}
280
281static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
282{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800283 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 __unix_insert_socket(list, sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800285 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286}
287
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800288static struct sock *__unix_find_socket_byname(struct net *net,
289 struct sockaddr_un *sunname,
Al Virobe752282021-06-19 03:50:33 +0000290 int len, unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291{
292 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293
Al Virobe752282021-06-19 03:50:33 +0000294 sk_for_each(s, &unix_socket_table[hash]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 struct unix_sock *u = unix_sk(s);
296
YOSHIFUJI Hideaki878628f2008-03-26 03:57:35 +0900297 if (!net_eq(sock_net(s), net))
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800298 continue;
299
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 if (u->addr->len == len &&
301 !memcmp(u->addr->name, sunname, len))
Vito Caputo262ce0a2019-10-09 20:43:47 -0700302 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 }
Vito Caputo262ce0a2019-10-09 20:43:47 -0700304 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305}
306
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800307static inline struct sock *unix_find_socket_byname(struct net *net,
308 struct sockaddr_un *sunname,
Al Virobe752282021-06-19 03:50:33 +0000309 int len, unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310{
311 struct sock *s;
312
David S. Millerfbe9cc42005-12-13 23:26:29 -0800313 spin_lock(&unix_table_lock);
Al Virobe752282021-06-19 03:50:33 +0000314 s = __unix_find_socket_byname(net, sunname, len, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 if (s)
316 sock_hold(s);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800317 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 return s;
319}
320
Eric W. Biederman6616f782010-06-13 03:35:48 +0000321static struct sock *unix_find_socket_byinode(struct inode *i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322{
323 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
David S. Millerfbe9cc42005-12-13 23:26:29 -0800325 spin_lock(&unix_table_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800326 sk_for_each(s,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
Al Viro40ffe672012-03-14 21:54:32 -0400328 struct dentry *dentry = unix_sk(s)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329
Miklos Szeredibeef5122016-12-16 11:02:53 +0100330 if (dentry && d_backing_inode(dentry) == i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 sock_hold(s);
332 goto found;
333 }
334 }
335 s = NULL;
336found:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800337 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 return s;
339}
340
Rainer Weikusat7d267272015-11-20 22:07:23 +0000341/* Support code for asymmetrically connected dgram sockets
342 *
343 * If a datagram socket is connected to a socket not itself connected
344 * to the first socket (eg, /dev/log), clients may only enqueue more
345 * messages if the present receive queue of the server socket is not
346 * "too large". This means there's a second writeability condition
347 * poll and sendmsg need to test. The dgram recv code will do a wake
348 * up on the peer_wait wait queue of a socket upon reception of a
349 * datagram which needs to be propagated to sleeping would-be writers
350 * since these might not have sent anything so far. This can't be
351 * accomplished via poll_wait because the lifetime of the server
352 * socket might be less than that of its clients if these break their
353 * association with it or if the server socket is closed while clients
354 * are still connected to it and there's no way to inform "a polling
355 * implementation" that it should let go of a certain wait queue
356 *
Ingo Molnarac6424b2017-06-20 12:06:13 +0200357 * In order to propagate a wake up, a wait_queue_entry_t of the client
Rainer Weikusat7d267272015-11-20 22:07:23 +0000358 * socket is enqueued on the peer_wait queue of the server socket
359 * whose wake function does a wake_up on the ordinary client socket
360 * wait queue. This connection is established whenever a write (or
361 * poll for write) hit the flow control condition and broken when the
362 * association to the server socket is dissolved or after a wake up
363 * was relayed.
364 */
365
Ingo Molnarac6424b2017-06-20 12:06:13 +0200366static int unix_dgram_peer_wake_relay(wait_queue_entry_t *q, unsigned mode, int flags,
Rainer Weikusat7d267272015-11-20 22:07:23 +0000367 void *key)
368{
369 struct unix_sock *u;
370 wait_queue_head_t *u_sleep;
371
372 u = container_of(q, struct unix_sock, peer_wake);
373
374 __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
375 q);
376 u->peer_wake.private = NULL;
377
378 /* relaying can only happen while the wq still exists */
379 u_sleep = sk_sleep(&u->sk);
380 if (u_sleep)
Al Viro3ad6f932017-07-03 20:14:56 -0400381 wake_up_interruptible_poll(u_sleep, key_to_poll(key));
Rainer Weikusat7d267272015-11-20 22:07:23 +0000382
383 return 0;
384}
385
386static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
387{
388 struct unix_sock *u, *u_other;
389 int rc;
390
391 u = unix_sk(sk);
392 u_other = unix_sk(other);
393 rc = 0;
394 spin_lock(&u_other->peer_wait.lock);
395
396 if (!u->peer_wake.private) {
397 u->peer_wake.private = other;
398 __add_wait_queue(&u_other->peer_wait, &u->peer_wake);
399
400 rc = 1;
401 }
402
403 spin_unlock(&u_other->peer_wait.lock);
404 return rc;
405}
406
407static void unix_dgram_peer_wake_disconnect(struct sock *sk,
408 struct sock *other)
409{
410 struct unix_sock *u, *u_other;
411
412 u = unix_sk(sk);
413 u_other = unix_sk(other);
414 spin_lock(&u_other->peer_wait.lock);
415
416 if (u->peer_wake.private == other) {
417 __remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
418 u->peer_wake.private = NULL;
419 }
420
421 spin_unlock(&u_other->peer_wait.lock);
422}
423
424static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
425 struct sock *other)
426{
427 unix_dgram_peer_wake_disconnect(sk, other);
428 wake_up_interruptible_poll(sk_sleep(sk),
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800429 EPOLLOUT |
430 EPOLLWRNORM |
431 EPOLLWRBAND);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000432}
433
434/* preconditions:
435 * - unix_peer(sk) == other
436 * - association is stable
437 */
438static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
439{
440 int connected;
441
442 connected = unix_dgram_peer_wake_connect(sk, other);
443
Jason Baron51f7e952018-08-03 17:24:53 -0400444 /* If other is SOCK_DEAD, we want to make sure we signal
445 * POLLOUT, such that a subsequent write() can get a
446 * -ECONNREFUSED. Otherwise, if we haven't queued any skbs
447 * to other and its full, we will hang waiting for POLLOUT.
448 */
449 if (unix_recvq_full(other) && !sock_flag(other, SOCK_DEAD))
Rainer Weikusat7d267272015-11-20 22:07:23 +0000450 return 1;
451
452 if (connected)
453 unix_dgram_peer_wake_disconnect(sk, other);
454
455 return 0;
456}
457
Eric Dumazet1586a582015-10-23 10:59:16 -0700458static int unix_writable(const struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459{
Eric Dumazet1586a582015-10-23 10:59:16 -0700460 return sk->sk_state != TCP_LISTEN &&
Reshetova, Elena14afee42017-06-30 13:08:00 +0300461 (refcount_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462}
463
464static void unix_write_space(struct sock *sk)
465{
Eric Dumazet43815482010-04-29 11:01:49 +0000466 struct socket_wq *wq;
467
468 rcu_read_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 if (unix_writable(sk)) {
Eric Dumazet43815482010-04-29 11:01:49 +0000470 wq = rcu_dereference(sk->sk_wq);
Herbert Xu1ce0bf52015-11-26 13:55:39 +0800471 if (skwq_has_sleeper(wq))
Eric Dumazet67426b72010-10-29 20:44:44 +0000472 wake_up_interruptible_sync_poll(&wq->wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800473 EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800474 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 }
Eric Dumazet43815482010-04-29 11:01:49 +0000476 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477}
478
479/* When dgram socket disconnects (or changes its peer), we clear its receive
480 * queue of packets arrived from previous peer. First, it allows to do
481 * flow control based only on wmem_alloc; second, sk connected to peer
482 * may receive messages only from that peer. */
483static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
484{
David S. Millerb03efcf2005-07-08 14:57:23 -0700485 if (!skb_queue_empty(&sk->sk_receive_queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486 skb_queue_purge(&sk->sk_receive_queue);
487 wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
488
489 /* If one link of bidirectional dgram pipe is disconnected,
490 * we signal error. Messages are lost. Do not make this,
491 * when peer was not connected to us.
492 */
493 if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) {
494 other->sk_err = ECONNRESET;
Alexander Aringe3ae2362021-06-27 18:48:21 -0400495 sk_error_report(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 }
497 }
Eric Dumazetdc56ad72021-08-30 10:21:37 -0700498 other->sk_state = TCP_CLOSE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499}
500
501static void unix_sock_destructor(struct sock *sk)
502{
503 struct unix_sock *u = unix_sk(sk);
504
505 skb_queue_purge(&sk->sk_receive_queue);
506
Rao Shoaib314001f2021-08-01 00:57:07 -0700507#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
508 if (u->oob_skb) {
509 kfree_skb(u->oob_skb);
510 u->oob_skb = NULL;
511 }
512#endif
Reshetova, Elena14afee42017-06-30 13:08:00 +0300513 WARN_ON(refcount_read(&sk->sk_wmem_alloc));
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700514 WARN_ON(!sk_unhashed(sk));
515 WARN_ON(sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 if (!sock_flag(sk, SOCK_DEAD)) {
wangweidong5cc208b2013-12-06 18:03:36 +0800517 pr_info("Attempt to release alive unix socket: %p\n", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 return;
519 }
520
521 if (u->addr)
522 unix_release_addr(u->addr);
523
Eric Dumazet518de9b2010-10-26 14:22:44 -0700524 atomic_long_dec(&unix_nr_socks);
David S. Miller6f756a82008-11-23 17:34:03 -0800525 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800526 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
David S. Miller6f756a82008-11-23 17:34:03 -0800527 local_bh_enable();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528#ifdef UNIX_REFCNT_DEBUG
wangweidong5cc208b2013-12-06 18:03:36 +0800529 pr_debug("UNIX %p is destroyed, %ld are still alive.\n", sk,
Eric Dumazet518de9b2010-10-26 14:22:44 -0700530 atomic_long_read(&unix_nr_socks));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531#endif
532}
533
Paul Mooreded34e02013-03-25 03:18:33 +0000534static void unix_release_sock(struct sock *sk, int embrion)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535{
536 struct unix_sock *u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400537 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 struct sock *skpair;
539 struct sk_buff *skb;
540 int state;
541
542 unix_remove_socket(sk);
543
544 /* Clear state */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700545 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 sock_orphan(sk);
547 sk->sk_shutdown = SHUTDOWN_MASK;
Al Viro40ffe672012-03-14 21:54:32 -0400548 path = u->path;
549 u->path.dentry = NULL;
550 u->path.mnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 state = sk->sk_state;
552 sk->sk_state = TCP_CLOSE;
Eric Dumazeta494bd62021-06-16 07:47:15 -0700553
554 skpair = unix_peer(sk);
555 unix_peer(sk) = NULL;
556
David S. Miller1c92b4e2007-05-31 13:24:26 -0700557 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
559 wake_up_interruptible_all(&u->peer_wait);
560
Jianjun Konge27dfce2008-11-01 21:38:31 -0700561 if (skpair != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
David S. Miller1c92b4e2007-05-31 13:24:26 -0700563 unix_state_lock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 /* No more writes */
565 skpair->sk_shutdown = SHUTDOWN_MASK;
566 if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
567 skpair->sk_err = ECONNRESET;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700568 unix_state_unlock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 skpair->sk_state_change(skpair);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800570 sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 }
Rainer Weikusat7d267272015-11-20 22:07:23 +0000572
573 unix_dgram_peer_wake_disconnect(sk, skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 sock_put(skpair); /* It may now die */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 }
576
577 /* Try to flush out this socket. Throw out buffers at least */
578
579 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
Jianjun Konge27dfce2008-11-01 21:38:31 -0700580 if (state == TCP_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 unix_release_sock(skb->sk, 1);
582 /* passed fds are erased in the kfree_skb hook */
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +0100583 UNIXCB(skb).consumed = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 kfree_skb(skb);
585 }
586
Al Viro40ffe672012-03-14 21:54:32 -0400587 if (path.dentry)
588 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
590 sock_put(sk);
591
592 /* ---- Socket is dead now and most probably destroyed ---- */
593
594 /*
Alan Coxe04dae82012-09-17 00:52:41 +0000595 * Fixme: BSD difference: In BSD all sockets connected to us get
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 * ECONNRESET and we die on the spot. In Linux we behave
597 * like files and pipes do and wait for the last
598 * dereference.
599 *
600 * Can't we simply set sock->err?
601 *
602 * What the above comment does talk about? --ANK(980817)
603 */
604
Pavel Emelyanov9305cfa2007-11-10 22:06:01 -0800605 if (unix_tot_inflight)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900606 unix_gc(); /* Garbage collect fds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607}
608
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000609static void init_peercred(struct sock *sk)
610{
611 put_pid(sk->sk_peer_pid);
612 if (sk->sk_peer_cred)
613 put_cred(sk->sk_peer_cred);
614 sk->sk_peer_pid = get_pid(task_tgid(current));
615 sk->sk_peer_cred = get_current_cred();
616}
617
618static void copy_peercred(struct sock *sk, struct sock *peersk)
619{
620 put_pid(sk->sk_peer_pid);
621 if (sk->sk_peer_cred)
622 put_cred(sk->sk_peer_cred);
623 sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
624 sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
625}
626
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627static int unix_listen(struct socket *sock, int backlog)
628{
629 int err;
630 struct sock *sk = sock->sk;
631 struct unix_sock *u = unix_sk(sk);
632
633 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800634 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
635 goto out; /* Only stream/seqpacket sockets accept */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 err = -EINVAL;
637 if (!u->addr)
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800638 goto out; /* No listens on an unbound socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700639 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
641 goto out_unlock;
642 if (backlog > sk->sk_max_ack_backlog)
643 wake_up_interruptible_all(&u->peer_wait);
644 sk->sk_max_ack_backlog = backlog;
645 sk->sk_state = TCP_LISTEN;
646 /* set credentials so connect can copy them */
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000647 init_peercred(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 err = 0;
649
650out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -0700651 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652out:
653 return err;
654}
655
656static int unix_release(struct socket *);
657static int unix_bind(struct socket *, struct sockaddr *, int);
658static int unix_stream_connect(struct socket *, struct sockaddr *,
659 int addr_len, int flags);
660static int unix_socketpair(struct socket *, struct socket *);
David Howellscdfbabf2017-03-09 08:09:05 +0000661static int unix_accept(struct socket *, struct socket *, int, bool);
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +0100662static int unix_getname(struct socket *, struct sockaddr *, int);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700663static __poll_t unix_poll(struct file *, struct socket *, poll_table *);
664static __poll_t unix_dgram_poll(struct file *, struct socket *,
665 poll_table *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666static int unix_ioctl(struct socket *, unsigned int, unsigned long);
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200667#ifdef CONFIG_COMPAT
668static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
669#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670static int unix_shutdown(struct socket *, int);
Ying Xue1b784142015-03-02 15:37:48 +0800671static int unix_stream_sendmsg(struct socket *, struct msghdr *, size_t);
672static int unix_stream_recvmsg(struct socket *, struct msghdr *, size_t, int);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200673static ssize_t unix_stream_sendpage(struct socket *, struct page *, int offset,
674 size_t size, int flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200675static ssize_t unix_stream_splice_read(struct socket *, loff_t *ppos,
676 struct pipe_inode_info *, size_t size,
677 unsigned int flags);
Ying Xue1b784142015-03-02 15:37:48 +0800678static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t);
679static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int);
Cong Wang29df44f2021-07-04 12:02:44 -0700680static int unix_read_sock(struct sock *sk, read_descriptor_t *desc,
681 sk_read_actor_t recv_actor);
Jiang Wang77462de2021-08-16 19:03:20 +0000682static int unix_stream_read_sock(struct sock *sk, read_descriptor_t *desc,
683 sk_read_actor_t recv_actor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684static int unix_dgram_connect(struct socket *, struct sockaddr *,
685 int, int);
Ying Xue1b784142015-03-02 15:37:48 +0800686static int unix_seqpacket_sendmsg(struct socket *, struct msghdr *, size_t);
687static int unix_seqpacket_recvmsg(struct socket *, struct msghdr *, size_t,
688 int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689
Sasha Levin12663bf2013-12-07 17:26:27 -0500690static int unix_set_peek_off(struct sock *sk, int val)
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000691{
692 struct unix_sock *u = unix_sk(sk);
693
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700694 if (mutex_lock_interruptible(&u->iolock))
Sasha Levin12663bf2013-12-07 17:26:27 -0500695 return -EINTR;
696
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000697 sk->sk_peek_off = val;
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700698 mutex_unlock(&u->iolock);
Sasha Levin12663bf2013-12-07 17:26:27 -0500699
700 return 0;
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000701}
702
David S. Miller5c05a162020-02-27 11:52:35 -0800703#ifdef CONFIG_PROC_FS
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300704static void unix_show_fdinfo(struct seq_file *m, struct socket *sock)
705{
706 struct sock *sk = sock->sk;
707 struct unix_sock *u;
708
709 if (sk) {
710 u = unix_sk(sock->sk);
Paolo Abeni77820402020-02-28 14:45:21 +0100711 seq_printf(m, "scm_fds: %u\n",
712 atomic_read(&u->scm_stat.nr_fds));
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300713 }
714}
Tobias Klauser3a125002020-02-26 18:29:53 +0100715#else
716#define unix_show_fdinfo NULL
717#endif
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000718
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800719static const struct proto_ops unix_stream_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 .family = PF_UNIX,
721 .owner = THIS_MODULE,
722 .release = unix_release,
723 .bind = unix_bind,
724 .connect = unix_stream_connect,
725 .socketpair = unix_socketpair,
726 .accept = unix_accept,
727 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700728 .poll = unix_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200730#ifdef CONFIG_COMPAT
731 .compat_ioctl = unix_compat_ioctl,
732#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 .listen = unix_listen,
734 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 .sendmsg = unix_stream_sendmsg,
736 .recvmsg = unix_stream_recvmsg,
Jiang Wang77462de2021-08-16 19:03:20 +0000737 .read_sock = unix_stream_read_sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 .mmap = sock_no_mmap,
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200739 .sendpage = unix_stream_sendpage,
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200740 .splice_read = unix_stream_splice_read,
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +0000741 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300742 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743};
744
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800745static const struct proto_ops unix_dgram_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 .family = PF_UNIX,
747 .owner = THIS_MODULE,
748 .release = unix_release,
749 .bind = unix_bind,
750 .connect = unix_dgram_connect,
751 .socketpair = unix_socketpair,
752 .accept = sock_no_accept,
753 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700754 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200756#ifdef CONFIG_COMPAT
757 .compat_ioctl = unix_compat_ioctl,
758#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 .listen = sock_no_listen,
760 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 .sendmsg = unix_dgram_sendmsg,
Cong Wang29df44f2021-07-04 12:02:44 -0700762 .read_sock = unix_read_sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 .recvmsg = unix_dgram_recvmsg,
764 .mmap = sock_no_mmap,
765 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000766 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300767 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768};
769
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800770static const struct proto_ops unix_seqpacket_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 .family = PF_UNIX,
772 .owner = THIS_MODULE,
773 .release = unix_release,
774 .bind = unix_bind,
775 .connect = unix_stream_connect,
776 .socketpair = unix_socketpair,
777 .accept = unix_accept,
778 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700779 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200781#ifdef CONFIG_COMPAT
782 .compat_ioctl = unix_compat_ioctl,
783#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 .listen = unix_listen,
785 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 .sendmsg = unix_seqpacket_sendmsg,
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +0000787 .recvmsg = unix_seqpacket_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 .mmap = sock_no_mmap,
789 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000790 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300791 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792};
793
Cong Wangc7272e12021-07-04 12:02:46 -0700794static void unix_close(struct sock *sk, long timeout)
795{
796 /* Nothing to do here, unix socket does not need a ->close().
797 * This is merely for sockmap.
798 */
799}
800
Jiang Wang94531cf2021-08-16 19:03:21 +0000801static void unix_unhash(struct sock *sk)
802{
803 /* Nothing to do here, unix socket does not need a ->unhash().
804 * This is merely for sockmap.
805 */
806}
807
808struct proto unix_dgram_proto = {
809 .name = "UNIX-DGRAM",
Eric Dumazet248969a2008-11-17 00:00:30 -0800810 .owner = THIS_MODULE,
Eric Dumazet248969a2008-11-17 00:00:30 -0800811 .obj_size = sizeof(struct unix_sock),
Cong Wangc7272e12021-07-04 12:02:46 -0700812 .close = unix_close,
Cong Wangc6382912021-07-04 12:02:47 -0700813#ifdef CONFIG_BPF_SYSCALL
Jiang Wang94531cf2021-08-16 19:03:21 +0000814 .psock_update_sk_prot = unix_dgram_bpf_update_proto,
Cong Wangc6382912021-07-04 12:02:47 -0700815#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816};
817
Jiang Wang94531cf2021-08-16 19:03:21 +0000818struct proto unix_stream_proto = {
819 .name = "UNIX-STREAM",
820 .owner = THIS_MODULE,
821 .obj_size = sizeof(struct unix_sock),
822 .close = unix_close,
823 .unhash = unix_unhash,
824#ifdef CONFIG_BPF_SYSCALL
825 .psock_update_sk_prot = unix_stream_bpf_update_proto,
826#endif
827};
828
829static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, int type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830{
831 struct sock *sk = NULL;
832 struct unix_sock *u;
833
Eric Dumazet518de9b2010-10-26 14:22:44 -0700834 atomic_long_inc(&unix_nr_socks);
835 if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 goto out;
837
Jiang Wang94531cf2021-08-16 19:03:21 +0000838 if (type == SOCK_STREAM)
839 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_stream_proto, kern);
840 else /*dgram and seqpacket */
841 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_dgram_proto, kern);
842
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 if (!sk)
844 goto out;
845
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800846 sock_init_data(sock, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847
Vladimir Davydov3aa97992016-07-26 15:24:36 -0700848 sk->sk_allocation = GFP_KERNEL_ACCOUNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 sk->sk_write_space = unix_write_space;
Denis V. Luneva0a53c82007-12-11 04:19:17 -0800850 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 sk->sk_destruct = unix_sock_destructor;
852 u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400853 u->path.dentry = NULL;
854 u->path.mnt = NULL;
Benjamin LaHaisefd19f322006-01-03 14:10:46 -0800855 spin_lock_init(&u->lock);
Al Viro516e0cc2008-07-26 00:39:17 -0400856 atomic_long_set(&u->inflight, 0);
Miklos Szeredi1fd05ba2007-07-11 14:22:39 -0700857 INIT_LIST_HEAD(&u->link);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700858 mutex_init(&u->iolock); /* single task reading lock */
859 mutex_init(&u->bindlock); /* single task binding lock */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 init_waitqueue_head(&u->peer_wait);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000861 init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300862 memset(&u->scm_stat, 0, sizeof(struct scm_stat));
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000863 unix_insert_socket(unix_sockets_unbound(sk), sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864out:
Pavel Emelyanov284b3272007-11-10 22:08:30 -0800865 if (sk == NULL)
Eric Dumazet518de9b2010-10-26 14:22:44 -0700866 atomic_long_dec(&unix_nr_socks);
Eric Dumazet920de802008-11-24 00:09:29 -0800867 else {
868 local_bh_disable();
Eric Dumazeta8076d82008-11-17 02:38:49 -0800869 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
Eric Dumazet920de802008-11-24 00:09:29 -0800870 local_bh_enable();
871 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 return sk;
873}
874
Eric Paris3f378b62009-11-05 22:18:14 -0800875static int unix_create(struct net *net, struct socket *sock, int protocol,
876 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877{
878 if (protocol && protocol != PF_UNIX)
879 return -EPROTONOSUPPORT;
880
881 sock->state = SS_UNCONNECTED;
882
883 switch (sock->type) {
884 case SOCK_STREAM:
885 sock->ops = &unix_stream_ops;
886 break;
887 /*
888 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
889 * nothing uses it.
890 */
891 case SOCK_RAW:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700892 sock->type = SOCK_DGRAM;
Gustavo A. R. Silvadf561f662020-08-23 17:36:59 -0500893 fallthrough;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 case SOCK_DGRAM:
895 sock->ops = &unix_dgram_ops;
896 break;
897 case SOCK_SEQPACKET:
898 sock->ops = &unix_seqpacket_ops;
899 break;
900 default:
901 return -ESOCKTNOSUPPORT;
902 }
903
Jiang Wang94531cf2021-08-16 19:03:21 +0000904 return unix_create1(net, sock, kern, sock->type) ? 0 : -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905}
906
907static int unix_release(struct socket *sock)
908{
909 struct sock *sk = sock->sk;
910
911 if (!sk)
912 return 0;
913
Cong Wangc7272e12021-07-04 12:02:46 -0700914 sk->sk_prot->close(sk, 0);
Paul Mooreded34e02013-03-25 03:18:33 +0000915 unix_release_sock(sk, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 sock->sk = NULL;
917
Paul Mooreded34e02013-03-25 03:18:33 +0000918 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919}
920
921static int unix_autobind(struct socket *sock)
922{
923 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +0900924 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 struct unix_sock *u = unix_sk(sk);
926 static u32 ordernum = 1;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800927 struct unix_address *addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 int err;
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000929 unsigned int retries = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700931 err = mutex_lock_interruptible(&u->bindlock);
Sasha Levin37ab4fa2013-12-13 10:54:22 -0500932 if (err)
933 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 if (u->addr)
936 goto out;
937
938 err = -ENOMEM;
Panagiotis Issaris0da974f2006-07-21 14:51:30 -0700939 addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 if (!addr)
941 goto out;
942
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 addr->name->sun_family = AF_UNIX;
Reshetova, Elena8c9814b2017-06-30 13:08:05 +0300944 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945
946retry:
947 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
Joe Perches07f07572008-11-19 15:44:53 -0800948 addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
Al Virobe752282021-06-19 03:50:33 +0000949 addr->hash ^= sk->sk_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950
David S. Millerfbe9cc42005-12-13 23:26:29 -0800951 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 ordernum = (ordernum+1)&0xFFFFF;
953
Al Virobe752282021-06-19 03:50:33 +0000954 if (__unix_find_socket_byname(net, addr->name, addr->len, addr->hash)) {
David S. Millerfbe9cc42005-12-13 23:26:29 -0800955 spin_unlock(&unix_table_lock);
Tetsuo Handa8df73ff2010-09-04 01:34:28 +0000956 /*
957 * __unix_find_socket_byname() may take long time if many names
958 * are already in use.
959 */
960 cond_resched();
961 /* Give up if all names seems to be in use. */
962 if (retries++ == 0xFFFFF) {
963 err = -ENOSPC;
964 kfree(addr);
965 goto out;
966 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 goto retry;
968 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969
Al Viro185ab882021-06-19 03:50:26 +0000970 __unix_set_addr(sk, addr, addr->hash);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800971 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 err = 0;
973
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700974out: mutex_unlock(&u->bindlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 return err;
976}
977
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800978static struct sock *unix_find_other(struct net *net,
979 struct sockaddr_un *sunname, int len,
Eric Dumazet95c96172012-04-15 05:58:06 +0000980 int type, unsigned int hash, int *error)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981{
982 struct sock *u;
Al Viro421748e2008-08-02 01:04:36 -0400983 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 int err = 0;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900985
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986 if (sunname->sun_path[0]) {
Al Viro421748e2008-08-02 01:04:36 -0400987 struct inode *inode;
988 err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 if (err)
990 goto fail;
Miklos Szeredibeef5122016-12-16 11:02:53 +0100991 inode = d_backing_inode(path.dentry);
Christian Brauner02f92b32021-01-21 14:19:22 +0100992 err = path_permission(&path, MAY_WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 if (err)
994 goto put_fail;
995
996 err = -ECONNREFUSED;
Al Viro421748e2008-08-02 01:04:36 -0400997 if (!S_ISSOCK(inode->i_mode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 goto put_fail;
Eric W. Biederman6616f782010-06-13 03:35:48 +0000999 u = unix_find_socket_byinode(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 if (!u)
1001 goto put_fail;
1002
1003 if (u->sk_type == type)
Al Viro68ac1232012-03-15 08:21:57 -04001004 touch_atime(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005
Al Viro421748e2008-08-02 01:04:36 -04001006 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007
Jianjun Konge27dfce2008-11-01 21:38:31 -07001008 err = -EPROTOTYPE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 if (u->sk_type != type) {
1010 sock_put(u);
1011 goto fail;
1012 }
1013 } else {
1014 err = -ECONNREFUSED;
Al Virobe752282021-06-19 03:50:33 +00001015 u = unix_find_socket_byname(net, sunname, len, type ^ hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 if (u) {
1017 struct dentry *dentry;
Al Viro40ffe672012-03-14 21:54:32 -04001018 dentry = unix_sk(u)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019 if (dentry)
Al Viro68ac1232012-03-15 08:21:57 -04001020 touch_atime(&unix_sk(u)->path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 } else
1022 goto fail;
1023 }
1024 return u;
1025
1026put_fail:
Al Viro421748e2008-08-02 01:04:36 -04001027 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028fail:
Jianjun Konge27dfce2008-11-01 21:38:31 -07001029 *error = err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 return NULL;
1031}
1032
Al Viro71e6be62021-06-19 03:50:30 +00001033static int unix_bind_bsd(struct sock *sk, struct unix_address *addr)
Al Virofaf02012012-07-20 02:37:29 +04001034{
Al Viro71e6be62021-06-19 03:50:30 +00001035 struct unix_sock *u = unix_sk(sk);
1036 umode_t mode = S_IFSOCK |
1037 (SOCK_INODE(sk->sk_socket)->i_mode & ~current_umask());
Al Viro71e6be62021-06-19 03:50:30 +00001038 struct user_namespace *ns; // barf...
Al Viro56c17312021-06-19 03:50:31 +00001039 struct path parent;
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001040 struct dentry *dentry;
Al Viro71e6be62021-06-19 03:50:30 +00001041 unsigned int hash;
1042 int err;
1043
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001044 /*
1045 * Get the parent directory, calculate the hash for last
1046 * component.
1047 */
Al Viro71e6be62021-06-19 03:50:30 +00001048 dentry = kern_path_create(AT_FDCWD, addr->name->sun_path, &parent, 0);
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001049 if (IS_ERR(dentry))
Al Viro71e6be62021-06-19 03:50:30 +00001050 return PTR_ERR(dentry);
1051 ns = mnt_user_ns(parent.mnt);
Al Virofaf02012012-07-20 02:37:29 +04001052
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001053 /*
1054 * All right, let's create it.
1055 */
Al Viro71e6be62021-06-19 03:50:30 +00001056 err = security_path_mknod(&parent, dentry, mode, 0);
Al Viro56c17312021-06-19 03:50:31 +00001057 if (!err)
Al Viro71e6be62021-06-19 03:50:30 +00001058 err = vfs_mknod(ns, d_inode(parent.dentry), dentry, mode, 0);
Al Viroc0c3b8d2021-06-19 03:50:32 +00001059 if (err)
1060 goto out;
Al Virofa42d912021-06-19 03:50:29 +00001061 err = mutex_lock_interruptible(&u->bindlock);
Al Viroc0c3b8d2021-06-19 03:50:32 +00001062 if (err)
1063 goto out_unlink;
1064 if (u->addr)
1065 goto out_unlock;
Al Virofa42d912021-06-19 03:50:29 +00001066
1067 addr->hash = UNIX_HASH_SIZE;
Al Viro56c17312021-06-19 03:50:31 +00001068 hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
Al Virofa42d912021-06-19 03:50:29 +00001069 spin_lock(&unix_table_lock);
Al Viro56c17312021-06-19 03:50:31 +00001070 u->path.mnt = mntget(parent.mnt);
1071 u->path.dentry = dget(dentry);
Al Virofa42d912021-06-19 03:50:29 +00001072 __unix_set_addr(sk, addr, hash);
1073 spin_unlock(&unix_table_lock);
1074 mutex_unlock(&u->bindlock);
Al Viro56c17312021-06-19 03:50:31 +00001075 done_path_create(&parent, dentry);
Al Virofa42d912021-06-19 03:50:29 +00001076 return 0;
Al Viroc0c3b8d2021-06-19 03:50:32 +00001077
1078out_unlock:
1079 mutex_unlock(&u->bindlock);
1080 err = -EINVAL;
1081out_unlink:
1082 /* failed after successful mknod? unlink what we'd created... */
1083 vfs_unlink(ns, d_inode(parent.dentry), dentry, NULL);
1084out:
1085 done_path_create(&parent, dentry);
1086 return err;
Al Virofa42d912021-06-19 03:50:29 +00001087}
1088
Al Virobe752282021-06-19 03:50:33 +00001089static int unix_bind_abstract(struct sock *sk, struct unix_address *addr)
Al Virofa42d912021-06-19 03:50:29 +00001090{
1091 struct unix_sock *u = unix_sk(sk);
1092 int err;
1093
1094 err = mutex_lock_interruptible(&u->bindlock);
1095 if (err)
1096 return err;
1097
1098 if (u->addr) {
1099 mutex_unlock(&u->bindlock);
1100 return -EINVAL;
1101 }
1102
1103 spin_lock(&unix_table_lock);
1104 if (__unix_find_socket_byname(sock_net(sk), addr->name, addr->len,
Al Virobe752282021-06-19 03:50:33 +00001105 addr->hash)) {
Al Virofa42d912021-06-19 03:50:29 +00001106 spin_unlock(&unix_table_lock);
1107 mutex_unlock(&u->bindlock);
1108 return -EADDRINUSE;
1109 }
1110 __unix_set_addr(sk, addr, addr->hash);
1111 spin_unlock(&unix_table_lock);
1112 mutex_unlock(&u->bindlock);
1113 return 0;
1114}
1115
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1117{
1118 struct sock *sk = sock->sk;
Jianjun Konge27dfce2008-11-01 21:38:31 -07001119 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Al Virodae6ad82011-06-26 11:50:15 -04001120 char *sun_path = sunaddr->sun_path;
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001121 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001122 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 struct unix_address *addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001125 if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
1126 sunaddr->sun_family != AF_UNIX)
Al Virofa42d912021-06-19 03:50:29 +00001127 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128
Al Virofa42d912021-06-19 03:50:29 +00001129 if (addr_len == sizeof(short))
1130 return unix_autobind(sock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131
1132 err = unix_mkname(sunaddr, addr_len, &hash);
1133 if (err < 0)
Al Virofa42d912021-06-19 03:50:29 +00001134 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 addr_len = err;
Al Viroc34d4582021-06-19 03:50:27 +00001136 addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
1137 if (!addr)
Al Virofa42d912021-06-19 03:50:29 +00001138 return -ENOMEM;
Al Viroc34d4582021-06-19 03:50:27 +00001139
1140 memcpy(addr->name, sunaddr, addr_len);
1141 addr->len = addr_len;
1142 addr->hash = hash ^ sk->sk_type;
1143 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144
Al Virofa42d912021-06-19 03:50:29 +00001145 if (sun_path[0])
1146 err = unix_bind_bsd(sk, addr);
1147 else
Al Virobe752282021-06-19 03:50:33 +00001148 err = unix_bind_abstract(sk, addr);
Al Virofa42d912021-06-19 03:50:29 +00001149 if (err)
Al Viroc34d4582021-06-19 03:50:27 +00001150 unix_release_addr(addr);
Al Virofa42d912021-06-19 03:50:29 +00001151 return err == -EEXIST ? -EADDRINUSE : err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152}
1153
David S. Miller278a3de2007-05-31 15:19:20 -07001154static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
1155{
1156 if (unlikely(sk1 == sk2) || !sk2) {
1157 unix_state_lock(sk1);
1158 return;
1159 }
1160 if (sk1 < sk2) {
1161 unix_state_lock(sk1);
1162 unix_state_lock_nested(sk2);
1163 } else {
1164 unix_state_lock(sk2);
1165 unix_state_lock_nested(sk1);
1166 }
1167}
1168
1169static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
1170{
1171 if (unlikely(sk1 == sk2) || !sk2) {
1172 unix_state_unlock(sk1);
1173 return;
1174 }
1175 unix_state_unlock(sk1);
1176 unix_state_unlock(sk2);
1177}
1178
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
1180 int alen, int flags)
1181{
1182 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001183 struct net *net = sock_net(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001184 struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185 struct sock *other;
Eric Dumazet95c96172012-04-15 05:58:06 +00001186 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 int err;
1188
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001189 err = -EINVAL;
1190 if (alen < offsetofend(struct sockaddr, sa_family))
1191 goto out;
1192
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 if (addr->sa_family != AF_UNSPEC) {
1194 err = unix_mkname(sunaddr, alen, &hash);
1195 if (err < 0)
1196 goto out;
1197 alen = err;
1198
1199 if (test_bit(SOCK_PASSCRED, &sock->flags) &&
1200 !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
1201 goto out;
1202
David S. Miller278a3de2007-05-31 15:19:20 -07001203restart:
Jianjun Konge27dfce2008-11-01 21:38:31 -07001204 other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 if (!other)
1206 goto out;
1207
David S. Miller278a3de2007-05-31 15:19:20 -07001208 unix_state_double_lock(sk, other);
1209
1210 /* Apparently VFS overslept socket death. Retry. */
1211 if (sock_flag(other, SOCK_DEAD)) {
1212 unix_state_double_unlock(sk, other);
1213 sock_put(other);
1214 goto restart;
1215 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216
1217 err = -EPERM;
1218 if (!unix_may_send(sk, other))
1219 goto out_unlock;
1220
1221 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1222 if (err)
1223 goto out_unlock;
1224
Eric Dumazetdc56ad72021-08-30 10:21:37 -07001225 sk->sk_state = other->sk_state = TCP_ESTABLISHED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 } else {
1227 /*
1228 * 1003.1g breaking connected state with AF_UNSPEC
1229 */
1230 other = NULL;
David S. Miller278a3de2007-05-31 15:19:20 -07001231 unix_state_double_lock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 }
1233
1234 /*
1235 * If it was connected, reconnect.
1236 */
1237 if (unix_peer(sk)) {
1238 struct sock *old_peer = unix_peer(sk);
Eric Dumazetdc56ad72021-08-30 10:21:37 -07001239
Jianjun Konge27dfce2008-11-01 21:38:31 -07001240 unix_peer(sk) = other;
Eric Dumazetdc56ad72021-08-30 10:21:37 -07001241 if (!other)
1242 sk->sk_state = TCP_CLOSE;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001243 unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
1244
David S. Miller278a3de2007-05-31 15:19:20 -07001245 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246
1247 if (other != old_peer)
1248 unix_dgram_disconnected(sk, old_peer);
1249 sock_put(old_peer);
1250 } else {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001251 unix_peer(sk) = other;
David S. Miller278a3de2007-05-31 15:19:20 -07001252 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 }
Cong Wang83301b52021-07-04 12:02:45 -07001254
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001255 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256
1257out_unlock:
David S. Miller278a3de2007-05-31 15:19:20 -07001258 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259 sock_put(other);
1260out:
1261 return err;
1262}
1263
1264static long unix_wait_for_peer(struct sock *other, long timeo)
Jules Irenge48851e92020-02-23 23:16:56 +00001265 __releases(&unix_sk(other)->lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266{
1267 struct unix_sock *u = unix_sk(other);
1268 int sched;
1269 DEFINE_WAIT(wait);
1270
1271 prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
1272
1273 sched = !sock_flag(other, SOCK_DEAD) &&
1274 !(other->sk_shutdown & RCV_SHUTDOWN) &&
Rainer Weikusat3c734192008-06-17 22:28:05 -07001275 unix_recvq_full(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276
David S. Miller1c92b4e2007-05-31 13:24:26 -07001277 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278
1279 if (sched)
1280 timeo = schedule_timeout(timeo);
1281
1282 finish_wait(&u->peer_wait, &wait);
1283 return timeo;
1284}
1285
1286static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
1287 int addr_len, int flags)
1288{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001289 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001291 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 struct unix_sock *u = unix_sk(sk), *newu, *otheru;
1293 struct sock *newsk = NULL;
1294 struct sock *other = NULL;
1295 struct sk_buff *skb = NULL;
Eric Dumazet95c96172012-04-15 05:58:06 +00001296 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 int st;
1298 int err;
1299 long timeo;
1300
1301 err = unix_mkname(sunaddr, addr_len, &hash);
1302 if (err < 0)
1303 goto out;
1304 addr_len = err;
1305
Joe Perchesf64f9e72009-11-29 16:55:45 -08001306 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr &&
1307 (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 goto out;
1309
1310 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
1311
1312 /* First of all allocate resources.
1313 If we will make it after state is locked,
1314 we will have to recheck all again in any case.
1315 */
1316
1317 err = -ENOMEM;
1318
1319 /* create new sock for complete connection */
Jiang Wang94531cf2021-08-16 19:03:21 +00001320 newsk = unix_create1(sock_net(sk), NULL, 0, sock->type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 if (newsk == NULL)
1322 goto out;
1323
1324 /* Allocate skb for sending to listening sock */
1325 skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL);
1326 if (skb == NULL)
1327 goto out;
1328
1329restart:
1330 /* Find listening sock. */
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001331 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 if (!other)
1333 goto out;
1334
1335 /* Latch state of peer */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001336 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337
1338 /* Apparently VFS overslept socket death. Retry. */
1339 if (sock_flag(other, SOCK_DEAD)) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001340 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 sock_put(other);
1342 goto restart;
1343 }
1344
1345 err = -ECONNREFUSED;
1346 if (other->sk_state != TCP_LISTEN)
1347 goto out_unlock;
Tomoki Sekiyama77238f22009-10-18 23:17:37 -07001348 if (other->sk_shutdown & RCV_SHUTDOWN)
1349 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350
Rainer Weikusat3c734192008-06-17 22:28:05 -07001351 if (unix_recvq_full(other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 err = -EAGAIN;
1353 if (!timeo)
1354 goto out_unlock;
1355
1356 timeo = unix_wait_for_peer(other, timeo);
1357
1358 err = sock_intr_errno(timeo);
1359 if (signal_pending(current))
1360 goto out;
1361 sock_put(other);
1362 goto restart;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001363 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364
1365 /* Latch our state.
1366
Daniel Balutae5537bf2011-03-14 15:25:33 -07001367 It is tricky place. We need to grab our state lock and cannot
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 drop lock on peer. It is dangerous because deadlock is
1369 possible. Connect to self case and simultaneous
1370 attempt to connect are eliminated by checking socket
1371 state. other is TCP_LISTEN, if sk is TCP_LISTEN we
1372 check this before attempt to grab lock.
1373
1374 Well, and we have to recheck the state after socket locked.
1375 */
1376 st = sk->sk_state;
1377
1378 switch (st) {
1379 case TCP_CLOSE:
1380 /* This is ok... continue with connect */
1381 break;
1382 case TCP_ESTABLISHED:
1383 /* Socket is already connected */
1384 err = -EISCONN;
1385 goto out_unlock;
1386 default:
1387 err = -EINVAL;
1388 goto out_unlock;
1389 }
1390
David S. Miller1c92b4e2007-05-31 13:24:26 -07001391 unix_state_lock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392
1393 if (sk->sk_state != st) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001394 unix_state_unlock(sk);
1395 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 sock_put(other);
1397 goto restart;
1398 }
1399
David S. Miller3610cda2011-01-05 15:38:53 -08001400 err = security_unix_stream_connect(sk, other, newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 if (err) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001402 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 goto out_unlock;
1404 }
1405
1406 /* The way is open! Fastly set all the necessary fields... */
1407
1408 sock_hold(sk);
1409 unix_peer(newsk) = sk;
1410 newsk->sk_state = TCP_ESTABLISHED;
1411 newsk->sk_type = sk->sk_type;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001412 init_peercred(newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 newu = unix_sk(newsk);
Eric Dumazeteaefd1102011-02-18 03:26:36 +00001414 RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 otheru = unix_sk(other);
1416
Al Viroae3b5642019-02-15 20:09:35 +00001417 /* copy address information from listening to new sock
1418 *
1419 * The contents of *(otheru->addr) and otheru->path
1420 * are seen fully set up here, since we have found
1421 * otheru in hash under unix_table_lock. Insertion
1422 * into the hash chain we'd found it in had been done
1423 * in an earlier critical area protected by unix_table_lock,
1424 * the same one where we'd set *(otheru->addr) contents,
1425 * as well as otheru->path and otheru->addr itself.
1426 *
1427 * Using smp_store_release() here to set newu->addr
1428 * is enough to make those stores, as well as stores
1429 * to newu->path visible to anyone who gets newu->addr
1430 * by smp_load_acquire(). IOW, the same warranties
1431 * as for unix_sock instances bound in unix_bind() or
1432 * in unix_autobind().
1433 */
Al Viro40ffe672012-03-14 21:54:32 -04001434 if (otheru->path.dentry) {
1435 path_get(&otheru->path);
1436 newu->path = otheru->path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437 }
Al Viroae3b5642019-02-15 20:09:35 +00001438 refcount_inc(&otheru->addr->refcnt);
1439 smp_store_release(&newu->addr, otheru->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440
1441 /* Set credentials */
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001442 copy_peercred(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 sock->state = SS_CONNECTED;
1445 sk->sk_state = TCP_ESTABLISHED;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001446 sock_hold(newsk);
1447
Peter Zijlstra4e857c52014-03-17 18:06:10 +01001448 smp_mb__after_atomic(); /* sock_hold() does an atomic_inc() */
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001449 unix_peer(sk) = newsk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450
David S. Miller1c92b4e2007-05-31 13:24:26 -07001451 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452
gushengxian4e03d072021-06-09 20:09:35 -07001453 /* take ten and send info to listening sock */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454 spin_lock(&other->sk_receive_queue.lock);
1455 __skb_queue_tail(&other->sk_receive_queue, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001457 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001458 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 sock_put(other);
1460 return 0;
1461
1462out_unlock:
1463 if (other)
David S. Miller1c92b4e2007-05-31 13:24:26 -07001464 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465
1466out:
Wei Yongjun40d44442009-02-25 00:32:45 +00001467 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 if (newsk)
1469 unix_release_sock(newsk, 0);
1470 if (other)
1471 sock_put(other);
1472 return err;
1473}
1474
1475static int unix_socketpair(struct socket *socka, struct socket *sockb)
1476{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001477 struct sock *ska = socka->sk, *skb = sockb->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478
1479 /* Join our sockets back to back */
1480 sock_hold(ska);
1481 sock_hold(skb);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001482 unix_peer(ska) = skb;
1483 unix_peer(skb) = ska;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001484 init_peercred(ska);
1485 init_peercred(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486
Cong Wang83301b52021-07-04 12:02:45 -07001487 ska->sk_state = TCP_ESTABLISHED;
1488 skb->sk_state = TCP_ESTABLISHED;
1489 socka->state = SS_CONNECTED;
1490 sockb->state = SS_CONNECTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 return 0;
1492}
1493
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001494static void unix_sock_inherit_flags(const struct socket *old,
1495 struct socket *new)
1496{
1497 if (test_bit(SOCK_PASSCRED, &old->flags))
1498 set_bit(SOCK_PASSCRED, &new->flags);
1499 if (test_bit(SOCK_PASSSEC, &old->flags))
1500 set_bit(SOCK_PASSSEC, &new->flags);
1501}
1502
David Howellscdfbabf2017-03-09 08:09:05 +00001503static int unix_accept(struct socket *sock, struct socket *newsock, int flags,
1504 bool kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505{
1506 struct sock *sk = sock->sk;
1507 struct sock *tsk;
1508 struct sk_buff *skb;
1509 int err;
1510
1511 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001512 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 goto out;
1514
1515 err = -EINVAL;
1516 if (sk->sk_state != TCP_LISTEN)
1517 goto out;
1518
1519 /* If socket state is TCP_LISTEN it cannot change (for now...),
1520 * so that no locks are necessary.
1521 */
1522
1523 skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
1524 if (!skb) {
1525 /* This means receive shutdown. */
1526 if (err == 0)
1527 err = -EINVAL;
1528 goto out;
1529 }
1530
1531 tsk = skb->sk;
1532 skb_free_datagram(sk, skb);
1533 wake_up_interruptible(&unix_sk(sk)->peer_wait);
1534
1535 /* attach accepted sock to socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001536 unix_state_lock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 newsock->state = SS_CONNECTED;
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001538 unix_sock_inherit_flags(sock, newsock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 sock_graft(tsk, newsock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001540 unix_state_unlock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 return 0;
1542
1543out:
1544 return err;
1545}
1546
1547
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001548static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549{
1550 struct sock *sk = sock->sk;
Al Viroae3b5642019-02-15 20:09:35 +00001551 struct unix_address *addr;
Cyrill Gorcunov13cfa972009-11-08 05:51:19 +00001552 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 int err = 0;
1554
1555 if (peer) {
1556 sk = unix_peer_get(sk);
1557
1558 err = -ENOTCONN;
1559 if (!sk)
1560 goto out;
1561 err = 0;
1562 } else {
1563 sock_hold(sk);
1564 }
1565
Al Viroae3b5642019-02-15 20:09:35 +00001566 addr = smp_load_acquire(&unix_sk(sk)->addr);
1567 if (!addr) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 sunaddr->sun_family = AF_UNIX;
1569 sunaddr->sun_path[0] = 0;
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001570 err = sizeof(short);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 } else {
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001572 err = addr->len;
1573 memcpy(sunaddr, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 sock_put(sk);
1576out:
1577 return err;
1578}
1579
Miklos Szeredicbcf0112021-07-28 14:47:20 +02001580static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb)
1581{
1582 scm->fp = scm_fp_dup(UNIXCB(skb).fp);
1583
1584 /*
1585 * Garbage collection of unix sockets starts by selecting a set of
1586 * candidate sockets which have reference only from being in flight
1587 * (total_refs == inflight_refs). This condition is checked once during
1588 * the candidate collection phase, and candidates are marked as such, so
1589 * that non-candidates can later be ignored. While inflight_refs is
1590 * protected by unix_gc_lock, total_refs (file count) is not, hence this
1591 * is an instantaneous decision.
1592 *
1593 * Once a candidate, however, the socket must not be reinstalled into a
1594 * file descriptor while the garbage collection is in progress.
1595 *
1596 * If the above conditions are met, then the directed graph of
1597 * candidates (*) does not change while unix_gc_lock is held.
1598 *
1599 * Any operations that changes the file count through file descriptors
1600 * (dup, close, sendmsg) does not change the graph since candidates are
1601 * not installed in fds.
1602 *
1603 * Dequeing a candidate via recvmsg would install it into an fd, but
1604 * that takes unix_gc_lock to decrement the inflight count, so it's
1605 * serialized with garbage collection.
1606 *
1607 * MSG_PEEK is special in that it does not change the inflight count,
1608 * yet does install the socket into an fd. The following lock/unlock
1609 * pair is to ensure serialization with garbage collection. It must be
1610 * done between incrementing the file count and installing the file into
1611 * an fd.
1612 *
1613 * If garbage collection starts after the barrier provided by the
1614 * lock/unlock, then it will see the elevated refcount and not mark this
1615 * as a candidate. If a garbage collection is already in progress
1616 * before the file count was incremented, then the lock/unlock pair will
1617 * ensure that garbage collection is finished before progressing to
1618 * installing the fd.
1619 *
1620 * (*) A -> B where B is on the queue of A or B is on the queue of C
1621 * which is on the queue of listening socket A.
1622 */
1623 spin_lock(&unix_gc_lock);
1624 spin_unlock(&unix_gc_lock);
1625}
1626
David S. Millerf78a5fd2011-09-16 19:34:00 -04001627static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001628{
1629 int err = 0;
Eric Dumazet16e57262011-09-19 05:52:27 +00001630
David S. Millerf78a5fd2011-09-16 19:34:00 -04001631 UNIXCB(skb).pid = get_pid(scm->pid);
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001632 UNIXCB(skb).uid = scm->creds.uid;
1633 UNIXCB(skb).gid = scm->creds.gid;
Eric W. Biederman7361c362010-06-13 03:34:33 +00001634 UNIXCB(skb).fp = NULL;
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04001635 unix_get_secdata(scm, skb);
Eric W. Biederman7361c362010-06-13 03:34:33 +00001636 if (scm->fp && send_fds)
1637 err = unix_attach_fds(scm, skb);
1638
1639 skb->destructor = unix_destruct_scm;
1640 return err;
1641}
1642
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001643static bool unix_passcred_enabled(const struct socket *sock,
1644 const struct sock *other)
1645{
1646 return test_bit(SOCK_PASSCRED, &sock->flags) ||
1647 !other->sk_socket ||
1648 test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
1649}
1650
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651/*
Eric Dumazet16e57262011-09-19 05:52:27 +00001652 * Some apps rely on write() giving SCM_CREDENTIALS
1653 * We include credentials if source or destination socket
1654 * asserted SOCK_PASSCRED.
1655 */
1656static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1657 const struct sock *other)
1658{
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001659 if (UNIXCB(skb).pid)
Eric Dumazet16e57262011-09-19 05:52:27 +00001660 return;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001661 if (unix_passcred_enabled(sock, other)) {
Eric Dumazet16e57262011-09-19 05:52:27 +00001662 UNIXCB(skb).pid = get_pid(task_tgid(current));
David S. Miller6e0895c2013-04-22 20:32:51 -04001663 current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
Eric Dumazet16e57262011-09-19 05:52:27 +00001664 }
1665}
1666
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001667static int maybe_init_creds(struct scm_cookie *scm,
1668 struct socket *socket,
1669 const struct sock *other)
1670{
1671 int err;
1672 struct msghdr msg = { .msg_controllen = 0 };
1673
1674 err = scm_send(socket, &msg, scm, false);
1675 if (err)
1676 return err;
1677
1678 if (unix_passcred_enabled(socket, other)) {
1679 scm->pid = get_pid(task_tgid(current));
1680 current_uid_gid(&scm->creds.uid, &scm->creds.gid);
1681 }
1682 return err;
1683}
1684
1685static bool unix_skb_scm_eq(struct sk_buff *skb,
1686 struct scm_cookie *scm)
1687{
1688 const struct unix_skb_parms *u = &UNIXCB(skb);
1689
1690 return u->pid == scm->pid &&
1691 uid_eq(u->uid, scm->creds.uid) &&
1692 gid_eq(u->gid, scm->creds.gid) &&
1693 unix_secdata_eq(scm, skb);
1694}
1695
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001696static void scm_stat_add(struct sock *sk, struct sk_buff *skb)
1697{
1698 struct scm_fp_list *fp = UNIXCB(skb).fp;
1699 struct unix_sock *u = unix_sk(sk);
1700
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001701 if (unlikely(fp && fp->count))
Paolo Abeni77820402020-02-28 14:45:21 +01001702 atomic_add(fp->count, &u->scm_stat.nr_fds);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001703}
1704
1705static void scm_stat_del(struct sock *sk, struct sk_buff *skb)
1706{
1707 struct scm_fp_list *fp = UNIXCB(skb).fp;
1708 struct unix_sock *u = unix_sk(sk);
1709
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001710 if (unlikely(fp && fp->count))
Paolo Abeni77820402020-02-28 14:45:21 +01001711 atomic_sub(fp->count, &u->scm_stat.nr_fds);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001712}
1713
Eric Dumazet16e57262011-09-19 05:52:27 +00001714/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 * Send AF_UNIX data.
1716 */
1717
Ying Xue1b784142015-03-02 15:37:48 +08001718static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
1719 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001722 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 struct unix_sock *u = unix_sk(sk);
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001724 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 struct sock *other = NULL;
1726 int namelen = 0; /* fake GCC */
1727 int err;
Eric Dumazet95c96172012-04-15 05:58:06 +00001728 unsigned int hash;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001729 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 long timeo;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001731 struct scm_cookie scm;
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001732 int data_len = 0;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001733 int sk_locked;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
dann frazier5f23b732008-11-26 15:32:27 -08001735 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001736 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 if (err < 0)
1738 return err;
1739
1740 err = -EOPNOTSUPP;
1741 if (msg->msg_flags&MSG_OOB)
1742 goto out;
1743
1744 if (msg->msg_namelen) {
1745 err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
1746 if (err < 0)
1747 goto out;
1748 namelen = err;
1749 } else {
1750 sunaddr = NULL;
1751 err = -ENOTCONN;
1752 other = unix_peer_get(sk);
1753 if (!other)
1754 goto out;
1755 }
1756
Joe Perchesf64f9e72009-11-29 16:55:45 -08001757 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr
1758 && (err = unix_autobind(sock)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 goto out;
1760
1761 err = -EMSGSIZE;
1762 if (len > sk->sk_sndbuf - 32)
1763 goto out;
1764
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001765 if (len > SKB_MAX_ALLOC) {
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001766 data_len = min_t(size_t,
1767 len - SKB_MAX_ALLOC,
1768 MAX_SKB_FRAGS * PAGE_SIZE);
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001769 data_len = PAGE_ALIGN(data_len);
1770
1771 BUILD_BUG_ON(SKB_MAX_ALLOC < PAGE_SIZE);
1772 }
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001773
1774 skb = sock_alloc_send_pskb(sk, len - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07001775 msg->msg_flags & MSG_DONTWAIT, &err,
1776 PAGE_ALLOC_COSTLY_ORDER);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001777 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 goto out;
1779
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001780 err = unix_scm_to_skb(&scm, skb, true);
Eric Dumazet25888e32010-11-25 04:11:39 +00001781 if (err < 0)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001782 goto out_free;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001783
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001784 skb_put(skb, len - data_len);
1785 skb->data_len = data_len;
1786 skb->len = len;
Al Viroc0371da2014-11-24 10:42:55 -05001787 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 if (err)
1789 goto out_free;
1790
1791 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1792
1793restart:
1794 if (!other) {
1795 err = -ECONNRESET;
1796 if (sunaddr == NULL)
1797 goto out_free;
1798
Denis V. Lunev097e66c2007-11-19 22:29:30 -08001799 other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 hash, &err);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001801 if (other == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 goto out_free;
1803 }
1804
Alban Crequyd6ae3ba2011-01-18 06:39:15 +00001805 if (sk_filter(other, skb) < 0) {
1806 /* Toss the packet but do not return any error to the sender */
1807 err = len;
1808 goto out_free;
1809 }
1810
Rainer Weikusat7d267272015-11-20 22:07:23 +00001811 sk_locked = 0;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001812 unix_state_lock(other);
Rainer Weikusat7d267272015-11-20 22:07:23 +00001813restart_locked:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 err = -EPERM;
1815 if (!unix_may_send(sk, other))
1816 goto out_unlock;
1817
Rainer Weikusat7d267272015-11-20 22:07:23 +00001818 if (unlikely(sock_flag(other, SOCK_DEAD))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 /*
1820 * Check with 1003.1g - what should
1821 * datagram error
1822 */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001823 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 sock_put(other);
1825
Rainer Weikusat7d267272015-11-20 22:07:23 +00001826 if (!sk_locked)
1827 unix_state_lock(sk);
1828
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 if (unix_peer(sk) == other) {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001831 unix_peer(sk) = NULL;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001832 unix_dgram_peer_wake_disconnect_wakeup(sk, other);
1833
David S. Miller1c92b4e2007-05-31 13:24:26 -07001834 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
Eric Dumazetdc56ad72021-08-30 10:21:37 -07001836 sk->sk_state = TCP_CLOSE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 unix_dgram_disconnected(sk, other);
1838 sock_put(other);
1839 err = -ECONNREFUSED;
1840 } else {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001841 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 }
1843
1844 other = NULL;
1845 if (err)
1846 goto out_free;
1847 goto restart;
1848 }
1849
1850 err = -EPIPE;
1851 if (other->sk_shutdown & RCV_SHUTDOWN)
1852 goto out_unlock;
1853
1854 if (sk->sk_type != SOCK_SEQPACKET) {
1855 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1856 if (err)
1857 goto out_unlock;
1858 }
1859
Rainer Weikusata5527dd2016-02-11 19:37:27 +00001860 /* other == sk && unix_peer(other) != sk if
1861 * - unix_peer(sk) == NULL, destination address bound to sk
1862 * - unix_peer(sk) == sk by time of get but disconnected before lock
1863 */
1864 if (other != sk &&
Qian Cai86b18aa2020-02-04 13:40:29 -05001865 unlikely(unix_peer(other) != sk &&
1866 unix_recvq_full_lockless(other))) {
Rainer Weikusat7d267272015-11-20 22:07:23 +00001867 if (timeo) {
1868 timeo = unix_wait_for_peer(other, timeo);
1869
1870 err = sock_intr_errno(timeo);
1871 if (signal_pending(current))
1872 goto out_free;
1873
1874 goto restart;
1875 }
1876
1877 if (!sk_locked) {
1878 unix_state_unlock(other);
1879 unix_state_double_lock(sk, other);
1880 }
1881
1882 if (unix_peer(sk) != other ||
1883 unix_dgram_peer_wake_me(sk, other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 err = -EAGAIN;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001885 sk_locked = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 goto out_unlock;
1887 }
1888
Rainer Weikusat7d267272015-11-20 22:07:23 +00001889 if (!sk_locked) {
1890 sk_locked = 1;
1891 goto restart_locked;
1892 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 }
1894
Rainer Weikusat7d267272015-11-20 22:07:23 +00001895 if (unlikely(sk_locked))
1896 unix_state_unlock(sk);
1897
Alban Crequy3f661162010-10-04 08:48:28 +00001898 if (sock_flag(other, SOCK_RCVTSTAMP))
1899 __net_timestamp(skb);
Eric Dumazet16e57262011-09-19 05:52:27 +00001900 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001901 scm_stat_add(other, skb);
Paolo Abeni77820402020-02-28 14:45:21 +01001902 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001903 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001904 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001906 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 return len;
1908
1909out_unlock:
Rainer Weikusat7d267272015-11-20 22:07:23 +00001910 if (sk_locked)
1911 unix_state_unlock(sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001912 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913out_free:
1914 kfree_skb(skb);
1915out:
1916 if (other)
1917 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001918 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 return err;
1920}
1921
Eric Dumazete370a722013-08-08 14:37:32 -07001922/* We use paged skbs for stream sockets, and limit occupancy to 32768
Tobias Klauserd4e9a402018-02-13 11:11:30 +01001923 * bytes, and a minimum of a full page.
Eric Dumazete370a722013-08-08 14:37:32 -07001924 */
1925#define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001926
Rao Shoaib314001f2021-08-01 00:57:07 -07001927#if (IS_ENABLED(CONFIG_AF_UNIX_OOB))
1928static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other)
1929{
1930 struct unix_sock *ousk = unix_sk(other);
1931 struct sk_buff *skb;
1932 int err = 0;
1933
1934 skb = sock_alloc_send_skb(sock->sk, 1, msg->msg_flags & MSG_DONTWAIT, &err);
1935
1936 if (!skb)
1937 return err;
1938
1939 skb_put(skb, 1);
Rao Shoaib314001f2021-08-01 00:57:07 -07001940 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, 1);
1941
1942 if (err) {
1943 kfree_skb(skb);
1944 return err;
1945 }
1946
1947 unix_state_lock(other);
Rao Shoaib19eed722021-08-13 11:19:34 -07001948
1949 if (sock_flag(other, SOCK_DEAD) ||
1950 (other->sk_shutdown & RCV_SHUTDOWN)) {
1951 unix_state_unlock(other);
1952 kfree_skb(skb);
1953 return -EPIPE;
1954 }
1955
Rao Shoaib314001f2021-08-01 00:57:07 -07001956 maybe_add_creds(skb, sock, other);
1957 skb_get(skb);
1958
1959 if (ousk->oob_skb)
Rao Shoaib19eed722021-08-13 11:19:34 -07001960 consume_skb(ousk->oob_skb);
Rao Shoaib314001f2021-08-01 00:57:07 -07001961
1962 ousk->oob_skb = skb;
1963
1964 scm_stat_add(other, skb);
1965 skb_queue_tail(&other->sk_receive_queue, skb);
1966 sk_send_sigurg(other);
1967 unix_state_unlock(other);
1968 other->sk_data_ready(other);
1969
1970 return err;
1971}
1972#endif
1973
Ying Xue1b784142015-03-02 15:37:48 +08001974static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1975 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 struct sock *sk = sock->sk;
1978 struct sock *other = NULL;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001979 int err, size;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001980 struct sk_buff *skb;
Jianjun Konge27dfce2008-11-01 21:38:31 -07001981 int sent = 0;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001982 struct scm_cookie scm;
Miklos Szeredi8ba69ba2009-09-11 11:31:45 -07001983 bool fds_sent = false;
Eric Dumazete370a722013-08-08 14:37:32 -07001984 int data_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985
dann frazier5f23b732008-11-26 15:32:27 -08001986 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001987 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988 if (err < 0)
1989 return err;
1990
1991 err = -EOPNOTSUPP;
Rao Shoaib314001f2021-08-01 00:57:07 -07001992 if (msg->msg_flags & MSG_OOB) {
1993#if (IS_ENABLED(CONFIG_AF_UNIX_OOB))
1994 if (len)
1995 len--;
1996 else
1997#endif
1998 goto out_err;
1999 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000
2001 if (msg->msg_namelen) {
2002 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
2003 goto out_err;
2004 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005 err = -ENOTCONN;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08002006 other = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007 if (!other)
2008 goto out_err;
2009 }
2010
2011 if (sk->sk_shutdown & SEND_SHUTDOWN)
2012 goto pipe_err;
2013
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002014 while (sent < len) {
Eric Dumazete370a722013-08-08 14:37:32 -07002015 size = len - sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016
2017 /* Keep two messages in the pipe so it schedules better */
Eric Dumazete370a722013-08-08 14:37:32 -07002018 size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019
Eric Dumazete370a722013-08-08 14:37:32 -07002020 /* allow fallback to order-0 allocations */
2021 size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002022
Eric Dumazete370a722013-08-08 14:37:32 -07002023 data_len = max_t(int, 0, size - SKB_MAX_HEAD(0));
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002024
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04002025 data_len = min_t(size_t, size, PAGE_ALIGN(data_len));
2026
Eric Dumazete370a722013-08-08 14:37:32 -07002027 skb = sock_alloc_send_pskb(sk, size - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07002028 msg->msg_flags & MSG_DONTWAIT, &err,
2029 get_order(UNIX_SKB_FRAGS_SZ));
Eric Dumazete370a722013-08-08 14:37:32 -07002030 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031 goto out_err;
2032
David S. Millerf78a5fd2011-09-16 19:34:00 -04002033 /* Only send the fds in the first buffer */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002034 err = unix_scm_to_skb(&scm, skb, !fds_sent);
Eric Dumazet25888e32010-11-25 04:11:39 +00002035 if (err < 0) {
Eric W. Biederman7361c362010-06-13 03:34:33 +00002036 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04002037 goto out_err;
Miklos Szeredi62093442008-11-09 15:23:57 +01002038 }
Eric W. Biederman7361c362010-06-13 03:34:33 +00002039 fds_sent = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002040
Eric Dumazete370a722013-08-08 14:37:32 -07002041 skb_put(skb, size - data_len);
2042 skb->data_len = data_len;
2043 skb->len = size;
Al Viroc0371da2014-11-24 10:42:55 -05002044 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002045 if (err) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04002047 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048 }
2049
David S. Miller1c92b4e2007-05-31 13:24:26 -07002050 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051
2052 if (sock_flag(other, SOCK_DEAD) ||
2053 (other->sk_shutdown & RCV_SHUTDOWN))
2054 goto pipe_err_free;
2055
Eric Dumazet16e57262011-09-19 05:52:27 +00002056 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002057 scm_stat_add(other, skb);
Paolo Abeni77820402020-02-28 14:45:21 +01002058 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002059 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04002060 other->sk_data_ready(other);
Jianjun Konge27dfce2008-11-01 21:38:31 -07002061 sent += size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063
Rao Shoaib314001f2021-08-01 00:57:07 -07002064#if (IS_ENABLED(CONFIG_AF_UNIX_OOB))
2065 if (msg->msg_flags & MSG_OOB) {
2066 err = queue_oob(sock, msg, other);
2067 if (err)
2068 goto out_err;
2069 sent++;
2070 }
2071#endif
2072
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002073 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074
2075 return sent;
2076
2077pipe_err_free:
David S. Miller1c92b4e2007-05-31 13:24:26 -07002078 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 kfree_skb(skb);
2080pipe_err:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002081 if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
2082 send_sig(SIGPIPE, current, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083 err = -EPIPE;
2084out_err:
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002085 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 return sent ? : err;
2087}
2088
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002089static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
2090 int offset, size_t size, int flags)
2091{
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002092 int err;
2093 bool send_sigpipe = false;
2094 bool init_scm = true;
2095 struct scm_cookie scm;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002096 struct sock *other, *sk = socket->sk;
2097 struct sk_buff *skb, *newskb = NULL, *tail = NULL;
2098
2099 if (flags & MSG_OOB)
2100 return -EOPNOTSUPP;
2101
2102 other = unix_peer(sk);
2103 if (!other || sk->sk_state != TCP_ESTABLISHED)
2104 return -ENOTCONN;
2105
2106 if (false) {
2107alloc_skb:
2108 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002109 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002110 newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
2111 &err, 0);
2112 if (!newskb)
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002113 goto err;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002114 }
2115
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002116 /* we must acquire iolock as we modify already present
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002117 * skbs in the sk_receive_queue and mess with skb->len
2118 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002119 err = mutex_lock_interruptible(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002120 if (err) {
2121 err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002122 goto err;
2123 }
2124
2125 if (sk->sk_shutdown & SEND_SHUTDOWN) {
2126 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002127 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002128 goto err_unlock;
2129 }
2130
2131 unix_state_lock(other);
2132
2133 if (sock_flag(other, SOCK_DEAD) ||
2134 other->sk_shutdown & RCV_SHUTDOWN) {
2135 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002136 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002137 goto err_state_unlock;
2138 }
2139
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002140 if (init_scm) {
2141 err = maybe_init_creds(&scm, socket, other);
2142 if (err)
2143 goto err_state_unlock;
2144 init_scm = false;
2145 }
2146
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002147 skb = skb_peek_tail(&other->sk_receive_queue);
2148 if (tail && tail == skb) {
2149 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002150 } else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
2151 if (newskb) {
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002152 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002153 } else {
2154 tail = skb;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002155 goto alloc_skb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002156 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002157 } else if (newskb) {
2158 /* this is fast path, we don't necessarily need to
2159 * call to kfree_skb even though with newskb == NULL
2160 * this - does no harm
2161 */
2162 consume_skb(newskb);
Hannes Frederic Sowa8844f972015-11-16 16:25:56 +01002163 newskb = NULL;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002164 }
2165
2166 if (skb_append_pagefrags(skb, page, offset, size)) {
2167 tail = skb;
2168 goto alloc_skb;
2169 }
2170
2171 skb->len += size;
2172 skb->data_len += size;
2173 skb->truesize += size;
Reshetova, Elena14afee42017-06-30 13:08:00 +03002174 refcount_add(size, &sk->sk_wmem_alloc);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002175
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002176 if (newskb) {
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002177 err = unix_scm_to_skb(&scm, skb, false);
2178 if (err)
2179 goto err_state_unlock;
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002180 spin_lock(&other->sk_receive_queue.lock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002181 __skb_queue_tail(&other->sk_receive_queue, newskb);
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002182 spin_unlock(&other->sk_receive_queue.lock);
2183 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002184
2185 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002186 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002187
2188 other->sk_data_ready(other);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002189 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002190 return size;
2191
2192err_state_unlock:
2193 unix_state_unlock(other);
2194err_unlock:
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002195 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002196err:
2197 kfree_skb(newskb);
2198 if (send_sigpipe && !(flags & MSG_NOSIGNAL))
2199 send_sig(SIGPIPE, current, 0);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002200 if (!init_scm)
2201 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002202 return err;
2203}
2204
Ying Xue1b784142015-03-02 15:37:48 +08002205static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg,
2206 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207{
2208 int err;
2209 struct sock *sk = sock->sk;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002210
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211 err = sock_error(sk);
2212 if (err)
2213 return err;
2214
2215 if (sk->sk_state != TCP_ESTABLISHED)
2216 return -ENOTCONN;
2217
2218 if (msg->msg_namelen)
2219 msg->msg_namelen = 0;
2220
Ying Xue1b784142015-03-02 15:37:48 +08002221 return unix_dgram_sendmsg(sock, msg, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222}
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002223
Ying Xue1b784142015-03-02 15:37:48 +08002224static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg,
2225 size_t size, int flags)
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002226{
2227 struct sock *sk = sock->sk;
2228
2229 if (sk->sk_state != TCP_ESTABLISHED)
2230 return -ENOTCONN;
2231
Ying Xue1b784142015-03-02 15:37:48 +08002232 return unix_dgram_recvmsg(sock, msg, size, flags);
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002233}
2234
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
2236{
Al Viroae3b5642019-02-15 20:09:35 +00002237 struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
Al Viroae3b5642019-02-15 20:09:35 +00002239 if (addr) {
2240 msg->msg_namelen = addr->len;
2241 memcpy(msg->msg_name, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242 }
2243}
2244
Cong Wang9825d862021-07-04 12:02:48 -07002245int __unix_dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t size,
2246 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002248 struct scm_cookie scm;
Cong Wang9825d862021-07-04 12:02:48 -07002249 struct socket *sock = sk->sk_socket;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 struct unix_sock *u = unix_sk(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002251 struct sk_buff *skb, *last;
2252 long timeo;
Paolo Abenifd69c392019-04-08 10:15:59 +02002253 int skip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254 int err;
2255
2256 err = -EOPNOTSUPP;
2257 if (flags&MSG_OOB)
2258 goto out;
2259
Rainer Weikusat64874282015-12-06 21:11:38 +00002260 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261
Rainer Weikusat64874282015-12-06 21:11:38 +00002262 do {
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002263 mutex_lock(&u->iolock);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002264
Rainer Weikusat64874282015-12-06 21:11:38 +00002265 skip = sk_peek_offset(sk, flags);
Sabrina Dubrocab50b0582019-11-25 14:48:57 +01002266 skb = __skb_try_recv_datagram(sk, &sk->sk_receive_queue, flags,
Paolo Abenie427cad2020-02-28 14:45:22 +01002267 &skip, &err, &last);
2268 if (skb) {
2269 if (!(flags & MSG_PEEK))
2270 scm_stat_del(sk, skb);
Rainer Weikusat64874282015-12-06 21:11:38 +00002271 break;
Paolo Abenie427cad2020-02-28 14:45:22 +01002272 }
Rainer Weikusat64874282015-12-06 21:11:38 +00002273
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002274 mutex_unlock(&u->iolock);
Rainer Weikusat64874282015-12-06 21:11:38 +00002275
2276 if (err != -EAGAIN)
2277 break;
2278 } while (timeo &&
Sabrina Dubrocab50b0582019-11-25 14:48:57 +01002279 !__skb_wait_for_more_packets(sk, &sk->sk_receive_queue,
2280 &err, &timeo, last));
Rainer Weikusat64874282015-12-06 21:11:38 +00002281
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002282 if (!skb) { /* implies iolock unlocked */
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002283 unix_state_lock(sk);
2284 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
2285 if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
2286 (sk->sk_shutdown & RCV_SHUTDOWN))
2287 err = 0;
2288 unix_state_unlock(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002289 goto out;
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002290 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291
Rainer Weikusat77b75f42015-11-26 19:23:15 +00002292 if (wq_has_sleeper(&u->peer_wait))
2293 wake_up_interruptible_sync_poll(&u->peer_wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002294 EPOLLOUT | EPOLLWRNORM |
2295 EPOLLWRBAND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296
2297 if (msg->msg_name)
2298 unix_copy_addr(msg, skb->sk);
2299
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002300 if (size > skb->len - skip)
2301 size = skb->len - skip;
2302 else if (size < skb->len - skip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303 msg->msg_flags |= MSG_TRUNC;
2304
David S. Miller51f3d022014-11-05 16:46:40 -05002305 err = skb_copy_datagram_msg(skb, skip, msg, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306 if (err)
2307 goto out_free;
2308
Alban Crequy3f661162010-10-04 08:48:28 +00002309 if (sock_flag(sk, SOCK_RCVTSTAMP))
2310 __sock_recv_timestamp(msg, sk, skb);
2311
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002312 memset(&scm, 0, sizeof(scm));
2313
2314 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
2315 unix_set_secdata(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002317 if (!(flags & MSG_PEEK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002319 unix_detach_fds(&scm, skb);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002320
2321 sk_peek_offset_bwd(sk, skb->len);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002322 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 /* It is questionable: on PEEK we could:
2324 - do not return fds - good, but too simple 8)
2325 - return fds, and do not return them on read (old strategy,
2326 apparently wrong)
2327 - clone fds (I chose it for now, it is the most universal
2328 solution)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002329
2330 POSIX 1003.1g does not actually define this clearly
2331 at all. POSIX 1003.1g doesn't define a lot of things
2332 clearly however!
2333
Linus Torvalds1da177e2005-04-16 15:20:36 -07002334 */
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002335
2336 sk_peek_offset_fwd(sk, size);
2337
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338 if (UNIXCB(skb).fp)
Miklos Szeredicbcf0112021-07-28 14:47:20 +02002339 unix_peek_fds(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340 }
Eric Dumazet9f6f9af2012-02-21 23:24:55 +00002341 err = (flags & MSG_TRUNC) ? skb->len - skip : size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002343 scm_recv(sock, msg, &scm, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344
2345out_free:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002346 skb_free_datagram(sk, skb);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002347 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348out:
2349 return err;
2350}
2351
Cong Wang9825d862021-07-04 12:02:48 -07002352static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
2353 int flags)
2354{
2355 struct sock *sk = sock->sk;
2356
2357#ifdef CONFIG_BPF_SYSCALL
Jiang Wang94531cf2021-08-16 19:03:21 +00002358 const struct proto *prot = READ_ONCE(sk->sk_prot);
2359
2360 if (prot != &unix_dgram_proto)
2361 return prot->recvmsg(sk, msg, size, flags & MSG_DONTWAIT,
Cong Wang9825d862021-07-04 12:02:48 -07002362 flags & ~MSG_DONTWAIT, NULL);
2363#endif
2364 return __unix_dgram_recvmsg(sk, msg, size, flags);
2365}
2366
Cong Wang29df44f2021-07-04 12:02:44 -07002367static int unix_read_sock(struct sock *sk, read_descriptor_t *desc,
2368 sk_read_actor_t recv_actor)
2369{
2370 int copied = 0;
2371
2372 while (1) {
2373 struct unix_sock *u = unix_sk(sk);
2374 struct sk_buff *skb;
2375 int used, err;
2376
2377 mutex_lock(&u->iolock);
2378 skb = skb_recv_datagram(sk, 0, 1, &err);
2379 mutex_unlock(&u->iolock);
2380 if (!skb)
2381 return err;
2382
2383 used = recv_actor(desc, skb, 0, skb->len);
2384 if (used <= 0) {
2385 if (!copied)
2386 copied = used;
2387 kfree_skb(skb);
2388 break;
2389 } else if (used <= skb->len) {
2390 copied += used;
2391 }
2392
2393 kfree_skb(skb);
2394 if (!desc->count)
2395 break;
2396 }
2397
2398 return copied;
2399}
2400
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401/*
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002402 * Sleep until more data has arrived. But check for races..
Linus Torvalds1da177e2005-04-16 15:20:36 -07002403 */
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002404static long unix_stream_data_wait(struct sock *sk, long timeo,
WANG Cong06a77b02016-11-17 15:55:26 -08002405 struct sk_buff *last, unsigned int last_len,
2406 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407{
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002408 struct sk_buff *tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409 DEFINE_WAIT(wait);
2410
David S. Miller1c92b4e2007-05-31 13:24:26 -07002411 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412
2413 for (;;) {
Eric Dumazetaa395142010-04-20 13:03:51 +00002414 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002416 tail = skb_peek_tail(&sk->sk_receive_queue);
2417 if (tail != last ||
2418 (tail && tail->len != last_len) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419 sk->sk_err ||
2420 (sk->sk_shutdown & RCV_SHUTDOWN) ||
2421 signal_pending(current) ||
2422 !timeo)
2423 break;
2424
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002425 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002426 unix_state_unlock(sk);
WANG Cong06a77b02016-11-17 15:55:26 -08002427 if (freezable)
2428 timeo = freezable_schedule_timeout(timeo);
2429 else
2430 timeo = schedule_timeout(timeo);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002431 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002432
2433 if (sock_flag(sk, SOCK_DEAD))
2434 break;
2435
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002436 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437 }
2438
Eric Dumazetaa395142010-04-20 13:03:51 +00002439 finish_wait(sk_sleep(sk), &wait);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002440 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441 return timeo;
2442}
2443
Eric Dumazete370a722013-08-08 14:37:32 -07002444static unsigned int unix_skb_len(const struct sk_buff *skb)
2445{
2446 return skb->len - UNIXCB(skb).consumed;
2447}
2448
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002449struct unix_stream_read_state {
2450 int (*recv_actor)(struct sk_buff *, int, int,
2451 struct unix_stream_read_state *);
2452 struct socket *socket;
2453 struct msghdr *msg;
2454 struct pipe_inode_info *pipe;
2455 size_t size;
2456 int flags;
2457 unsigned int splice_flags;
2458};
2459
Rao Shoaib314001f2021-08-01 00:57:07 -07002460#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
2461static int unix_stream_recv_urg(struct unix_stream_read_state *state)
2462{
2463 struct socket *sock = state->socket;
2464 struct sock *sk = sock->sk;
2465 struct unix_sock *u = unix_sk(sk);
2466 int chunk = 1;
Rao Shoaib876c14a2021-08-11 15:06:52 -07002467 struct sk_buff *oob_skb;
Rao Shoaib314001f2021-08-01 00:57:07 -07002468
Rao Shoaib876c14a2021-08-11 15:06:52 -07002469 mutex_lock(&u->iolock);
2470 unix_state_lock(sk);
2471
2472 if (sock_flag(sk, SOCK_URGINLINE) || !u->oob_skb) {
2473 unix_state_unlock(sk);
2474 mutex_unlock(&u->iolock);
Rao Shoaib314001f2021-08-01 00:57:07 -07002475 return -EINVAL;
Rao Shoaib876c14a2021-08-11 15:06:52 -07002476 }
Rao Shoaib314001f2021-08-01 00:57:07 -07002477
Rao Shoaib876c14a2021-08-11 15:06:52 -07002478 oob_skb = u->oob_skb;
2479
2480 if (!(state->flags & MSG_PEEK)) {
2481 u->oob_skb = NULL;
2482 }
2483
2484 unix_state_unlock(sk);
2485
2486 chunk = state->recv_actor(oob_skb, 0, chunk, state);
2487
2488 if (!(state->flags & MSG_PEEK)) {
2489 UNIXCB(oob_skb).consumed += 1;
2490 kfree_skb(oob_skb);
2491 }
2492
2493 mutex_unlock(&u->iolock);
2494
Rao Shoaib314001f2021-08-01 00:57:07 -07002495 if (chunk < 0)
2496 return -EFAULT;
2497
Rao Shoaib314001f2021-08-01 00:57:07 -07002498 state->msg->msg_flags |= MSG_OOB;
2499 return 1;
2500}
2501
2502static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
2503 int flags, int copied)
2504{
2505 struct unix_sock *u = unix_sk(sk);
2506
2507 if (!unix_skb_len(skb) && !(flags & MSG_PEEK)) {
2508 skb_unlink(skb, &sk->sk_receive_queue);
2509 consume_skb(skb);
2510 skb = NULL;
2511 } else {
2512 if (skb == u->oob_skb) {
2513 if (copied) {
2514 skb = NULL;
2515 } else if (sock_flag(sk, SOCK_URGINLINE)) {
2516 if (!(flags & MSG_PEEK)) {
2517 u->oob_skb = NULL;
2518 consume_skb(skb);
2519 }
2520 } else if (!(flags & MSG_PEEK)) {
2521 skb_unlink(skb, &sk->sk_receive_queue);
2522 consume_skb(skb);
2523 skb = skb_peek(&sk->sk_receive_queue);
2524 }
2525 }
2526 }
2527 return skb;
2528}
2529#endif
2530
Jiang Wang77462de2021-08-16 19:03:20 +00002531static int unix_stream_read_sock(struct sock *sk, read_descriptor_t *desc,
2532 sk_read_actor_t recv_actor)
2533{
2534 if (unlikely(sk->sk_state != TCP_ESTABLISHED))
2535 return -ENOTCONN;
2536
2537 return unix_read_sock(sk, desc, recv_actor);
2538}
2539
WANG Cong06a77b02016-11-17 15:55:26 -08002540static int unix_stream_read_generic(struct unix_stream_read_state *state,
2541 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002542{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002543 struct scm_cookie scm;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002544 struct socket *sock = state->socket;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545 struct sock *sk = sock->sk;
2546 struct unix_sock *u = unix_sk(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547 int copied = 0;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002548 int flags = state->flags;
Eric Dumazetde144392014-03-25 18:42:27 -07002549 int noblock = flags & MSG_DONTWAIT;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002550 bool check_creds = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 int target;
2552 int err = 0;
2553 long timeo;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002554 int skip;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002555 size_t size = state->size;
2556 unsigned int last_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002558 if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
2559 err = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002561 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002563 if (unlikely(flags & MSG_OOB)) {
2564 err = -EOPNOTSUPP;
Rao Shoaib314001f2021-08-01 00:57:07 -07002565#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
Rao Shoaib314001f2021-08-01 00:57:07 -07002566 err = unix_stream_recv_urg(state);
Rao Shoaib314001f2021-08-01 00:57:07 -07002567#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002569 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002571 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
Eric Dumazetde144392014-03-25 18:42:27 -07002572 timeo = sock_rcvtimeo(sk, noblock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002574 memset(&scm, 0, sizeof(scm));
2575
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576 /* Lock the socket to prevent queue disordering
2577 * while sleeps in memcpy_tomsg
2578 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002579 mutex_lock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580
Matthew Dawsona0917e02017-08-18 15:04:54 -04002581 skip = max(sk_peek_offset(sk, flags), 0);
Andrey Vagine9193d62015-10-02 00:05:36 +03002582
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002583 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584 int chunk;
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002585 bool drop_skb;
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002586 struct sk_buff *skb, *last;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002588redo:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002589 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002590 if (sock_flag(sk, SOCK_DEAD)) {
2591 err = -ECONNRESET;
2592 goto unlock;
2593 }
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002594 last = skb = skb_peek(&sk->sk_receive_queue);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002595 last_len = last ? last->len : 0;
Rao Shoaib314001f2021-08-01 00:57:07 -07002596
2597#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
2598 if (skb) {
2599 skb = manage_oob(skb, sk, flags, copied);
2600 if (!skb) {
2601 unix_state_unlock(sk);
2602 if (copied)
2603 break;
2604 goto redo;
2605 }
2606 }
2607#endif
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002608again:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002609 if (skb == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002610 if (copied >= target)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002611 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612
2613 /*
2614 * POSIX 1003.1g mandates this order.
2615 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002616
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002617 err = sock_error(sk);
2618 if (err)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002619 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620 if (sk->sk_shutdown & RCV_SHUTDOWN)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002621 goto unlock;
2622
2623 unix_state_unlock(sk);
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002624 if (!timeo) {
2625 err = -EAGAIN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626 break;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002627 }
2628
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002629 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002631 timeo = unix_stream_data_wait(sk, timeo, last,
WANG Cong06a77b02016-11-17 15:55:26 -08002632 last_len, freezable);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633
Rainer Weikusat3822b5c2015-12-16 20:09:25 +00002634 if (signal_pending(current)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635 err = sock_intr_errno(timeo);
Eric Dumazetfa0dc042016-01-24 13:53:50 -08002636 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637 goto out;
2638 }
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00002639
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002640 mutex_lock(&u->iolock);
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002641 goto redo;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002642unlock:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002643 unix_state_unlock(sk);
2644 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645 }
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002646
Eric Dumazete370a722013-08-08 14:37:32 -07002647 while (skip >= unix_skb_len(skb)) {
2648 skip -= unix_skb_len(skb);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002649 last = skb;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002650 last_len = skb->len;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002651 skb = skb_peek_next(skb, &sk->sk_receive_queue);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002652 if (!skb)
2653 goto again;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002654 }
2655
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002656 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657
2658 if (check_creds) {
2659 /* Never glue messages from different writers */
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002660 if (!unix_skb_scm_eq(skb, &scm))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002661 break;
Eric W. Biederman0e82e7f6d2013-04-03 16:14:47 +00002662 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 /* Copy credentials */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002664 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04002665 unix_set_secdata(&scm, skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002666 check_creds = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667 }
2668
2669 /* Copy address just once */
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002670 if (state->msg && state->msg->msg_name) {
2671 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr,
2672 state->msg->msg_name);
2673 unix_copy_addr(state->msg, skb->sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 sunaddr = NULL;
2675 }
2676
Eric Dumazete370a722013-08-08 14:37:32 -07002677 chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002678 skb_get(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002679 chunk = state->recv_actor(skb, skip, chunk, state);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002680 drop_skb = !unix_skb_len(skb);
2681 /* skb is only safe to use if !drop_skb */
2682 consume_skb(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002683 if (chunk < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684 if (copied == 0)
2685 copied = -EFAULT;
2686 break;
2687 }
2688 copied += chunk;
2689 size -= chunk;
2690
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002691 if (drop_skb) {
2692 /* the skb was touched by a concurrent reader;
2693 * we should not expect anything from this skb
2694 * anymore and assume it invalid - we can be
2695 * sure it was dropped from the socket queue
2696 *
2697 * let's report a short read
2698 */
2699 err = 0;
2700 break;
2701 }
2702
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703 /* Mark read part of skb as used */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002704 if (!(flags & MSG_PEEK)) {
Eric Dumazete370a722013-08-08 14:37:32 -07002705 UNIXCB(skb).consumed += chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002707 sk_peek_offset_bwd(sk, chunk);
2708
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002709 if (UNIXCB(skb).fp) {
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002710 scm_stat_del(sk, skb);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002711 unix_detach_fds(&scm, skb);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002712 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713
Eric Dumazete370a722013-08-08 14:37:32 -07002714 if (unix_skb_len(skb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716
Eric Dumazet6f01fd62012-01-28 16:11:03 +00002717 skb_unlink(skb, &sk->sk_receive_queue);
Neil Horman70d4bf62010-07-20 06:45:56 +00002718 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002720 if (scm.fp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002722 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723 /* It is questionable, see note in unix_dgram_recvmsg.
2724 */
2725 if (UNIXCB(skb).fp)
Miklos Szeredicbcf0112021-07-28 14:47:20 +02002726 unix_peek_fds(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727
Andrey Vagine9193d62015-10-02 00:05:36 +03002728 sk_peek_offset_fwd(sk, chunk);
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002729
Aaron Conole9f389e32015-09-26 18:50:43 -04002730 if (UNIXCB(skb).fp)
2731 break;
2732
Andrey Vagine9193d62015-10-02 00:05:36 +03002733 skip = 0;
Aaron Conole9f389e32015-09-26 18:50:43 -04002734 last = skb;
2735 last_len = skb->len;
2736 unix_state_lock(sk);
2737 skb = skb_peek_next(skb, &sk->sk_receive_queue);
2738 if (skb)
2739 goto again;
2740 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741 break;
2742 }
2743 } while (size);
2744
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002745 mutex_unlock(&u->iolock);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002746 if (state->msg)
2747 scm_recv(sock, state->msg, &scm, flags);
2748 else
2749 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750out:
2751 return copied ? : err;
2752}
2753
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002754static int unix_stream_read_actor(struct sk_buff *skb,
2755 int skip, int chunk,
2756 struct unix_stream_read_state *state)
2757{
2758 int ret;
2759
2760 ret = skb_copy_datagram_msg(skb, UNIXCB(skb).consumed + skip,
2761 state->msg, chunk);
2762 return ret ?: chunk;
2763}
2764
Jiang Wang94531cf2021-08-16 19:03:21 +00002765int __unix_stream_recvmsg(struct sock *sk, struct msghdr *msg,
2766 size_t size, int flags)
2767{
2768 struct unix_stream_read_state state = {
2769 .recv_actor = unix_stream_read_actor,
2770 .socket = sk->sk_socket,
2771 .msg = msg,
2772 .size = size,
2773 .flags = flags
2774 };
2775
2776 return unix_stream_read_generic(&state, true);
2777}
2778
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002779static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
2780 size_t size, int flags)
2781{
2782 struct unix_stream_read_state state = {
2783 .recv_actor = unix_stream_read_actor,
2784 .socket = sock,
2785 .msg = msg,
2786 .size = size,
2787 .flags = flags
2788 };
2789
Jiang Wang94531cf2021-08-16 19:03:21 +00002790#ifdef CONFIG_BPF_SYSCALL
2791 struct sock *sk = sock->sk;
2792 const struct proto *prot = READ_ONCE(sk->sk_prot);
2793
2794 if (prot != &unix_stream_proto)
2795 return prot->recvmsg(sk, msg, size, flags & MSG_DONTWAIT,
2796 flags & ~MSG_DONTWAIT, NULL);
2797#endif
WANG Cong06a77b02016-11-17 15:55:26 -08002798 return unix_stream_read_generic(&state, true);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002799}
2800
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002801static int unix_stream_splice_actor(struct sk_buff *skb,
2802 int skip, int chunk,
2803 struct unix_stream_read_state *state)
2804{
2805 return skb_splice_bits(skb, state->socket->sk,
2806 UNIXCB(skb).consumed + skip,
Al Viro25869262016-09-17 21:02:10 -04002807 state->pipe, chunk, state->splice_flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002808}
2809
2810static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos,
2811 struct pipe_inode_info *pipe,
2812 size_t size, unsigned int flags)
2813{
2814 struct unix_stream_read_state state = {
2815 .recv_actor = unix_stream_splice_actor,
2816 .socket = sock,
2817 .pipe = pipe,
2818 .size = size,
2819 .splice_flags = flags,
2820 };
2821
2822 if (unlikely(*ppos))
2823 return -ESPIPE;
2824
2825 if (sock->file->f_flags & O_NONBLOCK ||
2826 flags & SPLICE_F_NONBLOCK)
2827 state.flags = MSG_DONTWAIT;
2828
WANG Cong06a77b02016-11-17 15:55:26 -08002829 return unix_stream_read_generic(&state, false);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002830}
2831
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832static int unix_shutdown(struct socket *sock, int mode)
2833{
2834 struct sock *sk = sock->sk;
2835 struct sock *other;
2836
Xi Wangfc61b922012-08-26 16:47:13 +00002837 if (mode < SHUT_RD || mode > SHUT_RDWR)
2838 return -EINVAL;
2839 /* This maps:
2840 * SHUT_RD (0) -> RCV_SHUTDOWN (1)
2841 * SHUT_WR (1) -> SEND_SHUTDOWN (2)
2842 * SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
2843 */
2844 ++mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845
Alban Crequy7180a032011-01-19 04:56:36 +00002846 unix_state_lock(sk);
2847 sk->sk_shutdown |= mode;
2848 other = unix_peer(sk);
2849 if (other)
2850 sock_hold(other);
2851 unix_state_unlock(sk);
2852 sk->sk_state_change(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853
Alban Crequy7180a032011-01-19 04:56:36 +00002854 if (other &&
2855 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856
Alban Crequy7180a032011-01-19 04:56:36 +00002857 int peer_mode = 0;
Jiang Wang94531cf2021-08-16 19:03:21 +00002858 const struct proto *prot = READ_ONCE(other->sk_prot);
Alban Crequy7180a032011-01-19 04:56:36 +00002859
Jiang Wangd3599022021-08-21 18:07:36 +00002860 if (prot->unhash)
2861 prot->unhash(other);
Alban Crequy7180a032011-01-19 04:56:36 +00002862 if (mode&RCV_SHUTDOWN)
2863 peer_mode |= SEND_SHUTDOWN;
2864 if (mode&SEND_SHUTDOWN)
2865 peer_mode |= RCV_SHUTDOWN;
2866 unix_state_lock(other);
2867 other->sk_shutdown |= peer_mode;
2868 unix_state_unlock(other);
2869 other->sk_state_change(other);
Jiang Wang94531cf2021-08-16 19:03:21 +00002870 if (peer_mode == SHUTDOWN_MASK) {
Alban Crequy7180a032011-01-19 04:56:36 +00002871 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
Jiang Wang94531cf2021-08-16 19:03:21 +00002872 other->sk_state = TCP_CLOSE;
2873 } else if (peer_mode & RCV_SHUTDOWN) {
Alban Crequy7180a032011-01-19 04:56:36 +00002874 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
Jiang Wang94531cf2021-08-16 19:03:21 +00002875 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876 }
Alban Crequy7180a032011-01-19 04:56:36 +00002877 if (other)
2878 sock_put(other);
2879
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 return 0;
2881}
2882
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002883long unix_inq_len(struct sock *sk)
2884{
2885 struct sk_buff *skb;
2886 long amount = 0;
2887
2888 if (sk->sk_state == TCP_LISTEN)
2889 return -EINVAL;
2890
2891 spin_lock(&sk->sk_receive_queue.lock);
2892 if (sk->sk_type == SOCK_STREAM ||
2893 sk->sk_type == SOCK_SEQPACKET) {
2894 skb_queue_walk(&sk->sk_receive_queue, skb)
Eric Dumazete370a722013-08-08 14:37:32 -07002895 amount += unix_skb_len(skb);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002896 } else {
2897 skb = skb_peek(&sk->sk_receive_queue);
2898 if (skb)
2899 amount = skb->len;
2900 }
2901 spin_unlock(&sk->sk_receive_queue.lock);
2902
2903 return amount;
2904}
2905EXPORT_SYMBOL_GPL(unix_inq_len);
2906
2907long unix_outq_len(struct sock *sk)
2908{
2909 return sk_wmem_alloc_get(sk);
2910}
2911EXPORT_SYMBOL_GPL(unix_outq_len);
2912
Andrey Vaginba94f302017-02-01 11:00:45 -08002913static int unix_open_file(struct sock *sk)
2914{
2915 struct path path;
2916 struct file *f;
2917 int fd;
2918
2919 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
2920 return -EPERM;
2921
Al Viroae3b5642019-02-15 20:09:35 +00002922 if (!smp_load_acquire(&unix_sk(sk)->addr))
Andrey Vaginba94f302017-02-01 11:00:45 -08002923 return -ENOENT;
Al Viroae3b5642019-02-15 20:09:35 +00002924
2925 path = unix_sk(sk)->path;
2926 if (!path.dentry)
2927 return -ENOENT;
Andrey Vaginba94f302017-02-01 11:00:45 -08002928
2929 path_get(&path);
Andrey Vaginba94f302017-02-01 11:00:45 -08002930
2931 fd = get_unused_fd_flags(O_CLOEXEC);
2932 if (fd < 0)
2933 goto out;
2934
2935 f = dentry_open(&path, O_PATH, current_cred());
2936 if (IS_ERR(f)) {
2937 put_unused_fd(fd);
2938 fd = PTR_ERR(f);
2939 goto out;
2940 }
2941
2942 fd_install(fd, f);
2943out:
2944 path_put(&path);
2945
2946 return fd;
2947}
2948
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2950{
2951 struct sock *sk = sock->sk;
Jianjun Konge27dfce2008-11-01 21:38:31 -07002952 long amount = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 int err;
2954
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002955 switch (cmd) {
2956 case SIOCOUTQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002957 amount = unix_outq_len(sk);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002958 err = put_user(amount, (int __user *)arg);
2959 break;
2960 case SIOCINQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002961 amount = unix_inq_len(sk);
2962 if (amount < 0)
2963 err = amount;
2964 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965 err = put_user(amount, (int __user *)arg);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002966 break;
Andrey Vaginba94f302017-02-01 11:00:45 -08002967 case SIOCUNIXFILE:
2968 err = unix_open_file(sk);
2969 break;
Rao Shoaib314001f2021-08-01 00:57:07 -07002970#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
2971 case SIOCATMARK:
2972 {
2973 struct sk_buff *skb;
2974 struct unix_sock *u = unix_sk(sk);
2975 int answ = 0;
2976
2977 skb = skb_peek(&sk->sk_receive_queue);
2978 if (skb && skb == u->oob_skb)
2979 answ = 1;
2980 err = put_user(answ, (int __user *)arg);
2981 }
2982 break;
2983#endif
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002984 default:
2985 err = -ENOIOCTLCMD;
2986 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 }
2988 return err;
2989}
2990
Arnd Bergmann5f6beb92019-06-03 22:03:44 +02002991#ifdef CONFIG_COMPAT
2992static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2993{
2994 return unix_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
2995}
2996#endif
2997
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07002998static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999{
3000 struct sock *sk = sock->sk;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003001 __poll_t mask;
3002
Karsten Graul89ab0662018-10-23 13:40:39 +02003003 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003004 mask = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005
3006 /* exceptional events? */
3007 if (sk->sk_err)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003008 mask |= EPOLLERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003010 mask |= EPOLLHUP;
Davide Libenzif348d702006-03-25 03:07:39 -08003011 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003012 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013
3014 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07003015 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003016 mask |= EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017
3018 /* Connection-based need to check for termination and startup */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08003019 if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
3020 sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003021 mask |= EPOLLHUP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003022
3023 /*
3024 * we set writable also when the other side has shut down the
3025 * connection. This prevents stuck sockets.
3026 */
3027 if (unix_writable(sk))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003028 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029
3030 return mask;
3031}
3032
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003033static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
3034 poll_table *wait)
Rainer Weikusat3c734192008-06-17 22:28:05 -07003035{
Rainer Weikusatec0d2152008-06-27 19:34:18 -07003036 struct sock *sk = sock->sk, *other;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003037 unsigned int writable;
3038 __poll_t mask;
3039
Karsten Graul89ab0662018-10-23 13:40:39 +02003040 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003041 mask = 0;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003042
3043 /* exceptional events? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07003044 if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003045 mask |= EPOLLERR |
3046 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +00003047
Rainer Weikusat3c734192008-06-17 22:28:05 -07003048 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003049 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003050 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003051 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003052
3053 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07003054 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003055 mask |= EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003056
3057 /* Connection-based need to check for termination and startup */
3058 if (sk->sk_type == SOCK_SEQPACKET) {
3059 if (sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003060 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003061 /* connection hasn't started yet? */
3062 if (sk->sk_state == TCP_SYN_SENT)
3063 return mask;
3064 }
3065
Eric Dumazet973a34a2010-10-31 05:38:25 +00003066 /* No write status requested, avoid expensive OUT tests. */
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003067 if (!(poll_requested_events(wait) & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT)))
Eric Dumazet973a34a2010-10-31 05:38:25 +00003068 return mask;
3069
Rainer Weikusatec0d2152008-06-27 19:34:18 -07003070 writable = unix_writable(sk);
Rainer Weikusat7d267272015-11-20 22:07:23 +00003071 if (writable) {
3072 unix_state_lock(sk);
3073
3074 other = unix_peer(sk);
3075 if (other && unix_peer(other) != sk &&
Eric Dumazet04f08eb2021-09-08 17:00:29 -07003076 unix_recvq_full_lockless(other) &&
Rainer Weikusat7d267272015-11-20 22:07:23 +00003077 unix_dgram_peer_wake_me(sk, other))
3078 writable = 0;
3079
3080 unix_state_unlock(sk);
Rainer Weikusatec0d2152008-06-27 19:34:18 -07003081 }
3082
3083 if (writable)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003084 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003085 else
Eric Dumazet9cd3e072015-11-29 20:03:10 -08003086 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
Rainer Weikusat3c734192008-06-17 22:28:05 -07003087
Rainer Weikusat3c734192008-06-17 22:28:05 -07003088 return mask;
3089}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090
3091#ifdef CONFIG_PROC_FS
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08003092
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003093#define BUCKET_SPACE (BITS_PER_LONG - (UNIX_HASH_BITS + 1) - 1)
3094
3095#define get_bucket(x) ((x) >> BUCKET_SPACE)
3096#define get_offset(x) ((x) & ((1L << BUCKET_SPACE) - 1))
3097#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08003098
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003099static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003100{
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003101 unsigned long offset = get_offset(*pos);
3102 unsigned long bucket = get_bucket(*pos);
3103 struct sock *sk;
3104 unsigned long count = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003106 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
3107 if (sock_net(sk) != seq_file_net(seq))
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003108 continue;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003109 if (++count == offset)
3110 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111 }
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003112
3113 return sk;
3114}
3115
3116static struct sock *unix_next_socket(struct seq_file *seq,
3117 struct sock *sk,
3118 loff_t *pos)
3119{
3120 unsigned long bucket;
3121
3122 while (sk > (struct sock *)SEQ_START_TOKEN) {
3123 sk = sk_next(sk);
3124 if (!sk)
3125 goto next_bucket;
3126 if (sock_net(sk) == seq_file_net(seq))
3127 return sk;
3128 }
3129
3130 do {
3131 sk = unix_from_bucket(seq, pos);
3132 if (sk)
3133 return sk;
3134
3135next_bucket:
3136 bucket = get_bucket(*pos) + 1;
3137 *pos = set_bucket_offset(bucket, 1);
3138 } while (bucket < ARRAY_SIZE(unix_socket_table));
3139
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140 return NULL;
3141}
3142
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazet9a429c42008-01-01 21:58:02 -08003144 __acquires(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145{
David S. Millerfbe9cc42005-12-13 23:26:29 -08003146 spin_lock(&unix_table_lock);
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003147
3148 if (!*pos)
3149 return SEQ_START_TOKEN;
3150
3151 if (get_bucket(*pos) >= ARRAY_SIZE(unix_socket_table))
3152 return NULL;
3153
3154 return unix_next_socket(seq, NULL, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155}
3156
3157static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
3158{
3159 ++*pos;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003160 return unix_next_socket(seq, v, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161}
3162
3163static void unix_seq_stop(struct seq_file *seq, void *v)
Eric Dumazet9a429c42008-01-01 21:58:02 -08003164 __releases(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165{
David S. Millerfbe9cc42005-12-13 23:26:29 -08003166 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167}
3168
3169static int unix_seq_show(struct seq_file *seq, void *v)
3170{
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09003171
Joe Perchesb9f31242008-04-12 19:04:38 -07003172 if (v == SEQ_START_TOKEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173 seq_puts(seq, "Num RefCount Protocol Flags Type St "
3174 "Inode Path\n");
3175 else {
3176 struct sock *s = v;
3177 struct unix_sock *u = unix_sk(s);
David S. Miller1c92b4e2007-05-31 13:24:26 -07003178 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003179
Dan Rosenberg71338aa2011-05-23 12:17:35 +00003180 seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181 s,
Reshetova, Elena41c6d652017-06-30 13:08:01 +03003182 refcount_read(&s->sk_refcnt),
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183 0,
3184 s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
3185 s->sk_type,
3186 s->sk_socket ?
3187 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
3188 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
3189 sock_i_ino(s));
3190
Al Viroae3b5642019-02-15 20:09:35 +00003191 if (u->addr) { // under unix_table_lock here
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192 int i, len;
3193 seq_putc(seq, ' ');
3194
3195 i = 0;
3196 len = u->addr->len - sizeof(short);
3197 if (!UNIX_ABSTRACT(s))
3198 len--;
3199 else {
3200 seq_putc(seq, '@');
3201 i++;
3202 }
3203 for ( ; i < len; i++)
Isaac Boukrise7947ea2016-11-01 02:41:35 +02003204 seq_putc(seq, u->addr->name->sun_path[i] ?:
3205 '@');
Linus Torvalds1da177e2005-04-16 15:20:36 -07003206 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07003207 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003208 seq_putc(seq, '\n');
3209 }
3210
3211 return 0;
3212}
3213
Philippe De Muyter56b3d972007-07-10 23:07:31 -07003214static const struct seq_operations unix_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003215 .start = unix_seq_start,
3216 .next = unix_seq_next,
3217 .stop = unix_seq_stop,
3218 .show = unix_seq_show,
3219};
Kuniyuki Iwashima2c860a42021-08-14 10:57:15 +09003220
3221#if IS_BUILTIN(CONFIG_UNIX) && defined(CONFIG_BPF_SYSCALL)
3222struct bpf_iter__unix {
3223 __bpf_md_ptr(struct bpf_iter_meta *, meta);
3224 __bpf_md_ptr(struct unix_sock *, unix_sk);
3225 uid_t uid __aligned(8);
3226};
3227
3228static int unix_prog_seq_show(struct bpf_prog *prog, struct bpf_iter_meta *meta,
3229 struct unix_sock *unix_sk, uid_t uid)
3230{
3231 struct bpf_iter__unix ctx;
3232
3233 meta->seq_num--; /* skip SEQ_START_TOKEN */
3234 ctx.meta = meta;
3235 ctx.unix_sk = unix_sk;
3236 ctx.uid = uid;
3237 return bpf_iter_run_prog(prog, &ctx);
3238}
3239
3240static int bpf_iter_unix_seq_show(struct seq_file *seq, void *v)
3241{
3242 struct bpf_iter_meta meta;
3243 struct bpf_prog *prog;
3244 struct sock *sk = v;
3245 uid_t uid;
3246
3247 if (v == SEQ_START_TOKEN)
3248 return 0;
3249
3250 uid = from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk));
3251 meta.seq = seq;
3252 prog = bpf_iter_get_info(&meta, false);
3253 return unix_prog_seq_show(prog, &meta, v, uid);
3254}
3255
3256static void bpf_iter_unix_seq_stop(struct seq_file *seq, void *v)
3257{
3258 struct bpf_iter_meta meta;
3259 struct bpf_prog *prog;
3260
3261 if (!v) {
3262 meta.seq = seq;
3263 prog = bpf_iter_get_info(&meta, true);
3264 if (prog)
3265 (void)unix_prog_seq_show(prog, &meta, v, 0);
3266 }
3267
3268 unix_seq_stop(seq, v);
3269}
3270
3271static const struct seq_operations bpf_iter_unix_seq_ops = {
3272 .start = unix_seq_start,
3273 .next = unix_seq_next,
3274 .stop = bpf_iter_unix_seq_stop,
3275 .show = bpf_iter_unix_seq_show,
3276};
3277#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003278#endif
3279
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00003280static const struct net_proto_family unix_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281 .family = PF_UNIX,
3282 .create = unix_create,
3283 .owner = THIS_MODULE,
3284};
3285
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003286
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00003287static int __net_init unix_net_init(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003288{
3289 int error = -ENOMEM;
3290
Denis V. Luneva0a53c82007-12-11 04:19:17 -08003291 net->unx.sysctl_max_dgram_qlen = 10;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11003292 if (unix_sysctl_register(net))
3293 goto out;
Pavel Emelyanovd392e492007-12-01 23:44:15 +11003294
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003295#ifdef CONFIG_PROC_FS
Christoph Hellwigc3506372018-04-10 19:42:55 +02003296 if (!proc_create_net("unix", 0, net->proc_net, &unix_seq_ops,
3297 sizeof(struct seq_net_private))) {
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11003298 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003299 goto out;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11003300 }
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003301#endif
3302 error = 0;
3303out:
Jianjun Kong48dcc33e2008-11-01 21:37:27 -07003304 return error;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003305}
3306
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00003307static void __net_exit unix_net_exit(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003308{
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11003309 unix_sysctl_unregister(net);
Gao fengece31ff2013-02-18 01:34:56 +00003310 remove_proc_entry("unix", net->proc_net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003311}
3312
3313static struct pernet_operations unix_net_ops = {
3314 .init = unix_net_init,
3315 .exit = unix_net_exit,
3316};
3317
Kuniyuki Iwashima2c860a42021-08-14 10:57:15 +09003318#if IS_BUILTIN(CONFIG_UNIX) && defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS)
3319DEFINE_BPF_ITER_FUNC(unix, struct bpf_iter_meta *meta,
3320 struct unix_sock *unix_sk, uid_t uid)
3321
3322static const struct bpf_iter_seq_info unix_seq_info = {
3323 .seq_ops = &bpf_iter_unix_seq_ops,
3324 .init_seq_private = bpf_iter_init_seq_net,
3325 .fini_seq_private = bpf_iter_fini_seq_net,
3326 .seq_priv_size = sizeof(struct seq_net_private),
3327};
3328
3329static struct bpf_iter_reg unix_reg_info = {
3330 .target = "unix",
3331 .ctx_arg_info_size = 1,
3332 .ctx_arg_info = {
3333 { offsetof(struct bpf_iter__unix, unix_sk),
3334 PTR_TO_BTF_ID_OR_NULL },
3335 },
3336 .seq_info = &unix_seq_info,
3337};
3338
3339static void __init bpf_iter_register(void)
3340{
3341 unix_reg_info.ctx_arg_info[0].btf_id = btf_sock_ids[BTF_SOCK_TYPE_UNIX];
3342 if (bpf_iter_reg_target(&unix_reg_info))
3343 pr_warn("Warning: could not register bpf iterator unix\n");
3344}
3345#endif
3346
Linus Torvalds1da177e2005-04-16 15:20:36 -07003347static int __init af_unix_init(void)
3348{
3349 int rc = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003350
Pankaj Bharadiyac5936422019-12-09 10:31:43 -08003351 BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof_field(struct sk_buff, cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003352
Jiang Wang94531cf2021-08-16 19:03:21 +00003353 rc = proto_register(&unix_dgram_proto, 1);
3354 if (rc != 0) {
3355 pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
3356 goto out;
3357 }
3358
3359 rc = proto_register(&unix_stream_proto, 1);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09003360 if (rc != 0) {
wangweidong5cc208b2013-12-06 18:03:36 +08003361 pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003362 goto out;
3363 }
3364
3365 sock_register(&unix_family_ops);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003366 register_pernet_subsys(&unix_net_ops);
Cong Wangc6382912021-07-04 12:02:47 -07003367 unix_bpf_build_proto();
Kuniyuki Iwashima2c860a42021-08-14 10:57:15 +09003368
3369#if IS_BUILTIN(CONFIG_UNIX) && defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS)
3370 bpf_iter_register();
3371#endif
3372
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373out:
3374 return rc;
3375}
3376
3377static void __exit af_unix_exit(void)
3378{
3379 sock_unregister(PF_UNIX);
Jiang Wang94531cf2021-08-16 19:03:21 +00003380 proto_unregister(&unix_dgram_proto);
3381 proto_unregister(&unix_stream_proto);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003382 unregister_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383}
3384
David Woodhouse3d366962008-04-24 00:59:25 -07003385/* Earlier than device_initcall() so that other drivers invoking
3386 request_module() don't end up in a loop when modprobe tries
3387 to use a UNIX socket. But later than subsys_initcall() because
3388 we depend on stuff initialised there */
3389fs_initcall(af_unix_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390module_exit(af_unix_exit);
3391
3392MODULE_LICENSE("GPL");
3393MODULE_ALIAS_NETPROTO(PF_UNIX);