blob: 80752ab9ed97b99194ead7f1f710e1d82d35d06e [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
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700137#ifdef CONFIG_SECURITY_NETWORK
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700138static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700139{
Stephen Smalley37a9a8d2015-06-10 08:44:59 -0400140 UNIXCB(skb).secid = scm->secid;
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700141}
142
143static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
144{
Stephen Smalley37a9a8d2015-06-10 08:44:59 -0400145 scm->secid = UNIXCB(skb).secid;
146}
147
148static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
149{
150 return (scm->secid == UNIXCB(skb).secid);
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700151}
152#else
Catherine Zhangdc49c1f2006-08-02 14:12:06 -0700153static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700154{ }
155
156static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
157{ }
Stephen Smalley37a9a8d2015-06-10 08:44:59 -0400158
159static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
160{
161 return true;
162}
Catherine Zhang877ce7c2006-06-29 12:27:47 -0700163#endif /* CONFIG_SECURITY_NETWORK */
164
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165/*
166 * SMP locking strategy:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800167 * hash table is protected with spinlock unix_table_lock
Stephen Hemminger663717f2010-02-18 14:12:06 -0800168 * each socket state is protected by separate spin lock.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 */
170
Eric Dumazet95c96172012-04-15 05:58:06 +0000171static inline unsigned int unix_hash_fold(__wsum n)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172{
Anton Blanchard0a134042014-03-05 14:29:58 +1100173 unsigned int hash = (__force unsigned int)csum_fold(n);
Eric Dumazet95c96172012-04-15 05:58:06 +0000174
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 hash ^= hash>>8;
176 return hash&(UNIX_HASH_SIZE-1);
177}
178
179#define unix_peer(sk) (unix_sk(sk)->peer)
180
181static inline int unix_our_peer(struct sock *sk, struct sock *osk)
182{
183 return unix_peer(osk) == sk;
184}
185
186static inline int unix_may_send(struct sock *sk, struct sock *osk)
187{
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800188 return unix_peer(osk) == NULL || unix_our_peer(sk, osk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189}
190
Qian Cai86b18aa2020-02-04 13:40:29 -0500191static inline int unix_recvq_full(const struct sock *sk)
Rainer Weikusat3c734192008-06-17 22:28:05 -0700192{
193 return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
194}
195
Qian Cai86b18aa2020-02-04 13:40:29 -0500196static inline int unix_recvq_full_lockless(const struct sock *sk)
197{
198 return skb_queue_len_lockless(&sk->sk_receive_queue) >
199 READ_ONCE(sk->sk_max_ack_backlog);
200}
201
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000202struct sock *unix_peer_get(struct sock *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203{
204 struct sock *peer;
205
David S. Miller1c92b4e2007-05-31 13:24:26 -0700206 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 peer = unix_peer(s);
208 if (peer)
209 sock_hold(peer);
David S. Miller1c92b4e2007-05-31 13:24:26 -0700210 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 return peer;
212}
Pavel Emelyanovfa7ff562011-12-15 02:44:03 +0000213EXPORT_SYMBOL_GPL(unix_peer_get);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +0900215static struct unix_address *unix_create_addr(struct sockaddr_un *sunaddr,
216 int addr_len)
217{
218 struct unix_address *addr;
219
220 addr = kmalloc(sizeof(*addr) + addr_len, GFP_KERNEL);
221 if (!addr)
222 return NULL;
223
224 refcount_set(&addr->refcnt, 1);
225 addr->len = addr_len;
226 memcpy(addr->name, sunaddr, addr_len);
227
228 return addr;
229}
230
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231static inline void unix_release_addr(struct unix_address *addr)
232{
Reshetova, Elena8c9814b2017-06-30 13:08:05 +0300233 if (refcount_dec_and_test(&addr->refcnt))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 kfree(addr);
235}
236
237/*
238 * Check unix socket name:
239 * - should be not zero length.
240 * - if started by not zero, should be NULL terminated (FS object)
241 * - if started by zero, it is abstract name.
242 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900243
Kuniyuki Iwashimab8a58aa2021-11-24 11:14:23 +0900244static int unix_validate_addr(struct sockaddr_un *sunaddr, int addr_len)
245{
246 if (addr_len <= offsetof(struct sockaddr_un, sun_path) ||
247 addr_len > sizeof(*sunaddr))
248 return -EINVAL;
249
250 if (sunaddr->sun_family != AF_UNIX)
251 return -EINVAL;
252
253 return 0;
254}
255
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +0900256static void unix_mkname_bsd(struct sockaddr_un *sunaddr, int addr_len)
257{
258 /* This may look like an off by one error but it is a bit more
259 * subtle. 108 is the longest valid AF_UNIX path for a binding.
260 * sun_path[108] doesn't as such exist. However in kernel space
261 * we are guaranteed that it is a valid memory location in our
262 * kernel address buffer because syscall functions always pass
263 * a pointer of struct sockaddr_storage which has a bigger buffer
264 * than 108.
265 */
266 ((char *)sunaddr)[addr_len] = 0;
267}
268
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269static void __unix_remove_socket(struct sock *sk)
270{
271 sk_del_node_init(sk);
272}
273
274static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
275{
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700276 WARN_ON(!sk_unhashed(sk));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 sk_add_node(sk, list);
278}
279
Al Viro185ab882021-06-19 03:50:26 +0000280static void __unix_set_addr(struct sock *sk, struct unix_address *addr,
281 unsigned hash)
282{
283 __unix_remove_socket(sk);
284 smp_store_release(&unix_sk(sk)->addr, addr);
285 __unix_insert_socket(&unix_socket_table[hash], sk);
286}
287
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288static inline void unix_remove_socket(struct sock *sk)
289{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800290 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 __unix_remove_socket(sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800292 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293}
294
295static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
296{
David S. Millerfbe9cc42005-12-13 23:26:29 -0800297 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 __unix_insert_socket(list, sk);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800299 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300}
301
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800302static struct sock *__unix_find_socket_byname(struct net *net,
303 struct sockaddr_un *sunname,
Al Virobe752282021-06-19 03:50:33 +0000304 int len, unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305{
306 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307
Al Virobe752282021-06-19 03:50:33 +0000308 sk_for_each(s, &unix_socket_table[hash]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 struct unix_sock *u = unix_sk(s);
310
YOSHIFUJI Hideaki878628f2008-03-26 03:57:35 +0900311 if (!net_eq(sock_net(s), net))
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800312 continue;
313
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 if (u->addr->len == len &&
315 !memcmp(u->addr->name, sunname, len))
Vito Caputo262ce0a2019-10-09 20:43:47 -0700316 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 }
Vito Caputo262ce0a2019-10-09 20:43:47 -0700318 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319}
320
Denis V. Lunev097e66c2007-11-19 22:29:30 -0800321static inline struct sock *unix_find_socket_byname(struct net *net,
322 struct sockaddr_un *sunname,
Al Virobe752282021-06-19 03:50:33 +0000323 int len, unsigned int hash)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324{
325 struct sock *s;
326
David S. Millerfbe9cc42005-12-13 23:26:29 -0800327 spin_lock(&unix_table_lock);
Al Virobe752282021-06-19 03:50:33 +0000328 s = __unix_find_socket_byname(net, sunname, len, hash);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 if (s)
330 sock_hold(s);
David S. Millerfbe9cc42005-12-13 23:26:29 -0800331 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 return s;
333}
334
Eric W. Biederman6616f782010-06-13 03:35:48 +0000335static struct sock *unix_find_socket_byinode(struct inode *i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336{
337 struct sock *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338
David S. Millerfbe9cc42005-12-13 23:26:29 -0800339 spin_lock(&unix_table_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -0800340 sk_for_each(s,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
Al Viro40ffe672012-03-14 21:54:32 -0400342 struct dentry *dentry = unix_sk(s)->path.dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343
Miklos Szeredibeef5122016-12-16 11:02:53 +0100344 if (dentry && d_backing_inode(dentry) == i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 sock_hold(s);
346 goto found;
347 }
348 }
349 s = NULL;
350found:
David S. Millerfbe9cc42005-12-13 23:26:29 -0800351 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 return s;
353}
354
Rainer Weikusat7d267272015-11-20 22:07:23 +0000355/* Support code for asymmetrically connected dgram sockets
356 *
357 * If a datagram socket is connected to a socket not itself connected
358 * to the first socket (eg, /dev/log), clients may only enqueue more
359 * messages if the present receive queue of the server socket is not
360 * "too large". This means there's a second writeability condition
361 * poll and sendmsg need to test. The dgram recv code will do a wake
362 * up on the peer_wait wait queue of a socket upon reception of a
363 * datagram which needs to be propagated to sleeping would-be writers
364 * since these might not have sent anything so far. This can't be
365 * accomplished via poll_wait because the lifetime of the server
366 * socket might be less than that of its clients if these break their
367 * association with it or if the server socket is closed while clients
368 * are still connected to it and there's no way to inform "a polling
369 * implementation" that it should let go of a certain wait queue
370 *
Ingo Molnarac6424b2017-06-20 12:06:13 +0200371 * In order to propagate a wake up, a wait_queue_entry_t of the client
Rainer Weikusat7d267272015-11-20 22:07:23 +0000372 * socket is enqueued on the peer_wait queue of the server socket
373 * whose wake function does a wake_up on the ordinary client socket
374 * wait queue. This connection is established whenever a write (or
375 * poll for write) hit the flow control condition and broken when the
376 * association to the server socket is dissolved or after a wake up
377 * was relayed.
378 */
379
Ingo Molnarac6424b2017-06-20 12:06:13 +0200380static int unix_dgram_peer_wake_relay(wait_queue_entry_t *q, unsigned mode, int flags,
Rainer Weikusat7d267272015-11-20 22:07:23 +0000381 void *key)
382{
383 struct unix_sock *u;
384 wait_queue_head_t *u_sleep;
385
386 u = container_of(q, struct unix_sock, peer_wake);
387
388 __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
389 q);
390 u->peer_wake.private = NULL;
391
392 /* relaying can only happen while the wq still exists */
393 u_sleep = sk_sleep(&u->sk);
394 if (u_sleep)
Al Viro3ad6f932017-07-03 20:14:56 -0400395 wake_up_interruptible_poll(u_sleep, key_to_poll(key));
Rainer Weikusat7d267272015-11-20 22:07:23 +0000396
397 return 0;
398}
399
400static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
401{
402 struct unix_sock *u, *u_other;
403 int rc;
404
405 u = unix_sk(sk);
406 u_other = unix_sk(other);
407 rc = 0;
408 spin_lock(&u_other->peer_wait.lock);
409
410 if (!u->peer_wake.private) {
411 u->peer_wake.private = other;
412 __add_wait_queue(&u_other->peer_wait, &u->peer_wake);
413
414 rc = 1;
415 }
416
417 spin_unlock(&u_other->peer_wait.lock);
418 return rc;
419}
420
421static void unix_dgram_peer_wake_disconnect(struct sock *sk,
422 struct sock *other)
423{
424 struct unix_sock *u, *u_other;
425
426 u = unix_sk(sk);
427 u_other = unix_sk(other);
428 spin_lock(&u_other->peer_wait.lock);
429
430 if (u->peer_wake.private == other) {
431 __remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
432 u->peer_wake.private = NULL;
433 }
434
435 spin_unlock(&u_other->peer_wait.lock);
436}
437
438static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
439 struct sock *other)
440{
441 unix_dgram_peer_wake_disconnect(sk, other);
442 wake_up_interruptible_poll(sk_sleep(sk),
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800443 EPOLLOUT |
444 EPOLLWRNORM |
445 EPOLLWRBAND);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000446}
447
448/* preconditions:
449 * - unix_peer(sk) == other
450 * - association is stable
451 */
452static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
453{
454 int connected;
455
456 connected = unix_dgram_peer_wake_connect(sk, other);
457
Jason Baron51f7e952018-08-03 17:24:53 -0400458 /* If other is SOCK_DEAD, we want to make sure we signal
459 * POLLOUT, such that a subsequent write() can get a
460 * -ECONNREFUSED. Otherwise, if we haven't queued any skbs
461 * to other and its full, we will hang waiting for POLLOUT.
462 */
463 if (unix_recvq_full(other) && !sock_flag(other, SOCK_DEAD))
Rainer Weikusat7d267272015-11-20 22:07:23 +0000464 return 1;
465
466 if (connected)
467 unix_dgram_peer_wake_disconnect(sk, other);
468
469 return 0;
470}
471
Eric Dumazet1586a582015-10-23 10:59:16 -0700472static int unix_writable(const struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473{
Eric Dumazet1586a582015-10-23 10:59:16 -0700474 return sk->sk_state != TCP_LISTEN &&
Reshetova, Elena14afee42017-06-30 13:08:00 +0300475 (refcount_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476}
477
478static void unix_write_space(struct sock *sk)
479{
Eric Dumazet43815482010-04-29 11:01:49 +0000480 struct socket_wq *wq;
481
482 rcu_read_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 if (unix_writable(sk)) {
Eric Dumazet43815482010-04-29 11:01:49 +0000484 wq = rcu_dereference(sk->sk_wq);
Herbert Xu1ce0bf52015-11-26 13:55:39 +0800485 if (skwq_has_sleeper(wq))
Eric Dumazet67426b72010-10-29 20:44:44 +0000486 wake_up_interruptible_sync_poll(&wq->wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800487 EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800488 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 }
Eric Dumazet43815482010-04-29 11:01:49 +0000490 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491}
492
493/* When dgram socket disconnects (or changes its peer), we clear its receive
494 * queue of packets arrived from previous peer. First, it allows to do
495 * flow control based only on wmem_alloc; second, sk connected to peer
496 * may receive messages only from that peer. */
497static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
498{
David S. Millerb03efcf2005-07-08 14:57:23 -0700499 if (!skb_queue_empty(&sk->sk_receive_queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 skb_queue_purge(&sk->sk_receive_queue);
501 wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
502
503 /* If one link of bidirectional dgram pipe is disconnected,
504 * we signal error. Messages are lost. Do not make this,
505 * when peer was not connected to us.
506 */
507 if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) {
508 other->sk_err = ECONNRESET;
Alexander Aringe3ae2362021-06-27 18:48:21 -0400509 sk_error_report(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 }
511 }
Eric Dumazetdc56ad72021-08-30 10:21:37 -0700512 other->sk_state = TCP_CLOSE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513}
514
515static void unix_sock_destructor(struct sock *sk)
516{
517 struct unix_sock *u = unix_sk(sk);
518
519 skb_queue_purge(&sk->sk_receive_queue);
520
Rao Shoaib314001f2021-08-01 00:57:07 -0700521#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
522 if (u->oob_skb) {
523 kfree_skb(u->oob_skb);
524 u->oob_skb = NULL;
525 }
526#endif
Reshetova, Elena14afee42017-06-30 13:08:00 +0300527 WARN_ON(refcount_read(&sk->sk_wmem_alloc));
Ilpo Järvinen547b7922008-07-25 21:43:18 -0700528 WARN_ON(!sk_unhashed(sk));
529 WARN_ON(sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 if (!sock_flag(sk, SOCK_DEAD)) {
wangweidong5cc208b2013-12-06 18:03:36 +0800531 pr_info("Attempt to release alive unix socket: %p\n", sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 return;
533 }
534
535 if (u->addr)
536 unix_release_addr(u->addr);
537
Eric Dumazet518de9b2010-10-26 14:22:44 -0700538 atomic_long_dec(&unix_nr_socks);
Eric Dumazeta8076d82008-11-17 02:38:49 -0800539 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540#ifdef UNIX_REFCNT_DEBUG
wangweidong5cc208b2013-12-06 18:03:36 +0800541 pr_debug("UNIX %p is destroyed, %ld are still alive.\n", sk,
Eric Dumazet518de9b2010-10-26 14:22:44 -0700542 atomic_long_read(&unix_nr_socks));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543#endif
544}
545
Paul Mooreded34e02013-03-25 03:18:33 +0000546static void unix_release_sock(struct sock *sk, int embrion)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547{
548 struct unix_sock *u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400549 struct path path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 struct sock *skpair;
551 struct sk_buff *skb;
552 int state;
553
554 unix_remove_socket(sk);
555
556 /* Clear state */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700557 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 sock_orphan(sk);
559 sk->sk_shutdown = SHUTDOWN_MASK;
Al Viro40ffe672012-03-14 21:54:32 -0400560 path = u->path;
561 u->path.dentry = NULL;
562 u->path.mnt = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 state = sk->sk_state;
564 sk->sk_state = TCP_CLOSE;
Eric Dumazeta494bd62021-06-16 07:47:15 -0700565
566 skpair = unix_peer(sk);
567 unix_peer(sk) = NULL;
568
David S. Miller1c92b4e2007-05-31 13:24:26 -0700569 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
571 wake_up_interruptible_all(&u->peer_wait);
572
Jianjun Konge27dfce2008-11-01 21:38:31 -0700573 if (skpair != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
David S. Miller1c92b4e2007-05-31 13:24:26 -0700575 unix_state_lock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 /* No more writes */
577 skpair->sk_shutdown = SHUTDOWN_MASK;
578 if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
579 skpair->sk_err = ECONNRESET;
David S. Miller1c92b4e2007-05-31 13:24:26 -0700580 unix_state_unlock(skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 skpair->sk_state_change(skpair);
Pavel Emelyanov8d8ad9d2007-11-26 20:10:50 +0800582 sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 }
Rainer Weikusat7d267272015-11-20 22:07:23 +0000584
585 unix_dgram_peer_wake_disconnect(sk, skpair);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 sock_put(skpair); /* It may now die */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 }
588
589 /* Try to flush out this socket. Throw out buffers at least */
590
591 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
Jianjun Konge27dfce2008-11-01 21:38:31 -0700592 if (state == TCP_LISTEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 unix_release_sock(skb->sk, 1);
594 /* passed fds are erased in the kfree_skb hook */
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +0100595 UNIXCB(skb).consumed = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 kfree_skb(skb);
597 }
598
Al Viro40ffe672012-03-14 21:54:32 -0400599 if (path.dentry)
600 path_put(&path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601
602 sock_put(sk);
603
604 /* ---- Socket is dead now and most probably destroyed ---- */
605
606 /*
Alan Coxe04dae82012-09-17 00:52:41 +0000607 * Fixme: BSD difference: In BSD all sockets connected to us get
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 * ECONNRESET and we die on the spot. In Linux we behave
609 * like files and pipes do and wait for the last
610 * dereference.
611 *
612 * Can't we simply set sock->err?
613 *
614 * What the above comment does talk about? --ANK(980817)
615 */
616
Pavel Emelyanov9305cfa2007-11-10 22:06:01 -0800617 if (unix_tot_inflight)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +0900618 unix_gc(); /* Garbage collect fds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619}
620
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000621static void init_peercred(struct sock *sk)
622{
Eric Dumazet35306eb2021-09-29 15:57:50 -0700623 const struct cred *old_cred;
624 struct pid *old_pid;
625
626 spin_lock(&sk->sk_peer_lock);
627 old_pid = sk->sk_peer_pid;
628 old_cred = sk->sk_peer_cred;
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000629 sk->sk_peer_pid = get_pid(task_tgid(current));
630 sk->sk_peer_cred = get_current_cred();
Eric Dumazet35306eb2021-09-29 15:57:50 -0700631 spin_unlock(&sk->sk_peer_lock);
632
633 put_pid(old_pid);
634 put_cred(old_cred);
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000635}
636
637static void copy_peercred(struct sock *sk, struct sock *peersk)
638{
Eric Dumazet35306eb2021-09-29 15:57:50 -0700639 const struct cred *old_cred;
640 struct pid *old_pid;
641
642 if (sk < peersk) {
643 spin_lock(&sk->sk_peer_lock);
644 spin_lock_nested(&peersk->sk_peer_lock, SINGLE_DEPTH_NESTING);
645 } else {
646 spin_lock(&peersk->sk_peer_lock);
647 spin_lock_nested(&sk->sk_peer_lock, SINGLE_DEPTH_NESTING);
648 }
649 old_pid = sk->sk_peer_pid;
650 old_cred = sk->sk_peer_cred;
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000651 sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
652 sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
Eric Dumazet35306eb2021-09-29 15:57:50 -0700653
654 spin_unlock(&sk->sk_peer_lock);
655 spin_unlock(&peersk->sk_peer_lock);
656
657 put_pid(old_pid);
658 put_cred(old_cred);
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000659}
660
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661static int unix_listen(struct socket *sock, int backlog)
662{
663 int err;
664 struct sock *sk = sock->sk;
665 struct unix_sock *u = unix_sk(sk);
666
667 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800668 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
669 goto out; /* Only stream/seqpacket sockets accept */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 err = -EINVAL;
671 if (!u->addr)
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800672 goto out; /* No listens on an unbound socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -0700673 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
675 goto out_unlock;
676 if (backlog > sk->sk_max_ack_backlog)
677 wake_up_interruptible_all(&u->peer_wait);
678 sk->sk_max_ack_backlog = backlog;
679 sk->sk_state = TCP_LISTEN;
680 /* set credentials so connect can copy them */
Eric W. Biederman109f6e32010-06-13 03:30:14 +0000681 init_peercred(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 err = 0;
683
684out_unlock:
David S. Miller1c92b4e2007-05-31 13:24:26 -0700685 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686out:
687 return err;
688}
689
690static int unix_release(struct socket *);
691static int unix_bind(struct socket *, struct sockaddr *, int);
692static int unix_stream_connect(struct socket *, struct sockaddr *,
693 int addr_len, int flags);
694static int unix_socketpair(struct socket *, struct socket *);
David Howellscdfbabf2017-03-09 08:09:05 +0000695static int unix_accept(struct socket *, struct socket *, int, bool);
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +0100696static int unix_getname(struct socket *, struct sockaddr *, int);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700697static __poll_t unix_poll(struct file *, struct socket *, poll_table *);
698static __poll_t unix_dgram_poll(struct file *, struct socket *,
699 poll_table *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700static int unix_ioctl(struct socket *, unsigned int, unsigned long);
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200701#ifdef CONFIG_COMPAT
702static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
703#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704static int unix_shutdown(struct socket *, int);
Ying Xue1b784142015-03-02 15:37:48 +0800705static int unix_stream_sendmsg(struct socket *, struct msghdr *, size_t);
706static int unix_stream_recvmsg(struct socket *, struct msghdr *, size_t, int);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200707static ssize_t unix_stream_sendpage(struct socket *, struct page *, int offset,
708 size_t size, int flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200709static ssize_t unix_stream_splice_read(struct socket *, loff_t *ppos,
710 struct pipe_inode_info *, size_t size,
711 unsigned int flags);
Ying Xue1b784142015-03-02 15:37:48 +0800712static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t);
713static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int);
Cong Wang29df44f2021-07-04 12:02:44 -0700714static int unix_read_sock(struct sock *sk, read_descriptor_t *desc,
715 sk_read_actor_t recv_actor);
Jiang Wang77462de2021-08-16 19:03:20 +0000716static int unix_stream_read_sock(struct sock *sk, read_descriptor_t *desc,
717 sk_read_actor_t recv_actor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718static int unix_dgram_connect(struct socket *, struct sockaddr *,
719 int, int);
Ying Xue1b784142015-03-02 15:37:48 +0800720static int unix_seqpacket_sendmsg(struct socket *, struct msghdr *, size_t);
721static int unix_seqpacket_recvmsg(struct socket *, struct msghdr *, size_t,
722 int);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723
Sasha Levin12663bf2013-12-07 17:26:27 -0500724static int unix_set_peek_off(struct sock *sk, int val)
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000725{
726 struct unix_sock *u = unix_sk(sk);
727
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700728 if (mutex_lock_interruptible(&u->iolock))
Sasha Levin12663bf2013-12-07 17:26:27 -0500729 return -EINTR;
730
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000731 sk->sk_peek_off = val;
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700732 mutex_unlock(&u->iolock);
Sasha Levin12663bf2013-12-07 17:26:27 -0500733
734 return 0;
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000735}
736
David S. Miller5c05a162020-02-27 11:52:35 -0800737#ifdef CONFIG_PROC_FS
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300738static void unix_show_fdinfo(struct seq_file *m, struct socket *sock)
739{
740 struct sock *sk = sock->sk;
741 struct unix_sock *u;
742
743 if (sk) {
744 u = unix_sk(sock->sk);
Paolo Abeni77820402020-02-28 14:45:21 +0100745 seq_printf(m, "scm_fds: %u\n",
746 atomic_read(&u->scm_stat.nr_fds));
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300747 }
748}
Tobias Klauser3a125002020-02-26 18:29:53 +0100749#else
750#define unix_show_fdinfo NULL
751#endif
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000752
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800753static const struct proto_ops unix_stream_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 .family = PF_UNIX,
755 .owner = THIS_MODULE,
756 .release = unix_release,
757 .bind = unix_bind,
758 .connect = unix_stream_connect,
759 .socketpair = unix_socketpair,
760 .accept = unix_accept,
761 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700762 .poll = unix_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200764#ifdef CONFIG_COMPAT
765 .compat_ioctl = unix_compat_ioctl,
766#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 .listen = unix_listen,
768 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 .sendmsg = unix_stream_sendmsg,
770 .recvmsg = unix_stream_recvmsg,
Jiang Wang77462de2021-08-16 19:03:20 +0000771 .read_sock = unix_stream_read_sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 .mmap = sock_no_mmap,
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +0200773 .sendpage = unix_stream_sendpage,
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +0200774 .splice_read = unix_stream_splice_read,
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +0000775 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300776 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777};
778
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800779static const struct proto_ops unix_dgram_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 .family = PF_UNIX,
781 .owner = THIS_MODULE,
782 .release = unix_release,
783 .bind = unix_bind,
784 .connect = unix_dgram_connect,
785 .socketpair = unix_socketpair,
786 .accept = sock_no_accept,
787 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700788 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200790#ifdef CONFIG_COMPAT
791 .compat_ioctl = unix_compat_ioctl,
792#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 .listen = sock_no_listen,
794 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 .sendmsg = unix_dgram_sendmsg,
Cong Wang29df44f2021-07-04 12:02:44 -0700796 .read_sock = unix_read_sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 .recvmsg = unix_dgram_recvmsg,
798 .mmap = sock_no_mmap,
799 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000800 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300801 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802};
803
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800804static const struct proto_ops unix_seqpacket_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 .family = PF_UNIX,
806 .owner = THIS_MODULE,
807 .release = unix_release,
808 .bind = unix_bind,
809 .connect = unix_stream_connect,
810 .socketpair = unix_socketpair,
811 .accept = unix_accept,
812 .getname = unix_getname,
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700813 .poll = unix_dgram_poll,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 .ioctl = unix_ioctl,
Arnd Bergmann5f6beb92019-06-03 22:03:44 +0200815#ifdef CONFIG_COMPAT
816 .compat_ioctl = unix_compat_ioctl,
817#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 .listen = unix_listen,
819 .shutdown = unix_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820 .sendmsg = unix_seqpacket_sendmsg,
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +0000821 .recvmsg = unix_seqpacket_recvmsg,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 .mmap = sock_no_mmap,
823 .sendpage = sock_no_sendpage,
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +0000824 .set_peek_off = unix_set_peek_off,
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300825 .show_fdinfo = unix_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826};
827
Cong Wangc7272e12021-07-04 12:02:46 -0700828static void unix_close(struct sock *sk, long timeout)
829{
830 /* Nothing to do here, unix socket does not need a ->close().
831 * This is merely for sockmap.
832 */
833}
834
Jiang Wang94531cf2021-08-16 19:03:21 +0000835static void unix_unhash(struct sock *sk)
836{
837 /* Nothing to do here, unix socket does not need a ->unhash().
838 * This is merely for sockmap.
839 */
840}
841
842struct proto unix_dgram_proto = {
Stephen Boyd0edf0822021-10-08 14:59:45 -0700843 .name = "UNIX",
Eric Dumazet248969a2008-11-17 00:00:30 -0800844 .owner = THIS_MODULE,
Eric Dumazet248969a2008-11-17 00:00:30 -0800845 .obj_size = sizeof(struct unix_sock),
Cong Wangc7272e12021-07-04 12:02:46 -0700846 .close = unix_close,
Cong Wangc6382912021-07-04 12:02:47 -0700847#ifdef CONFIG_BPF_SYSCALL
Jiang Wang94531cf2021-08-16 19:03:21 +0000848 .psock_update_sk_prot = unix_dgram_bpf_update_proto,
Cong Wangc6382912021-07-04 12:02:47 -0700849#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850};
851
Jiang Wang94531cf2021-08-16 19:03:21 +0000852struct proto unix_stream_proto = {
853 .name = "UNIX-STREAM",
854 .owner = THIS_MODULE,
855 .obj_size = sizeof(struct unix_sock),
856 .close = unix_close,
857 .unhash = unix_unhash,
858#ifdef CONFIG_BPF_SYSCALL
859 .psock_update_sk_prot = unix_stream_bpf_update_proto,
860#endif
861};
862
863static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, int type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 struct unix_sock *u;
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +0900866 struct sock *sk;
867 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868
Eric Dumazet518de9b2010-10-26 14:22:44 -0700869 atomic_long_inc(&unix_nr_socks);
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +0900870 if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files()) {
871 err = -ENFILE;
872 goto err;
873 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874
Jiang Wang94531cf2021-08-16 19:03:21 +0000875 if (type == SOCK_STREAM)
876 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_stream_proto, kern);
877 else /*dgram and seqpacket */
878 sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_dgram_proto, kern);
879
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +0900880 if (!sk) {
881 err = -ENOMEM;
882 goto err;
883 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
Eric Dumazet6eba6a32008-11-16 22:58:44 -0800885 sock_init_data(sock, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
Vladimir Davydov3aa97992016-07-26 15:24:36 -0700887 sk->sk_allocation = GFP_KERNEL_ACCOUNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 sk->sk_write_space = unix_write_space;
Denis V. Luneva0a53c82007-12-11 04:19:17 -0800889 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 sk->sk_destruct = unix_sock_destructor;
891 u = unix_sk(sk);
Al Viro40ffe672012-03-14 21:54:32 -0400892 u->path.dentry = NULL;
893 u->path.mnt = NULL;
Benjamin LaHaisefd19f322006-01-03 14:10:46 -0800894 spin_lock_init(&u->lock);
Al Viro516e0cc2008-07-26 00:39:17 -0400895 atomic_long_set(&u->inflight, 0);
Miklos Szeredi1fd05ba2007-07-11 14:22:39 -0700896 INIT_LIST_HEAD(&u->link);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -0700897 mutex_init(&u->iolock); /* single task reading lock */
898 mutex_init(&u->bindlock); /* single task binding lock */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 init_waitqueue_head(&u->peer_wait);
Rainer Weikusat7d267272015-11-20 22:07:23 +0000900 init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
Kirill Tkhai3c32da12019-12-09 13:03:46 +0300901 memset(&u->scm_stat, 0, sizeof(struct scm_stat));
Eric Dumazet7123aaa2012-06-08 05:03:21 +0000902 unix_insert_socket(unix_sockets_unbound(sk), sk);
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +0900903
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +0900904 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +0900905
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 return sk;
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +0900907
908err:
909 atomic_long_dec(&unix_nr_socks);
910 return ERR_PTR(err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911}
912
Eric Paris3f378b62009-11-05 22:18:14 -0800913static int unix_create(struct net *net, struct socket *sock, int protocol,
914 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915{
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +0900916 struct sock *sk;
917
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 if (protocol && protocol != PF_UNIX)
919 return -EPROTONOSUPPORT;
920
921 sock->state = SS_UNCONNECTED;
922
923 switch (sock->type) {
924 case SOCK_STREAM:
925 sock->ops = &unix_stream_ops;
926 break;
927 /*
928 * Believe it or not BSD has AF_UNIX, SOCK_RAW though
929 * nothing uses it.
930 */
931 case SOCK_RAW:
Jianjun Konge27dfce2008-11-01 21:38:31 -0700932 sock->type = SOCK_DGRAM;
Gustavo A. R. Silvadf561f662020-08-23 17:36:59 -0500933 fallthrough;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 case SOCK_DGRAM:
935 sock->ops = &unix_dgram_ops;
936 break;
937 case SOCK_SEQPACKET:
938 sock->ops = &unix_seqpacket_ops;
939 break;
940 default:
941 return -ESOCKTNOSUPPORT;
942 }
943
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +0900944 sk = unix_create1(net, sock, kern, sock->type);
945 if (IS_ERR(sk))
946 return PTR_ERR(sk);
947
948 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949}
950
951static int unix_release(struct socket *sock)
952{
953 struct sock *sk = sock->sk;
954
955 if (!sk)
956 return 0;
957
Cong Wangc7272e12021-07-04 12:02:46 -0700958 sk->sk_prot->close(sk, 0);
Paul Mooreded34e02013-03-25 03:18:33 +0000959 unix_release_sock(sk, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 sock->sk = NULL;
961
Paul Mooreded34e02013-03-25 03:18:33 +0000962 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963}
964
Kuniyuki Iwashimafa39ef02021-11-24 11:14:21 +0900965static struct sock *unix_find_bsd(struct net *net, struct sockaddr_un *sunaddr,
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +0900966 int addr_len, int type)
Kuniyuki Iwashimafa39ef02021-11-24 11:14:21 +0900967{
968 struct inode *inode;
969 struct path path;
970 struct sock *sk;
971 int err;
972
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +0900973 unix_mkname_bsd(sunaddr, addr_len);
Kuniyuki Iwashimafa39ef02021-11-24 11:14:21 +0900974 err = kern_path(sunaddr->sun_path, LOOKUP_FOLLOW, &path);
975 if (err)
976 goto fail;
977
978 err = path_permission(&path, MAY_WRITE);
979 if (err)
980 goto path_put;
981
982 err = -ECONNREFUSED;
983 inode = d_backing_inode(path.dentry);
984 if (!S_ISSOCK(inode->i_mode))
985 goto path_put;
986
987 sk = unix_find_socket_byinode(inode);
988 if (!sk)
989 goto path_put;
990
991 err = -EPROTOTYPE;
992 if (sk->sk_type == type)
993 touch_atime(&path);
994 else
995 goto sock_put;
996
997 path_put(&path);
998
999 return sk;
1000
1001sock_put:
1002 sock_put(sk);
1003path_put:
1004 path_put(&path);
1005fail:
Kuniyuki Iwashimaaed26f52021-11-24 11:14:22 +09001006 return ERR_PTR(err);
Kuniyuki Iwashimafa39ef02021-11-24 11:14:21 +09001007}
1008
1009static struct sock *unix_find_abstract(struct net *net,
1010 struct sockaddr_un *sunaddr,
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +09001011 int addr_len, int type)
Kuniyuki Iwashimafa39ef02021-11-24 11:14:21 +09001012{
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +09001013 unsigned int hash = unix_hash_fold(csum_partial(sunaddr, addr_len, 0));
Kuniyuki Iwashimafa39ef02021-11-24 11:14:21 +09001014 struct dentry *dentry;
1015 struct sock *sk;
1016
1017 sk = unix_find_socket_byname(net, sunaddr, addr_len, type ^ hash);
Kuniyuki Iwashimaaed26f52021-11-24 11:14:22 +09001018 if (!sk)
1019 return ERR_PTR(-ECONNREFUSED);
Kuniyuki Iwashimafa39ef02021-11-24 11:14:21 +09001020
1021 dentry = unix_sk(sk)->path.dentry;
1022 if (dentry)
1023 touch_atime(&unix_sk(sk)->path);
1024
1025 return sk;
1026}
1027
1028static struct sock *unix_find_other(struct net *net,
1029 struct sockaddr_un *sunaddr,
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +09001030 int addr_len, int type)
Kuniyuki Iwashimafa39ef02021-11-24 11:14:21 +09001031{
1032 struct sock *sk;
1033
1034 if (sunaddr->sun_path[0])
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +09001035 sk = unix_find_bsd(net, sunaddr, addr_len, type);
Kuniyuki Iwashimafa39ef02021-11-24 11:14:21 +09001036 else
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +09001037 sk = unix_find_abstract(net, sunaddr, addr_len, type);
Kuniyuki Iwashimafa39ef02021-11-24 11:14:21 +09001038
1039 return sk;
1040}
1041
Kuniyuki Iwashimaf7ed31f2021-11-24 11:14:20 +09001042static int unix_autobind(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 struct unix_sock *u = unix_sk(sk);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001045 struct unix_address *addr;
Tetsuo Handa8df73ff2010-09-04 01:34:28 +00001046 unsigned int retries = 0;
Kuniyuki Iwashimaf7ed31f2021-11-24 11:14:20 +09001047 static u32 ordernum = 1;
1048 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001050 err = mutex_lock_interruptible(&u->bindlock);
Sasha Levin37ab4fa2013-12-13 10:54:22 -05001051 if (err)
1052 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 if (u->addr)
1055 goto out;
1056
1057 err = -ENOMEM;
Kuniyuki Iwashima755662c2021-11-24 11:14:19 +09001058 addr = kzalloc(sizeof(*addr) +
1059 offsetof(struct sockaddr_un, sun_path) + 16, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 if (!addr)
1061 goto out;
1062
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 addr->name->sun_family = AF_UNIX;
Reshetova, Elena8c9814b2017-06-30 13:08:05 +03001064 refcount_set(&addr->refcnt, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065
1066retry:
Kuniyuki Iwashima755662c2021-11-24 11:14:19 +09001067 addr->len = sprintf(addr->name->sun_path + 1, "%05x", ordernum) +
1068 offsetof(struct sockaddr_un, sun_path) + 1;
Joe Perches07f07572008-11-19 15:44:53 -08001069 addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
Al Virobe752282021-06-19 03:50:33 +00001070 addr->hash ^= sk->sk_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
David S. Millerfbe9cc42005-12-13 23:26:29 -08001072 spin_lock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 ordernum = (ordernum+1)&0xFFFFF;
1074
Kuniyuki Iwashimaf7ed31f2021-11-24 11:14:20 +09001075 if (__unix_find_socket_byname(sock_net(sk), addr->name, addr->len,
1076 addr->hash)) {
David S. Millerfbe9cc42005-12-13 23:26:29 -08001077 spin_unlock(&unix_table_lock);
Tetsuo Handa8df73ff2010-09-04 01:34:28 +00001078 /*
1079 * __unix_find_socket_byname() may take long time if many names
1080 * are already in use.
1081 */
1082 cond_resched();
1083 /* Give up if all names seems to be in use. */
1084 if (retries++ == 0xFFFFF) {
1085 err = -ENOSPC;
1086 kfree(addr);
1087 goto out;
1088 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 goto retry;
1090 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091
Al Viro185ab882021-06-19 03:50:26 +00001092 __unix_set_addr(sk, addr, addr->hash);
David S. Millerfbe9cc42005-12-13 23:26:29 -08001093 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 err = 0;
1095
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07001096out: mutex_unlock(&u->bindlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 return err;
1098}
1099
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001100static int unix_bind_bsd(struct sock *sk, struct sockaddr_un *sunaddr,
1101 int addr_len)
Al Virofaf02012012-07-20 02:37:29 +04001102{
Al Viro71e6be62021-06-19 03:50:30 +00001103 umode_t mode = S_IFSOCK |
1104 (SOCK_INODE(sk->sk_socket)->i_mode & ~current_umask());
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001105 struct unix_sock *u = unix_sk(sk);
Al Viro71e6be62021-06-19 03:50:30 +00001106 struct user_namespace *ns; // barf...
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001107 struct unix_address *addr;
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001108 struct dentry *dentry;
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001109 struct path parent;
Al Viro71e6be62021-06-19 03:50:30 +00001110 unsigned int hash;
1111 int err;
1112
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001113 unix_mkname_bsd(sunaddr, addr_len);
1114 addr_len = strlen(sunaddr->sun_path) +
1115 offsetof(struct sockaddr_un, sun_path) + 1;
1116
1117 addr = unix_create_addr(sunaddr, addr_len);
1118 if (!addr)
1119 return -ENOMEM;
1120
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001121 /*
1122 * Get the parent directory, calculate the hash for last
1123 * component.
1124 */
Al Viro71e6be62021-06-19 03:50:30 +00001125 dentry = kern_path_create(AT_FDCWD, addr->name->sun_path, &parent, 0);
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001126 if (IS_ERR(dentry)) {
1127 err = PTR_ERR(dentry);
1128 goto out;
1129 }
Al Virofaf02012012-07-20 02:37:29 +04001130
Linus Torvalds38f7bd942016-09-01 14:56:49 -07001131 /*
1132 * All right, let's create it.
1133 */
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001134 ns = mnt_user_ns(parent.mnt);
Al Viro71e6be62021-06-19 03:50:30 +00001135 err = security_path_mknod(&parent, dentry, mode, 0);
Al Viro56c17312021-06-19 03:50:31 +00001136 if (!err)
Al Viro71e6be62021-06-19 03:50:30 +00001137 err = vfs_mknod(ns, d_inode(parent.dentry), dentry, mode, 0);
Al Viroc0c3b8d2021-06-19 03:50:32 +00001138 if (err)
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001139 goto out_path;
Al Virofa42d912021-06-19 03:50:29 +00001140 err = mutex_lock_interruptible(&u->bindlock);
Al Viroc0c3b8d2021-06-19 03:50:32 +00001141 if (err)
1142 goto out_unlink;
1143 if (u->addr)
1144 goto out_unlock;
Al Virofa42d912021-06-19 03:50:29 +00001145
1146 addr->hash = UNIX_HASH_SIZE;
Al Viro56c17312021-06-19 03:50:31 +00001147 hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
Al Virofa42d912021-06-19 03:50:29 +00001148 spin_lock(&unix_table_lock);
Al Viro56c17312021-06-19 03:50:31 +00001149 u->path.mnt = mntget(parent.mnt);
1150 u->path.dentry = dget(dentry);
Al Virofa42d912021-06-19 03:50:29 +00001151 __unix_set_addr(sk, addr, hash);
1152 spin_unlock(&unix_table_lock);
1153 mutex_unlock(&u->bindlock);
Al Viro56c17312021-06-19 03:50:31 +00001154 done_path_create(&parent, dentry);
Al Virofa42d912021-06-19 03:50:29 +00001155 return 0;
Al Viroc0c3b8d2021-06-19 03:50:32 +00001156
1157out_unlock:
1158 mutex_unlock(&u->bindlock);
1159 err = -EINVAL;
1160out_unlink:
1161 /* failed after successful mknod? unlink what we'd created... */
1162 vfs_unlink(ns, d_inode(parent.dentry), dentry, NULL);
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001163out_path:
Al Viroc0c3b8d2021-06-19 03:50:32 +00001164 done_path_create(&parent, dentry);
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001165out:
1166 unix_release_addr(addr);
1167 return err == -EEXIST ? -EADDRINUSE : err;
Al Virofa42d912021-06-19 03:50:29 +00001168}
1169
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001170static int unix_bind_abstract(struct sock *sk, struct sockaddr_un *sunaddr,
1171 int addr_len)
Al Virofa42d912021-06-19 03:50:29 +00001172{
1173 struct unix_sock *u = unix_sk(sk);
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001174 struct unix_address *addr;
Al Virofa42d912021-06-19 03:50:29 +00001175 int err;
1176
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001177 addr = unix_create_addr(sunaddr, addr_len);
1178 if (!addr)
1179 return -ENOMEM;
1180
Al Virofa42d912021-06-19 03:50:29 +00001181 err = mutex_lock_interruptible(&u->bindlock);
1182 if (err)
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001183 goto out;
Al Virofa42d912021-06-19 03:50:29 +00001184
1185 if (u->addr) {
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001186 err = -EINVAL;
1187 goto out_mutex;
Al Virofa42d912021-06-19 03:50:29 +00001188 }
1189
Kuniyuki Iwashima5c32a3e2021-11-24 11:14:25 +09001190 addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
1191 addr->hash ^= sk->sk_type;
1192
Al Virofa42d912021-06-19 03:50:29 +00001193 spin_lock(&unix_table_lock);
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001194
Al Virofa42d912021-06-19 03:50:29 +00001195 if (__unix_find_socket_byname(sock_net(sk), addr->name, addr->len,
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001196 addr->hash))
1197 goto out_spin;
1198
Al Virofa42d912021-06-19 03:50:29 +00001199 __unix_set_addr(sk, addr, addr->hash);
1200 spin_unlock(&unix_table_lock);
1201 mutex_unlock(&u->bindlock);
1202 return 0;
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001203
1204out_spin:
1205 spin_unlock(&unix_table_lock);
1206 err = -EADDRINUSE;
1207out_mutex:
1208 mutex_unlock(&u->bindlock);
1209out:
1210 unix_release_addr(addr);
1211 return err;
Al Virofa42d912021-06-19 03:50:29 +00001212}
1213
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1215{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001216 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Kuniyuki Iwashima5c32a3e2021-11-24 11:14:25 +09001217 struct sock *sk = sock->sk;
Kuniyuki Iwashima5c32a3e2021-11-24 11:14:25 +09001218 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
Kuniyuki Iwashimab8a58aa2021-11-24 11:14:23 +09001220 if (addr_len == offsetof(struct sockaddr_un, sun_path) &&
1221 sunaddr->sun_family == AF_UNIX)
Kuniyuki Iwashimaf7ed31f2021-11-24 11:14:20 +09001222 return unix_autobind(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223
Kuniyuki Iwashimab8a58aa2021-11-24 11:14:23 +09001224 err = unix_validate_addr(sunaddr, addr_len);
1225 if (err)
1226 return err;
1227
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001228 if (sunaddr->sun_path[0])
1229 err = unix_bind_bsd(sk, sunaddr, addr_len);
Al Virofa42d912021-06-19 03:50:29 +00001230 else
Kuniyuki Iwashima12f21c42021-11-24 11:14:26 +09001231 err = unix_bind_abstract(sk, sunaddr, addr_len);
1232
1233 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234}
1235
David S. Miller278a3de2007-05-31 15:19:20 -07001236static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
1237{
1238 if (unlikely(sk1 == sk2) || !sk2) {
1239 unix_state_lock(sk1);
1240 return;
1241 }
1242 if (sk1 < sk2) {
1243 unix_state_lock(sk1);
1244 unix_state_lock_nested(sk2);
1245 } else {
1246 unix_state_lock(sk2);
1247 unix_state_lock_nested(sk1);
1248 }
1249}
1250
1251static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
1252{
1253 if (unlikely(sk1 == sk2) || !sk2) {
1254 unix_state_unlock(sk1);
1255 return;
1256 }
1257 unix_state_unlock(sk1);
1258 unix_state_unlock(sk2);
1259}
1260
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
1262 int alen, int flags)
1263{
1264 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001265 struct net *net = sock_net(sk);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001266 struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 struct sock *other;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268 int err;
1269
Mateusz Jurczykdefbcf22017-06-08 11:13:36 +02001270 err = -EINVAL;
1271 if (alen < offsetofend(struct sockaddr, sa_family))
1272 goto out;
1273
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 if (addr->sa_family != AF_UNSPEC) {
Kuniyuki Iwashimab8a58aa2021-11-24 11:14:23 +09001275 err = unix_validate_addr(sunaddr, alen);
1276 if (err)
1277 goto out;
1278
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 if (test_bit(SOCK_PASSCRED, &sock->flags) &&
Kuniyuki Iwashimaf7ed31f2021-11-24 11:14:20 +09001280 !unix_sk(sk)->addr) {
1281 err = unix_autobind(sk);
1282 if (err)
1283 goto out;
1284 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285
David S. Miller278a3de2007-05-31 15:19:20 -07001286restart:
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +09001287 other = unix_find_other(net, sunaddr, alen, sock->type);
Kuniyuki Iwashimaaed26f52021-11-24 11:14:22 +09001288 if (IS_ERR(other)) {
1289 err = PTR_ERR(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290 goto out;
Kuniyuki Iwashimaaed26f52021-11-24 11:14:22 +09001291 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292
David S. Miller278a3de2007-05-31 15:19:20 -07001293 unix_state_double_lock(sk, other);
1294
1295 /* Apparently VFS overslept socket death. Retry. */
1296 if (sock_flag(other, SOCK_DEAD)) {
1297 unix_state_double_unlock(sk, other);
1298 sock_put(other);
1299 goto restart;
1300 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301
1302 err = -EPERM;
1303 if (!unix_may_send(sk, other))
1304 goto out_unlock;
1305
1306 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1307 if (err)
1308 goto out_unlock;
1309
Eric Dumazetdc56ad72021-08-30 10:21:37 -07001310 sk->sk_state = other->sk_state = TCP_ESTABLISHED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311 } else {
1312 /*
1313 * 1003.1g breaking connected state with AF_UNSPEC
1314 */
1315 other = NULL;
David S. Miller278a3de2007-05-31 15:19:20 -07001316 unix_state_double_lock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 }
1318
1319 /*
1320 * If it was connected, reconnect.
1321 */
1322 if (unix_peer(sk)) {
1323 struct sock *old_peer = unix_peer(sk);
Eric Dumazetdc56ad72021-08-30 10:21:37 -07001324
Jianjun Konge27dfce2008-11-01 21:38:31 -07001325 unix_peer(sk) = other;
Eric Dumazetdc56ad72021-08-30 10:21:37 -07001326 if (!other)
1327 sk->sk_state = TCP_CLOSE;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001328 unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
1329
David S. Miller278a3de2007-05-31 15:19:20 -07001330 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331
1332 if (other != old_peer)
1333 unix_dgram_disconnected(sk, old_peer);
1334 sock_put(old_peer);
1335 } else {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001336 unix_peer(sk) = other;
David S. Miller278a3de2007-05-31 15:19:20 -07001337 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 }
Cong Wang83301b52021-07-04 12:02:45 -07001339
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001340 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341
1342out_unlock:
David S. Miller278a3de2007-05-31 15:19:20 -07001343 unix_state_double_unlock(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 sock_put(other);
1345out:
1346 return err;
1347}
1348
1349static long unix_wait_for_peer(struct sock *other, long timeo)
Jules Irenge48851e92020-02-23 23:16:56 +00001350 __releases(&unix_sk(other)->lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351{
1352 struct unix_sock *u = unix_sk(other);
1353 int sched;
1354 DEFINE_WAIT(wait);
1355
1356 prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
1357
1358 sched = !sock_flag(other, SOCK_DEAD) &&
1359 !(other->sk_shutdown & RCV_SHUTDOWN) &&
Rainer Weikusat3c734192008-06-17 22:28:05 -07001360 unix_recvq_full(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
David S. Miller1c92b4e2007-05-31 13:24:26 -07001362 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363
1364 if (sched)
1365 timeo = schedule_timeout(timeo);
1366
1367 finish_wait(&u->peer_wait, &wait);
1368 return timeo;
1369}
1370
1371static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
1372 int addr_len, int flags)
1373{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001374 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001376 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 struct unix_sock *u = unix_sk(sk), *newu, *otheru;
1378 struct sock *newsk = NULL;
1379 struct sock *other = NULL;
1380 struct sk_buff *skb = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 int st;
1382 int err;
1383 long timeo;
1384
Kuniyuki Iwashimab8a58aa2021-11-24 11:14:23 +09001385 err = unix_validate_addr(sunaddr, addr_len);
1386 if (err)
1387 goto out;
1388
Kuniyuki Iwashimaf7ed31f2021-11-24 11:14:20 +09001389 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr) {
1390 err = unix_autobind(sk);
1391 if (err)
1392 goto out;
1393 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394
1395 timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
1396
1397 /* First of all allocate resources.
1398 If we will make it after state is locked,
1399 we will have to recheck all again in any case.
1400 */
1401
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 /* create new sock for complete connection */
Jiang Wang94531cf2021-08-16 19:03:21 +00001403 newsk = unix_create1(sock_net(sk), NULL, 0, sock->type);
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +09001404 if (IS_ERR(newsk)) {
1405 err = PTR_ERR(newsk);
1406 newsk = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 goto out;
Kuniyuki Iwashimaf4bd73b2021-09-28 09:42:27 +09001408 }
1409
1410 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411
1412 /* Allocate skb for sending to listening sock */
1413 skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL);
1414 if (skb == NULL)
1415 goto out;
1416
1417restart:
1418 /* Find listening sock. */
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +09001419 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type);
Kuniyuki Iwashimaaed26f52021-11-24 11:14:22 +09001420 if (IS_ERR(other)) {
1421 err = PTR_ERR(other);
1422 other = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 goto out;
Kuniyuki Iwashimaaed26f52021-11-24 11:14:22 +09001424 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425
1426 /* Latch state of peer */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001427 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
1429 /* Apparently VFS overslept socket death. Retry. */
1430 if (sock_flag(other, SOCK_DEAD)) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001431 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 sock_put(other);
1433 goto restart;
1434 }
1435
1436 err = -ECONNREFUSED;
1437 if (other->sk_state != TCP_LISTEN)
1438 goto out_unlock;
Tomoki Sekiyama77238f22009-10-18 23:17:37 -07001439 if (other->sk_shutdown & RCV_SHUTDOWN)
1440 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441
Rainer Weikusat3c734192008-06-17 22:28:05 -07001442 if (unix_recvq_full(other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 err = -EAGAIN;
1444 if (!timeo)
1445 goto out_unlock;
1446
1447 timeo = unix_wait_for_peer(other, timeo);
1448
1449 err = sock_intr_errno(timeo);
1450 if (signal_pending(current))
1451 goto out;
1452 sock_put(other);
1453 goto restart;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09001454 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
1456 /* Latch our state.
1457
Daniel Balutae5537bf2011-03-14 15:25:33 -07001458 It is tricky place. We need to grab our state lock and cannot
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 drop lock on peer. It is dangerous because deadlock is
1460 possible. Connect to self case and simultaneous
1461 attempt to connect are eliminated by checking socket
1462 state. other is TCP_LISTEN, if sk is TCP_LISTEN we
1463 check this before attempt to grab lock.
1464
1465 Well, and we have to recheck the state after socket locked.
1466 */
1467 st = sk->sk_state;
1468
1469 switch (st) {
1470 case TCP_CLOSE:
1471 /* This is ok... continue with connect */
1472 break;
1473 case TCP_ESTABLISHED:
1474 /* Socket is already connected */
1475 err = -EISCONN;
1476 goto out_unlock;
1477 default:
1478 err = -EINVAL;
1479 goto out_unlock;
1480 }
1481
David S. Miller1c92b4e2007-05-31 13:24:26 -07001482 unix_state_lock_nested(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483
1484 if (sk->sk_state != st) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001485 unix_state_unlock(sk);
1486 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 sock_put(other);
1488 goto restart;
1489 }
1490
David S. Miller3610cda2011-01-05 15:38:53 -08001491 err = security_unix_stream_connect(sk, other, newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 if (err) {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001493 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 goto out_unlock;
1495 }
1496
1497 /* The way is open! Fastly set all the necessary fields... */
1498
1499 sock_hold(sk);
1500 unix_peer(newsk) = sk;
1501 newsk->sk_state = TCP_ESTABLISHED;
1502 newsk->sk_type = sk->sk_type;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001503 init_peercred(newsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 newu = unix_sk(newsk);
Eric Dumazeteaefd1102011-02-18 03:26:36 +00001505 RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 otheru = unix_sk(other);
1507
Al Viroae3b5642019-02-15 20:09:35 +00001508 /* copy address information from listening to new sock
1509 *
1510 * The contents of *(otheru->addr) and otheru->path
1511 * are seen fully set up here, since we have found
1512 * otheru in hash under unix_table_lock. Insertion
1513 * into the hash chain we'd found it in had been done
1514 * in an earlier critical area protected by unix_table_lock,
1515 * the same one where we'd set *(otheru->addr) contents,
1516 * as well as otheru->path and otheru->addr itself.
1517 *
1518 * Using smp_store_release() here to set newu->addr
1519 * is enough to make those stores, as well as stores
1520 * to newu->path visible to anyone who gets newu->addr
1521 * by smp_load_acquire(). IOW, the same warranties
1522 * as for unix_sock instances bound in unix_bind() or
1523 * in unix_autobind().
1524 */
Al Viro40ffe672012-03-14 21:54:32 -04001525 if (otheru->path.dentry) {
1526 path_get(&otheru->path);
1527 newu->path = otheru->path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 }
Al Viroae3b5642019-02-15 20:09:35 +00001529 refcount_inc(&otheru->addr->refcnt);
1530 smp_store_release(&newu->addr, otheru->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531
1532 /* Set credentials */
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001533 copy_peercred(sk, other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 sock->state = SS_CONNECTED;
1536 sk->sk_state = TCP_ESTABLISHED;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001537 sock_hold(newsk);
1538
Peter Zijlstra4e857c52014-03-17 18:06:10 +01001539 smp_mb__after_atomic(); /* sock_hold() does an atomic_inc() */
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08001540 unix_peer(sk) = newsk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
David S. Miller1c92b4e2007-05-31 13:24:26 -07001542 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543
gushengxian4e03d072021-06-09 20:09:35 -07001544 /* take ten and send info to listening sock */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 spin_lock(&other->sk_receive_queue.lock);
1546 __skb_queue_tail(&other->sk_receive_queue, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 spin_unlock(&other->sk_receive_queue.lock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001548 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001549 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 sock_put(other);
1551 return 0;
1552
1553out_unlock:
1554 if (other)
David S. Miller1c92b4e2007-05-31 13:24:26 -07001555 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556
1557out:
Wei Yongjun40d44442009-02-25 00:32:45 +00001558 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 if (newsk)
1560 unix_release_sock(newsk, 0);
1561 if (other)
1562 sock_put(other);
1563 return err;
1564}
1565
1566static int unix_socketpair(struct socket *socka, struct socket *sockb)
1567{
Jianjun Konge27dfce2008-11-01 21:38:31 -07001568 struct sock *ska = socka->sk, *skb = sockb->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569
1570 /* Join our sockets back to back */
1571 sock_hold(ska);
1572 sock_hold(skb);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001573 unix_peer(ska) = skb;
1574 unix_peer(skb) = ska;
Eric W. Biederman109f6e32010-06-13 03:30:14 +00001575 init_peercred(ska);
1576 init_peercred(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
Cong Wang83301b52021-07-04 12:02:45 -07001578 ska->sk_state = TCP_ESTABLISHED;
1579 skb->sk_state = TCP_ESTABLISHED;
1580 socka->state = SS_CONNECTED;
1581 sockb->state = SS_CONNECTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 return 0;
1583}
1584
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001585static void unix_sock_inherit_flags(const struct socket *old,
1586 struct socket *new)
1587{
1588 if (test_bit(SOCK_PASSCRED, &old->flags))
1589 set_bit(SOCK_PASSCRED, &new->flags);
1590 if (test_bit(SOCK_PASSSEC, &old->flags))
1591 set_bit(SOCK_PASSSEC, &new->flags);
1592}
1593
David Howellscdfbabf2017-03-09 08:09:05 +00001594static int unix_accept(struct socket *sock, struct socket *newsock, int flags,
1595 bool kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596{
1597 struct sock *sk = sock->sk;
1598 struct sock *tsk;
1599 struct sk_buff *skb;
1600 int err;
1601
1602 err = -EOPNOTSUPP;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08001603 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 goto out;
1605
1606 err = -EINVAL;
1607 if (sk->sk_state != TCP_LISTEN)
1608 goto out;
1609
1610 /* If socket state is TCP_LISTEN it cannot change (for now...),
1611 * so that no locks are necessary.
1612 */
1613
1614 skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
1615 if (!skb) {
1616 /* This means receive shutdown. */
1617 if (err == 0)
1618 err = -EINVAL;
1619 goto out;
1620 }
1621
1622 tsk = skb->sk;
1623 skb_free_datagram(sk, skb);
1624 wake_up_interruptible(&unix_sk(sk)->peer_wait);
1625
1626 /* attach accepted sock to socket */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001627 unix_state_lock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628 newsock->state = SS_CONNECTED;
Daniel Borkmann90c6bd32013-10-17 22:51:31 +02001629 unix_sock_inherit_flags(sock, newsock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 sock_graft(tsk, newsock);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001631 unix_state_unlock(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 return 0;
1633
1634out:
1635 return err;
1636}
1637
1638
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001639static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640{
1641 struct sock *sk = sock->sk;
Al Viroae3b5642019-02-15 20:09:35 +00001642 struct unix_address *addr;
Cyrill Gorcunov13cfa972009-11-08 05:51:19 +00001643 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 int err = 0;
1645
1646 if (peer) {
1647 sk = unix_peer_get(sk);
1648
1649 err = -ENOTCONN;
1650 if (!sk)
1651 goto out;
1652 err = 0;
1653 } else {
1654 sock_hold(sk);
1655 }
1656
Al Viroae3b5642019-02-15 20:09:35 +00001657 addr = smp_load_acquire(&unix_sk(sk)->addr);
1658 if (!addr) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 sunaddr->sun_family = AF_UNIX;
1660 sunaddr->sun_path[0] = 0;
Kuniyuki Iwashima755662c2021-11-24 11:14:19 +09001661 err = offsetof(struct sockaddr_un, sun_path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 } else {
Denys Vlasenko9b2c45d2018-02-12 20:00:20 +01001663 err = addr->len;
1664 memcpy(sunaddr, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 sock_put(sk);
1667out:
1668 return err;
1669}
1670
Miklos Szeredicbcf0112021-07-28 14:47:20 +02001671static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb)
1672{
1673 scm->fp = scm_fp_dup(UNIXCB(skb).fp);
1674
1675 /*
1676 * Garbage collection of unix sockets starts by selecting a set of
1677 * candidate sockets which have reference only from being in flight
1678 * (total_refs == inflight_refs). This condition is checked once during
1679 * the candidate collection phase, and candidates are marked as such, so
1680 * that non-candidates can later be ignored. While inflight_refs is
1681 * protected by unix_gc_lock, total_refs (file count) is not, hence this
1682 * is an instantaneous decision.
1683 *
1684 * Once a candidate, however, the socket must not be reinstalled into a
1685 * file descriptor while the garbage collection is in progress.
1686 *
1687 * If the above conditions are met, then the directed graph of
1688 * candidates (*) does not change while unix_gc_lock is held.
1689 *
1690 * Any operations that changes the file count through file descriptors
1691 * (dup, close, sendmsg) does not change the graph since candidates are
1692 * not installed in fds.
1693 *
1694 * Dequeing a candidate via recvmsg would install it into an fd, but
1695 * that takes unix_gc_lock to decrement the inflight count, so it's
1696 * serialized with garbage collection.
1697 *
1698 * MSG_PEEK is special in that it does not change the inflight count,
1699 * yet does install the socket into an fd. The following lock/unlock
1700 * pair is to ensure serialization with garbage collection. It must be
1701 * done between incrementing the file count and installing the file into
1702 * an fd.
1703 *
1704 * If garbage collection starts after the barrier provided by the
1705 * lock/unlock, then it will see the elevated refcount and not mark this
1706 * as a candidate. If a garbage collection is already in progress
1707 * before the file count was incremented, then the lock/unlock pair will
1708 * ensure that garbage collection is finished before progressing to
1709 * installing the fd.
1710 *
1711 * (*) A -> B where B is on the queue of A or B is on the queue of C
1712 * which is on the queue of listening socket A.
1713 */
1714 spin_lock(&unix_gc_lock);
1715 spin_unlock(&unix_gc_lock);
1716}
1717
David S. Millerf78a5fd2011-09-16 19:34:00 -04001718static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001719{
1720 int err = 0;
Eric Dumazet16e57262011-09-19 05:52:27 +00001721
David S. Millerf78a5fd2011-09-16 19:34:00 -04001722 UNIXCB(skb).pid = get_pid(scm->pid);
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001723 UNIXCB(skb).uid = scm->creds.uid;
1724 UNIXCB(skb).gid = scm->creds.gid;
Eric W. Biederman7361c362010-06-13 03:34:33 +00001725 UNIXCB(skb).fp = NULL;
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04001726 unix_get_secdata(scm, skb);
Eric W. Biederman7361c362010-06-13 03:34:33 +00001727 if (scm->fp && send_fds)
1728 err = unix_attach_fds(scm, skb);
1729
1730 skb->destructor = unix_destruct_scm;
1731 return err;
1732}
1733
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001734static bool unix_passcred_enabled(const struct socket *sock,
1735 const struct sock *other)
1736{
1737 return test_bit(SOCK_PASSCRED, &sock->flags) ||
1738 !other->sk_socket ||
1739 test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
1740}
1741
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742/*
Eric Dumazet16e57262011-09-19 05:52:27 +00001743 * Some apps rely on write() giving SCM_CREDENTIALS
1744 * We include credentials if source or destination socket
1745 * asserted SOCK_PASSCRED.
1746 */
1747static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1748 const struct sock *other)
1749{
Eric W. Biederman6b0ee8c02013-04-03 17:28:16 +00001750 if (UNIXCB(skb).pid)
Eric Dumazet16e57262011-09-19 05:52:27 +00001751 return;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001752 if (unix_passcred_enabled(sock, other)) {
Eric Dumazet16e57262011-09-19 05:52:27 +00001753 UNIXCB(skb).pid = get_pid(task_tgid(current));
David S. Miller6e0895c2013-04-22 20:32:51 -04001754 current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
Eric Dumazet16e57262011-09-19 05:52:27 +00001755 }
1756}
1757
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01001758static int maybe_init_creds(struct scm_cookie *scm,
1759 struct socket *socket,
1760 const struct sock *other)
1761{
1762 int err;
1763 struct msghdr msg = { .msg_controllen = 0 };
1764
1765 err = scm_send(socket, &msg, scm, false);
1766 if (err)
1767 return err;
1768
1769 if (unix_passcred_enabled(socket, other)) {
1770 scm->pid = get_pid(task_tgid(current));
1771 current_uid_gid(&scm->creds.uid, &scm->creds.gid);
1772 }
1773 return err;
1774}
1775
1776static bool unix_skb_scm_eq(struct sk_buff *skb,
1777 struct scm_cookie *scm)
1778{
1779 const struct unix_skb_parms *u = &UNIXCB(skb);
1780
1781 return u->pid == scm->pid &&
1782 uid_eq(u->uid, scm->creds.uid) &&
1783 gid_eq(u->gid, scm->creds.gid) &&
1784 unix_secdata_eq(scm, skb);
1785}
1786
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001787static void scm_stat_add(struct sock *sk, struct sk_buff *skb)
1788{
1789 struct scm_fp_list *fp = UNIXCB(skb).fp;
1790 struct unix_sock *u = unix_sk(sk);
1791
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001792 if (unlikely(fp && fp->count))
Paolo Abeni77820402020-02-28 14:45:21 +01001793 atomic_add(fp->count, &u->scm_stat.nr_fds);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001794}
1795
1796static void scm_stat_del(struct sock *sk, struct sk_buff *skb)
1797{
1798 struct scm_fp_list *fp = UNIXCB(skb).fp;
1799 struct unix_sock *u = unix_sk(sk);
1800
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001801 if (unlikely(fp && fp->count))
Paolo Abeni77820402020-02-28 14:45:21 +01001802 atomic_sub(fp->count, &u->scm_stat.nr_fds);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001803}
1804
Eric Dumazet16e57262011-09-19 05:52:27 +00001805/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 * Send AF_UNIX data.
1807 */
1808
Ying Xue1b784142015-03-02 15:37:48 +08001809static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
1810 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 struct sock *sk = sock->sk;
YOSHIFUJI Hideaki3b1e0a62008-03-26 02:26:21 +09001813 struct net *net = sock_net(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 struct unix_sock *u = unix_sk(sk);
Steffen Hurrle342dfc32014-01-17 22:53:15 +01001815 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 struct sock *other = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 int err;
David S. Millerf78a5fd2011-09-16 19:34:00 -04001818 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 long timeo;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001820 struct scm_cookie scm;
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001821 int data_len = 0;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001822 int sk_locked;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
dann frazier5f23b732008-11-26 15:32:27 -08001824 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001825 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 if (err < 0)
1827 return err;
1828
1829 err = -EOPNOTSUPP;
1830 if (msg->msg_flags&MSG_OOB)
1831 goto out;
1832
1833 if (msg->msg_namelen) {
Kuniyuki Iwashimab8a58aa2021-11-24 11:14:23 +09001834 err = unix_validate_addr(sunaddr, msg->msg_namelen);
1835 if (err)
1836 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 } else {
1838 sunaddr = NULL;
1839 err = -ENOTCONN;
1840 other = unix_peer_get(sk);
1841 if (!other)
1842 goto out;
1843 }
1844
Kuniyuki Iwashimaf7ed31f2021-11-24 11:14:20 +09001845 if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr) {
1846 err = unix_autobind(sk);
1847 if (err)
1848 goto out;
1849 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850
1851 err = -EMSGSIZE;
1852 if (len > sk->sk_sndbuf - 32)
1853 goto out;
1854
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001855 if (len > SKB_MAX_ALLOC) {
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001856 data_len = min_t(size_t,
1857 len - SKB_MAX_ALLOC,
1858 MAX_SKB_FRAGS * PAGE_SIZE);
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04001859 data_len = PAGE_ALIGN(data_len);
1860
1861 BUILD_BUG_ON(SKB_MAX_ALLOC < PAGE_SIZE);
1862 }
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001863
1864 skb = sock_alloc_send_pskb(sk, len - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07001865 msg->msg_flags & MSG_DONTWAIT, &err,
1866 PAGE_ALLOC_COSTLY_ORDER);
Jianjun Konge27dfce2008-11-01 21:38:31 -07001867 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 goto out;
1869
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001870 err = unix_scm_to_skb(&scm, skb, true);
Eric Dumazet25888e32010-11-25 04:11:39 +00001871 if (err < 0)
Eric W. Biederman7361c362010-06-13 03:34:33 +00001872 goto out_free;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07001873
Eric Dumazeteb6a2482012-04-03 05:28:28 +00001874 skb_put(skb, len - data_len);
1875 skb->data_len = data_len;
1876 skb->len = len;
Al Viroc0371da2014-11-24 10:42:55 -05001877 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 if (err)
1879 goto out_free;
1880
1881 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
1882
1883restart:
1884 if (!other) {
1885 err = -ECONNRESET;
1886 if (sunaddr == NULL)
1887 goto out_free;
1888
Kuniyuki Iwashimad2d8c9f2021-11-24 11:14:24 +09001889 other = unix_find_other(net, sunaddr, msg->msg_namelen,
1890 sk->sk_type);
Kuniyuki Iwashimaaed26f52021-11-24 11:14:22 +09001891 if (IS_ERR(other)) {
1892 err = PTR_ERR(other);
1893 other = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 goto out_free;
Kuniyuki Iwashimaaed26f52021-11-24 11:14:22 +09001895 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 }
1897
Alban Crequyd6ae3ba2011-01-18 06:39:15 +00001898 if (sk_filter(other, skb) < 0) {
1899 /* Toss the packet but do not return any error to the sender */
1900 err = len;
1901 goto out_free;
1902 }
1903
Rainer Weikusat7d267272015-11-20 22:07:23 +00001904 sk_locked = 0;
David S. Miller1c92b4e2007-05-31 13:24:26 -07001905 unix_state_lock(other);
Rainer Weikusat7d267272015-11-20 22:07:23 +00001906restart_locked:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 err = -EPERM;
1908 if (!unix_may_send(sk, other))
1909 goto out_unlock;
1910
Rainer Weikusat7d267272015-11-20 22:07:23 +00001911 if (unlikely(sock_flag(other, SOCK_DEAD))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 /*
1913 * Check with 1003.1g - what should
1914 * datagram error
1915 */
David S. Miller1c92b4e2007-05-31 13:24:26 -07001916 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917 sock_put(other);
1918
Rainer Weikusat7d267272015-11-20 22:07:23 +00001919 if (!sk_locked)
1920 unix_state_lock(sk);
1921
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 if (unix_peer(sk) == other) {
Jianjun Konge27dfce2008-11-01 21:38:31 -07001924 unix_peer(sk) = NULL;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001925 unix_dgram_peer_wake_disconnect_wakeup(sk, other);
1926
David S. Miller1c92b4e2007-05-31 13:24:26 -07001927 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928
Eric Dumazetdc56ad72021-08-30 10:21:37 -07001929 sk->sk_state = TCP_CLOSE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 unix_dgram_disconnected(sk, other);
1931 sock_put(other);
1932 err = -ECONNREFUSED;
1933 } else {
David S. Miller1c92b4e2007-05-31 13:24:26 -07001934 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935 }
1936
1937 other = NULL;
1938 if (err)
1939 goto out_free;
1940 goto restart;
1941 }
1942
1943 err = -EPIPE;
1944 if (other->sk_shutdown & RCV_SHUTDOWN)
1945 goto out_unlock;
1946
1947 if (sk->sk_type != SOCK_SEQPACKET) {
1948 err = security_unix_may_send(sk->sk_socket, other->sk_socket);
1949 if (err)
1950 goto out_unlock;
1951 }
1952
Rainer Weikusata5527dd2016-02-11 19:37:27 +00001953 /* other == sk && unix_peer(other) != sk if
1954 * - unix_peer(sk) == NULL, destination address bound to sk
1955 * - unix_peer(sk) == sk by time of get but disconnected before lock
1956 */
1957 if (other != sk &&
Qian Cai86b18aa2020-02-04 13:40:29 -05001958 unlikely(unix_peer(other) != sk &&
1959 unix_recvq_full_lockless(other))) {
Rainer Weikusat7d267272015-11-20 22:07:23 +00001960 if (timeo) {
1961 timeo = unix_wait_for_peer(other, timeo);
1962
1963 err = sock_intr_errno(timeo);
1964 if (signal_pending(current))
1965 goto out_free;
1966
1967 goto restart;
1968 }
1969
1970 if (!sk_locked) {
1971 unix_state_unlock(other);
1972 unix_state_double_lock(sk, other);
1973 }
1974
1975 if (unix_peer(sk) != other ||
1976 unix_dgram_peer_wake_me(sk, other)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 err = -EAGAIN;
Rainer Weikusat7d267272015-11-20 22:07:23 +00001978 sk_locked = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979 goto out_unlock;
1980 }
1981
Rainer Weikusat7d267272015-11-20 22:07:23 +00001982 if (!sk_locked) {
1983 sk_locked = 1;
1984 goto restart_locked;
1985 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986 }
1987
Rainer Weikusat7d267272015-11-20 22:07:23 +00001988 if (unlikely(sk_locked))
1989 unix_state_unlock(sk);
1990
Alban Crequy3f661162010-10-04 08:48:28 +00001991 if (sock_flag(other, SOCK_RCVTSTAMP))
1992 __net_timestamp(skb);
Eric Dumazet16e57262011-09-19 05:52:27 +00001993 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03001994 scm_stat_add(other, skb);
Paolo Abeni77820402020-02-28 14:45:21 +01001995 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07001996 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04001997 other->sk_data_ready(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01001999 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 return len;
2001
2002out_unlock:
Rainer Weikusat7d267272015-11-20 22:07:23 +00002003 if (sk_locked)
2004 unix_state_unlock(sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002005 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006out_free:
2007 kfree_skb(skb);
2008out:
2009 if (other)
2010 sock_put(other);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002011 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012 return err;
2013}
2014
Eric Dumazete370a722013-08-08 14:37:32 -07002015/* We use paged skbs for stream sockets, and limit occupancy to 32768
Tobias Klauserd4e9a402018-02-13 11:11:30 +01002016 * bytes, and a minimum of a full page.
Eric Dumazete370a722013-08-08 14:37:32 -07002017 */
2018#define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002019
Rao Shoaib314001f2021-08-01 00:57:07 -07002020#if (IS_ENABLED(CONFIG_AF_UNIX_OOB))
2021static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other)
2022{
2023 struct unix_sock *ousk = unix_sk(other);
2024 struct sk_buff *skb;
2025 int err = 0;
2026
2027 skb = sock_alloc_send_skb(sock->sk, 1, msg->msg_flags & MSG_DONTWAIT, &err);
2028
2029 if (!skb)
2030 return err;
2031
2032 skb_put(skb, 1);
Rao Shoaib314001f2021-08-01 00:57:07 -07002033 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, 1);
2034
2035 if (err) {
2036 kfree_skb(skb);
2037 return err;
2038 }
2039
2040 unix_state_lock(other);
Rao Shoaib19eed722021-08-13 11:19:34 -07002041
2042 if (sock_flag(other, SOCK_DEAD) ||
2043 (other->sk_shutdown & RCV_SHUTDOWN)) {
2044 unix_state_unlock(other);
2045 kfree_skb(skb);
2046 return -EPIPE;
2047 }
2048
Rao Shoaib314001f2021-08-01 00:57:07 -07002049 maybe_add_creds(skb, sock, other);
2050 skb_get(skb);
2051
2052 if (ousk->oob_skb)
Rao Shoaib19eed722021-08-13 11:19:34 -07002053 consume_skb(ousk->oob_skb);
Rao Shoaib314001f2021-08-01 00:57:07 -07002054
2055 ousk->oob_skb = skb;
2056
2057 scm_stat_add(other, skb);
2058 skb_queue_tail(&other->sk_receive_queue, skb);
2059 sk_send_sigurg(other);
2060 unix_state_unlock(other);
2061 other->sk_data_ready(other);
2062
2063 return err;
2064}
2065#endif
2066
Ying Xue1b784142015-03-02 15:37:48 +08002067static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
2068 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070 struct sock *sk = sock->sk;
2071 struct sock *other = NULL;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002072 int err, size;
David S. Millerf78a5fd2011-09-16 19:34:00 -04002073 struct sk_buff *skb;
Jianjun Konge27dfce2008-11-01 21:38:31 -07002074 int sent = 0;
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002075 struct scm_cookie scm;
Miklos Szeredi8ba69ba2009-09-11 11:31:45 -07002076 bool fds_sent = false;
Eric Dumazete370a722013-08-08 14:37:32 -07002077 int data_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078
dann frazier5f23b732008-11-26 15:32:27 -08002079 wait_for_unix_gc();
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002080 err = scm_send(sock, msg, &scm, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081 if (err < 0)
2082 return err;
2083
2084 err = -EOPNOTSUPP;
Rao Shoaib314001f2021-08-01 00:57:07 -07002085 if (msg->msg_flags & MSG_OOB) {
2086#if (IS_ENABLED(CONFIG_AF_UNIX_OOB))
2087 if (len)
2088 len--;
2089 else
2090#endif
2091 goto out_err;
2092 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093
2094 if (msg->msg_namelen) {
2095 err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
2096 goto out_err;
2097 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 err = -ENOTCONN;
Benjamin LaHaise830a1e52005-12-13 23:22:32 -08002099 other = unix_peer(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100 if (!other)
2101 goto out_err;
2102 }
2103
2104 if (sk->sk_shutdown & SEND_SHUTDOWN)
2105 goto pipe_err;
2106
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002107 while (sent < len) {
Eric Dumazete370a722013-08-08 14:37:32 -07002108 size = len - sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109
2110 /* Keep two messages in the pipe so it schedules better */
Eric Dumazete370a722013-08-08 14:37:32 -07002111 size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112
Eric Dumazete370a722013-08-08 14:37:32 -07002113 /* allow fallback to order-0 allocations */
2114 size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002115
Eric Dumazete370a722013-08-08 14:37:32 -07002116 data_len = max_t(int, 0, size - SKB_MAX_HEAD(0));
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002117
Kirill Tkhai31ff6aa2014-05-15 19:56:28 +04002118 data_len = min_t(size_t, size, PAGE_ALIGN(data_len));
2119
Eric Dumazete370a722013-08-08 14:37:32 -07002120 skb = sock_alloc_send_pskb(sk, size - data_len, data_len,
Eric Dumazet28d64272013-08-08 14:38:47 -07002121 msg->msg_flags & MSG_DONTWAIT, &err,
2122 get_order(UNIX_SKB_FRAGS_SZ));
Eric Dumazete370a722013-08-08 14:37:32 -07002123 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 goto out_err;
2125
David S. Millerf78a5fd2011-09-16 19:34:00 -04002126 /* Only send the fds in the first buffer */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002127 err = unix_scm_to_skb(&scm, skb, !fds_sent);
Eric Dumazet25888e32010-11-25 04:11:39 +00002128 if (err < 0) {
Eric W. Biederman7361c362010-06-13 03:34:33 +00002129 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04002130 goto out_err;
Miklos Szeredi62093442008-11-09 15:23:57 +01002131 }
Eric W. Biederman7361c362010-06-13 03:34:33 +00002132 fds_sent = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133
Eric Dumazete370a722013-08-08 14:37:32 -07002134 skb_put(skb, size - data_len);
2135 skb->data_len = data_len;
2136 skb->len = size;
Al Viroc0371da2014-11-24 10:42:55 -05002137 err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002138 if (err) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139 kfree_skb(skb);
David S. Millerf78a5fd2011-09-16 19:34:00 -04002140 goto out_err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 }
2142
David S. Miller1c92b4e2007-05-31 13:24:26 -07002143 unix_state_lock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144
2145 if (sock_flag(other, SOCK_DEAD) ||
2146 (other->sk_shutdown & RCV_SHUTDOWN))
2147 goto pipe_err_free;
2148
Eric Dumazet16e57262011-09-19 05:52:27 +00002149 maybe_add_creds(skb, sock, other);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002150 scm_stat_add(other, skb);
Paolo Abeni77820402020-02-28 14:45:21 +01002151 skb_queue_tail(&other->sk_receive_queue, skb);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002152 unix_state_unlock(other);
David S. Miller676d2362014-04-11 16:15:36 -04002153 other->sk_data_ready(other);
Jianjun Konge27dfce2008-11-01 21:38:31 -07002154 sent += size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156
Rao Shoaib314001f2021-08-01 00:57:07 -07002157#if (IS_ENABLED(CONFIG_AF_UNIX_OOB))
2158 if (msg->msg_flags & MSG_OOB) {
2159 err = queue_oob(sock, msg, other);
2160 if (err)
2161 goto out_err;
2162 sent++;
2163 }
2164#endif
2165
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002166 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167
2168 return sent;
2169
2170pipe_err_free:
David S. Miller1c92b4e2007-05-31 13:24:26 -07002171 unix_state_unlock(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002172 kfree_skb(skb);
2173pipe_err:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002174 if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
2175 send_sig(SIGPIPE, current, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176 err = -EPIPE;
2177out_err:
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002178 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179 return sent ? : err;
2180}
2181
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002182static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
2183 int offset, size_t size, int flags)
2184{
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002185 int err;
2186 bool send_sigpipe = false;
2187 bool init_scm = true;
2188 struct scm_cookie scm;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002189 struct sock *other, *sk = socket->sk;
2190 struct sk_buff *skb, *newskb = NULL, *tail = NULL;
2191
2192 if (flags & MSG_OOB)
2193 return -EOPNOTSUPP;
2194
2195 other = unix_peer(sk);
2196 if (!other || sk->sk_state != TCP_ESTABLISHED)
2197 return -ENOTCONN;
2198
2199 if (false) {
2200alloc_skb:
2201 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002202 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002203 newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
2204 &err, 0);
2205 if (!newskb)
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002206 goto err;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002207 }
2208
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002209 /* we must acquire iolock as we modify already present
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002210 * skbs in the sk_receive_queue and mess with skb->len
2211 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002212 err = mutex_lock_interruptible(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002213 if (err) {
2214 err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002215 goto err;
2216 }
2217
2218 if (sk->sk_shutdown & SEND_SHUTDOWN) {
2219 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002220 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002221 goto err_unlock;
2222 }
2223
2224 unix_state_lock(other);
2225
2226 if (sock_flag(other, SOCK_DEAD) ||
2227 other->sk_shutdown & RCV_SHUTDOWN) {
2228 err = -EPIPE;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002229 send_sigpipe = true;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002230 goto err_state_unlock;
2231 }
2232
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002233 if (init_scm) {
2234 err = maybe_init_creds(&scm, socket, other);
2235 if (err)
2236 goto err_state_unlock;
2237 init_scm = false;
2238 }
2239
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002240 skb = skb_peek_tail(&other->sk_receive_queue);
2241 if (tail && tail == skb) {
2242 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002243 } else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
2244 if (newskb) {
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002245 skb = newskb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002246 } else {
2247 tail = skb;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002248 goto alloc_skb;
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002249 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002250 } else if (newskb) {
2251 /* this is fast path, we don't necessarily need to
2252 * call to kfree_skb even though with newskb == NULL
2253 * this - does no harm
2254 */
2255 consume_skb(newskb);
Hannes Frederic Sowa8844f972015-11-16 16:25:56 +01002256 newskb = NULL;
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002257 }
2258
2259 if (skb_append_pagefrags(skb, page, offset, size)) {
2260 tail = skb;
2261 goto alloc_skb;
2262 }
2263
2264 skb->len += size;
2265 skb->data_len += size;
2266 skb->truesize += size;
Reshetova, Elena14afee42017-06-30 13:08:00 +03002267 refcount_add(size, &sk->sk_wmem_alloc);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002268
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002269 if (newskb) {
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002270 err = unix_scm_to_skb(&scm, skb, false);
2271 if (err)
2272 goto err_state_unlock;
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002273 spin_lock(&other->sk_receive_queue.lock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002274 __skb_queue_tail(&other->sk_receive_queue, newskb);
Hannes Frederic Sowaa3a116e2015-11-17 15:10:59 +01002275 spin_unlock(&other->sk_receive_queue.lock);
2276 }
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002277
2278 unix_state_unlock(other);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002279 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002280
2281 other->sk_data_ready(other);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002282 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002283 return size;
2284
2285err_state_unlock:
2286 unix_state_unlock(other);
2287err_unlock:
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002288 mutex_unlock(&unix_sk(other)->iolock);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002289err:
2290 kfree_skb(newskb);
2291 if (send_sigpipe && !(flags & MSG_NOSIGNAL))
2292 send_sig(SIGPIPE, current, 0);
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002293 if (!init_scm)
2294 scm_destroy(&scm);
Hannes Frederic Sowa869e7c62015-05-21 16:59:59 +02002295 return err;
2296}
2297
Ying Xue1b784142015-03-02 15:37:48 +08002298static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg,
2299 size_t len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002300{
2301 int err;
2302 struct sock *sk = sock->sk;
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002303
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304 err = sock_error(sk);
2305 if (err)
2306 return err;
2307
2308 if (sk->sk_state != TCP_ESTABLISHED)
2309 return -ENOTCONN;
2310
2311 if (msg->msg_namelen)
2312 msg->msg_namelen = 0;
2313
Ying Xue1b784142015-03-02 15:37:48 +08002314 return unix_dgram_sendmsg(sock, msg, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315}
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002316
Ying Xue1b784142015-03-02 15:37:48 +08002317static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg,
2318 size_t size, int flags)
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002319{
2320 struct sock *sk = sock->sk;
2321
2322 if (sk->sk_state != TCP_ESTABLISHED)
2323 return -ENOTCONN;
2324
Ying Xue1b784142015-03-02 15:37:48 +08002325 return unix_dgram_recvmsg(sock, msg, size, flags);
Eric W. Biedermana05d2ad2011-04-24 01:54:57 +00002326}
2327
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
2329{
Al Viroae3b5642019-02-15 20:09:35 +00002330 struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331
Al Viroae3b5642019-02-15 20:09:35 +00002332 if (addr) {
2333 msg->msg_namelen = addr->len;
2334 memcpy(msg->msg_name, addr->name, addr->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335 }
2336}
2337
Cong Wang9825d862021-07-04 12:02:48 -07002338int __unix_dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t size,
2339 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002341 struct scm_cookie scm;
Cong Wang9825d862021-07-04 12:02:48 -07002342 struct socket *sock = sk->sk_socket;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002343 struct unix_sock *u = unix_sk(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002344 struct sk_buff *skb, *last;
2345 long timeo;
Paolo Abenifd69c392019-04-08 10:15:59 +02002346 int skip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002347 int err;
2348
2349 err = -EOPNOTSUPP;
2350 if (flags&MSG_OOB)
2351 goto out;
2352
Rainer Weikusat64874282015-12-06 21:11:38 +00002353 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002354
Rainer Weikusat64874282015-12-06 21:11:38 +00002355 do {
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002356 mutex_lock(&u->iolock);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002357
Rainer Weikusat64874282015-12-06 21:11:38 +00002358 skip = sk_peek_offset(sk, flags);
Sabrina Dubrocab50b0582019-11-25 14:48:57 +01002359 skb = __skb_try_recv_datagram(sk, &sk->sk_receive_queue, flags,
Paolo Abenie427cad2020-02-28 14:45:22 +01002360 &skip, &err, &last);
2361 if (skb) {
2362 if (!(flags & MSG_PEEK))
2363 scm_stat_del(sk, skb);
Rainer Weikusat64874282015-12-06 21:11:38 +00002364 break;
Paolo Abenie427cad2020-02-28 14:45:22 +01002365 }
Rainer Weikusat64874282015-12-06 21:11:38 +00002366
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002367 mutex_unlock(&u->iolock);
Rainer Weikusat64874282015-12-06 21:11:38 +00002368
2369 if (err != -EAGAIN)
2370 break;
2371 } while (timeo &&
Sabrina Dubrocab50b0582019-11-25 14:48:57 +01002372 !__skb_wait_for_more_packets(sk, &sk->sk_receive_queue,
2373 &err, &timeo, last));
Rainer Weikusat64874282015-12-06 21:11:38 +00002374
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002375 if (!skb) { /* implies iolock unlocked */
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002376 unix_state_lock(sk);
2377 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
2378 if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
2379 (sk->sk_shutdown & RCV_SHUTDOWN))
2380 err = 0;
2381 unix_state_unlock(sk);
Rainer Weikusat64874282015-12-06 21:11:38 +00002382 goto out;
Florian Zumbiehl0a112252007-11-29 23:19:23 +11002383 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384
Rainer Weikusat77b75f42015-11-26 19:23:15 +00002385 if (wq_has_sleeper(&u->peer_wait))
2386 wake_up_interruptible_sync_poll(&u->peer_wait,
Linus Torvaldsa9a08842018-02-11 14:34:03 -08002387 EPOLLOUT | EPOLLWRNORM |
2388 EPOLLWRBAND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389
2390 if (msg->msg_name)
2391 unix_copy_addr(msg, skb->sk);
2392
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002393 if (size > skb->len - skip)
2394 size = skb->len - skip;
2395 else if (size < skb->len - skip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396 msg->msg_flags |= MSG_TRUNC;
2397
David S. Miller51f3d022014-11-05 16:46:40 -05002398 err = skb_copy_datagram_msg(skb, skip, msg, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399 if (err)
2400 goto out_free;
2401
Alban Crequy3f661162010-10-04 08:48:28 +00002402 if (sock_flag(sk, SOCK_RCVTSTAMP))
2403 __sock_recv_timestamp(msg, sk, skb);
2404
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002405 memset(&scm, 0, sizeof(scm));
2406
2407 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
2408 unix_set_secdata(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002410 if (!(flags & MSG_PEEK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411 if (UNIXCB(skb).fp)
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002412 unix_detach_fds(&scm, skb);
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002413
2414 sk_peek_offset_bwd(sk, skb->len);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002415 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 /* It is questionable: on PEEK we could:
2417 - do not return fds - good, but too simple 8)
2418 - return fds, and do not return them on read (old strategy,
2419 apparently wrong)
2420 - clone fds (I chose it for now, it is the most universal
2421 solution)
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002422
2423 POSIX 1003.1g does not actually define this clearly
2424 at all. POSIX 1003.1g doesn't define a lot of things
2425 clearly however!
2426
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 */
Pavel Emelyanovf55bb7f2012-02-21 07:31:51 +00002428
2429 sk_peek_offset_fwd(sk, size);
2430
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431 if (UNIXCB(skb).fp)
Miklos Szeredicbcf0112021-07-28 14:47:20 +02002432 unix_peek_fds(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433 }
Eric Dumazet9f6f9af2012-02-21 23:24:55 +00002434 err = (flags & MSG_TRUNC) ? skb->len - skip : size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002436 scm_recv(sock, msg, &scm, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437
2438out_free:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002439 skb_free_datagram(sk, skb);
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002440 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441out:
2442 return err;
2443}
2444
Cong Wang9825d862021-07-04 12:02:48 -07002445static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
2446 int flags)
2447{
2448 struct sock *sk = sock->sk;
2449
2450#ifdef CONFIG_BPF_SYSCALL
Jiang Wang94531cf2021-08-16 19:03:21 +00002451 const struct proto *prot = READ_ONCE(sk->sk_prot);
2452
2453 if (prot != &unix_dgram_proto)
2454 return prot->recvmsg(sk, msg, size, flags & MSG_DONTWAIT,
Cong Wang9825d862021-07-04 12:02:48 -07002455 flags & ~MSG_DONTWAIT, NULL);
2456#endif
2457 return __unix_dgram_recvmsg(sk, msg, size, flags);
2458}
2459
Cong Wang29df44f2021-07-04 12:02:44 -07002460static int unix_read_sock(struct sock *sk, read_descriptor_t *desc,
2461 sk_read_actor_t recv_actor)
2462{
2463 int copied = 0;
2464
2465 while (1) {
2466 struct unix_sock *u = unix_sk(sk);
2467 struct sk_buff *skb;
2468 int used, err;
2469
2470 mutex_lock(&u->iolock);
2471 skb = skb_recv_datagram(sk, 0, 1, &err);
2472 mutex_unlock(&u->iolock);
2473 if (!skb)
2474 return err;
2475
2476 used = recv_actor(desc, skb, 0, skb->len);
2477 if (used <= 0) {
2478 if (!copied)
2479 copied = used;
2480 kfree_skb(skb);
2481 break;
2482 } else if (used <= skb->len) {
2483 copied += used;
2484 }
2485
2486 kfree_skb(skb);
2487 if (!desc->count)
2488 break;
2489 }
2490
2491 return copied;
2492}
2493
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494/*
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002495 * Sleep until more data has arrived. But check for races..
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496 */
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002497static long unix_stream_data_wait(struct sock *sk, long timeo,
WANG Cong06a77b02016-11-17 15:55:26 -08002498 struct sk_buff *last, unsigned int last_len,
2499 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500{
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002501 struct sk_buff *tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502 DEFINE_WAIT(wait);
2503
David S. Miller1c92b4e2007-05-31 13:24:26 -07002504 unix_state_lock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505
2506 for (;;) {
Eric Dumazetaa395142010-04-20 13:03:51 +00002507 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002509 tail = skb_peek_tail(&sk->sk_receive_queue);
2510 if (tail != last ||
2511 (tail && tail->len != last_len) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512 sk->sk_err ||
2513 (sk->sk_shutdown & RCV_SHUTDOWN) ||
2514 signal_pending(current) ||
2515 !timeo)
2516 break;
2517
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002518 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002519 unix_state_unlock(sk);
WANG Cong06a77b02016-11-17 15:55:26 -08002520 if (freezable)
2521 timeo = freezable_schedule_timeout(timeo);
2522 else
2523 timeo = schedule_timeout(timeo);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002524 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002525
2526 if (sock_flag(sk, SOCK_DEAD))
2527 break;
2528
Eric Dumazet9cd3e072015-11-29 20:03:10 -08002529 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 }
2531
Eric Dumazetaa395142010-04-20 13:03:51 +00002532 finish_wait(sk_sleep(sk), &wait);
David S. Miller1c92b4e2007-05-31 13:24:26 -07002533 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534 return timeo;
2535}
2536
Eric Dumazete370a722013-08-08 14:37:32 -07002537static unsigned int unix_skb_len(const struct sk_buff *skb)
2538{
2539 return skb->len - UNIXCB(skb).consumed;
2540}
2541
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002542struct unix_stream_read_state {
2543 int (*recv_actor)(struct sk_buff *, int, int,
2544 struct unix_stream_read_state *);
2545 struct socket *socket;
2546 struct msghdr *msg;
2547 struct pipe_inode_info *pipe;
2548 size_t size;
2549 int flags;
2550 unsigned int splice_flags;
2551};
2552
Rao Shoaib314001f2021-08-01 00:57:07 -07002553#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
2554static int unix_stream_recv_urg(struct unix_stream_read_state *state)
2555{
2556 struct socket *sock = state->socket;
2557 struct sock *sk = sock->sk;
2558 struct unix_sock *u = unix_sk(sk);
2559 int chunk = 1;
Rao Shoaib876c14a2021-08-11 15:06:52 -07002560 struct sk_buff *oob_skb;
Rao Shoaib314001f2021-08-01 00:57:07 -07002561
Rao Shoaib876c14a2021-08-11 15:06:52 -07002562 mutex_lock(&u->iolock);
2563 unix_state_lock(sk);
2564
2565 if (sock_flag(sk, SOCK_URGINLINE) || !u->oob_skb) {
2566 unix_state_unlock(sk);
2567 mutex_unlock(&u->iolock);
Rao Shoaib314001f2021-08-01 00:57:07 -07002568 return -EINVAL;
Rao Shoaib876c14a2021-08-11 15:06:52 -07002569 }
Rao Shoaib314001f2021-08-01 00:57:07 -07002570
Rao Shoaib876c14a2021-08-11 15:06:52 -07002571 oob_skb = u->oob_skb;
2572
2573 if (!(state->flags & MSG_PEEK)) {
2574 u->oob_skb = NULL;
2575 }
2576
2577 unix_state_unlock(sk);
2578
2579 chunk = state->recv_actor(oob_skb, 0, chunk, state);
2580
2581 if (!(state->flags & MSG_PEEK)) {
2582 UNIXCB(oob_skb).consumed += 1;
2583 kfree_skb(oob_skb);
2584 }
2585
2586 mutex_unlock(&u->iolock);
2587
Rao Shoaib314001f2021-08-01 00:57:07 -07002588 if (chunk < 0)
2589 return -EFAULT;
2590
Rao Shoaib314001f2021-08-01 00:57:07 -07002591 state->msg->msg_flags |= MSG_OOB;
2592 return 1;
2593}
2594
2595static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
2596 int flags, int copied)
2597{
2598 struct unix_sock *u = unix_sk(sk);
2599
2600 if (!unix_skb_len(skb) && !(flags & MSG_PEEK)) {
2601 skb_unlink(skb, &sk->sk_receive_queue);
2602 consume_skb(skb);
2603 skb = NULL;
2604 } else {
2605 if (skb == u->oob_skb) {
2606 if (copied) {
2607 skb = NULL;
2608 } else if (sock_flag(sk, SOCK_URGINLINE)) {
2609 if (!(flags & MSG_PEEK)) {
2610 u->oob_skb = NULL;
2611 consume_skb(skb);
2612 }
2613 } else if (!(flags & MSG_PEEK)) {
2614 skb_unlink(skb, &sk->sk_receive_queue);
2615 consume_skb(skb);
2616 skb = skb_peek(&sk->sk_receive_queue);
2617 }
2618 }
2619 }
2620 return skb;
2621}
2622#endif
2623
Jiang Wang77462de2021-08-16 19:03:20 +00002624static int unix_stream_read_sock(struct sock *sk, read_descriptor_t *desc,
2625 sk_read_actor_t recv_actor)
2626{
2627 if (unlikely(sk->sk_state != TCP_ESTABLISHED))
2628 return -ENOTCONN;
2629
2630 return unix_read_sock(sk, desc, recv_actor);
2631}
2632
WANG Cong06a77b02016-11-17 15:55:26 -08002633static int unix_stream_read_generic(struct unix_stream_read_state *state,
2634 bool freezable)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635{
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002636 struct scm_cookie scm;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002637 struct socket *sock = state->socket;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638 struct sock *sk = sock->sk;
2639 struct unix_sock *u = unix_sk(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640 int copied = 0;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002641 int flags = state->flags;
Eric Dumazetde144392014-03-25 18:42:27 -07002642 int noblock = flags & MSG_DONTWAIT;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002643 bool check_creds = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644 int target;
2645 int err = 0;
2646 long timeo;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002647 int skip;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002648 size_t size = state->size;
2649 unsigned int last_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002651 if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
2652 err = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002654 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002656 if (unlikely(flags & MSG_OOB)) {
2657 err = -EOPNOTSUPP;
Rao Shoaib314001f2021-08-01 00:57:07 -07002658#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
Rao Shoaib314001f2021-08-01 00:57:07 -07002659 err = unix_stream_recv_urg(state);
Rao Shoaib314001f2021-08-01 00:57:07 -07002660#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002661 goto out;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002662 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002664 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
Eric Dumazetde144392014-03-25 18:42:27 -07002665 timeo = sock_rcvtimeo(sk, noblock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002667 memset(&scm, 0, sizeof(scm));
2668
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 /* Lock the socket to prevent queue disordering
2670 * while sleeps in memcpy_tomsg
2671 */
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002672 mutex_lock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673
Matthew Dawsona0917e02017-08-18 15:04:54 -04002674 skip = max(sk_peek_offset(sk, flags), 0);
Andrey Vagine9193d62015-10-02 00:05:36 +03002675
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002676 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677 int chunk;
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002678 bool drop_skb;
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002679 struct sk_buff *skb, *last;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002680
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002681redo:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002682 unix_state_lock(sk);
Mark Salyzynb48732e2015-05-26 08:22:19 -07002683 if (sock_flag(sk, SOCK_DEAD)) {
2684 err = -ECONNRESET;
2685 goto unlock;
2686 }
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002687 last = skb = skb_peek(&sk->sk_receive_queue);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002688 last_len = last ? last->len : 0;
Rao Shoaib314001f2021-08-01 00:57:07 -07002689
2690#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
2691 if (skb) {
2692 skb = manage_oob(skb, sk, flags, copied);
2693 if (!skb) {
2694 unix_state_unlock(sk);
2695 if (copied)
2696 break;
2697 goto redo;
2698 }
2699 }
2700#endif
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002701again:
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002702 if (skb == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703 if (copied >= target)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002704 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705
2706 /*
2707 * POSIX 1003.1g mandates this order.
2708 */
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09002709
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002710 err = sock_error(sk);
2711 if (err)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002712 goto unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713 if (sk->sk_shutdown & RCV_SHUTDOWN)
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002714 goto unlock;
2715
2716 unix_state_unlock(sk);
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002717 if (!timeo) {
2718 err = -EAGAIN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719 break;
Rainer Weikusat1b92ee32016-02-08 18:47:19 +00002720 }
2721
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002722 mutex_unlock(&u->iolock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002724 timeo = unix_stream_data_wait(sk, timeo, last,
WANG Cong06a77b02016-11-17 15:55:26 -08002725 last_len, freezable);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002726
Rainer Weikusat3822b5c2015-12-16 20:09:25 +00002727 if (signal_pending(current)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 err = sock_intr_errno(timeo);
Eric Dumazetfa0dc042016-01-24 13:53:50 -08002729 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730 goto out;
2731 }
Rainer Weikusatb3ca9b02011-02-28 04:50:55 +00002732
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002733 mutex_lock(&u->iolock);
Rainer Weikusat18eceb82016-02-18 12:39:46 +00002734 goto redo;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002735unlock:
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002736 unix_state_unlock(sk);
2737 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738 }
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002739
Eric Dumazete370a722013-08-08 14:37:32 -07002740 while (skip >= unix_skb_len(skb)) {
2741 skip -= unix_skb_len(skb);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002742 last = skb;
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002743 last_len = skb->len;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002744 skb = skb_peek_next(skb, &sk->sk_receive_queue);
Benjamin Poirier79f632c2013-04-29 11:42:14 +00002745 if (!skb)
2746 goto again;
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002747 }
2748
Miklos Szeredi3c0d2f32007-06-05 13:10:29 -07002749 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750
2751 if (check_creds) {
2752 /* Never glue messages from different writers */
Hannes Frederic Sowa9490f882015-11-26 12:08:18 +01002753 if (!unix_skb_scm_eq(skb, &scm))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754 break;
Eric W. Biederman0e82e7f6d2013-04-03 16:14:47 +00002755 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756 /* Copy credentials */
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002757 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
Stephen Smalley37a9a8d2015-06-10 08:44:59 -04002758 unix_set_secdata(&scm, skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002759 check_creds = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760 }
2761
2762 /* Copy address just once */
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002763 if (state->msg && state->msg->msg_name) {
2764 DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr,
2765 state->msg->msg_name);
2766 unix_copy_addr(state->msg, skb->sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767 sunaddr = NULL;
2768 }
2769
Eric Dumazete370a722013-08-08 14:37:32 -07002770 chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002771 skb_get(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002772 chunk = state->recv_actor(skb, skip, chunk, state);
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002773 drop_skb = !unix_skb_len(skb);
2774 /* skb is only safe to use if !drop_skb */
2775 consume_skb(skb);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002776 if (chunk < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777 if (copied == 0)
2778 copied = -EFAULT;
2779 break;
2780 }
2781 copied += chunk;
2782 size -= chunk;
2783
Hannes Frederic Sowa73ed5d22015-11-10 16:23:15 +01002784 if (drop_skb) {
2785 /* the skb was touched by a concurrent reader;
2786 * we should not expect anything from this skb
2787 * anymore and assume it invalid - we can be
2788 * sure it was dropped from the socket queue
2789 *
2790 * let's report a short read
2791 */
2792 err = 0;
2793 break;
2794 }
2795
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796 /* Mark read part of skb as used */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002797 if (!(flags & MSG_PEEK)) {
Eric Dumazete370a722013-08-08 14:37:32 -07002798 UNIXCB(skb).consumed += chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002800 sk_peek_offset_bwd(sk, chunk);
2801
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002802 if (UNIXCB(skb).fp) {
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002803 scm_stat_del(sk, skb);
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002804 unix_detach_fds(&scm, skb);
Kirill Tkhai3c32da12019-12-09 13:03:46 +03002805 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002806
Eric Dumazete370a722013-08-08 14:37:32 -07002807 if (unix_skb_len(skb))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002809
Eric Dumazet6f01fd62012-01-28 16:11:03 +00002810 skb_unlink(skb, &sk->sk_receive_queue);
Neil Horman70d4bf62010-07-20 06:45:56 +00002811 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812
Christoph Hellwig7cc05662015-01-28 18:04:53 +01002813 if (scm.fp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814 break;
Eric Dumazet6eba6a32008-11-16 22:58:44 -08002815 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816 /* It is questionable, see note in unix_dgram_recvmsg.
2817 */
2818 if (UNIXCB(skb).fp)
Miklos Szeredicbcf0112021-07-28 14:47:20 +02002819 unix_peek_fds(&scm, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820
Andrey Vagine9193d62015-10-02 00:05:36 +03002821 sk_peek_offset_fwd(sk, chunk);
Pavel Emelyanovfc0d7532012-02-21 07:32:06 +00002822
Aaron Conole9f389e32015-09-26 18:50:43 -04002823 if (UNIXCB(skb).fp)
2824 break;
2825
Andrey Vagine9193d62015-10-02 00:05:36 +03002826 skip = 0;
Aaron Conole9f389e32015-09-26 18:50:43 -04002827 last = skb;
2828 last_len = skb->len;
2829 unix_state_lock(sk);
2830 skb = skb_peek_next(skb, &sk->sk_receive_queue);
2831 if (skb)
2832 goto again;
2833 unix_state_unlock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 break;
2835 }
2836 } while (size);
2837
Linus Torvalds6e1ce3c2016-09-01 14:43:53 -07002838 mutex_unlock(&u->iolock);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002839 if (state->msg)
2840 scm_recv(sock, state->msg, &scm, flags);
2841 else
2842 scm_destroy(&scm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843out:
2844 return copied ? : err;
2845}
2846
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002847static int unix_stream_read_actor(struct sk_buff *skb,
2848 int skip, int chunk,
2849 struct unix_stream_read_state *state)
2850{
2851 int ret;
2852
2853 ret = skb_copy_datagram_msg(skb, UNIXCB(skb).consumed + skip,
2854 state->msg, chunk);
2855 return ret ?: chunk;
2856}
2857
Jiang Wang94531cf2021-08-16 19:03:21 +00002858int __unix_stream_recvmsg(struct sock *sk, struct msghdr *msg,
2859 size_t size, int flags)
2860{
2861 struct unix_stream_read_state state = {
2862 .recv_actor = unix_stream_read_actor,
2863 .socket = sk->sk_socket,
2864 .msg = msg,
2865 .size = size,
2866 .flags = flags
2867 };
2868
2869 return unix_stream_read_generic(&state, true);
2870}
2871
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002872static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
2873 size_t size, int flags)
2874{
2875 struct unix_stream_read_state state = {
2876 .recv_actor = unix_stream_read_actor,
2877 .socket = sock,
2878 .msg = msg,
2879 .size = size,
2880 .flags = flags
2881 };
2882
Jiang Wang94531cf2021-08-16 19:03:21 +00002883#ifdef CONFIG_BPF_SYSCALL
2884 struct sock *sk = sock->sk;
2885 const struct proto *prot = READ_ONCE(sk->sk_prot);
2886
2887 if (prot != &unix_stream_proto)
2888 return prot->recvmsg(sk, msg, size, flags & MSG_DONTWAIT,
2889 flags & ~MSG_DONTWAIT, NULL);
2890#endif
WANG Cong06a77b02016-11-17 15:55:26 -08002891 return unix_stream_read_generic(&state, true);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002892}
2893
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002894static int unix_stream_splice_actor(struct sk_buff *skb,
2895 int skip, int chunk,
2896 struct unix_stream_read_state *state)
2897{
2898 return skb_splice_bits(skb, state->socket->sk,
2899 UNIXCB(skb).consumed + skip,
Al Viro25869262016-09-17 21:02:10 -04002900 state->pipe, chunk, state->splice_flags);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002901}
2902
2903static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos,
2904 struct pipe_inode_info *pipe,
2905 size_t size, unsigned int flags)
2906{
2907 struct unix_stream_read_state state = {
2908 .recv_actor = unix_stream_splice_actor,
2909 .socket = sock,
2910 .pipe = pipe,
2911 .size = size,
2912 .splice_flags = flags,
2913 };
2914
2915 if (unlikely(*ppos))
2916 return -ESPIPE;
2917
2918 if (sock->file->f_flags & O_NONBLOCK ||
2919 flags & SPLICE_F_NONBLOCK)
2920 state.flags = MSG_DONTWAIT;
2921
WANG Cong06a77b02016-11-17 15:55:26 -08002922 return unix_stream_read_generic(&state, false);
Hannes Frederic Sowa2b514572015-05-21 17:00:01 +02002923}
2924
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925static int unix_shutdown(struct socket *sock, int mode)
2926{
2927 struct sock *sk = sock->sk;
2928 struct sock *other;
2929
Xi Wangfc61b922012-08-26 16:47:13 +00002930 if (mode < SHUT_RD || mode > SHUT_RDWR)
2931 return -EINVAL;
2932 /* This maps:
2933 * SHUT_RD (0) -> RCV_SHUTDOWN (1)
2934 * SHUT_WR (1) -> SEND_SHUTDOWN (2)
2935 * SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
2936 */
2937 ++mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938
Alban Crequy7180a032011-01-19 04:56:36 +00002939 unix_state_lock(sk);
2940 sk->sk_shutdown |= mode;
2941 other = unix_peer(sk);
2942 if (other)
2943 sock_hold(other);
2944 unix_state_unlock(sk);
2945 sk->sk_state_change(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
Alban Crequy7180a032011-01-19 04:56:36 +00002947 if (other &&
2948 (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949
Alban Crequy7180a032011-01-19 04:56:36 +00002950 int peer_mode = 0;
Jiang Wang94531cf2021-08-16 19:03:21 +00002951 const struct proto *prot = READ_ONCE(other->sk_prot);
Alban Crequy7180a032011-01-19 04:56:36 +00002952
Jiang Wangd3599022021-08-21 18:07:36 +00002953 if (prot->unhash)
2954 prot->unhash(other);
Alban Crequy7180a032011-01-19 04:56:36 +00002955 if (mode&RCV_SHUTDOWN)
2956 peer_mode |= SEND_SHUTDOWN;
2957 if (mode&SEND_SHUTDOWN)
2958 peer_mode |= RCV_SHUTDOWN;
2959 unix_state_lock(other);
2960 other->sk_shutdown |= peer_mode;
2961 unix_state_unlock(other);
2962 other->sk_state_change(other);
Jiang Wangd0c6416b2021-10-04 23:25:28 +00002963 if (peer_mode == SHUTDOWN_MASK)
Alban Crequy7180a032011-01-19 04:56:36 +00002964 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
Jiang Wangd0c6416b2021-10-04 23:25:28 +00002965 else if (peer_mode & RCV_SHUTDOWN)
Alban Crequy7180a032011-01-19 04:56:36 +00002966 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967 }
Alban Crequy7180a032011-01-19 04:56:36 +00002968 if (other)
2969 sock_put(other);
2970
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971 return 0;
2972}
2973
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002974long unix_inq_len(struct sock *sk)
2975{
2976 struct sk_buff *skb;
2977 long amount = 0;
2978
2979 if (sk->sk_state == TCP_LISTEN)
2980 return -EINVAL;
2981
2982 spin_lock(&sk->sk_receive_queue.lock);
2983 if (sk->sk_type == SOCK_STREAM ||
2984 sk->sk_type == SOCK_SEQPACKET) {
2985 skb_queue_walk(&sk->sk_receive_queue, skb)
Eric Dumazete370a722013-08-08 14:37:32 -07002986 amount += unix_skb_len(skb);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00002987 } else {
2988 skb = skb_peek(&sk->sk_receive_queue);
2989 if (skb)
2990 amount = skb->len;
2991 }
2992 spin_unlock(&sk->sk_receive_queue.lock);
2993
2994 return amount;
2995}
2996EXPORT_SYMBOL_GPL(unix_inq_len);
2997
2998long unix_outq_len(struct sock *sk)
2999{
3000 return sk_wmem_alloc_get(sk);
3001}
3002EXPORT_SYMBOL_GPL(unix_outq_len);
3003
Andrey Vaginba94f302017-02-01 11:00:45 -08003004static int unix_open_file(struct sock *sk)
3005{
3006 struct path path;
3007 struct file *f;
3008 int fd;
3009
3010 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
3011 return -EPERM;
3012
Al Viroae3b5642019-02-15 20:09:35 +00003013 if (!smp_load_acquire(&unix_sk(sk)->addr))
Andrey Vaginba94f302017-02-01 11:00:45 -08003014 return -ENOENT;
Al Viroae3b5642019-02-15 20:09:35 +00003015
3016 path = unix_sk(sk)->path;
3017 if (!path.dentry)
3018 return -ENOENT;
Andrey Vaginba94f302017-02-01 11:00:45 -08003019
3020 path_get(&path);
Andrey Vaginba94f302017-02-01 11:00:45 -08003021
3022 fd = get_unused_fd_flags(O_CLOEXEC);
3023 if (fd < 0)
3024 goto out;
3025
3026 f = dentry_open(&path, O_PATH, current_cred());
3027 if (IS_ERR(f)) {
3028 put_unused_fd(fd);
3029 fd = PTR_ERR(f);
3030 goto out;
3031 }
3032
3033 fd_install(fd, f);
3034out:
3035 path_put(&path);
3036
3037 return fd;
3038}
3039
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
3041{
3042 struct sock *sk = sock->sk;
Jianjun Konge27dfce2008-11-01 21:38:31 -07003043 long amount = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003044 int err;
3045
Eric Dumazet6eba6a32008-11-16 22:58:44 -08003046 switch (cmd) {
3047 case SIOCOUTQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00003048 amount = unix_outq_len(sk);
Eric Dumazet6eba6a32008-11-16 22:58:44 -08003049 err = put_user(amount, (int __user *)arg);
3050 break;
3051 case SIOCINQ:
Pavel Emelyanov885ee742011-12-30 00:54:11 +00003052 amount = unix_inq_len(sk);
3053 if (amount < 0)
3054 err = amount;
3055 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07003056 err = put_user(amount, (int __user *)arg);
Pavel Emelyanov885ee742011-12-30 00:54:11 +00003057 break;
Andrey Vaginba94f302017-02-01 11:00:45 -08003058 case SIOCUNIXFILE:
3059 err = unix_open_file(sk);
3060 break;
Rao Shoaib314001f2021-08-01 00:57:07 -07003061#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
3062 case SIOCATMARK:
3063 {
3064 struct sk_buff *skb;
3065 struct unix_sock *u = unix_sk(sk);
3066 int answ = 0;
3067
3068 skb = skb_peek(&sk->sk_receive_queue);
3069 if (skb && skb == u->oob_skb)
3070 answ = 1;
3071 err = put_user(answ, (int __user *)arg);
3072 }
3073 break;
3074#endif
Eric Dumazet6eba6a32008-11-16 22:58:44 -08003075 default:
3076 err = -ENOIOCTLCMD;
3077 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003078 }
3079 return err;
3080}
3081
Arnd Bergmann5f6beb92019-06-03 22:03:44 +02003082#ifdef CONFIG_COMPAT
3083static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
3084{
3085 return unix_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
3086}
3087#endif
3088
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003089static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090{
3091 struct sock *sk = sock->sk;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003092 __poll_t mask;
3093
Karsten Graul89ab0662018-10-23 13:40:39 +02003094 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003095 mask = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096
3097 /* exceptional events? */
3098 if (sk->sk_err)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003099 mask |= EPOLLERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003100 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003101 mask |= EPOLLHUP;
Davide Libenzif348d702006-03-25 03:07:39 -08003102 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003103 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104
3105 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07003106 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003107 mask |= EPOLLIN | EPOLLRDNORM;
Cong Wangaf493382021-10-08 13:33:05 -07003108 if (sk_is_readable(sk))
3109 mask |= EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110
3111 /* Connection-based need to check for termination and startup */
Eric Dumazet6eba6a32008-11-16 22:58:44 -08003112 if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
3113 sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003114 mask |= EPOLLHUP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115
3116 /*
3117 * we set writable also when the other side has shut down the
3118 * connection. This prevents stuck sockets.
3119 */
3120 if (unix_writable(sk))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003121 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122
3123 return mask;
3124}
3125
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003126static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
3127 poll_table *wait)
Rainer Weikusat3c734192008-06-17 22:28:05 -07003128{
Rainer Weikusatec0d2152008-06-27 19:34:18 -07003129 struct sock *sk = sock->sk, *other;
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003130 unsigned int writable;
3131 __poll_t mask;
3132
Karsten Graul89ab0662018-10-23 13:40:39 +02003133 sock_poll_wait(file, sock, wait);
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003134 mask = 0;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003135
3136 /* exceptional events? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07003137 if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003138 mask |= EPOLLERR |
3139 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
Keller, Jacob E7d4c04f2013-03-28 11:19:25 +00003140
Rainer Weikusat3c734192008-06-17 22:28:05 -07003141 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003142 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003143 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003144 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003145
3146 /* readable? */
Eric Dumazet3ef7cf52019-10-23 22:44:50 -07003147 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003148 mask |= EPOLLIN | EPOLLRDNORM;
Cong Wangaf493382021-10-08 13:33:05 -07003149 if (sk_is_readable(sk))
3150 mask |= EPOLLIN | EPOLLRDNORM;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003151
3152 /* Connection-based need to check for termination and startup */
3153 if (sk->sk_type == SOCK_SEQPACKET) {
3154 if (sk->sk_state == TCP_CLOSE)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003155 mask |= EPOLLHUP;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003156 /* connection hasn't started yet? */
3157 if (sk->sk_state == TCP_SYN_SENT)
3158 return mask;
3159 }
3160
Eric Dumazet973a34a2010-10-31 05:38:25 +00003161 /* No write status requested, avoid expensive OUT tests. */
Linus Torvaldsa11e1d42018-06-28 09:43:44 -07003162 if (!(poll_requested_events(wait) & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT)))
Eric Dumazet973a34a2010-10-31 05:38:25 +00003163 return mask;
3164
Rainer Weikusatec0d2152008-06-27 19:34:18 -07003165 writable = unix_writable(sk);
Rainer Weikusat7d267272015-11-20 22:07:23 +00003166 if (writable) {
3167 unix_state_lock(sk);
3168
3169 other = unix_peer(sk);
3170 if (other && unix_peer(other) != sk &&
Eric Dumazet04f08eb2021-09-08 17:00:29 -07003171 unix_recvq_full_lockless(other) &&
Rainer Weikusat7d267272015-11-20 22:07:23 +00003172 unix_dgram_peer_wake_me(sk, other))
3173 writable = 0;
3174
3175 unix_state_unlock(sk);
Rainer Weikusatec0d2152008-06-27 19:34:18 -07003176 }
3177
3178 if (writable)
Linus Torvaldsa9a08842018-02-11 14:34:03 -08003179 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Rainer Weikusat3c734192008-06-17 22:28:05 -07003180 else
Eric Dumazet9cd3e072015-11-29 20:03:10 -08003181 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
Rainer Weikusat3c734192008-06-17 22:28:05 -07003182
Rainer Weikusat3c734192008-06-17 22:28:05 -07003183 return mask;
3184}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003185
3186#ifdef CONFIG_PROC_FS
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08003187
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003188#define BUCKET_SPACE (BITS_PER_LONG - (UNIX_HASH_BITS + 1) - 1)
3189
3190#define get_bucket(x) ((x) >> BUCKET_SPACE)
3191#define get_offset(x) ((x) & ((1L << BUCKET_SPACE) - 1))
3192#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
Pavel Emelyanova53eb3f2007-11-23 20:30:01 +08003193
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003194static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195{
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003196 unsigned long offset = get_offset(*pos);
3197 unsigned long bucket = get_bucket(*pos);
3198 struct sock *sk;
3199 unsigned long count = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003201 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
3202 if (sock_net(sk) != seq_file_net(seq))
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003203 continue;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003204 if (++count == offset)
3205 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003206 }
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003207
3208 return sk;
3209}
3210
3211static struct sock *unix_next_socket(struct seq_file *seq,
3212 struct sock *sk,
3213 loff_t *pos)
3214{
3215 unsigned long bucket;
3216
3217 while (sk > (struct sock *)SEQ_START_TOKEN) {
3218 sk = sk_next(sk);
3219 if (!sk)
3220 goto next_bucket;
3221 if (sock_net(sk) == seq_file_net(seq))
3222 return sk;
3223 }
3224
3225 do {
3226 sk = unix_from_bucket(seq, pos);
3227 if (sk)
3228 return sk;
3229
3230next_bucket:
3231 bucket = get_bucket(*pos) + 1;
3232 *pos = set_bucket_offset(bucket, 1);
3233 } while (bucket < ARRAY_SIZE(unix_socket_table));
3234
Linus Torvalds1da177e2005-04-16 15:20:36 -07003235 return NULL;
3236}
3237
Linus Torvalds1da177e2005-04-16 15:20:36 -07003238static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
Eric Dumazet9a429c42008-01-01 21:58:02 -08003239 __acquires(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003240{
David S. Millerfbe9cc42005-12-13 23:26:29 -08003241 spin_lock(&unix_table_lock);
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003242
3243 if (!*pos)
3244 return SEQ_START_TOKEN;
3245
3246 if (get_bucket(*pos) >= ARRAY_SIZE(unix_socket_table))
3247 return NULL;
3248
3249 return unix_next_socket(seq, NULL, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003250}
3251
3252static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
3253{
3254 ++*pos;
Eric Dumazet7123aaa2012-06-08 05:03:21 +00003255 return unix_next_socket(seq, v, pos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256}
3257
3258static void unix_seq_stop(struct seq_file *seq, void *v)
Eric Dumazet9a429c42008-01-01 21:58:02 -08003259 __releases(unix_table_lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003260{
David S. Millerfbe9cc42005-12-13 23:26:29 -08003261 spin_unlock(&unix_table_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003262}
3263
3264static int unix_seq_show(struct seq_file *seq, void *v)
3265{
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09003266
Joe Perchesb9f31242008-04-12 19:04:38 -07003267 if (v == SEQ_START_TOKEN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268 seq_puts(seq, "Num RefCount Protocol Flags Type St "
3269 "Inode Path\n");
3270 else {
3271 struct sock *s = v;
3272 struct unix_sock *u = unix_sk(s);
David S. Miller1c92b4e2007-05-31 13:24:26 -07003273 unix_state_lock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003274
Dan Rosenberg71338aa2011-05-23 12:17:35 +00003275 seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003276 s,
Reshetova, Elena41c6d652017-06-30 13:08:01 +03003277 refcount_read(&s->sk_refcnt),
Linus Torvalds1da177e2005-04-16 15:20:36 -07003278 0,
3279 s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
3280 s->sk_type,
3281 s->sk_socket ?
3282 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
3283 (s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
3284 sock_i_ino(s));
3285
Al Viroae3b5642019-02-15 20:09:35 +00003286 if (u->addr) { // under unix_table_lock here
Linus Torvalds1da177e2005-04-16 15:20:36 -07003287 int i, len;
3288 seq_putc(seq, ' ');
3289
3290 i = 0;
Kuniyuki Iwashima755662c2021-11-24 11:14:19 +09003291 len = u->addr->len -
3292 offsetof(struct sockaddr_un, sun_path);
Kuniyuki Iwashima5ce7ab42021-11-24 11:14:27 +09003293 if (u->addr->name->sun_path[0]) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003294 len--;
Kuniyuki Iwashima5ce7ab42021-11-24 11:14:27 +09003295 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003296 seq_putc(seq, '@');
3297 i++;
3298 }
3299 for ( ; i < len; i++)
Isaac Boukrise7947ea2016-11-01 02:41:35 +02003300 seq_putc(seq, u->addr->name->sun_path[i] ?:
3301 '@');
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302 }
David S. Miller1c92b4e2007-05-31 13:24:26 -07003303 unix_state_unlock(s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003304 seq_putc(seq, '\n');
3305 }
3306
3307 return 0;
3308}
3309
Philippe De Muyter56b3d972007-07-10 23:07:31 -07003310static const struct seq_operations unix_seq_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311 .start = unix_seq_start,
3312 .next = unix_seq_next,
3313 .stop = unix_seq_stop,
3314 .show = unix_seq_show,
3315};
Kuniyuki Iwashima2c860a42021-08-14 10:57:15 +09003316
3317#if IS_BUILTIN(CONFIG_UNIX) && defined(CONFIG_BPF_SYSCALL)
3318struct bpf_iter__unix {
3319 __bpf_md_ptr(struct bpf_iter_meta *, meta);
3320 __bpf_md_ptr(struct unix_sock *, unix_sk);
3321 uid_t uid __aligned(8);
3322};
3323
3324static int unix_prog_seq_show(struct bpf_prog *prog, struct bpf_iter_meta *meta,
3325 struct unix_sock *unix_sk, uid_t uid)
3326{
3327 struct bpf_iter__unix ctx;
3328
3329 meta->seq_num--; /* skip SEQ_START_TOKEN */
3330 ctx.meta = meta;
3331 ctx.unix_sk = unix_sk;
3332 ctx.uid = uid;
3333 return bpf_iter_run_prog(prog, &ctx);
3334}
3335
3336static int bpf_iter_unix_seq_show(struct seq_file *seq, void *v)
3337{
3338 struct bpf_iter_meta meta;
3339 struct bpf_prog *prog;
3340 struct sock *sk = v;
3341 uid_t uid;
3342
3343 if (v == SEQ_START_TOKEN)
3344 return 0;
3345
3346 uid = from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk));
3347 meta.seq = seq;
3348 prog = bpf_iter_get_info(&meta, false);
3349 return unix_prog_seq_show(prog, &meta, v, uid);
3350}
3351
3352static void bpf_iter_unix_seq_stop(struct seq_file *seq, void *v)
3353{
3354 struct bpf_iter_meta meta;
3355 struct bpf_prog *prog;
3356
3357 if (!v) {
3358 meta.seq = seq;
3359 prog = bpf_iter_get_info(&meta, true);
3360 if (prog)
3361 (void)unix_prog_seq_show(prog, &meta, v, 0);
3362 }
3363
3364 unix_seq_stop(seq, v);
3365}
3366
3367static const struct seq_operations bpf_iter_unix_seq_ops = {
3368 .start = unix_seq_start,
3369 .next = unix_seq_next,
3370 .stop = bpf_iter_unix_seq_stop,
3371 .show = bpf_iter_unix_seq_show,
3372};
3373#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003374#endif
3375
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00003376static const struct net_proto_family unix_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003377 .family = PF_UNIX,
3378 .create = unix_create,
3379 .owner = THIS_MODULE,
3380};
3381
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003382
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00003383static int __net_init unix_net_init(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003384{
3385 int error = -ENOMEM;
3386
Denis V. Luneva0a53c82007-12-11 04:19:17 -08003387 net->unx.sysctl_max_dgram_qlen = 10;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11003388 if (unix_sysctl_register(net))
3389 goto out;
Pavel Emelyanovd392e492007-12-01 23:44:15 +11003390
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003391#ifdef CONFIG_PROC_FS
Christoph Hellwigc3506372018-04-10 19:42:55 +02003392 if (!proc_create_net("unix", 0, net->proc_net, &unix_seq_ops,
3393 sizeof(struct seq_net_private))) {
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11003394 unix_sysctl_unregister(net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003395 goto out;
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11003396 }
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003397#endif
3398 error = 0;
3399out:
Jianjun Kong48dcc33e2008-11-01 21:37:27 -07003400 return error;
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003401}
3402
Alexey Dobriyan2c8c1e72010-01-17 03:35:32 +00003403static void __net_exit unix_net_exit(struct net *net)
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003404{
Pavel Emelyanov1597fbc2007-12-01 23:51:01 +11003405 unix_sysctl_unregister(net);
Gao fengece31ff2013-02-18 01:34:56 +00003406 remove_proc_entry("unix", net->proc_net);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003407}
3408
3409static struct pernet_operations unix_net_ops = {
3410 .init = unix_net_init,
3411 .exit = unix_net_exit,
3412};
3413
Kuniyuki Iwashima2c860a42021-08-14 10:57:15 +09003414#if IS_BUILTIN(CONFIG_UNIX) && defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS)
3415DEFINE_BPF_ITER_FUNC(unix, struct bpf_iter_meta *meta,
3416 struct unix_sock *unix_sk, uid_t uid)
3417
3418static const struct bpf_iter_seq_info unix_seq_info = {
3419 .seq_ops = &bpf_iter_unix_seq_ops,
3420 .init_seq_private = bpf_iter_init_seq_net,
3421 .fini_seq_private = bpf_iter_fini_seq_net,
3422 .seq_priv_size = sizeof(struct seq_net_private),
3423};
3424
3425static struct bpf_iter_reg unix_reg_info = {
3426 .target = "unix",
3427 .ctx_arg_info_size = 1,
3428 .ctx_arg_info = {
3429 { offsetof(struct bpf_iter__unix, unix_sk),
3430 PTR_TO_BTF_ID_OR_NULL },
3431 },
3432 .seq_info = &unix_seq_info,
3433};
3434
3435static void __init bpf_iter_register(void)
3436{
3437 unix_reg_info.ctx_arg_info[0].btf_id = btf_sock_ids[BTF_SOCK_TYPE_UNIX];
3438 if (bpf_iter_reg_target(&unix_reg_info))
3439 pr_warn("Warning: could not register bpf iterator unix\n");
3440}
3441#endif
3442
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443static int __init af_unix_init(void)
3444{
3445 int rc = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003446
Pankaj Bharadiyac5936422019-12-09 10:31:43 -08003447 BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof_field(struct sk_buff, cb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448
Jiang Wang94531cf2021-08-16 19:03:21 +00003449 rc = proto_register(&unix_dgram_proto, 1);
3450 if (rc != 0) {
3451 pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
3452 goto out;
3453 }
3454
3455 rc = proto_register(&unix_stream_proto, 1);
YOSHIFUJI Hideakiac7bfa62007-02-09 23:25:23 +09003456 if (rc != 0) {
wangweidong5cc208b2013-12-06 18:03:36 +08003457 pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003458 goto out;
3459 }
3460
3461 sock_register(&unix_family_ops);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003462 register_pernet_subsys(&unix_net_ops);
Cong Wangc6382912021-07-04 12:02:47 -07003463 unix_bpf_build_proto();
Kuniyuki Iwashima2c860a42021-08-14 10:57:15 +09003464
3465#if IS_BUILTIN(CONFIG_UNIX) && defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS)
3466 bpf_iter_register();
3467#endif
3468
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469out:
3470 return rc;
3471}
3472
3473static void __exit af_unix_exit(void)
3474{
3475 sock_unregister(PF_UNIX);
Jiang Wang94531cf2021-08-16 19:03:21 +00003476 proto_unregister(&unix_dgram_proto);
3477 proto_unregister(&unix_stream_proto);
Denis V. Lunev097e66c2007-11-19 22:29:30 -08003478 unregister_pernet_subsys(&unix_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003479}
3480
David Woodhouse3d366962008-04-24 00:59:25 -07003481/* Earlier than device_initcall() so that other drivers invoking
3482 request_module() don't end up in a loop when modprobe tries
3483 to use a UNIX socket. But later than subsys_initcall() because
3484 we depend on stuff initialised there */
3485fs_initcall(af_unix_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003486module_exit(af_unix_exit);
3487
3488MODULE_LICENSE("GPL");
3489MODULE_ALIAS_NETPROTO(PF_UNIX);