xref: /openbmc/linux/net/socket.c (revision a5ef058d)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * NET		An implementation of the SOCKET network access protocol.
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Version:	@(#)socket.c	1.1.93	18/02/95
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  * Authors:	Orest Zborowski, <obz@Kodak.COM>
802c30a84SJesper Juhl  *		Ross Biro
91da177e4SLinus Torvalds  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  * Fixes:
121da177e4SLinus Torvalds  *		Anonymous	:	NOTSOCK/BADF cleanup. Error fix in
131da177e4SLinus Torvalds  *					shutdown()
141da177e4SLinus Torvalds  *		Alan Cox	:	verify_area() fixes
151da177e4SLinus Torvalds  *		Alan Cox	:	Removed DDI
161da177e4SLinus Torvalds  *		Jonathan Kamens	:	SOCK_DGRAM reconnect bug
171da177e4SLinus Torvalds  *		Alan Cox	:	Moved a load of checks to the very
181da177e4SLinus Torvalds  *					top level.
191da177e4SLinus Torvalds  *		Alan Cox	:	Move address structures to/from user
201da177e4SLinus Torvalds  *					mode above the protocol layers.
211da177e4SLinus Torvalds  *		Rob Janssen	:	Allow 0 length sends.
221da177e4SLinus Torvalds  *		Alan Cox	:	Asynchronous I/O support (cribbed from the
231da177e4SLinus Torvalds  *					tty drivers).
241da177e4SLinus Torvalds  *		Niibe Yutaka	:	Asynchronous I/O for writes (4.4BSD style)
251da177e4SLinus Torvalds  *		Jeff Uphoff	:	Made max number of sockets command-line
261da177e4SLinus Torvalds  *					configurable.
271da177e4SLinus Torvalds  *		Matti Aarnio	:	Made the number of sockets dynamic,
281da177e4SLinus Torvalds  *					to be allocated when needed, and mr.
291da177e4SLinus Torvalds  *					Uphoff's max is used as max to be
301da177e4SLinus Torvalds  *					allowed to allocate.
311da177e4SLinus Torvalds  *		Linus		:	Argh. removed all the socket allocation
321da177e4SLinus Torvalds  *					altogether: it's in the inode now.
331da177e4SLinus Torvalds  *		Alan Cox	:	Made sock_alloc()/sock_release() public
341da177e4SLinus Torvalds  *					for NetROM and future kernel nfsd type
351da177e4SLinus Torvalds  *					stuff.
361da177e4SLinus Torvalds  *		Alan Cox	:	sendmsg/recvmsg basics.
371da177e4SLinus Torvalds  *		Tom Dyas	:	Export net symbols.
381da177e4SLinus Torvalds  *		Marcin Dalecki	:	Fixed problems with CONFIG_NET="n".
391da177e4SLinus Torvalds  *		Alan Cox	:	Added thread locking to sys_* calls
401da177e4SLinus Torvalds  *					for sockets. May have errors at the
411da177e4SLinus Torvalds  *					moment.
421da177e4SLinus Torvalds  *		Kevin Buhr	:	Fixed the dumb errors in the above.
431da177e4SLinus Torvalds  *		Andi Kleen	:	Some small cleanups, optimizations,
441da177e4SLinus Torvalds  *					and fixed a copy_from_user() bug.
451da177e4SLinus Torvalds  *		Tigran Aivazian	:	sys_send(args) calls sys_sendto(args, NULL, 0)
461da177e4SLinus Torvalds  *		Tigran Aivazian	:	Made listen(2) backlog sanity checks
471da177e4SLinus Torvalds  *					protocol-independent
481da177e4SLinus Torvalds  *
491da177e4SLinus Torvalds  *	This module is effectively the top level interface to the BSD socket
501da177e4SLinus Torvalds  *	paradigm.
511da177e4SLinus Torvalds  *
521da177e4SLinus Torvalds  *	Based upon Swansea University Computer Society NET3.039
531da177e4SLinus Torvalds  */
541da177e4SLinus Torvalds 
55aef2fedaSJakub Kicinski #include <linux/bpf-cgroup.h>
56cc69837fSJakub Kicinski #include <linux/ethtool.h>
571da177e4SLinus Torvalds #include <linux/mm.h>
581da177e4SLinus Torvalds #include <linux/socket.h>
591da177e4SLinus Torvalds #include <linux/file.h>
601da177e4SLinus Torvalds #include <linux/net.h>
611da177e4SLinus Torvalds #include <linux/interrupt.h>
62aaca0bdcSUlrich Drepper #include <linux/thread_info.h>
6355737fdaSStephen Hemminger #include <linux/rcupdate.h>
641da177e4SLinus Torvalds #include <linux/netdevice.h>
651da177e4SLinus Torvalds #include <linux/proc_fs.h>
661da177e4SLinus Torvalds #include <linux/seq_file.h>
674a3e2f71SArjan van de Ven #include <linux/mutex.h>
681da177e4SLinus Torvalds #include <linux/if_bridge.h>
6920380731SArnaldo Carvalho de Melo #include <linux/if_vlan.h>
70408eccceSDaniel Borkmann #include <linux/ptp_classify.h>
711da177e4SLinus Torvalds #include <linux/init.h>
721da177e4SLinus Torvalds #include <linux/poll.h>
731da177e4SLinus Torvalds #include <linux/cache.h>
741da177e4SLinus Torvalds #include <linux/module.h>
751da177e4SLinus Torvalds #include <linux/highmem.h>
761da177e4SLinus Torvalds #include <linux/mount.h>
77fba9be49SDavid Howells #include <linux/pseudo_fs.h>
781da177e4SLinus Torvalds #include <linux/security.h>
791da177e4SLinus Torvalds #include <linux/syscalls.h>
801da177e4SLinus Torvalds #include <linux/compat.h>
811da177e4SLinus Torvalds #include <linux/kmod.h>
823ec3b2fbSDavid Woodhouse #include <linux/audit.h>
83d86b5e0eSAdrian Bunk #include <linux/wireless.h>
841b8d7ae4SEric W. Biederman #include <linux/nsproxy.h>
851fd7317dSNick Black #include <linux/magic.h>
865a0e3ad6STejun Heo #include <linux/slab.h>
87600e1779SMasatake YAMATO #include <linux/xattr.h>
88c8e8cd57SJeremy Cline #include <linux/nospec.h>
898c3c447bSPaolo Abeni #include <linux/indirect_call_wrapper.h>
901da177e4SLinus Torvalds 
917c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
921da177e4SLinus Torvalds #include <asm/unistd.h>
931da177e4SLinus Torvalds 
941da177e4SLinus Torvalds #include <net/compat.h>
9587de87d5SDavid S. Miller #include <net/wext.h>
96f8451725SHerbert Xu #include <net/cls_cgroup.h>
971da177e4SLinus Torvalds 
981da177e4SLinus Torvalds #include <net/sock.h>
991da177e4SLinus Torvalds #include <linux/netfilter.h>
1001da177e4SLinus Torvalds 
1016b96018bSArnd Bergmann #include <linux/if_tun.h>
1026b96018bSArnd Bergmann #include <linux/ipv6_route.h>
1036b96018bSArnd Bergmann #include <linux/route.h>
104c7dc504eSArnd Bergmann #include <linux/termios.h>
1056b96018bSArnd Bergmann #include <linux/sockios.h>
106076bb0c8SEliezer Tamir #include <net/busy_poll.h>
107f24b9be5SWillem de Bruijn #include <linux/errqueue.h>
108d7c08826SYangbo Lu #include <linux/ptp_clock_kernel.h>
10906021292SEliezer Tamir 
110e0d1095aSCong Wang #ifdef CONFIG_NET_RX_BUSY_POLL
11164b0dc51SEliezer Tamir unsigned int sysctl_net_busy_read __read_mostly;
11264b0dc51SEliezer Tamir unsigned int sysctl_net_busy_poll __read_mostly;
11306021292SEliezer Tamir #endif
1146b96018bSArnd Bergmann 
1158ae5e030SAl Viro static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to);
1168ae5e030SAl Viro static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from);
1171da177e4SLinus Torvalds static int sock_mmap(struct file *file, struct vm_area_struct *vma);
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds static int sock_close(struct inode *inode, struct file *file);
120a11e1d43SLinus Torvalds static __poll_t sock_poll(struct file *file,
121a11e1d43SLinus Torvalds 			      struct poll_table_struct *wait);
12289bddce5SStephen Hemminger static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
12389bbfc95SShaun Pereira #ifdef CONFIG_COMPAT
12489bbfc95SShaun Pereira static long compat_sock_ioctl(struct file *file,
12589bbfc95SShaun Pereira 			      unsigned int cmd, unsigned long arg);
12689bbfc95SShaun Pereira #endif
1271da177e4SLinus Torvalds static int sock_fasync(int fd, struct file *filp, int on);
1281da177e4SLinus Torvalds static ssize_t sock_sendpage(struct file *file, struct page *page,
1291da177e4SLinus Torvalds 			     int offset, size_t size, loff_t *ppos, int more);
1309c55e01cSJens Axboe static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
1319c55e01cSJens Axboe 				struct pipe_inode_info *pipe, size_t len,
1329c55e01cSJens Axboe 				unsigned int flags);
133542d3065SArnd Bergmann 
134542d3065SArnd Bergmann #ifdef CONFIG_PROC_FS
135542d3065SArnd Bergmann static void sock_show_fdinfo(struct seq_file *m, struct file *f)
136542d3065SArnd Bergmann {
137542d3065SArnd Bergmann 	struct socket *sock = f->private_data;
138542d3065SArnd Bergmann 
139542d3065SArnd Bergmann 	if (sock->ops->show_fdinfo)
140542d3065SArnd Bergmann 		sock->ops->show_fdinfo(m, sock);
141542d3065SArnd Bergmann }
142542d3065SArnd Bergmann #else
143542d3065SArnd Bergmann #define sock_show_fdinfo NULL
144542d3065SArnd Bergmann #endif
1451da177e4SLinus Torvalds 
1461da177e4SLinus Torvalds /*
1471da177e4SLinus Torvalds  *	Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
1481da177e4SLinus Torvalds  *	in the operation structures but are done directly via the socketcall() multiplexor.
1491da177e4SLinus Torvalds  */
1501da177e4SLinus Torvalds 
151da7071d7SArjan van de Ven static const struct file_operations socket_file_ops = {
1521da177e4SLinus Torvalds 	.owner =	THIS_MODULE,
1531da177e4SLinus Torvalds 	.llseek =	no_llseek,
1548ae5e030SAl Viro 	.read_iter =	sock_read_iter,
1558ae5e030SAl Viro 	.write_iter =	sock_write_iter,
1561da177e4SLinus Torvalds 	.poll =		sock_poll,
1571da177e4SLinus Torvalds 	.unlocked_ioctl = sock_ioctl,
15889bbfc95SShaun Pereira #ifdef CONFIG_COMPAT
15989bbfc95SShaun Pereira 	.compat_ioctl = compat_sock_ioctl,
16089bbfc95SShaun Pereira #endif
1611da177e4SLinus Torvalds 	.mmap =		sock_mmap,
1621da177e4SLinus Torvalds 	.release =	sock_close,
1631da177e4SLinus Torvalds 	.fasync =	sock_fasync,
1645274f052SJens Axboe 	.sendpage =	sock_sendpage,
1655274f052SJens Axboe 	.splice_write = generic_splice_sendpage,
1669c55e01cSJens Axboe 	.splice_read =	sock_splice_read,
167b4653342SKirill Tkhai 	.show_fdinfo =	sock_show_fdinfo,
1681da177e4SLinus Torvalds };
1691da177e4SLinus Torvalds 
170fe0bdbdeSYejune Deng static const char * const pf_family_names[] = {
171fe0bdbdeSYejune Deng 	[PF_UNSPEC]	= "PF_UNSPEC",
172fe0bdbdeSYejune Deng 	[PF_UNIX]	= "PF_UNIX/PF_LOCAL",
173fe0bdbdeSYejune Deng 	[PF_INET]	= "PF_INET",
174fe0bdbdeSYejune Deng 	[PF_AX25]	= "PF_AX25",
175fe0bdbdeSYejune Deng 	[PF_IPX]	= "PF_IPX",
176fe0bdbdeSYejune Deng 	[PF_APPLETALK]	= "PF_APPLETALK",
177fe0bdbdeSYejune Deng 	[PF_NETROM]	= "PF_NETROM",
178fe0bdbdeSYejune Deng 	[PF_BRIDGE]	= "PF_BRIDGE",
179fe0bdbdeSYejune Deng 	[PF_ATMPVC]	= "PF_ATMPVC",
180fe0bdbdeSYejune Deng 	[PF_X25]	= "PF_X25",
181fe0bdbdeSYejune Deng 	[PF_INET6]	= "PF_INET6",
182fe0bdbdeSYejune Deng 	[PF_ROSE]	= "PF_ROSE",
183fe0bdbdeSYejune Deng 	[PF_DECnet]	= "PF_DECnet",
184fe0bdbdeSYejune Deng 	[PF_NETBEUI]	= "PF_NETBEUI",
185fe0bdbdeSYejune Deng 	[PF_SECURITY]	= "PF_SECURITY",
186fe0bdbdeSYejune Deng 	[PF_KEY]	= "PF_KEY",
187fe0bdbdeSYejune Deng 	[PF_NETLINK]	= "PF_NETLINK/PF_ROUTE",
188fe0bdbdeSYejune Deng 	[PF_PACKET]	= "PF_PACKET",
189fe0bdbdeSYejune Deng 	[PF_ASH]	= "PF_ASH",
190fe0bdbdeSYejune Deng 	[PF_ECONET]	= "PF_ECONET",
191fe0bdbdeSYejune Deng 	[PF_ATMSVC]	= "PF_ATMSVC",
192fe0bdbdeSYejune Deng 	[PF_RDS]	= "PF_RDS",
193fe0bdbdeSYejune Deng 	[PF_SNA]	= "PF_SNA",
194fe0bdbdeSYejune Deng 	[PF_IRDA]	= "PF_IRDA",
195fe0bdbdeSYejune Deng 	[PF_PPPOX]	= "PF_PPPOX",
196fe0bdbdeSYejune Deng 	[PF_WANPIPE]	= "PF_WANPIPE",
197fe0bdbdeSYejune Deng 	[PF_LLC]	= "PF_LLC",
198fe0bdbdeSYejune Deng 	[PF_IB]		= "PF_IB",
199fe0bdbdeSYejune Deng 	[PF_MPLS]	= "PF_MPLS",
200fe0bdbdeSYejune Deng 	[PF_CAN]	= "PF_CAN",
201fe0bdbdeSYejune Deng 	[PF_TIPC]	= "PF_TIPC",
202fe0bdbdeSYejune Deng 	[PF_BLUETOOTH]	= "PF_BLUETOOTH",
203fe0bdbdeSYejune Deng 	[PF_IUCV]	= "PF_IUCV",
204fe0bdbdeSYejune Deng 	[PF_RXRPC]	= "PF_RXRPC",
205fe0bdbdeSYejune Deng 	[PF_ISDN]	= "PF_ISDN",
206fe0bdbdeSYejune Deng 	[PF_PHONET]	= "PF_PHONET",
207fe0bdbdeSYejune Deng 	[PF_IEEE802154]	= "PF_IEEE802154",
208fe0bdbdeSYejune Deng 	[PF_CAIF]	= "PF_CAIF",
209fe0bdbdeSYejune Deng 	[PF_ALG]	= "PF_ALG",
210fe0bdbdeSYejune Deng 	[PF_NFC]	= "PF_NFC",
211fe0bdbdeSYejune Deng 	[PF_VSOCK]	= "PF_VSOCK",
212fe0bdbdeSYejune Deng 	[PF_KCM]	= "PF_KCM",
213fe0bdbdeSYejune Deng 	[PF_QIPCRTR]	= "PF_QIPCRTR",
214fe0bdbdeSYejune Deng 	[PF_SMC]	= "PF_SMC",
215fe0bdbdeSYejune Deng 	[PF_XDP]	= "PF_XDP",
216bc49d816SJeremy Kerr 	[PF_MCTP]	= "PF_MCTP",
217fe0bdbdeSYejune Deng };
218fe0bdbdeSYejune Deng 
2191da177e4SLinus Torvalds /*
2201da177e4SLinus Torvalds  *	The protocol list. Each protocol is registered in here.
2211da177e4SLinus Torvalds  */
2221da177e4SLinus Torvalds 
2231da177e4SLinus Torvalds static DEFINE_SPINLOCK(net_family_lock);
224190683a9SEric Dumazet static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
2251da177e4SLinus Torvalds 
2261da177e4SLinus Torvalds /*
22789bddce5SStephen Hemminger  * Support routines.
22889bddce5SStephen Hemminger  * Move socket addresses back and forth across the kernel/user
2291da177e4SLinus Torvalds  * divide and look after the messy bits.
2301da177e4SLinus Torvalds  */
2311da177e4SLinus Torvalds 
2321da177e4SLinus Torvalds /**
2331da177e4SLinus Torvalds  *	move_addr_to_kernel	-	copy a socket address into kernel space
2341da177e4SLinus Torvalds  *	@uaddr: Address in user space
2351da177e4SLinus Torvalds  *	@kaddr: Address in kernel space
2361da177e4SLinus Torvalds  *	@ulen: Length in user space
2371da177e4SLinus Torvalds  *
2381da177e4SLinus Torvalds  *	The address is copied into kernel space. If the provided address is
2391da177e4SLinus Torvalds  *	too long an error code of -EINVAL is returned. If the copy gives
2401da177e4SLinus Torvalds  *	invalid addresses -EFAULT is returned. On a success 0 is returned.
2411da177e4SLinus Torvalds  */
2421da177e4SLinus Torvalds 
24343db362dSMaciej Żenczykowski int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr)
2441da177e4SLinus Torvalds {
245230b1839SYOSHIFUJI Hideaki 	if (ulen < 0 || ulen > sizeof(struct sockaddr_storage))
2461da177e4SLinus Torvalds 		return -EINVAL;
2471da177e4SLinus Torvalds 	if (ulen == 0)
2481da177e4SLinus Torvalds 		return 0;
2491da177e4SLinus Torvalds 	if (copy_from_user(kaddr, uaddr, ulen))
2501da177e4SLinus Torvalds 		return -EFAULT;
2513ec3b2fbSDavid Woodhouse 	return audit_sockaddr(ulen, kaddr);
2521da177e4SLinus Torvalds }
2531da177e4SLinus Torvalds 
2541da177e4SLinus Torvalds /**
2551da177e4SLinus Torvalds  *	move_addr_to_user	-	copy an address to user space
2561da177e4SLinus Torvalds  *	@kaddr: kernel space address
2571da177e4SLinus Torvalds  *	@klen: length of address in kernel
2581da177e4SLinus Torvalds  *	@uaddr: user space address
2591da177e4SLinus Torvalds  *	@ulen: pointer to user length field
2601da177e4SLinus Torvalds  *
2611da177e4SLinus Torvalds  *	The value pointed to by ulen on entry is the buffer length available.
2621da177e4SLinus Torvalds  *	This is overwritten with the buffer space used. -EINVAL is returned
2631da177e4SLinus Torvalds  *	if an overlong buffer is specified or a negative buffer size. -EFAULT
2641da177e4SLinus Torvalds  *	is returned if either the buffer or the length field are not
2651da177e4SLinus Torvalds  *	accessible.
2661da177e4SLinus Torvalds  *	After copying the data up to the limit the user specifies, the true
2671da177e4SLinus Torvalds  *	length of the data is written over the length limit the user
2681da177e4SLinus Torvalds  *	specified. Zero is returned for a success.
2691da177e4SLinus Torvalds  */
2701da177e4SLinus Torvalds 
27143db362dSMaciej Żenczykowski static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
27211165f14Sstephen hemminger 			     void __user *uaddr, int __user *ulen)
2731da177e4SLinus Torvalds {
2741da177e4SLinus Torvalds 	int err;
2751da177e4SLinus Torvalds 	int len;
2761da177e4SLinus Torvalds 
27768c6beb3SHannes Frederic Sowa 	BUG_ON(klen > sizeof(struct sockaddr_storage));
27889bddce5SStephen Hemminger 	err = get_user(len, ulen);
27989bddce5SStephen Hemminger 	if (err)
2801da177e4SLinus Torvalds 		return err;
2811da177e4SLinus Torvalds 	if (len > klen)
2821da177e4SLinus Torvalds 		len = klen;
28368c6beb3SHannes Frederic Sowa 	if (len < 0)
2841da177e4SLinus Torvalds 		return -EINVAL;
28589bddce5SStephen Hemminger 	if (len) {
286d6fe3945SSteve Grubb 		if (audit_sockaddr(klen, kaddr))
287d6fe3945SSteve Grubb 			return -ENOMEM;
2881da177e4SLinus Torvalds 		if (copy_to_user(uaddr, kaddr, len))
2891da177e4SLinus Torvalds 			return -EFAULT;
2901da177e4SLinus Torvalds 	}
2911da177e4SLinus Torvalds 	/*
2921da177e4SLinus Torvalds 	 *      "fromlen shall refer to the value before truncation.."
2931da177e4SLinus Torvalds 	 *                      1003.1g
2941da177e4SLinus Torvalds 	 */
2951da177e4SLinus Torvalds 	return __put_user(klen, ulen);
2961da177e4SLinus Torvalds }
2971da177e4SLinus Torvalds 
29808009a76SAlexey Dobriyan static struct kmem_cache *sock_inode_cachep __ro_after_init;
2991da177e4SLinus Torvalds 
3001da177e4SLinus Torvalds static struct inode *sock_alloc_inode(struct super_block *sb)
3011da177e4SLinus Torvalds {
3021da177e4SLinus Torvalds 	struct socket_alloc *ei;
30389bddce5SStephen Hemminger 
304fd60b288SMuchun Song 	ei = alloc_inode_sb(sb, sock_inode_cachep, GFP_KERNEL);
3051da177e4SLinus Torvalds 	if (!ei)
3061da177e4SLinus Torvalds 		return NULL;
307333f7909SAl Viro 	init_waitqueue_head(&ei->socket.wq.wait);
308333f7909SAl Viro 	ei->socket.wq.fasync_list = NULL;
309333f7909SAl Viro 	ei->socket.wq.flags = 0;
3101da177e4SLinus Torvalds 
3111da177e4SLinus Torvalds 	ei->socket.state = SS_UNCONNECTED;
3121da177e4SLinus Torvalds 	ei->socket.flags = 0;
3131da177e4SLinus Torvalds 	ei->socket.ops = NULL;
3141da177e4SLinus Torvalds 	ei->socket.sk = NULL;
3151da177e4SLinus Torvalds 	ei->socket.file = NULL;
3161da177e4SLinus Torvalds 
3171da177e4SLinus Torvalds 	return &ei->vfs_inode;
3181da177e4SLinus Torvalds }
3191da177e4SLinus Torvalds 
3206d7855c5SAl Viro static void sock_free_inode(struct inode *inode)
3211da177e4SLinus Torvalds {
32243815482SEric Dumazet 	struct socket_alloc *ei;
32343815482SEric Dumazet 
32443815482SEric Dumazet 	ei = container_of(inode, struct socket_alloc, vfs_inode);
32543815482SEric Dumazet 	kmem_cache_free(sock_inode_cachep, ei);
3261da177e4SLinus Torvalds }
3271da177e4SLinus Torvalds 
32851cc5068SAlexey Dobriyan static void init_once(void *foo)
3291da177e4SLinus Torvalds {
3301da177e4SLinus Torvalds 	struct socket_alloc *ei = (struct socket_alloc *)foo;
3311da177e4SLinus Torvalds 
3321da177e4SLinus Torvalds 	inode_init_once(&ei->vfs_inode);
3331da177e4SLinus Torvalds }
3341da177e4SLinus Torvalds 
3351e911632Syuan linyu static void init_inodecache(void)
3361da177e4SLinus Torvalds {
3371da177e4SLinus Torvalds 	sock_inode_cachep = kmem_cache_create("sock_inode_cache",
3381da177e4SLinus Torvalds 					      sizeof(struct socket_alloc),
33989bddce5SStephen Hemminger 					      0,
34089bddce5SStephen Hemminger 					      (SLAB_HWCACHE_ALIGN |
34189bddce5SStephen Hemminger 					       SLAB_RECLAIM_ACCOUNT |
3425d097056SVladimir Davydov 					       SLAB_MEM_SPREAD | SLAB_ACCOUNT),
34320c2df83SPaul Mundt 					      init_once);
3441e911632Syuan linyu 	BUG_ON(sock_inode_cachep == NULL);
3451da177e4SLinus Torvalds }
3461da177e4SLinus Torvalds 
347b87221deSAlexey Dobriyan static const struct super_operations sockfs_ops = {
3481da177e4SLinus Torvalds 	.alloc_inode	= sock_alloc_inode,
3496d7855c5SAl Viro 	.free_inode	= sock_free_inode,
3501da177e4SLinus Torvalds 	.statfs		= simple_statfs,
3511da177e4SLinus Torvalds };
3521da177e4SLinus Torvalds 
353c23fbb6bSEric Dumazet /*
354c23fbb6bSEric Dumazet  * sockfs_dname() is called from d_path().
355c23fbb6bSEric Dumazet  */
356c23fbb6bSEric Dumazet static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
357c23fbb6bSEric Dumazet {
3580f60d288SAl Viro 	return dynamic_dname(buffer, buflen, "socket:[%lu]",
359c5ef6035SDavid Howells 				d_inode(dentry)->i_ino);
360c23fbb6bSEric Dumazet }
361c23fbb6bSEric Dumazet 
3623ba13d17SAl Viro static const struct dentry_operations sockfs_dentry_operations = {
363c23fbb6bSEric Dumazet 	.d_dname  = sockfs_dname,
3641da177e4SLinus Torvalds };
3651da177e4SLinus Torvalds 
366bba0bd31SAndreas Gruenbacher static int sockfs_xattr_get(const struct xattr_handler *handler,
367bba0bd31SAndreas Gruenbacher 			    struct dentry *dentry, struct inode *inode,
368bba0bd31SAndreas Gruenbacher 			    const char *suffix, void *value, size_t size)
369bba0bd31SAndreas Gruenbacher {
370bba0bd31SAndreas Gruenbacher 	if (value) {
371bba0bd31SAndreas Gruenbacher 		if (dentry->d_name.len + 1 > size)
372bba0bd31SAndreas Gruenbacher 			return -ERANGE;
373bba0bd31SAndreas Gruenbacher 		memcpy(value, dentry->d_name.name, dentry->d_name.len + 1);
374bba0bd31SAndreas Gruenbacher 	}
375bba0bd31SAndreas Gruenbacher 	return dentry->d_name.len + 1;
376bba0bd31SAndreas Gruenbacher }
377bba0bd31SAndreas Gruenbacher 
378bba0bd31SAndreas Gruenbacher #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
379bba0bd31SAndreas Gruenbacher #define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
380bba0bd31SAndreas Gruenbacher #define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
381bba0bd31SAndreas Gruenbacher 
382bba0bd31SAndreas Gruenbacher static const struct xattr_handler sockfs_xattr_handler = {
383bba0bd31SAndreas Gruenbacher 	.name = XATTR_NAME_SOCKPROTONAME,
384bba0bd31SAndreas Gruenbacher 	.get = sockfs_xattr_get,
385bba0bd31SAndreas Gruenbacher };
386bba0bd31SAndreas Gruenbacher 
3874a590153SAndreas Gruenbacher static int sockfs_security_xattr_set(const struct xattr_handler *handler,
388e65ce2a5SChristian Brauner 				     struct user_namespace *mnt_userns,
3894a590153SAndreas Gruenbacher 				     struct dentry *dentry, struct inode *inode,
3904a590153SAndreas Gruenbacher 				     const char *suffix, const void *value,
3914a590153SAndreas Gruenbacher 				     size_t size, int flags)
3924a590153SAndreas Gruenbacher {
3934a590153SAndreas Gruenbacher 	/* Handled by LSM. */
3944a590153SAndreas Gruenbacher 	return -EAGAIN;
3954a590153SAndreas Gruenbacher }
3964a590153SAndreas Gruenbacher 
3974a590153SAndreas Gruenbacher static const struct xattr_handler sockfs_security_xattr_handler = {
3984a590153SAndreas Gruenbacher 	.prefix = XATTR_SECURITY_PREFIX,
3994a590153SAndreas Gruenbacher 	.set = sockfs_security_xattr_set,
4004a590153SAndreas Gruenbacher };
4014a590153SAndreas Gruenbacher 
402bba0bd31SAndreas Gruenbacher static const struct xattr_handler *sockfs_xattr_handlers[] = {
403bba0bd31SAndreas Gruenbacher 	&sockfs_xattr_handler,
4044a590153SAndreas Gruenbacher 	&sockfs_security_xattr_handler,
405bba0bd31SAndreas Gruenbacher 	NULL
406bba0bd31SAndreas Gruenbacher };
407bba0bd31SAndreas Gruenbacher 
408fba9be49SDavid Howells static int sockfs_init_fs_context(struct fs_context *fc)
409c74a1cbbSAl Viro {
410fba9be49SDavid Howells 	struct pseudo_fs_context *ctx = init_pseudo(fc, SOCKFS_MAGIC);
411fba9be49SDavid Howells 	if (!ctx)
412fba9be49SDavid Howells 		return -ENOMEM;
413fba9be49SDavid Howells 	ctx->ops = &sockfs_ops;
414fba9be49SDavid Howells 	ctx->dops = &sockfs_dentry_operations;
415fba9be49SDavid Howells 	ctx->xattr = sockfs_xattr_handlers;
416fba9be49SDavid Howells 	return 0;
417c74a1cbbSAl Viro }
418c74a1cbbSAl Viro 
419c74a1cbbSAl Viro static struct vfsmount *sock_mnt __read_mostly;
420c74a1cbbSAl Viro 
421c74a1cbbSAl Viro static struct file_system_type sock_fs_type = {
422c74a1cbbSAl Viro 	.name =		"sockfs",
423fba9be49SDavid Howells 	.init_fs_context = sockfs_init_fs_context,
424c74a1cbbSAl Viro 	.kill_sb =	kill_anon_super,
425c74a1cbbSAl Viro };
426c74a1cbbSAl Viro 
4271da177e4SLinus Torvalds /*
4281da177e4SLinus Torvalds  *	Obtains the first available file descriptor and sets it up for use.
4291da177e4SLinus Torvalds  *
43039d8c1b6SDavid S. Miller  *	These functions create file structures and maps them to fd space
43139d8c1b6SDavid S. Miller  *	of the current process. On success it returns file descriptor
4321da177e4SLinus Torvalds  *	and file struct implicitly stored in sock->file.
4331da177e4SLinus Torvalds  *	Note that another thread may close file descriptor before we return
4341da177e4SLinus Torvalds  *	from this function. We use the fact that now we do not refer
4351da177e4SLinus Torvalds  *	to socket after mapping. If one day we will need it, this
4361da177e4SLinus Torvalds  *	function will increment ref. count on file by 1.
4371da177e4SLinus Torvalds  *
4381da177e4SLinus Torvalds  *	In any case returned fd MAY BE not valid!
4391da177e4SLinus Torvalds  *	This race condition is unavoidable
4401da177e4SLinus Torvalds  *	with shared fd spaces, we cannot solve it inside kernel,
4411da177e4SLinus Torvalds  *	but we take care of internal coherence yet.
4421da177e4SLinus Torvalds  */
4431da177e4SLinus Torvalds 
4448a3c245cSPedro Tammela /**
4458a3c245cSPedro Tammela  *	sock_alloc_file - Bind a &socket to a &file
4468a3c245cSPedro Tammela  *	@sock: socket
4478a3c245cSPedro Tammela  *	@flags: file status flags
4488a3c245cSPedro Tammela  *	@dname: protocol name
4498a3c245cSPedro Tammela  *
4508a3c245cSPedro Tammela  *	Returns the &file bound with @sock, implicitly storing it
4518a3c245cSPedro Tammela  *	in sock->file. If dname is %NULL, sets to "".
4528a3c245cSPedro Tammela  *	On failure the return is a ERR pointer (see linux/err.h).
4538a3c245cSPedro Tammela  *	This function uses GFP_KERNEL internally.
4548a3c245cSPedro Tammela  */
4558a3c245cSPedro Tammela 
456aab174f0SLinus Torvalds struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)
4571da177e4SLinus Torvalds {
4587cbe66b6SAl Viro 	struct file *file;
4591da177e4SLinus Torvalds 
460d93aa9d8SAl Viro 	if (!dname)
461d93aa9d8SAl Viro 		dname = sock->sk ? sock->sk->sk_prot_creator->name : "";
46239d8c1b6SDavid S. Miller 
463d93aa9d8SAl Viro 	file = alloc_file_pseudo(SOCK_INODE(sock), sock_mnt, dname,
464d93aa9d8SAl Viro 				O_RDWR | (flags & O_NONBLOCK),
465cc3808f8SAl Viro 				&socket_file_ops);
466b5ffe634SViresh Kumar 	if (IS_ERR(file)) {
4678e1611e2SAl Viro 		sock_release(sock);
46839b65252SAnatol Pomozov 		return file;
469cc3808f8SAl Viro 	}
4701da177e4SLinus Torvalds 
4711da177e4SLinus Torvalds 	sock->file = file;
47207dc3f07SBenjamin LaHaise 	file->private_data = sock;
473d8e464ecSLinus Torvalds 	stream_open(SOCK_INODE(sock), file);
47428407630SAl Viro 	return file;
4751da177e4SLinus Torvalds }
47656b31d1cSAl Viro EXPORT_SYMBOL(sock_alloc_file);
4771da177e4SLinus Torvalds 
47856b31d1cSAl Viro static int sock_map_fd(struct socket *sock, int flags)
47939d8c1b6SDavid S. Miller {
48039d8c1b6SDavid S. Miller 	struct file *newfile;
48128407630SAl Viro 	int fd = get_unused_fd_flags(flags);
482ce4bb04cSAl Viro 	if (unlikely(fd < 0)) {
483ce4bb04cSAl Viro 		sock_release(sock);
4841da177e4SLinus Torvalds 		return fd;
485ce4bb04cSAl Viro 	}
4861da177e4SLinus Torvalds 
487aab174f0SLinus Torvalds 	newfile = sock_alloc_file(sock, flags, NULL);
4884546e44cSEnrico Weigelt 	if (!IS_ERR(newfile)) {
4891da177e4SLinus Torvalds 		fd_install(fd, newfile);
4901da177e4SLinus Torvalds 		return fd;
4911da177e4SLinus Torvalds 	}
49228407630SAl Viro 
49328407630SAl Viro 	put_unused_fd(fd);
49428407630SAl Viro 	return PTR_ERR(newfile);
4951da177e4SLinus Torvalds }
4961da177e4SLinus Torvalds 
4978a3c245cSPedro Tammela /**
4988a3c245cSPedro Tammela  *	sock_from_file - Return the &socket bounded to @file.
4998a3c245cSPedro Tammela  *	@file: file
5008a3c245cSPedro Tammela  *
501dba4a925SFlorent Revest  *	On failure returns %NULL.
5028a3c245cSPedro Tammela  */
5038a3c245cSPedro Tammela 
504dba4a925SFlorent Revest struct socket *sock_from_file(struct file *file)
5056cb153caSBenjamin LaHaise {
5066cb153caSBenjamin LaHaise 	if (file->f_op == &socket_file_ops)
507da214a47SJens Axboe 		return file->private_data;	/* set in sock_alloc_file */
5086cb153caSBenjamin LaHaise 
5096cb153caSBenjamin LaHaise 	return NULL;
5106cb153caSBenjamin LaHaise }
511406a3c63SJohn Fastabend EXPORT_SYMBOL(sock_from_file);
5126cb153caSBenjamin LaHaise 
5131da177e4SLinus Torvalds /**
5141da177e4SLinus Torvalds  *	sockfd_lookup - Go from a file number to its socket slot
5151da177e4SLinus Torvalds  *	@fd: file handle
5161da177e4SLinus Torvalds  *	@err: pointer to an error code return
5171da177e4SLinus Torvalds  *
5181da177e4SLinus Torvalds  *	The file handle passed in is locked and the socket it is bound
519241c4667SRosen, Rami  *	to is returned. If an error occurs the err pointer is overwritten
5201da177e4SLinus Torvalds  *	with a negative errno code and NULL is returned. The function checks
5211da177e4SLinus Torvalds  *	for both invalid handles and passing a handle which is not a socket.
5221da177e4SLinus Torvalds  *
5231da177e4SLinus Torvalds  *	On a success the socket object pointer is returned.
5241da177e4SLinus Torvalds  */
5251da177e4SLinus Torvalds 
5261da177e4SLinus Torvalds struct socket *sockfd_lookup(int fd, int *err)
5271da177e4SLinus Torvalds {
5281da177e4SLinus Torvalds 	struct file *file;
5291da177e4SLinus Torvalds 	struct socket *sock;
5301da177e4SLinus Torvalds 
53189bddce5SStephen Hemminger 	file = fget(fd);
53289bddce5SStephen Hemminger 	if (!file) {
5331da177e4SLinus Torvalds 		*err = -EBADF;
5341da177e4SLinus Torvalds 		return NULL;
5351da177e4SLinus Torvalds 	}
53689bddce5SStephen Hemminger 
537dba4a925SFlorent Revest 	sock = sock_from_file(file);
538dba4a925SFlorent Revest 	if (!sock) {
539dba4a925SFlorent Revest 		*err = -ENOTSOCK;
5401da177e4SLinus Torvalds 		fput(file);
541dba4a925SFlorent Revest 	}
5426cb153caSBenjamin LaHaise 	return sock;
5431da177e4SLinus Torvalds }
544c6d409cfSEric Dumazet EXPORT_SYMBOL(sockfd_lookup);
5451da177e4SLinus Torvalds 
5466cb153caSBenjamin LaHaise static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
5476cb153caSBenjamin LaHaise {
54800e188efSAl Viro 	struct fd f = fdget(fd);
5496cb153caSBenjamin LaHaise 	struct socket *sock;
5506cb153caSBenjamin LaHaise 
5513672558cSHua Zhong 	*err = -EBADF;
55200e188efSAl Viro 	if (f.file) {
553dba4a925SFlorent Revest 		sock = sock_from_file(f.file);
55400e188efSAl Viro 		if (likely(sock)) {
555ce787a5aSMiaohe Lin 			*fput_needed = f.flags & FDPUT_FPUT;
5561da177e4SLinus Torvalds 			return sock;
55700e188efSAl Viro 		}
558dba4a925SFlorent Revest 		*err = -ENOTSOCK;
55900e188efSAl Viro 		fdput(f);
5606cb153caSBenjamin LaHaise 	}
5616cb153caSBenjamin LaHaise 	return NULL;
5621da177e4SLinus Torvalds }
5631da177e4SLinus Torvalds 
564600e1779SMasatake YAMATO static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
565600e1779SMasatake YAMATO 				size_t size)
566600e1779SMasatake YAMATO {
567600e1779SMasatake YAMATO 	ssize_t len;
568600e1779SMasatake YAMATO 	ssize_t used = 0;
569600e1779SMasatake YAMATO 
570c5ef6035SDavid Howells 	len = security_inode_listsecurity(d_inode(dentry), buffer, size);
571600e1779SMasatake YAMATO 	if (len < 0)
572600e1779SMasatake YAMATO 		return len;
573600e1779SMasatake YAMATO 	used += len;
574600e1779SMasatake YAMATO 	if (buffer) {
575600e1779SMasatake YAMATO 		if (size < used)
576600e1779SMasatake YAMATO 			return -ERANGE;
577600e1779SMasatake YAMATO 		buffer += len;
578600e1779SMasatake YAMATO 	}
579600e1779SMasatake YAMATO 
580600e1779SMasatake YAMATO 	len = (XATTR_NAME_SOCKPROTONAME_LEN + 1);
581600e1779SMasatake YAMATO 	used += len;
582600e1779SMasatake YAMATO 	if (buffer) {
583600e1779SMasatake YAMATO 		if (size < used)
584600e1779SMasatake YAMATO 			return -ERANGE;
585600e1779SMasatake YAMATO 		memcpy(buffer, XATTR_NAME_SOCKPROTONAME, len);
586600e1779SMasatake YAMATO 		buffer += len;
587600e1779SMasatake YAMATO 	}
588600e1779SMasatake YAMATO 
589600e1779SMasatake YAMATO 	return used;
590600e1779SMasatake YAMATO }
591600e1779SMasatake YAMATO 
592549c7297SChristian Brauner static int sockfs_setattr(struct user_namespace *mnt_userns,
593549c7297SChristian Brauner 			  struct dentry *dentry, struct iattr *iattr)
59486741ec2SLorenzo Colitti {
595549c7297SChristian Brauner 	int err = simple_setattr(&init_user_ns, dentry, iattr);
59686741ec2SLorenzo Colitti 
597e1a3a60aSEric Biggers 	if (!err && (iattr->ia_valid & ATTR_UID)) {
59886741ec2SLorenzo Colitti 		struct socket *sock = SOCKET_I(d_inode(dentry));
59986741ec2SLorenzo Colitti 
6006d8c50dcSCong Wang 		if (sock->sk)
60186741ec2SLorenzo Colitti 			sock->sk->sk_uid = iattr->ia_uid;
6026d8c50dcSCong Wang 		else
6036d8c50dcSCong Wang 			err = -ENOENT;
60486741ec2SLorenzo Colitti 	}
60586741ec2SLorenzo Colitti 
60686741ec2SLorenzo Colitti 	return err;
60786741ec2SLorenzo Colitti }
60886741ec2SLorenzo Colitti 
609600e1779SMasatake YAMATO static const struct inode_operations sockfs_inode_ops = {
610600e1779SMasatake YAMATO 	.listxattr = sockfs_listxattr,
61186741ec2SLorenzo Colitti 	.setattr = sockfs_setattr,
612600e1779SMasatake YAMATO };
613600e1779SMasatake YAMATO 
6141da177e4SLinus Torvalds /**
6151da177e4SLinus Torvalds  *	sock_alloc - allocate a socket
6161da177e4SLinus Torvalds  *
6171da177e4SLinus Torvalds  *	Allocate a new inode and socket object. The two are bound together
6181da177e4SLinus Torvalds  *	and initialised. The socket is then returned. If we are out of inodes
6198a3c245cSPedro Tammela  *	NULL is returned. This functions uses GFP_KERNEL internally.
6201da177e4SLinus Torvalds  */
6211da177e4SLinus Torvalds 
622f4a00aacSTom Herbert struct socket *sock_alloc(void)
6231da177e4SLinus Torvalds {
6241da177e4SLinus Torvalds 	struct inode *inode;
6251da177e4SLinus Torvalds 	struct socket *sock;
6261da177e4SLinus Torvalds 
627a209dfc7SEric Dumazet 	inode = new_inode_pseudo(sock_mnt->mnt_sb);
6281da177e4SLinus Torvalds 	if (!inode)
6291da177e4SLinus Torvalds 		return NULL;
6301da177e4SLinus Torvalds 
6311da177e4SLinus Torvalds 	sock = SOCKET_I(inode);
6321da177e4SLinus Torvalds 
63385fe4025SChristoph Hellwig 	inode->i_ino = get_next_ino();
6341da177e4SLinus Torvalds 	inode->i_mode = S_IFSOCK | S_IRWXUGO;
6358192b0c4SDavid Howells 	inode->i_uid = current_fsuid();
6368192b0c4SDavid Howells 	inode->i_gid = current_fsgid();
637600e1779SMasatake YAMATO 	inode->i_op = &sockfs_inode_ops;
6381da177e4SLinus Torvalds 
6391da177e4SLinus Torvalds 	return sock;
6401da177e4SLinus Torvalds }
641f4a00aacSTom Herbert EXPORT_SYMBOL(sock_alloc);
6421da177e4SLinus Torvalds 
6436d8c50dcSCong Wang static void __sock_release(struct socket *sock, struct inode *inode)
6441da177e4SLinus Torvalds {
6451da177e4SLinus Torvalds 	if (sock->ops) {
6461da177e4SLinus Torvalds 		struct module *owner = sock->ops->owner;
6471da177e4SLinus Torvalds 
6486d8c50dcSCong Wang 		if (inode)
6496d8c50dcSCong Wang 			inode_lock(inode);
6501da177e4SLinus Torvalds 		sock->ops->release(sock);
651ff7b11aaSEric Biggers 		sock->sk = NULL;
6526d8c50dcSCong Wang 		if (inode)
6536d8c50dcSCong Wang 			inode_unlock(inode);
6541da177e4SLinus Torvalds 		sock->ops = NULL;
6551da177e4SLinus Torvalds 		module_put(owner);
6561da177e4SLinus Torvalds 	}
6571da177e4SLinus Torvalds 
658333f7909SAl Viro 	if (sock->wq.fasync_list)
6593410f22eSYang Yingliang 		pr_err("%s: fasync list not empty!\n", __func__);
6601da177e4SLinus Torvalds 
6611da177e4SLinus Torvalds 	if (!sock->file) {
6621da177e4SLinus Torvalds 		iput(SOCK_INODE(sock));
6631da177e4SLinus Torvalds 		return;
6641da177e4SLinus Torvalds 	}
6651da177e4SLinus Torvalds 	sock->file = NULL;
6661da177e4SLinus Torvalds }
6676d8c50dcSCong Wang 
6689a8ad9acSAndrew Lunn /**
6699a8ad9acSAndrew Lunn  *	sock_release - close a socket
6709a8ad9acSAndrew Lunn  *	@sock: socket to close
6719a8ad9acSAndrew Lunn  *
6729a8ad9acSAndrew Lunn  *	The socket is released from the protocol stack if it has a release
6739a8ad9acSAndrew Lunn  *	callback, and the inode is then released if the socket is bound to
6749a8ad9acSAndrew Lunn  *	an inode not a file.
6759a8ad9acSAndrew Lunn  */
6766d8c50dcSCong Wang void sock_release(struct socket *sock)
6776d8c50dcSCong Wang {
6786d8c50dcSCong Wang 	__sock_release(sock, NULL);
6796d8c50dcSCong Wang }
680c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_release);
6811da177e4SLinus Torvalds 
682c14ac945SSoheil Hassas Yeganeh void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags)
68320d49473SPatrick Ohly {
684140c55d4SEric Dumazet 	u8 flags = *tx_flags;
685140c55d4SEric Dumazet 
68651eb7492SGerhard Engleder 	if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE) {
687140c55d4SEric Dumazet 		flags |= SKBTX_HW_TSTAMP;
688140c55d4SEric Dumazet 
68951eb7492SGerhard Engleder 		/* PTP hardware clocks can provide a free running cycle counter
69051eb7492SGerhard Engleder 		 * as a time base for virtual clocks. Tell driver to use the
69151eb7492SGerhard Engleder 		 * free running cycle counter for timestamp if socket is bound
69251eb7492SGerhard Engleder 		 * to virtual clock.
69351eb7492SGerhard Engleder 		 */
69451eb7492SGerhard Engleder 		if (tsflags & SOF_TIMESTAMPING_BIND_PHC)
69551eb7492SGerhard Engleder 			flags |= SKBTX_HW_TSTAMP_USE_CYCLES;
69651eb7492SGerhard Engleder 	}
69751eb7492SGerhard Engleder 
698c14ac945SSoheil Hassas Yeganeh 	if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE)
699140c55d4SEric Dumazet 		flags |= SKBTX_SW_TSTAMP;
700140c55d4SEric Dumazet 
701c14ac945SSoheil Hassas Yeganeh 	if (tsflags & SOF_TIMESTAMPING_TX_SCHED)
702140c55d4SEric Dumazet 		flags |= SKBTX_SCHED_TSTAMP;
703140c55d4SEric Dumazet 
704140c55d4SEric Dumazet 	*tx_flags = flags;
70520d49473SPatrick Ohly }
70667cc0d40SWillem de Bruijn EXPORT_SYMBOL(__sock_tx_timestamp);
70720d49473SPatrick Ohly 
7088c3c447bSPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet_sendmsg(struct socket *, struct msghdr *,
7098c3c447bSPaolo Abeni 					   size_t));
710a648a592SPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet6_sendmsg(struct socket *, struct msghdr *,
711a648a592SPaolo Abeni 					    size_t));
712d8725c86SAl Viro static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
7131da177e4SLinus Torvalds {
714a648a592SPaolo Abeni 	int ret = INDIRECT_CALL_INET(sock->ops->sendmsg, inet6_sendmsg,
715a648a592SPaolo Abeni 				     inet_sendmsg, sock, msg,
716a648a592SPaolo Abeni 				     msg_data_left(msg));
717d8725c86SAl Viro 	BUG_ON(ret == -EIOCBQUEUED);
718d8725c86SAl Viro 	return ret;
7191da177e4SLinus Torvalds }
7200cf00c6fSGu Zheng 
72185806af0SRandy Dunlap /**
72285806af0SRandy Dunlap  *	sock_sendmsg - send a message through @sock
72385806af0SRandy Dunlap  *	@sock: socket
72485806af0SRandy Dunlap  *	@msg: message to send
72585806af0SRandy Dunlap  *
72685806af0SRandy Dunlap  *	Sends @msg through @sock, passing through LSM.
72785806af0SRandy Dunlap  *	Returns the number of bytes sent, or an error code.
72885806af0SRandy Dunlap  */
729d8725c86SAl Viro int sock_sendmsg(struct socket *sock, struct msghdr *msg)
7300cf00c6fSGu Zheng {
731d8725c86SAl Viro 	int err = security_socket_sendmsg(sock, msg,
73201e97e65SAl Viro 					  msg_data_left(msg));
7331b784140SYing Xue 
734d8725c86SAl Viro 	return err ?: sock_sendmsg_nosec(sock, msg);
7350cf00c6fSGu Zheng }
736c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_sendmsg);
7371da177e4SLinus Torvalds 
7388a3c245cSPedro Tammela /**
7398a3c245cSPedro Tammela  *	kernel_sendmsg - send a message through @sock (kernel-space)
7408a3c245cSPedro Tammela  *	@sock: socket
7418a3c245cSPedro Tammela  *	@msg: message header
7428a3c245cSPedro Tammela  *	@vec: kernel vec
7438a3c245cSPedro Tammela  *	@num: vec array length
7448a3c245cSPedro Tammela  *	@size: total message data size
7458a3c245cSPedro Tammela  *
7468a3c245cSPedro Tammela  *	Builds the message data with @vec and sends it through @sock.
7478a3c245cSPedro Tammela  *	Returns the number of bytes sent, or an error code.
7488a3c245cSPedro Tammela  */
7498a3c245cSPedro Tammela 
7501da177e4SLinus Torvalds int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
7511da177e4SLinus Torvalds 		   struct kvec *vec, size_t num, size_t size)
7521da177e4SLinus Torvalds {
753aa563d7bSDavid Howells 	iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size);
754d8725c86SAl Viro 	return sock_sendmsg(sock, msg);
7551da177e4SLinus Torvalds }
756c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_sendmsg);
7571da177e4SLinus Torvalds 
7588a3c245cSPedro Tammela /**
7598a3c245cSPedro Tammela  *	kernel_sendmsg_locked - send a message through @sock (kernel-space)
7608a3c245cSPedro Tammela  *	@sk: sock
7618a3c245cSPedro Tammela  *	@msg: message header
7628a3c245cSPedro Tammela  *	@vec: output s/g array
7638a3c245cSPedro Tammela  *	@num: output s/g array length
7648a3c245cSPedro Tammela  *	@size: total message data size
7658a3c245cSPedro Tammela  *
7668a3c245cSPedro Tammela  *	Builds the message data with @vec and sends it through @sock.
7678a3c245cSPedro Tammela  *	Returns the number of bytes sent, or an error code.
7688a3c245cSPedro Tammela  *	Caller must hold @sk.
7698a3c245cSPedro Tammela  */
7708a3c245cSPedro Tammela 
771306b13ebSTom Herbert int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg,
772306b13ebSTom Herbert 			  struct kvec *vec, size_t num, size_t size)
773306b13ebSTom Herbert {
774306b13ebSTom Herbert 	struct socket *sock = sk->sk_socket;
775306b13ebSTom Herbert 
776306b13ebSTom Herbert 	if (!sock->ops->sendmsg_locked)
777db5980d8SJohn Fastabend 		return sock_no_sendmsg_locked(sk, msg, size);
778306b13ebSTom Herbert 
779aa563d7bSDavid Howells 	iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size);
780306b13ebSTom Herbert 
781306b13ebSTom Herbert 	return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg));
782306b13ebSTom Herbert }
783306b13ebSTom Herbert EXPORT_SYMBOL(kernel_sendmsg_locked);
784306b13ebSTom Herbert 
7858605330aSSoheil Hassas Yeganeh static bool skb_is_err_queue(const struct sk_buff *skb)
7868605330aSSoheil Hassas Yeganeh {
7878605330aSSoheil Hassas Yeganeh 	/* pkt_type of skbs enqueued on the error queue are set to
7888605330aSSoheil Hassas Yeganeh 	 * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
7898605330aSSoheil Hassas Yeganeh 	 * in recvmsg, since skbs received on a local socket will never
7908605330aSSoheil Hassas Yeganeh 	 * have a pkt_type of PACKET_OUTGOING.
7918605330aSSoheil Hassas Yeganeh 	 */
7928605330aSSoheil Hassas Yeganeh 	return skb->pkt_type == PACKET_OUTGOING;
7938605330aSSoheil Hassas Yeganeh }
7948605330aSSoheil Hassas Yeganeh 
795b50a5c70SMiroslav Lichvar /* On transmit, software and hardware timestamps are returned independently.
796b50a5c70SMiroslav Lichvar  * As the two skb clones share the hardware timestamp, which may be updated
797b50a5c70SMiroslav Lichvar  * before the software timestamp is received, a hardware TX timestamp may be
798b50a5c70SMiroslav Lichvar  * returned only if there is no software TX timestamp. Ignore false software
799b50a5c70SMiroslav Lichvar  * timestamps, which may be made in the __sock_recv_timestamp() call when the
8007f1bc6e9SDeepa Dinamani  * option SO_TIMESTAMP_OLD(NS) is enabled on the socket, even when the skb has a
801b50a5c70SMiroslav Lichvar  * hardware timestamp.
802b50a5c70SMiroslav Lichvar  */
803b50a5c70SMiroslav Lichvar static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp)
804b50a5c70SMiroslav Lichvar {
805b50a5c70SMiroslav Lichvar 	return skb->tstamp && !false_tstamp && skb_is_err_queue(skb);
806b50a5c70SMiroslav Lichvar }
807b50a5c70SMiroslav Lichvar 
80897dc7cd9SGerhard Engleder static ktime_t get_timestamp(struct sock *sk, struct sk_buff *skb, int *if_index)
80997dc7cd9SGerhard Engleder {
81097dc7cd9SGerhard Engleder 	bool cycles = sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC;
81197dc7cd9SGerhard Engleder 	struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
81297dc7cd9SGerhard Engleder 	struct net_device *orig_dev;
81397dc7cd9SGerhard Engleder 	ktime_t hwtstamp;
81497dc7cd9SGerhard Engleder 
81597dc7cd9SGerhard Engleder 	rcu_read_lock();
81697dc7cd9SGerhard Engleder 	orig_dev = dev_get_by_napi_id(skb_napi_id(skb));
81797dc7cd9SGerhard Engleder 	if (orig_dev) {
81897dc7cd9SGerhard Engleder 		*if_index = orig_dev->ifindex;
81997dc7cd9SGerhard Engleder 		hwtstamp = netdev_get_tstamp(orig_dev, shhwtstamps, cycles);
82097dc7cd9SGerhard Engleder 	} else {
82197dc7cd9SGerhard Engleder 		hwtstamp = shhwtstamps->hwtstamp;
82297dc7cd9SGerhard Engleder 	}
82397dc7cd9SGerhard Engleder 	rcu_read_unlock();
82497dc7cd9SGerhard Engleder 
82597dc7cd9SGerhard Engleder 	return hwtstamp;
82697dc7cd9SGerhard Engleder }
82797dc7cd9SGerhard Engleder 
82897dc7cd9SGerhard Engleder static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb,
82997dc7cd9SGerhard Engleder 			   int if_index)
830aad9c8c4SMiroslav Lichvar {
831aad9c8c4SMiroslav Lichvar 	struct scm_ts_pktinfo ts_pktinfo;
832aad9c8c4SMiroslav Lichvar 	struct net_device *orig_dev;
833aad9c8c4SMiroslav Lichvar 
834aad9c8c4SMiroslav Lichvar 	if (!skb_mac_header_was_set(skb))
835aad9c8c4SMiroslav Lichvar 		return;
836aad9c8c4SMiroslav Lichvar 
837aad9c8c4SMiroslav Lichvar 	memset(&ts_pktinfo, 0, sizeof(ts_pktinfo));
838aad9c8c4SMiroslav Lichvar 
83997dc7cd9SGerhard Engleder 	if (!if_index) {
840aad9c8c4SMiroslav Lichvar 		rcu_read_lock();
841aad9c8c4SMiroslav Lichvar 		orig_dev = dev_get_by_napi_id(skb_napi_id(skb));
842aad9c8c4SMiroslav Lichvar 		if (orig_dev)
84397dc7cd9SGerhard Engleder 			if_index = orig_dev->ifindex;
844aad9c8c4SMiroslav Lichvar 		rcu_read_unlock();
84597dc7cd9SGerhard Engleder 	}
84697dc7cd9SGerhard Engleder 	ts_pktinfo.if_index = if_index;
847aad9c8c4SMiroslav Lichvar 
848aad9c8c4SMiroslav Lichvar 	ts_pktinfo.pkt_length = skb->len - skb_mac_offset(skb);
849aad9c8c4SMiroslav Lichvar 	put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO,
850aad9c8c4SMiroslav Lichvar 		 sizeof(ts_pktinfo), &ts_pktinfo);
851aad9c8c4SMiroslav Lichvar }
852aad9c8c4SMiroslav Lichvar 
85392f37fd2SEric Dumazet /*
85492f37fd2SEric Dumazet  * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
85592f37fd2SEric Dumazet  */
85692f37fd2SEric Dumazet void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
85792f37fd2SEric Dumazet 	struct sk_buff *skb)
85892f37fd2SEric Dumazet {
85920d49473SPatrick Ohly 	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
860887feae3SDeepa Dinamani 	int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
8619718475eSDeepa Dinamani 	struct scm_timestamping_internal tss;
8629718475eSDeepa Dinamani 
863b50a5c70SMiroslav Lichvar 	int empty = 1, false_tstamp = 0;
86420d49473SPatrick Ohly 	struct skb_shared_hwtstamps *shhwtstamps =
86520d49473SPatrick Ohly 		skb_hwtstamps(skb);
86697dc7cd9SGerhard Engleder 	int if_index;
867007747a9SMiroslav Lichvar 	ktime_t hwtstamp;
86892f37fd2SEric Dumazet 
86920d49473SPatrick Ohly 	/* Race occurred between timestamp enabling and packet
87020d49473SPatrick Ohly 	   receiving.  Fill in the current time for now. */
871b50a5c70SMiroslav Lichvar 	if (need_software_tstamp && skb->tstamp == 0) {
87220d49473SPatrick Ohly 		__net_timestamp(skb);
873b50a5c70SMiroslav Lichvar 		false_tstamp = 1;
874b50a5c70SMiroslav Lichvar 	}
87520d49473SPatrick Ohly 
87620d49473SPatrick Ohly 	if (need_software_tstamp) {
87792f37fd2SEric Dumazet 		if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
878887feae3SDeepa Dinamani 			if (new_tstamp) {
879887feae3SDeepa Dinamani 				struct __kernel_sock_timeval tv;
880887feae3SDeepa Dinamani 
881887feae3SDeepa Dinamani 				skb_get_new_timestamp(skb, &tv);
882887feae3SDeepa Dinamani 				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
883887feae3SDeepa Dinamani 					 sizeof(tv), &tv);
884887feae3SDeepa Dinamani 			} else {
88513c6ee2aSDeepa Dinamani 				struct __kernel_old_timeval tv;
886887feae3SDeepa Dinamani 
88720d49473SPatrick Ohly 				skb_get_timestamp(skb, &tv);
8887f1bc6e9SDeepa Dinamani 				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
88920d49473SPatrick Ohly 					 sizeof(tv), &tv);
890887feae3SDeepa Dinamani 			}
891887feae3SDeepa Dinamani 		} else {
892887feae3SDeepa Dinamani 			if (new_tstamp) {
893887feae3SDeepa Dinamani 				struct __kernel_timespec ts;
894887feae3SDeepa Dinamani 
895887feae3SDeepa Dinamani 				skb_get_new_timestampns(skb, &ts);
896887feae3SDeepa Dinamani 				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
897887feae3SDeepa Dinamani 					 sizeof(ts), &ts);
89892f37fd2SEric Dumazet 			} else {
899df1b4ba9SArnd Bergmann 				struct __kernel_old_timespec ts;
900887feae3SDeepa Dinamani 
901f24b9be5SWillem de Bruijn 				skb_get_timestampns(skb, &ts);
9027f1bc6e9SDeepa Dinamani 				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
903f24b9be5SWillem de Bruijn 					 sizeof(ts), &ts);
90492f37fd2SEric Dumazet 			}
90592f37fd2SEric Dumazet 		}
906887feae3SDeepa Dinamani 	}
90792f37fd2SEric Dumazet 
908f24b9be5SWillem de Bruijn 	memset(&tss, 0, sizeof(tss));
909c199105dSWillem de Bruijn 	if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
9109718475eSDeepa Dinamani 	    ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
91120d49473SPatrick Ohly 		empty = 0;
9124d276eb6SWillem de Bruijn 	if (shhwtstamps &&
913b9f40e21SWillem de Bruijn 	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
914d7c08826SYangbo Lu 	    !skb_is_swtx_tstamp(skb, false_tstamp)) {
91597dc7cd9SGerhard Engleder 		if_index = 0;
91697dc7cd9SGerhard Engleder 		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV)
91797dc7cd9SGerhard Engleder 			hwtstamp = get_timestamp(sk, skb, &if_index);
918007747a9SMiroslav Lichvar 		else
919007747a9SMiroslav Lichvar 			hwtstamp = shhwtstamps->hwtstamp;
920d7c08826SYangbo Lu 
92197dc7cd9SGerhard Engleder 		if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC)
92297dc7cd9SGerhard Engleder 			hwtstamp = ptp_convert_timestamp(&hwtstamp,
92397dc7cd9SGerhard Engleder 							 sk->sk_bind_phc);
92497dc7cd9SGerhard Engleder 
925007747a9SMiroslav Lichvar 		if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) {
92620d49473SPatrick Ohly 			empty = 0;
927d7c08826SYangbo Lu 
928aad9c8c4SMiroslav Lichvar 			if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
929aad9c8c4SMiroslav Lichvar 			    !skb_is_err_queue(skb))
93097dc7cd9SGerhard Engleder 				put_ts_pktinfo(msg, skb, if_index);
931aad9c8c4SMiroslav Lichvar 		}
932d7c08826SYangbo Lu 	}
9331c885808SFrancis Yan 	if (!empty) {
9349718475eSDeepa Dinamani 		if (sock_flag(sk, SOCK_TSTAMP_NEW))
9359718475eSDeepa Dinamani 			put_cmsg_scm_timestamping64(msg, &tss);
9369718475eSDeepa Dinamani 		else
9379718475eSDeepa Dinamani 			put_cmsg_scm_timestamping(msg, &tss);
9381c885808SFrancis Yan 
9398605330aSSoheil Hassas Yeganeh 		if (skb_is_err_queue(skb) && skb->len &&
9404ef1b286SSoheil Hassas Yeganeh 		    SKB_EXT_ERR(skb)->opt_stats)
9411c885808SFrancis Yan 			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS,
9421c885808SFrancis Yan 				 skb->len, skb->data);
9431c885808SFrancis Yan 	}
94420d49473SPatrick Ohly }
9457c81fd8bSArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
9467c81fd8bSArnaldo Carvalho de Melo 
9476e3e939fSJohannes Berg void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
9486e3e939fSJohannes Berg 	struct sk_buff *skb)
9496e3e939fSJohannes Berg {
9506e3e939fSJohannes Berg 	int ack;
9516e3e939fSJohannes Berg 
9526e3e939fSJohannes Berg 	if (!sock_flag(sk, SOCK_WIFI_STATUS))
9536e3e939fSJohannes Berg 		return;
9546e3e939fSJohannes Berg 	if (!skb->wifi_acked_valid)
9556e3e939fSJohannes Berg 		return;
9566e3e939fSJohannes Berg 
9576e3e939fSJohannes Berg 	ack = skb->wifi_acked;
9586e3e939fSJohannes Berg 
9596e3e939fSJohannes Berg 	put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack);
9606e3e939fSJohannes Berg }
9616e3e939fSJohannes Berg EXPORT_SYMBOL_GPL(__sock_recv_wifi_status);
9626e3e939fSJohannes Berg 
96311165f14Sstephen hemminger static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
96411165f14Sstephen hemminger 				   struct sk_buff *skb)
9653b885787SNeil Horman {
966744d5a3eSEyal Birger 	if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount)
9673b885787SNeil Horman 		put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
968744d5a3eSEyal Birger 			sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
9693b885787SNeil Horman }
9703b885787SNeil Horman 
9716fd1d51cSErin MacNeil static void sock_recv_mark(struct msghdr *msg, struct sock *sk,
9726fd1d51cSErin MacNeil 			   struct sk_buff *skb)
9736fd1d51cSErin MacNeil {
9746fd1d51cSErin MacNeil 	if (sock_flag(sk, SOCK_RCVMARK) && skb)
9756fd1d51cSErin MacNeil 		put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32),
9766fd1d51cSErin MacNeil 			 &skb->mark);
9776fd1d51cSErin MacNeil }
9786fd1d51cSErin MacNeil 
9796fd1d51cSErin MacNeil void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
9803b885787SNeil Horman 		       struct sk_buff *skb)
9813b885787SNeil Horman {
9823b885787SNeil Horman 	sock_recv_timestamp(msg, sk, skb);
9833b885787SNeil Horman 	sock_recv_drops(msg, sk, skb);
9846fd1d51cSErin MacNeil 	sock_recv_mark(msg, sk, skb);
9853b885787SNeil Horman }
9866fd1d51cSErin MacNeil EXPORT_SYMBOL_GPL(__sock_recv_cmsgs);
9873b885787SNeil Horman 
9888c3c447bSPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *,
9898c3c447bSPaolo Abeni 					   size_t, int));
990a648a592SPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet6_recvmsg(struct socket *, struct msghdr *,
991a648a592SPaolo Abeni 					    size_t, int));
9921b784140SYing Xue static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
9931b784140SYing Xue 				     int flags)
994a2e27255SArnaldo Carvalho de Melo {
995a648a592SPaolo Abeni 	return INDIRECT_CALL_INET(sock->ops->recvmsg, inet6_recvmsg,
996a648a592SPaolo Abeni 				  inet_recvmsg, sock, msg, msg_data_left(msg),
997a648a592SPaolo Abeni 				  flags);
9982da62906SAl Viro }
999a2e27255SArnaldo Carvalho de Melo 
100085806af0SRandy Dunlap /**
100185806af0SRandy Dunlap  *	sock_recvmsg - receive a message from @sock
100285806af0SRandy Dunlap  *	@sock: socket
100385806af0SRandy Dunlap  *	@msg: message to receive
100485806af0SRandy Dunlap  *	@flags: message flags
100585806af0SRandy Dunlap  *
100685806af0SRandy Dunlap  *	Receives @msg from @sock, passing through LSM. Returns the total number
100785806af0SRandy Dunlap  *	of bytes received, or an error.
100885806af0SRandy Dunlap  */
10092da62906SAl Viro int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags)
10102da62906SAl Viro {
10112da62906SAl Viro 	int err = security_socket_recvmsg(sock, msg, msg_data_left(msg), flags);
10122da62906SAl Viro 
10132da62906SAl Viro 	return err ?: sock_recvmsg_nosec(sock, msg, flags);
10141da177e4SLinus Torvalds }
1015c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_recvmsg);
10161da177e4SLinus Torvalds 
1017c1249c0aSMartin Lucina /**
1018c1249c0aSMartin Lucina  *	kernel_recvmsg - Receive a message from a socket (kernel space)
1019c1249c0aSMartin Lucina  *	@sock: The socket to receive the message from
1020c1249c0aSMartin Lucina  *	@msg: Received message
1021c1249c0aSMartin Lucina  *	@vec: Input s/g array for message data
1022c1249c0aSMartin Lucina  *	@num: Size of input s/g array
1023c1249c0aSMartin Lucina  *	@size: Number of bytes to read
1024c1249c0aSMartin Lucina  *	@flags: Message flags (MSG_DONTWAIT, etc...)
1025c1249c0aSMartin Lucina  *
1026c1249c0aSMartin Lucina  *	On return the msg structure contains the scatter/gather array passed in the
1027c1249c0aSMartin Lucina  *	vec argument. The array is modified so that it consists of the unfilled
1028c1249c0aSMartin Lucina  *	portion of the original array.
1029c1249c0aSMartin Lucina  *
1030c1249c0aSMartin Lucina  *	The returned value is the total number of bytes received, or an error.
1031c1249c0aSMartin Lucina  */
10328a3c245cSPedro Tammela 
10331da177e4SLinus Torvalds int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
103489bddce5SStephen Hemminger 		   struct kvec *vec, size_t num, size_t size, int flags)
10351da177e4SLinus Torvalds {
10361f466e1fSChristoph Hellwig 	msg->msg_control_is_user = false;
1037aa563d7bSDavid Howells 	iov_iter_kvec(&msg->msg_iter, READ, vec, num, size);
10381f466e1fSChristoph Hellwig 	return sock_recvmsg(sock, msg, flags);
10391da177e4SLinus Torvalds }
1040c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_recvmsg);
10411da177e4SLinus Torvalds 
104220380731SArnaldo Carvalho de Melo static ssize_t sock_sendpage(struct file *file, struct page *page,
10431da177e4SLinus Torvalds 			     int offset, size_t size, loff_t *ppos, int more)
10441da177e4SLinus Torvalds {
10451da177e4SLinus Torvalds 	struct socket *sock;
10461da177e4SLinus Torvalds 	int flags;
10471da177e4SLinus Torvalds 
1048b69aee04SEric Dumazet 	sock = file->private_data;
10491da177e4SLinus Torvalds 
105035f9c09fSEric Dumazet 	flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
105135f9c09fSEric Dumazet 	/* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */
105235f9c09fSEric Dumazet 	flags |= more;
10531da177e4SLinus Torvalds 
1054e6949583SLinus Torvalds 	return kernel_sendpage(sock, page, offset, size, flags);
10551da177e4SLinus Torvalds }
10561da177e4SLinus Torvalds 
10579c55e01cSJens Axboe static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
10589c55e01cSJens Axboe 				struct pipe_inode_info *pipe, size_t len,
10599c55e01cSJens Axboe 				unsigned int flags)
10609c55e01cSJens Axboe {
10619c55e01cSJens Axboe 	struct socket *sock = file->private_data;
10629c55e01cSJens Axboe 
1063997b37daSRémi Denis-Courmont 	if (unlikely(!sock->ops->splice_read))
106495506588SSlavomir Kaslev 		return generic_file_splice_read(file, ppos, pipe, len, flags);
1065997b37daSRémi Denis-Courmont 
10669c55e01cSJens Axboe 	return sock->ops->splice_read(sock, ppos, pipe, len, flags);
10679c55e01cSJens Axboe }
10689c55e01cSJens Axboe 
10698ae5e030SAl Viro static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
1070ce1d4d3eSChristoph Hellwig {
10716d652330SAl Viro 	struct file *file = iocb->ki_filp;
10726d652330SAl Viro 	struct socket *sock = file->private_data;
10730345f931Stadeusz.struk@intel.com 	struct msghdr msg = {.msg_iter = *to,
10740345f931Stadeusz.struk@intel.com 			     .msg_iocb = iocb};
10758ae5e030SAl Viro 	ssize_t res;
1076ce1d4d3eSChristoph Hellwig 
1077ebfcd895SJens Axboe 	if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT))
10788ae5e030SAl Viro 		msg.msg_flags = MSG_DONTWAIT;
10798ae5e030SAl Viro 
10808ae5e030SAl Viro 	if (iocb->ki_pos != 0)
1081ce1d4d3eSChristoph Hellwig 		return -ESPIPE;
1082027445c3SBadari Pulavarty 
108366ee59afSChristoph Hellwig 	if (!iov_iter_count(to))	/* Match SYS5 behaviour */
1084ce1d4d3eSChristoph Hellwig 		return 0;
1085ce1d4d3eSChristoph Hellwig 
10862da62906SAl Viro 	res = sock_recvmsg(sock, &msg, msg.msg_flags);
10878ae5e030SAl Viro 	*to = msg.msg_iter;
10888ae5e030SAl Viro 	return res;
1089ce1d4d3eSChristoph Hellwig }
1090ce1d4d3eSChristoph Hellwig 
10918ae5e030SAl Viro static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
10921da177e4SLinus Torvalds {
10936d652330SAl Viro 	struct file *file = iocb->ki_filp;
10946d652330SAl Viro 	struct socket *sock = file->private_data;
10950345f931Stadeusz.struk@intel.com 	struct msghdr msg = {.msg_iter = *from,
10960345f931Stadeusz.struk@intel.com 			     .msg_iocb = iocb};
10978ae5e030SAl Viro 	ssize_t res;
10981da177e4SLinus Torvalds 
10998ae5e030SAl Viro 	if (iocb->ki_pos != 0)
1100ce1d4d3eSChristoph Hellwig 		return -ESPIPE;
1101027445c3SBadari Pulavarty 
1102ebfcd895SJens Axboe 	if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT))
11038ae5e030SAl Viro 		msg.msg_flags = MSG_DONTWAIT;
11048ae5e030SAl Viro 
11056d652330SAl Viro 	if (sock->type == SOCK_SEQPACKET)
11066d652330SAl Viro 		msg.msg_flags |= MSG_EOR;
11076d652330SAl Viro 
1108d8725c86SAl Viro 	res = sock_sendmsg(sock, &msg);
11098ae5e030SAl Viro 	*from = msg.msg_iter;
11108ae5e030SAl Viro 	return res;
11111da177e4SLinus Torvalds }
11121da177e4SLinus Torvalds 
11131da177e4SLinus Torvalds /*
11141da177e4SLinus Torvalds  * Atomic setting of ioctl hooks to avoid race
11151da177e4SLinus Torvalds  * with module unload.
11161da177e4SLinus Torvalds  */
11171da177e4SLinus Torvalds 
11184a3e2f71SArjan van de Ven static DEFINE_MUTEX(br_ioctl_mutex);
1119ad2f99aeSArnd Bergmann static int (*br_ioctl_hook)(struct net *net, struct net_bridge *br,
1120ad2f99aeSArnd Bergmann 			    unsigned int cmd, struct ifreq *ifr,
1121ad2f99aeSArnd Bergmann 			    void __user *uarg);
11221da177e4SLinus Torvalds 
1123ad2f99aeSArnd Bergmann void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br,
1124ad2f99aeSArnd Bergmann 			     unsigned int cmd, struct ifreq *ifr,
1125ad2f99aeSArnd Bergmann 			     void __user *uarg))
11261da177e4SLinus Torvalds {
11274a3e2f71SArjan van de Ven 	mutex_lock(&br_ioctl_mutex);
11281da177e4SLinus Torvalds 	br_ioctl_hook = hook;
11294a3e2f71SArjan van de Ven 	mutex_unlock(&br_ioctl_mutex);
11301da177e4SLinus Torvalds }
11311da177e4SLinus Torvalds EXPORT_SYMBOL(brioctl_set);
11321da177e4SLinus Torvalds 
1133ad2f99aeSArnd Bergmann int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd,
1134ad2f99aeSArnd Bergmann 		  struct ifreq *ifr, void __user *uarg)
1135ad2f99aeSArnd Bergmann {
1136ad2f99aeSArnd Bergmann 	int err = -ENOPKG;
1137ad2f99aeSArnd Bergmann 
1138ad2f99aeSArnd Bergmann 	if (!br_ioctl_hook)
1139ad2f99aeSArnd Bergmann 		request_module("bridge");
1140ad2f99aeSArnd Bergmann 
1141ad2f99aeSArnd Bergmann 	mutex_lock(&br_ioctl_mutex);
1142ad2f99aeSArnd Bergmann 	if (br_ioctl_hook)
1143ad2f99aeSArnd Bergmann 		err = br_ioctl_hook(net, br, cmd, ifr, uarg);
1144ad2f99aeSArnd Bergmann 	mutex_unlock(&br_ioctl_mutex);
1145ad2f99aeSArnd Bergmann 
1146ad2f99aeSArnd Bergmann 	return err;
1147ad2f99aeSArnd Bergmann }
1148ad2f99aeSArnd Bergmann 
11494a3e2f71SArjan van de Ven static DEFINE_MUTEX(vlan_ioctl_mutex);
1150881d966bSEric W. Biederman static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
11511da177e4SLinus Torvalds 
1152881d966bSEric W. Biederman void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
11531da177e4SLinus Torvalds {
11544a3e2f71SArjan van de Ven 	mutex_lock(&vlan_ioctl_mutex);
11551da177e4SLinus Torvalds 	vlan_ioctl_hook = hook;
11564a3e2f71SArjan van de Ven 	mutex_unlock(&vlan_ioctl_mutex);
11571da177e4SLinus Torvalds }
11581da177e4SLinus Torvalds EXPORT_SYMBOL(vlan_ioctl_set);
11591da177e4SLinus Torvalds 
11606b96018bSArnd Bergmann static long sock_do_ioctl(struct net *net, struct socket *sock,
116163ff03abSJohannes Berg 			  unsigned int cmd, unsigned long arg)
11626b96018bSArnd Bergmann {
1163876f0bf9SArnd Bergmann 	struct ifreq ifr;
1164876f0bf9SArnd Bergmann 	bool need_copyout;
11656b96018bSArnd Bergmann 	int err;
11666b96018bSArnd Bergmann 	void __user *argp = (void __user *)arg;
1167a554bf96SArnd Bergmann 	void __user *data;
11686b96018bSArnd Bergmann 
11696b96018bSArnd Bergmann 	err = sock->ops->ioctl(sock, cmd, arg);
11706b96018bSArnd Bergmann 
11716b96018bSArnd Bergmann 	/*
11726b96018bSArnd Bergmann 	 * If this ioctl is unknown try to hand it down
11736b96018bSArnd Bergmann 	 * to the NIC driver.
11746b96018bSArnd Bergmann 	 */
117536fd633eSAl Viro 	if (err != -ENOIOCTLCMD)
11766b96018bSArnd Bergmann 		return err;
11776b96018bSArnd Bergmann 
117829ce8f97SJakub Kicinski 	if (!is_socket_ioctl_cmd(cmd))
117929ce8f97SJakub Kicinski 		return -ENOTTY;
118029ce8f97SJakub Kicinski 
1181a554bf96SArnd Bergmann 	if (get_user_ifreq(&ifr, &data, argp))
118236fd633eSAl Viro 		return -EFAULT;
1183a554bf96SArnd Bergmann 	err = dev_ioctl(net, cmd, &ifr, data, &need_copyout);
118444c02a2cSAl Viro 	if (!err && need_copyout)
1185a554bf96SArnd Bergmann 		if (put_user_ifreq(&ifr, argp))
118644c02a2cSAl Viro 			return -EFAULT;
1187876f0bf9SArnd Bergmann 
11886b96018bSArnd Bergmann 	return err;
11896b96018bSArnd Bergmann }
11906b96018bSArnd Bergmann 
11911da177e4SLinus Torvalds /*
11921da177e4SLinus Torvalds  *	With an ioctl, arg may well be a user mode pointer, but we don't know
11931da177e4SLinus Torvalds  *	what to do with it - that's up to the protocol still.
11941da177e4SLinus Torvalds  */
11951da177e4SLinus Torvalds 
11961da177e4SLinus Torvalds static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
11971da177e4SLinus Torvalds {
11981da177e4SLinus Torvalds 	struct socket *sock;
1199881d966bSEric W. Biederman 	struct sock *sk;
12001da177e4SLinus Torvalds 	void __user *argp = (void __user *)arg;
12011da177e4SLinus Torvalds 	int pid, err;
1202881d966bSEric W. Biederman 	struct net *net;
12031da177e4SLinus Torvalds 
1204b69aee04SEric Dumazet 	sock = file->private_data;
1205881d966bSEric W. Biederman 	sk = sock->sk;
12063b1e0a65SYOSHIFUJI Hideaki 	net = sock_net(sk);
120744c02a2cSAl Viro 	if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) {
120844c02a2cSAl Viro 		struct ifreq ifr;
1209a554bf96SArnd Bergmann 		void __user *data;
121044c02a2cSAl Viro 		bool need_copyout;
1211a554bf96SArnd Bergmann 		if (get_user_ifreq(&ifr, &data, argp))
121244c02a2cSAl Viro 			return -EFAULT;
1213a554bf96SArnd Bergmann 		err = dev_ioctl(net, cmd, &ifr, data, &need_copyout);
121444c02a2cSAl Viro 		if (!err && need_copyout)
1215a554bf96SArnd Bergmann 			if (put_user_ifreq(&ifr, argp))
121644c02a2cSAl Viro 				return -EFAULT;
12171da177e4SLinus Torvalds 	} else
12183d23e349SJohannes Berg #ifdef CONFIG_WEXT_CORE
12191da177e4SLinus Torvalds 	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
1220b1b0c245SAl Viro 		err = wext_handle_ioctl(net, cmd, argp);
12211da177e4SLinus Torvalds 	} else
12223d23e349SJohannes Berg #endif
12231da177e4SLinus Torvalds 		switch (cmd) {
12241da177e4SLinus Torvalds 		case FIOSETOWN:
12251da177e4SLinus Torvalds 		case SIOCSPGRP:
12261da177e4SLinus Torvalds 			err = -EFAULT;
12271da177e4SLinus Torvalds 			if (get_user(pid, (int __user *)argp))
12281da177e4SLinus Torvalds 				break;
1229393cc3f5SJiri Slaby 			err = f_setown(sock->file, pid, 1);
12301da177e4SLinus Torvalds 			break;
12311da177e4SLinus Torvalds 		case FIOGETOWN:
12321da177e4SLinus Torvalds 		case SIOCGPGRP:
1233609d7fa9SEric W. Biederman 			err = put_user(f_getown(sock->file),
123489bddce5SStephen Hemminger 				       (int __user *)argp);
12351da177e4SLinus Torvalds 			break;
12361da177e4SLinus Torvalds 		case SIOCGIFBR:
12371da177e4SLinus Torvalds 		case SIOCSIFBR:
12381da177e4SLinus Torvalds 		case SIOCBRADDBR:
12391da177e4SLinus Torvalds 		case SIOCBRDELBR:
1240ad2f99aeSArnd Bergmann 			err = br_ioctl_call(net, NULL, cmd, NULL, argp);
12411da177e4SLinus Torvalds 			break;
12421da177e4SLinus Torvalds 		case SIOCGIFVLAN:
12431da177e4SLinus Torvalds 		case SIOCSIFVLAN:
12441da177e4SLinus Torvalds 			err = -ENOPKG;
12451da177e4SLinus Torvalds 			if (!vlan_ioctl_hook)
12461da177e4SLinus Torvalds 				request_module("8021q");
12471da177e4SLinus Torvalds 
12484a3e2f71SArjan van de Ven 			mutex_lock(&vlan_ioctl_mutex);
12491da177e4SLinus Torvalds 			if (vlan_ioctl_hook)
1250881d966bSEric W. Biederman 				err = vlan_ioctl_hook(net, argp);
12514a3e2f71SArjan van de Ven 			mutex_unlock(&vlan_ioctl_mutex);
12521da177e4SLinus Torvalds 			break;
1253c62cce2cSAndrey Vagin 		case SIOCGSKNS:
1254c62cce2cSAndrey Vagin 			err = -EPERM;
1255c62cce2cSAndrey Vagin 			if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1256c62cce2cSAndrey Vagin 				break;
1257c62cce2cSAndrey Vagin 
1258c62cce2cSAndrey Vagin 			err = open_related_ns(&net->ns, get_net_ns);
1259c62cce2cSAndrey Vagin 			break;
12600768e170SArnd Bergmann 		case SIOCGSTAMP_OLD:
12610768e170SArnd Bergmann 		case SIOCGSTAMPNS_OLD:
1262c7cbdbf2SArnd Bergmann 			if (!sock->ops->gettstamp) {
1263c7cbdbf2SArnd Bergmann 				err = -ENOIOCTLCMD;
1264c7cbdbf2SArnd Bergmann 				break;
1265c7cbdbf2SArnd Bergmann 			}
1266c7cbdbf2SArnd Bergmann 			err = sock->ops->gettstamp(sock, argp,
12670768e170SArnd Bergmann 						   cmd == SIOCGSTAMP_OLD,
12680768e170SArnd Bergmann 						   !IS_ENABLED(CONFIG_64BIT));
126960747828SGustavo A. R. Silva 			break;
12700768e170SArnd Bergmann 		case SIOCGSTAMP_NEW:
12710768e170SArnd Bergmann 		case SIOCGSTAMPNS_NEW:
12720768e170SArnd Bergmann 			if (!sock->ops->gettstamp) {
12730768e170SArnd Bergmann 				err = -ENOIOCTLCMD;
12740768e170SArnd Bergmann 				break;
12750768e170SArnd Bergmann 			}
12760768e170SArnd Bergmann 			err = sock->ops->gettstamp(sock, argp,
12770768e170SArnd Bergmann 						   cmd == SIOCGSTAMP_NEW,
12780768e170SArnd Bergmann 						   false);
1279c7cbdbf2SArnd Bergmann 			break;
1280876f0bf9SArnd Bergmann 
1281876f0bf9SArnd Bergmann 		case SIOCGIFCONF:
1282876f0bf9SArnd Bergmann 			err = dev_ifconf(net, argp);
1283876f0bf9SArnd Bergmann 			break;
1284876f0bf9SArnd Bergmann 
12851da177e4SLinus Torvalds 		default:
128663ff03abSJohannes Berg 			err = sock_do_ioctl(net, sock, cmd, arg);
12871da177e4SLinus Torvalds 			break;
12881da177e4SLinus Torvalds 		}
12891da177e4SLinus Torvalds 	return err;
12901da177e4SLinus Torvalds }
12911da177e4SLinus Torvalds 
12928a3c245cSPedro Tammela /**
12938a3c245cSPedro Tammela  *	sock_create_lite - creates a socket
12948a3c245cSPedro Tammela  *	@family: protocol family (AF_INET, ...)
12958a3c245cSPedro Tammela  *	@type: communication type (SOCK_STREAM, ...)
12968a3c245cSPedro Tammela  *	@protocol: protocol (0, ...)
12978a3c245cSPedro Tammela  *	@res: new socket
12988a3c245cSPedro Tammela  *
12998a3c245cSPedro Tammela  *	Creates a new socket and assigns it to @res, passing through LSM.
13008a3c245cSPedro Tammela  *	The new socket initialization is not complete, see kernel_accept().
13018a3c245cSPedro Tammela  *	Returns 0 or an error. On failure @res is set to %NULL.
13028a3c245cSPedro Tammela  *	This function internally uses GFP_KERNEL.
13038a3c245cSPedro Tammela  */
13048a3c245cSPedro Tammela 
13051da177e4SLinus Torvalds int sock_create_lite(int family, int type, int protocol, struct socket **res)
13061da177e4SLinus Torvalds {
13071da177e4SLinus Torvalds 	int err;
13081da177e4SLinus Torvalds 	struct socket *sock = NULL;
13091da177e4SLinus Torvalds 
13101da177e4SLinus Torvalds 	err = security_socket_create(family, type, protocol, 1);
13111da177e4SLinus Torvalds 	if (err)
13121da177e4SLinus Torvalds 		goto out;
13131da177e4SLinus Torvalds 
13141da177e4SLinus Torvalds 	sock = sock_alloc();
13151da177e4SLinus Torvalds 	if (!sock) {
13161da177e4SLinus Torvalds 		err = -ENOMEM;
13171da177e4SLinus Torvalds 		goto out;
13181da177e4SLinus Torvalds 	}
13191da177e4SLinus Torvalds 
13201da177e4SLinus Torvalds 	sock->type = type;
13217420ed23SVenkat Yekkirala 	err = security_socket_post_create(sock, family, type, protocol, 1);
13227420ed23SVenkat Yekkirala 	if (err)
13237420ed23SVenkat Yekkirala 		goto out_release;
13247420ed23SVenkat Yekkirala 
13251da177e4SLinus Torvalds out:
13261da177e4SLinus Torvalds 	*res = sock;
13271da177e4SLinus Torvalds 	return err;
13287420ed23SVenkat Yekkirala out_release:
13297420ed23SVenkat Yekkirala 	sock_release(sock);
13307420ed23SVenkat Yekkirala 	sock = NULL;
13317420ed23SVenkat Yekkirala 	goto out;
13321da177e4SLinus Torvalds }
1333c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_create_lite);
13341da177e4SLinus Torvalds 
13351da177e4SLinus Torvalds /* No kernel lock held - perfect */
1336ade994f4SAl Viro static __poll_t sock_poll(struct file *file, poll_table *wait)
13371da177e4SLinus Torvalds {
13383cafb376SChristoph Hellwig 	struct socket *sock = file->private_data;
1339a331de3bSChristoph Hellwig 	__poll_t events = poll_requested_events(wait), flag = 0;
13401da177e4SLinus Torvalds 
1341e88958e6SChristoph Hellwig 	if (!sock->ops->poll)
1342e88958e6SChristoph Hellwig 		return 0;
1343f641f13bSChristoph Hellwig 
1344a331de3bSChristoph Hellwig 	if (sk_can_busy_loop(sock->sk)) {
1345f641f13bSChristoph Hellwig 		/* poll once if requested by the syscall */
1346a331de3bSChristoph Hellwig 		if (events & POLL_BUSY_LOOP)
1347f641f13bSChristoph Hellwig 			sk_busy_loop(sock->sk, 1);
1348a331de3bSChristoph Hellwig 
1349a331de3bSChristoph Hellwig 		/* if this socket can poll_ll, tell the system call */
1350a331de3bSChristoph Hellwig 		flag = POLL_BUSY_LOOP;
1351a331de3bSChristoph Hellwig 	}
1352a331de3bSChristoph Hellwig 
1353a331de3bSChristoph Hellwig 	return sock->ops->poll(file, sock, wait) | flag;
13541da177e4SLinus Torvalds }
13551da177e4SLinus Torvalds 
13561da177e4SLinus Torvalds static int sock_mmap(struct file *file, struct vm_area_struct *vma)
13571da177e4SLinus Torvalds {
1358b69aee04SEric Dumazet 	struct socket *sock = file->private_data;
13591da177e4SLinus Torvalds 
13601da177e4SLinus Torvalds 	return sock->ops->mmap(file, sock, vma);
13611da177e4SLinus Torvalds }
13621da177e4SLinus Torvalds 
136320380731SArnaldo Carvalho de Melo static int sock_close(struct inode *inode, struct file *filp)
13641da177e4SLinus Torvalds {
13656d8c50dcSCong Wang 	__sock_release(SOCKET_I(inode), inode);
13661da177e4SLinus Torvalds 	return 0;
13671da177e4SLinus Torvalds }
13681da177e4SLinus Torvalds 
13691da177e4SLinus Torvalds /*
13701da177e4SLinus Torvalds  *	Update the socket async list
13711da177e4SLinus Torvalds  *
13721da177e4SLinus Torvalds  *	Fasync_list locking strategy.
13731da177e4SLinus Torvalds  *
13741da177e4SLinus Torvalds  *	1. fasync_list is modified only under process context socket lock
13751da177e4SLinus Torvalds  *	   i.e. under semaphore.
13761da177e4SLinus Torvalds  *	2. fasync_list is used under read_lock(&sk->sk_callback_lock)
1377989a2979SEric Dumazet  *	   or under socket lock
13781da177e4SLinus Torvalds  */
13791da177e4SLinus Torvalds 
13801da177e4SLinus Torvalds static int sock_fasync(int fd, struct file *filp, int on)
13811da177e4SLinus Torvalds {
1382989a2979SEric Dumazet 	struct socket *sock = filp->private_data;
1383989a2979SEric Dumazet 	struct sock *sk = sock->sk;
1384333f7909SAl Viro 	struct socket_wq *wq = &sock->wq;
13851da177e4SLinus Torvalds 
1386989a2979SEric Dumazet 	if (sk == NULL)
13871da177e4SLinus Torvalds 		return -EINVAL;
13881da177e4SLinus Torvalds 
13891da177e4SLinus Torvalds 	lock_sock(sk);
1390eaefd110SEric Dumazet 	fasync_helper(fd, filp, on, &wq->fasync_list);
13911da177e4SLinus Torvalds 
1392eaefd110SEric Dumazet 	if (!wq->fasync_list)
1393bcdce719SEric Dumazet 		sock_reset_flag(sk, SOCK_FASYNC);
1394989a2979SEric Dumazet 	else
1395989a2979SEric Dumazet 		sock_set_flag(sk, SOCK_FASYNC);
13961da177e4SLinus Torvalds 
1397989a2979SEric Dumazet 	release_sock(sk);
13981da177e4SLinus Torvalds 	return 0;
13991da177e4SLinus Torvalds }
14001da177e4SLinus Torvalds 
1401ceb5d58bSEric Dumazet /* This function may be called only under rcu_lock */
14021da177e4SLinus Torvalds 
1403ceb5d58bSEric Dumazet int sock_wake_async(struct socket_wq *wq, int how, int band)
14041da177e4SLinus Torvalds {
1405ceb5d58bSEric Dumazet 	if (!wq || !wq->fasync_list)
1406ceb5d58bSEric Dumazet 		return -1;
140743815482SEric Dumazet 
140889bddce5SStephen Hemminger 	switch (how) {
14098d8ad9d7SPavel Emelyanov 	case SOCK_WAKE_WAITD:
1410ceb5d58bSEric Dumazet 		if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags))
14111da177e4SLinus Torvalds 			break;
14121da177e4SLinus Torvalds 		goto call_kill;
14138d8ad9d7SPavel Emelyanov 	case SOCK_WAKE_SPACE:
1414ceb5d58bSEric Dumazet 		if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags))
14151da177e4SLinus Torvalds 			break;
14167c7ab580SMiaohe Lin 		fallthrough;
14178d8ad9d7SPavel Emelyanov 	case SOCK_WAKE_IO:
14181da177e4SLinus Torvalds call_kill:
141943815482SEric Dumazet 		kill_fasync(&wq->fasync_list, SIGIO, band);
14201da177e4SLinus Torvalds 		break;
14218d8ad9d7SPavel Emelyanov 	case SOCK_WAKE_URG:
142243815482SEric Dumazet 		kill_fasync(&wq->fasync_list, SIGURG, band);
14231da177e4SLinus Torvalds 	}
1424ceb5d58bSEric Dumazet 
14251da177e4SLinus Torvalds 	return 0;
14261da177e4SLinus Torvalds }
1427c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_wake_async);
14281da177e4SLinus Torvalds 
14298a3c245cSPedro Tammela /**
14308a3c245cSPedro Tammela  *	__sock_create - creates a socket
14318a3c245cSPedro Tammela  *	@net: net namespace
14328a3c245cSPedro Tammela  *	@family: protocol family (AF_INET, ...)
14338a3c245cSPedro Tammela  *	@type: communication type (SOCK_STREAM, ...)
14348a3c245cSPedro Tammela  *	@protocol: protocol (0, ...)
14358a3c245cSPedro Tammela  *	@res: new socket
14368a3c245cSPedro Tammela  *	@kern: boolean for kernel space sockets
14378a3c245cSPedro Tammela  *
14388a3c245cSPedro Tammela  *	Creates a new socket and assigns it to @res, passing through LSM.
14398a3c245cSPedro Tammela  *	Returns 0 or an error. On failure @res is set to %NULL. @kern must
14408a3c245cSPedro Tammela  *	be set to true if the socket resides in kernel space.
14418a3c245cSPedro Tammela  *	This function internally uses GFP_KERNEL.
14428a3c245cSPedro Tammela  */
14438a3c245cSPedro Tammela 
1444721db93aSPavel Emelyanov int __sock_create(struct net *net, int family, int type, int protocol,
144589bddce5SStephen Hemminger 			 struct socket **res, int kern)
14461da177e4SLinus Torvalds {
14471da177e4SLinus Torvalds 	int err;
14481da177e4SLinus Torvalds 	struct socket *sock;
144955737fdaSStephen Hemminger 	const struct net_proto_family *pf;
14501da177e4SLinus Torvalds 
14511da177e4SLinus Torvalds 	/*
14521da177e4SLinus Torvalds 	 *      Check protocol is in range
14531da177e4SLinus Torvalds 	 */
14541da177e4SLinus Torvalds 	if (family < 0 || family >= NPROTO)
14551da177e4SLinus Torvalds 		return -EAFNOSUPPORT;
14561da177e4SLinus Torvalds 	if (type < 0 || type >= SOCK_MAX)
14571da177e4SLinus Torvalds 		return -EINVAL;
14581da177e4SLinus Torvalds 
14591da177e4SLinus Torvalds 	/* Compatibility.
14601da177e4SLinus Torvalds 
14611da177e4SLinus Torvalds 	   This uglymoron is moved from INET layer to here to avoid
14621da177e4SLinus Torvalds 	   deadlock in module load.
14631da177e4SLinus Torvalds 	 */
14641da177e4SLinus Torvalds 	if (family == PF_INET && type == SOCK_PACKET) {
1465f3c98690Sliping.zhang 		pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)\n",
146689bddce5SStephen Hemminger 			     current->comm);
14671da177e4SLinus Torvalds 		family = PF_PACKET;
14681da177e4SLinus Torvalds 	}
14691da177e4SLinus Torvalds 
14701da177e4SLinus Torvalds 	err = security_socket_create(family, type, protocol, kern);
14711da177e4SLinus Torvalds 	if (err)
14721da177e4SLinus Torvalds 		return err;
14731da177e4SLinus Torvalds 
147455737fdaSStephen Hemminger 	/*
147555737fdaSStephen Hemminger 	 *	Allocate the socket and allow the family to set things up. if
147655737fdaSStephen Hemminger 	 *	the protocol is 0, the family is instructed to select an appropriate
147755737fdaSStephen Hemminger 	 *	default.
147855737fdaSStephen Hemminger 	 */
147955737fdaSStephen Hemminger 	sock = sock_alloc();
148055737fdaSStephen Hemminger 	if (!sock) {
1481e87cc472SJoe Perches 		net_warn_ratelimited("socket: no more sockets\n");
148255737fdaSStephen Hemminger 		return -ENFILE;	/* Not exactly a match, but its the
148355737fdaSStephen Hemminger 				   closest posix thing */
148455737fdaSStephen Hemminger 	}
148555737fdaSStephen Hemminger 
148655737fdaSStephen Hemminger 	sock->type = type;
148755737fdaSStephen Hemminger 
148895a5afcaSJohannes Berg #ifdef CONFIG_MODULES
14891da177e4SLinus Torvalds 	/* Attempt to load a protocol module if the find failed.
14901da177e4SLinus Torvalds 	 *
14911da177e4SLinus Torvalds 	 * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
14921da177e4SLinus Torvalds 	 * requested real, full-featured networking support upon configuration.
14931da177e4SLinus Torvalds 	 * Otherwise module support will break!
14941da177e4SLinus Torvalds 	 */
1495190683a9SEric Dumazet 	if (rcu_access_pointer(net_families[family]) == NULL)
14961da177e4SLinus Torvalds 		request_module("net-pf-%d", family);
14971da177e4SLinus Torvalds #endif
14981da177e4SLinus Torvalds 
149955737fdaSStephen Hemminger 	rcu_read_lock();
150055737fdaSStephen Hemminger 	pf = rcu_dereference(net_families[family]);
15011da177e4SLinus Torvalds 	err = -EAFNOSUPPORT;
150255737fdaSStephen Hemminger 	if (!pf)
150355737fdaSStephen Hemminger 		goto out_release;
15041da177e4SLinus Torvalds 
15051da177e4SLinus Torvalds 	/*
15061da177e4SLinus Torvalds 	 * We will call the ->create function, that possibly is in a loadable
15071da177e4SLinus Torvalds 	 * module, so we have to bump that loadable module refcnt first.
15081da177e4SLinus Torvalds 	 */
150955737fdaSStephen Hemminger 	if (!try_module_get(pf->owner))
15101da177e4SLinus Torvalds 		goto out_release;
15111da177e4SLinus Torvalds 
151255737fdaSStephen Hemminger 	/* Now protected by module ref count */
151355737fdaSStephen Hemminger 	rcu_read_unlock();
151455737fdaSStephen Hemminger 
15153f378b68SEric Paris 	err = pf->create(net, sock, protocol, kern);
151655737fdaSStephen Hemminger 	if (err < 0)
15171da177e4SLinus Torvalds 		goto out_module_put;
1518a79af59eSFrank Filz 
15191da177e4SLinus Torvalds 	/*
15201da177e4SLinus Torvalds 	 * Now to bump the refcnt of the [loadable] module that owns this
15211da177e4SLinus Torvalds 	 * socket at sock_release time we decrement its refcnt.
15221da177e4SLinus Torvalds 	 */
152355737fdaSStephen Hemminger 	if (!try_module_get(sock->ops->owner))
152455737fdaSStephen Hemminger 		goto out_module_busy;
152555737fdaSStephen Hemminger 
15261da177e4SLinus Torvalds 	/*
15271da177e4SLinus Torvalds 	 * Now that we're done with the ->create function, the [loadable]
15281da177e4SLinus Torvalds 	 * module can have its refcnt decremented
15291da177e4SLinus Torvalds 	 */
153055737fdaSStephen Hemminger 	module_put(pf->owner);
15317420ed23SVenkat Yekkirala 	err = security_socket_post_create(sock, family, type, protocol, kern);
15327420ed23SVenkat Yekkirala 	if (err)
15333b185525SHerbert Xu 		goto out_sock_release;
153455737fdaSStephen Hemminger 	*res = sock;
15351da177e4SLinus Torvalds 
153655737fdaSStephen Hemminger 	return 0;
153755737fdaSStephen Hemminger 
153855737fdaSStephen Hemminger out_module_busy:
153955737fdaSStephen Hemminger 	err = -EAFNOSUPPORT;
15401da177e4SLinus Torvalds out_module_put:
154155737fdaSStephen Hemminger 	sock->ops = NULL;
154255737fdaSStephen Hemminger 	module_put(pf->owner);
154355737fdaSStephen Hemminger out_sock_release:
15441da177e4SLinus Torvalds 	sock_release(sock);
154555737fdaSStephen Hemminger 	return err;
154655737fdaSStephen Hemminger 
154755737fdaSStephen Hemminger out_release:
154855737fdaSStephen Hemminger 	rcu_read_unlock();
154955737fdaSStephen Hemminger 	goto out_sock_release;
15501da177e4SLinus Torvalds }
1551721db93aSPavel Emelyanov EXPORT_SYMBOL(__sock_create);
15521da177e4SLinus Torvalds 
15538a3c245cSPedro Tammela /**
15548a3c245cSPedro Tammela  *	sock_create - creates a socket
15558a3c245cSPedro Tammela  *	@family: protocol family (AF_INET, ...)
15568a3c245cSPedro Tammela  *	@type: communication type (SOCK_STREAM, ...)
15578a3c245cSPedro Tammela  *	@protocol: protocol (0, ...)
15588a3c245cSPedro Tammela  *	@res: new socket
15598a3c245cSPedro Tammela  *
15608a3c245cSPedro Tammela  *	A wrapper around __sock_create().
15618a3c245cSPedro Tammela  *	Returns 0 or an error. This function internally uses GFP_KERNEL.
15628a3c245cSPedro Tammela  */
15638a3c245cSPedro Tammela 
15641da177e4SLinus Torvalds int sock_create(int family, int type, int protocol, struct socket **res)
15651da177e4SLinus Torvalds {
15661b8d7ae4SEric W. Biederman 	return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
15671da177e4SLinus Torvalds }
1568c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_create);
15691da177e4SLinus Torvalds 
15708a3c245cSPedro Tammela /**
15718a3c245cSPedro Tammela  *	sock_create_kern - creates a socket (kernel space)
15728a3c245cSPedro Tammela  *	@net: net namespace
15738a3c245cSPedro Tammela  *	@family: protocol family (AF_INET, ...)
15748a3c245cSPedro Tammela  *	@type: communication type (SOCK_STREAM, ...)
15758a3c245cSPedro Tammela  *	@protocol: protocol (0, ...)
15768a3c245cSPedro Tammela  *	@res: new socket
15778a3c245cSPedro Tammela  *
15788a3c245cSPedro Tammela  *	A wrapper around __sock_create().
15798a3c245cSPedro Tammela  *	Returns 0 or an error. This function internally uses GFP_KERNEL.
15808a3c245cSPedro Tammela  */
15818a3c245cSPedro Tammela 
1582eeb1bd5cSEric W. Biederman int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
15831da177e4SLinus Torvalds {
1584eeb1bd5cSEric W. Biederman 	return __sock_create(net, family, type, protocol, res, 1);
15851da177e4SLinus Torvalds }
1586c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_create_kern);
15871da177e4SLinus Torvalds 
1588da214a47SJens Axboe static struct socket *__sys_socket_create(int family, int type, int protocol)
15891da177e4SLinus Torvalds {
15901da177e4SLinus Torvalds 	struct socket *sock;
1591da214a47SJens Axboe 	int retval;
1592a677a039SUlrich Drepper 
1593e38b36f3SUlrich Drepper 	/* Check the SOCK_* constants for consistency.  */
1594e38b36f3SUlrich Drepper 	BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC);
1595e38b36f3SUlrich Drepper 	BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK);
1596e38b36f3SUlrich Drepper 	BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK);
1597e38b36f3SUlrich Drepper 	BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK);
1598e38b36f3SUlrich Drepper 
1599da214a47SJens Axboe 	if ((type & ~SOCK_TYPE_MASK) & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
1600da214a47SJens Axboe 		return ERR_PTR(-EINVAL);
1601a677a039SUlrich Drepper 	type &= SOCK_TYPE_MASK;
16021da177e4SLinus Torvalds 
16031da177e4SLinus Torvalds 	retval = sock_create(family, type, protocol, &sock);
16041da177e4SLinus Torvalds 	if (retval < 0)
1605da214a47SJens Axboe 		return ERR_PTR(retval);
1606da214a47SJens Axboe 
1607da214a47SJens Axboe 	return sock;
1608da214a47SJens Axboe }
1609da214a47SJens Axboe 
1610da214a47SJens Axboe struct file *__sys_socket_file(int family, int type, int protocol)
1611da214a47SJens Axboe {
1612da214a47SJens Axboe 	struct socket *sock;
1613da214a47SJens Axboe 	struct file *file;
1614da214a47SJens Axboe 	int flags;
1615da214a47SJens Axboe 
1616da214a47SJens Axboe 	sock = __sys_socket_create(family, type, protocol);
1617da214a47SJens Axboe 	if (IS_ERR(sock))
1618da214a47SJens Axboe 		return ERR_CAST(sock);
1619da214a47SJens Axboe 
1620da214a47SJens Axboe 	flags = type & ~SOCK_TYPE_MASK;
1621da214a47SJens Axboe 	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1622da214a47SJens Axboe 		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1623da214a47SJens Axboe 
1624da214a47SJens Axboe 	file = sock_alloc_file(sock, flags, NULL);
1625da214a47SJens Axboe 	if (IS_ERR(file))
1626da214a47SJens Axboe 		sock_release(sock);
1627da214a47SJens Axboe 
1628da214a47SJens Axboe 	return file;
1629da214a47SJens Axboe }
1630da214a47SJens Axboe 
1631da214a47SJens Axboe int __sys_socket(int family, int type, int protocol)
1632da214a47SJens Axboe {
1633da214a47SJens Axboe 	struct socket *sock;
1634da214a47SJens Axboe 	int flags;
1635da214a47SJens Axboe 
1636da214a47SJens Axboe 	sock = __sys_socket_create(family, type, protocol);
1637da214a47SJens Axboe 	if (IS_ERR(sock))
1638da214a47SJens Axboe 		return PTR_ERR(sock);
1639da214a47SJens Axboe 
1640da214a47SJens Axboe 	flags = type & ~SOCK_TYPE_MASK;
1641da214a47SJens Axboe 	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1642da214a47SJens Axboe 		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
16431da177e4SLinus Torvalds 
16448e1611e2SAl Viro 	return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
16451da177e4SLinus Torvalds }
16461da177e4SLinus Torvalds 
16479d6a15c3SDominik Brodowski SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
16489d6a15c3SDominik Brodowski {
16499d6a15c3SDominik Brodowski 	return __sys_socket(family, type, protocol);
16509d6a15c3SDominik Brodowski }
16519d6a15c3SDominik Brodowski 
16521da177e4SLinus Torvalds /*
16531da177e4SLinus Torvalds  *	Create a pair of connected sockets.
16541da177e4SLinus Torvalds  */
16551da177e4SLinus Torvalds 
16566debc8d8SDominik Brodowski int __sys_socketpair(int family, int type, int protocol, int __user *usockvec)
16571da177e4SLinus Torvalds {
16581da177e4SLinus Torvalds 	struct socket *sock1, *sock2;
16591da177e4SLinus Torvalds 	int fd1, fd2, err;
1660db349509SAl Viro 	struct file *newfile1, *newfile2;
1661a677a039SUlrich Drepper 	int flags;
1662a677a039SUlrich Drepper 
1663a677a039SUlrich Drepper 	flags = type & ~SOCK_TYPE_MASK;
166477d27200SUlrich Drepper 	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
1665a677a039SUlrich Drepper 		return -EINVAL;
1666a677a039SUlrich Drepper 	type &= SOCK_TYPE_MASK;
16671da177e4SLinus Torvalds 
1668aaca0bdcSUlrich Drepper 	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1669aaca0bdcSUlrich Drepper 		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1670aaca0bdcSUlrich Drepper 
16711da177e4SLinus Torvalds 	/*
1672016a266bSAl Viro 	 * reserve descriptors and make sure we won't fail
1673016a266bSAl Viro 	 * to return them to userland.
1674016a266bSAl Viro 	 */
1675016a266bSAl Viro 	fd1 = get_unused_fd_flags(flags);
1676016a266bSAl Viro 	if (unlikely(fd1 < 0))
1677016a266bSAl Viro 		return fd1;
1678016a266bSAl Viro 
1679016a266bSAl Viro 	fd2 = get_unused_fd_flags(flags);
1680016a266bSAl Viro 	if (unlikely(fd2 < 0)) {
1681016a266bSAl Viro 		put_unused_fd(fd1);
1682016a266bSAl Viro 		return fd2;
1683016a266bSAl Viro 	}
1684016a266bSAl Viro 
1685016a266bSAl Viro 	err = put_user(fd1, &usockvec[0]);
1686016a266bSAl Viro 	if (err)
1687016a266bSAl Viro 		goto out;
1688016a266bSAl Viro 
1689016a266bSAl Viro 	err = put_user(fd2, &usockvec[1]);
1690016a266bSAl Viro 	if (err)
1691016a266bSAl Viro 		goto out;
1692016a266bSAl Viro 
1693016a266bSAl Viro 	/*
16941da177e4SLinus Torvalds 	 * Obtain the first socket and check if the underlying protocol
16951da177e4SLinus Torvalds 	 * supports the socketpair call.
16961da177e4SLinus Torvalds 	 */
16971da177e4SLinus Torvalds 
16981da177e4SLinus Torvalds 	err = sock_create(family, type, protocol, &sock1);
1699016a266bSAl Viro 	if (unlikely(err < 0))
17001da177e4SLinus Torvalds 		goto out;
17011da177e4SLinus Torvalds 
17021da177e4SLinus Torvalds 	err = sock_create(family, type, protocol, &sock2);
1703016a266bSAl Viro 	if (unlikely(err < 0)) {
1704016a266bSAl Viro 		sock_release(sock1);
1705016a266bSAl Viro 		goto out;
1706bf3c23d1SDavid S. Miller 	}
1707d73aa286SYann Droneaud 
1708d47cd945SDavid Herrmann 	err = security_socket_socketpair(sock1, sock2);
1709d47cd945SDavid Herrmann 	if (unlikely(err)) {
1710d47cd945SDavid Herrmann 		sock_release(sock2);
1711d47cd945SDavid Herrmann 		sock_release(sock1);
1712d47cd945SDavid Herrmann 		goto out;
1713d47cd945SDavid Herrmann 	}
1714d47cd945SDavid Herrmann 
1715016a266bSAl Viro 	err = sock1->ops->socketpair(sock1, sock2);
1716016a266bSAl Viro 	if (unlikely(err < 0)) {
1717016a266bSAl Viro 		sock_release(sock2);
1718016a266bSAl Viro 		sock_release(sock1);
1719016a266bSAl Viro 		goto out;
172028407630SAl Viro 	}
172128407630SAl Viro 
1722aab174f0SLinus Torvalds 	newfile1 = sock_alloc_file(sock1, flags, NULL);
1723b5ffe634SViresh Kumar 	if (IS_ERR(newfile1)) {
172428407630SAl Viro 		err = PTR_ERR(newfile1);
1725016a266bSAl Viro 		sock_release(sock2);
1726016a266bSAl Viro 		goto out;
172728407630SAl Viro 	}
172828407630SAl Viro 
1729aab174f0SLinus Torvalds 	newfile2 = sock_alloc_file(sock2, flags, NULL);
173028407630SAl Viro 	if (IS_ERR(newfile2)) {
173128407630SAl Viro 		err = PTR_ERR(newfile2);
1732016a266bSAl Viro 		fput(newfile1);
1733016a266bSAl Viro 		goto out;
1734db349509SAl Viro 	}
1735db349509SAl Viro 
1736157cf649SAl Viro 	audit_fd_pair(fd1, fd2);
1737d73aa286SYann Droneaud 
1738db349509SAl Viro 	fd_install(fd1, newfile1);
1739db349509SAl Viro 	fd_install(fd2, newfile2);
17401da177e4SLinus Torvalds 	return 0;
17411da177e4SLinus Torvalds 
17421da177e4SLinus Torvalds out:
1743016a266bSAl Viro 	put_unused_fd(fd2);
1744016a266bSAl Viro 	put_unused_fd(fd1);
17451da177e4SLinus Torvalds 	return err;
17461da177e4SLinus Torvalds }
17471da177e4SLinus Torvalds 
17486debc8d8SDominik Brodowski SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
17496debc8d8SDominik Brodowski 		int __user *, usockvec)
17506debc8d8SDominik Brodowski {
17516debc8d8SDominik Brodowski 	return __sys_socketpair(family, type, protocol, usockvec);
17526debc8d8SDominik Brodowski }
17536debc8d8SDominik Brodowski 
17541da177e4SLinus Torvalds /*
17551da177e4SLinus Torvalds  *	Bind a name to a socket. Nothing much to do here since it's
17561da177e4SLinus Torvalds  *	the protocol's responsibility to handle the local address.
17571da177e4SLinus Torvalds  *
17581da177e4SLinus Torvalds  *	We move the socket address to kernel space before we call
17591da177e4SLinus Torvalds  *	the protocol layer (having also checked the address is ok).
17601da177e4SLinus Torvalds  */
17611da177e4SLinus Torvalds 
1762a87d35d8SDominik Brodowski int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
17631da177e4SLinus Torvalds {
17641da177e4SLinus Torvalds 	struct socket *sock;
1765230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
17666cb153caSBenjamin LaHaise 	int err, fput_needed;
17671da177e4SLinus Torvalds 
176889bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
176989bddce5SStephen Hemminger 	if (sock) {
177043db362dSMaciej Żenczykowski 		err = move_addr_to_kernel(umyaddr, addrlen, &address);
1771068b88ccSJakub Sitnicki 		if (!err) {
177289bddce5SStephen Hemminger 			err = security_socket_bind(sock,
1773230b1839SYOSHIFUJI Hideaki 						   (struct sockaddr *)&address,
177489bddce5SStephen Hemminger 						   addrlen);
17756cb153caSBenjamin LaHaise 			if (!err)
17766cb153caSBenjamin LaHaise 				err = sock->ops->bind(sock,
177789bddce5SStephen Hemminger 						      (struct sockaddr *)
1778230b1839SYOSHIFUJI Hideaki 						      &address, addrlen);
17791da177e4SLinus Torvalds 		}
17806cb153caSBenjamin LaHaise 		fput_light(sock->file, fput_needed);
17811da177e4SLinus Torvalds 	}
17821da177e4SLinus Torvalds 	return err;
17831da177e4SLinus Torvalds }
17841da177e4SLinus Torvalds 
1785a87d35d8SDominik Brodowski SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
1786a87d35d8SDominik Brodowski {
1787a87d35d8SDominik Brodowski 	return __sys_bind(fd, umyaddr, addrlen);
1788a87d35d8SDominik Brodowski }
1789a87d35d8SDominik Brodowski 
17901da177e4SLinus Torvalds /*
17911da177e4SLinus Torvalds  *	Perform a listen. Basically, we allow the protocol to do anything
17921da177e4SLinus Torvalds  *	necessary for a listen, and if that works, we mark the socket as
17931da177e4SLinus Torvalds  *	ready for listening.
17941da177e4SLinus Torvalds  */
17951da177e4SLinus Torvalds 
179625e290eeSDominik Brodowski int __sys_listen(int fd, int backlog)
17971da177e4SLinus Torvalds {
17981da177e4SLinus Torvalds 	struct socket *sock;
17996cb153caSBenjamin LaHaise 	int err, fput_needed;
1800b8e1f9b5SPavel Emelyanov 	int somaxconn;
18011da177e4SLinus Torvalds 
180289bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
180389bddce5SStephen Hemminger 	if (sock) {
18043c9ba81dSKuniyuki Iwashima 		somaxconn = READ_ONCE(sock_net(sock->sk)->core.sysctl_somaxconn);
180595c96174SEric Dumazet 		if ((unsigned int)backlog > somaxconn)
1806b8e1f9b5SPavel Emelyanov 			backlog = somaxconn;
18071da177e4SLinus Torvalds 
18081da177e4SLinus Torvalds 		err = security_socket_listen(sock, backlog);
18096cb153caSBenjamin LaHaise 		if (!err)
18101da177e4SLinus Torvalds 			err = sock->ops->listen(sock, backlog);
18116cb153caSBenjamin LaHaise 
18126cb153caSBenjamin LaHaise 		fput_light(sock->file, fput_needed);
18131da177e4SLinus Torvalds 	}
18141da177e4SLinus Torvalds 	return err;
18151da177e4SLinus Torvalds }
18161da177e4SLinus Torvalds 
181725e290eeSDominik Brodowski SYSCALL_DEFINE2(listen, int, fd, int, backlog)
181825e290eeSDominik Brodowski {
181925e290eeSDominik Brodowski 	return __sys_listen(fd, backlog);
182025e290eeSDominik Brodowski }
182125e290eeSDominik Brodowski 
1822d32f89daSPavel Begunkov struct file *do_accept(struct file *file, unsigned file_flags,
1823de2ea4b6SJens Axboe 		       struct sockaddr __user *upeer_sockaddr,
1824d32f89daSPavel Begunkov 		       int __user *upeer_addrlen, int flags)
18251da177e4SLinus Torvalds {
18261da177e4SLinus Torvalds 	struct socket *sock, *newsock;
182739d8c1b6SDavid S. Miller 	struct file *newfile;
1828d32f89daSPavel Begunkov 	int err, len;
1829230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
18301da177e4SLinus Torvalds 
1831dba4a925SFlorent Revest 	sock = sock_from_file(file);
1832d32f89daSPavel Begunkov 	if (!sock)
1833d32f89daSPavel Begunkov 		return ERR_PTR(-ENOTSOCK);
18341da177e4SLinus Torvalds 
1835c6d409cfSEric Dumazet 	newsock = sock_alloc();
1836c6d409cfSEric Dumazet 	if (!newsock)
1837d32f89daSPavel Begunkov 		return ERR_PTR(-ENFILE);
18381da177e4SLinus Torvalds 
18391da177e4SLinus Torvalds 	newsock->type = sock->type;
18401da177e4SLinus Torvalds 	newsock->ops = sock->ops;
18411da177e4SLinus Torvalds 
18421da177e4SLinus Torvalds 	/*
18431da177e4SLinus Torvalds 	 * We don't need try_module_get here, as the listening socket (sock)
18441da177e4SLinus Torvalds 	 * has the protocol module (sock->ops->owner) held.
18451da177e4SLinus Torvalds 	 */
18461da177e4SLinus Torvalds 	__module_get(newsock->ops->owner);
18471da177e4SLinus Torvalds 
1848aab174f0SLinus Torvalds 	newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
1849d32f89daSPavel Begunkov 	if (IS_ERR(newfile))
1850d32f89daSPavel Begunkov 		return newfile;
185139d8c1b6SDavid S. Miller 
1852a79af59eSFrank Filz 	err = security_socket_accept(sock, newsock);
1853a79af59eSFrank Filz 	if (err)
185439d8c1b6SDavid S. Miller 		goto out_fd;
1855a79af59eSFrank Filz 
1856de2ea4b6SJens Axboe 	err = sock->ops->accept(sock, newsock, sock->file->f_flags | file_flags,
1857de2ea4b6SJens Axboe 					false);
18581da177e4SLinus Torvalds 	if (err < 0)
185939d8c1b6SDavid S. Miller 		goto out_fd;
18601da177e4SLinus Torvalds 
18611da177e4SLinus Torvalds 	if (upeer_sockaddr) {
18629b2c45d4SDenys Vlasenko 		len = newsock->ops->getname(newsock,
18639b2c45d4SDenys Vlasenko 					(struct sockaddr *)&address, 2);
18649b2c45d4SDenys Vlasenko 		if (len < 0) {
18651da177e4SLinus Torvalds 			err = -ECONNABORTED;
186639d8c1b6SDavid S. Miller 			goto out_fd;
18671da177e4SLinus Torvalds 		}
186843db362dSMaciej Żenczykowski 		err = move_addr_to_user(&address,
1869230b1839SYOSHIFUJI Hideaki 					len, upeer_sockaddr, upeer_addrlen);
18701da177e4SLinus Torvalds 		if (err < 0)
187139d8c1b6SDavid S. Miller 			goto out_fd;
18721da177e4SLinus Torvalds 	}
18731da177e4SLinus Torvalds 
18741da177e4SLinus Torvalds 	/* File flags are not inherited via accept() unlike another OSes. */
1875d32f89daSPavel Begunkov 	return newfile;
187639d8c1b6SDavid S. Miller out_fd:
18779606a216SDavid S. Miller 	fput(newfile);
1878d32f89daSPavel Begunkov 	return ERR_PTR(err);
1879d32f89daSPavel Begunkov }
1880de2ea4b6SJens Axboe 
1881c0424532SYajun Deng static int __sys_accept4_file(struct file *file, struct sockaddr __user *upeer_sockaddr,
1882c0424532SYajun Deng 			      int __user *upeer_addrlen, int flags)
1883d32f89daSPavel Begunkov {
1884d32f89daSPavel Begunkov 	struct file *newfile;
1885d32f89daSPavel Begunkov 	int newfd;
1886d32f89daSPavel Begunkov 
1887d32f89daSPavel Begunkov 	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
1888d32f89daSPavel Begunkov 		return -EINVAL;
1889d32f89daSPavel Begunkov 
1890d32f89daSPavel Begunkov 	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1891d32f89daSPavel Begunkov 		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1892d32f89daSPavel Begunkov 
1893c0424532SYajun Deng 	newfd = get_unused_fd_flags(flags);
1894d32f89daSPavel Begunkov 	if (unlikely(newfd < 0))
1895d32f89daSPavel Begunkov 		return newfd;
1896d32f89daSPavel Begunkov 
1897c0424532SYajun Deng 	newfile = do_accept(file, 0, upeer_sockaddr, upeer_addrlen,
1898d32f89daSPavel Begunkov 			    flags);
1899d32f89daSPavel Begunkov 	if (IS_ERR(newfile)) {
1900d32f89daSPavel Begunkov 		put_unused_fd(newfd);
1901d32f89daSPavel Begunkov 		return PTR_ERR(newfile);
1902d32f89daSPavel Begunkov 	}
1903d32f89daSPavel Begunkov 	fd_install(newfd, newfile);
1904d32f89daSPavel Begunkov 	return newfd;
1905de2ea4b6SJens Axboe }
1906de2ea4b6SJens Axboe 
1907de2ea4b6SJens Axboe /*
1908de2ea4b6SJens Axboe  *	For accept, we attempt to create a new socket, set up the link
1909de2ea4b6SJens Axboe  *	with the client, wake up the client, then return the new
1910de2ea4b6SJens Axboe  *	connected fd. We collect the address of the connector in kernel
1911de2ea4b6SJens Axboe  *	space and move it to user at the very end. This is unclean because
1912de2ea4b6SJens Axboe  *	we open the socket then return an error.
1913de2ea4b6SJens Axboe  *
1914de2ea4b6SJens Axboe  *	1003.1g adds the ability to recvmsg() to query connection pending
1915de2ea4b6SJens Axboe  *	status to recvmsg. We need to add that support in a way thats
1916de2ea4b6SJens Axboe  *	clean when we restructure accept also.
1917de2ea4b6SJens Axboe  */
1918de2ea4b6SJens Axboe 
1919de2ea4b6SJens Axboe int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
1920de2ea4b6SJens Axboe 		  int __user *upeer_addrlen, int flags)
1921de2ea4b6SJens Axboe {
1922de2ea4b6SJens Axboe 	int ret = -EBADF;
1923de2ea4b6SJens Axboe 	struct fd f;
1924de2ea4b6SJens Axboe 
1925de2ea4b6SJens Axboe 	f = fdget(fd);
1926de2ea4b6SJens Axboe 	if (f.file) {
1927c0424532SYajun Deng 		ret = __sys_accept4_file(f.file, upeer_sockaddr,
1928c0424532SYajun Deng 					 upeer_addrlen, flags);
19296b07edebSMiaohe Lin 		fdput(f);
1930de2ea4b6SJens Axboe 	}
1931de2ea4b6SJens Axboe 
1932de2ea4b6SJens Axboe 	return ret;
19331da177e4SLinus Torvalds }
19341da177e4SLinus Torvalds 
19354541e805SDominik Brodowski SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
19364541e805SDominik Brodowski 		int __user *, upeer_addrlen, int, flags)
19374541e805SDominik Brodowski {
19384541e805SDominik Brodowski 	return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, flags);
19394541e805SDominik Brodowski }
19404541e805SDominik Brodowski 
194120f37034SHeiko Carstens SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
194220f37034SHeiko Carstens 		int __user *, upeer_addrlen)
1943aaca0bdcSUlrich Drepper {
19444541e805SDominik Brodowski 	return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
1945aaca0bdcSUlrich Drepper }
1946aaca0bdcSUlrich Drepper 
19471da177e4SLinus Torvalds /*
19481da177e4SLinus Torvalds  *	Attempt to connect to a socket with the server address.  The address
19491da177e4SLinus Torvalds  *	is in user space so we verify it is OK and move it to kernel space.
19501da177e4SLinus Torvalds  *
19511da177e4SLinus Torvalds  *	For 1003.1g we need to add clean support for a bind to AF_UNSPEC to
19521da177e4SLinus Torvalds  *	break bindings
19531da177e4SLinus Torvalds  *
19541da177e4SLinus Torvalds  *	NOTE: 1003.1g draft 6.3 is broken with respect to AX.25/NetROM and
19551da177e4SLinus Torvalds  *	other SEQPACKET protocols that take time to connect() as it doesn't
19561da177e4SLinus Torvalds  *	include the -EINPROGRESS status for such sockets.
19571da177e4SLinus Torvalds  */
19581da177e4SLinus Torvalds 
1959f499a021SJens Axboe int __sys_connect_file(struct file *file, struct sockaddr_storage *address,
1960bd3ded31SJens Axboe 		       int addrlen, int file_flags)
19611da177e4SLinus Torvalds {
19621da177e4SLinus Torvalds 	struct socket *sock;
1963bd3ded31SJens Axboe 	int err;
19641da177e4SLinus Torvalds 
1965dba4a925SFlorent Revest 	sock = sock_from_file(file);
1966dba4a925SFlorent Revest 	if (!sock) {
1967dba4a925SFlorent Revest 		err = -ENOTSOCK;
19681da177e4SLinus Torvalds 		goto out;
1969dba4a925SFlorent Revest 	}
19701da177e4SLinus Torvalds 
197189bddce5SStephen Hemminger 	err =
1972f499a021SJens Axboe 	    security_socket_connect(sock, (struct sockaddr *)address, addrlen);
19731da177e4SLinus Torvalds 	if (err)
1974bd3ded31SJens Axboe 		goto out;
19751da177e4SLinus Torvalds 
1976f499a021SJens Axboe 	err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen,
1977bd3ded31SJens Axboe 				 sock->file->f_flags | file_flags);
19781da177e4SLinus Torvalds out:
19791da177e4SLinus Torvalds 	return err;
19801da177e4SLinus Torvalds }
19811da177e4SLinus Torvalds 
1982bd3ded31SJens Axboe int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
1983bd3ded31SJens Axboe {
1984bd3ded31SJens Axboe 	int ret = -EBADF;
1985bd3ded31SJens Axboe 	struct fd f;
1986bd3ded31SJens Axboe 
1987bd3ded31SJens Axboe 	f = fdget(fd);
1988bd3ded31SJens Axboe 	if (f.file) {
1989f499a021SJens Axboe 		struct sockaddr_storage address;
1990f499a021SJens Axboe 
1991f499a021SJens Axboe 		ret = move_addr_to_kernel(uservaddr, addrlen, &address);
1992f499a021SJens Axboe 		if (!ret)
1993f499a021SJens Axboe 			ret = __sys_connect_file(f.file, &address, addrlen, 0);
19946b07edebSMiaohe Lin 		fdput(f);
1995bd3ded31SJens Axboe 	}
1996bd3ded31SJens Axboe 
1997bd3ded31SJens Axboe 	return ret;
1998bd3ded31SJens Axboe }
1999bd3ded31SJens Axboe 
20001387c2c2SDominik Brodowski SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
20011387c2c2SDominik Brodowski 		int, addrlen)
20021387c2c2SDominik Brodowski {
20031387c2c2SDominik Brodowski 	return __sys_connect(fd, uservaddr, addrlen);
20041387c2c2SDominik Brodowski }
20051387c2c2SDominik Brodowski 
20061da177e4SLinus Torvalds /*
20071da177e4SLinus Torvalds  *	Get the local address ('name') of a socket object. Move the obtained
20081da177e4SLinus Torvalds  *	name to user space.
20091da177e4SLinus Torvalds  */
20101da177e4SLinus Torvalds 
20118882a107SDominik Brodowski int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
20128882a107SDominik Brodowski 		      int __user *usockaddr_len)
20131da177e4SLinus Torvalds {
20141da177e4SLinus Torvalds 	struct socket *sock;
2015230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
20169b2c45d4SDenys Vlasenko 	int err, fput_needed;
20171da177e4SLinus Torvalds 
20186cb153caSBenjamin LaHaise 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
20191da177e4SLinus Torvalds 	if (!sock)
20201da177e4SLinus Torvalds 		goto out;
20211da177e4SLinus Torvalds 
20221da177e4SLinus Torvalds 	err = security_socket_getsockname(sock);
20231da177e4SLinus Torvalds 	if (err)
20241da177e4SLinus Torvalds 		goto out_put;
20251da177e4SLinus Torvalds 
20269b2c45d4SDenys Vlasenko 	err = sock->ops->getname(sock, (struct sockaddr *)&address, 0);
20279b2c45d4SDenys Vlasenko 	if (err < 0)
20281da177e4SLinus Torvalds 		goto out_put;
20299b2c45d4SDenys Vlasenko 	/* "err" is actually length in this case */
20309b2c45d4SDenys Vlasenko 	err = move_addr_to_user(&address, err, usockaddr, usockaddr_len);
20311da177e4SLinus Torvalds 
20321da177e4SLinus Torvalds out_put:
20336cb153caSBenjamin LaHaise 	fput_light(sock->file, fput_needed);
20341da177e4SLinus Torvalds out:
20351da177e4SLinus Torvalds 	return err;
20361da177e4SLinus Torvalds }
20371da177e4SLinus Torvalds 
20388882a107SDominik Brodowski SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
20398882a107SDominik Brodowski 		int __user *, usockaddr_len)
20408882a107SDominik Brodowski {
20418882a107SDominik Brodowski 	return __sys_getsockname(fd, usockaddr, usockaddr_len);
20428882a107SDominik Brodowski }
20438882a107SDominik Brodowski 
20441da177e4SLinus Torvalds /*
20451da177e4SLinus Torvalds  *	Get the remote address ('name') of a socket object. Move the obtained
20461da177e4SLinus Torvalds  *	name to user space.
20471da177e4SLinus Torvalds  */
20481da177e4SLinus Torvalds 
2049b21c8f83SDominik Brodowski int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
2050b21c8f83SDominik Brodowski 		      int __user *usockaddr_len)
20511da177e4SLinus Torvalds {
20521da177e4SLinus Torvalds 	struct socket *sock;
2053230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
20549b2c45d4SDenys Vlasenko 	int err, fput_needed;
20551da177e4SLinus Torvalds 
205689bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
205789bddce5SStephen Hemminger 	if (sock != NULL) {
20581da177e4SLinus Torvalds 		err = security_socket_getpeername(sock);
20591da177e4SLinus Torvalds 		if (err) {
20606cb153caSBenjamin LaHaise 			fput_light(sock->file, fput_needed);
20611da177e4SLinus Torvalds 			return err;
20621da177e4SLinus Torvalds 		}
20631da177e4SLinus Torvalds 
20649b2c45d4SDenys Vlasenko 		err = sock->ops->getname(sock, (struct sockaddr *)&address, 1);
20659b2c45d4SDenys Vlasenko 		if (err >= 0)
20669b2c45d4SDenys Vlasenko 			/* "err" is actually length in this case */
20679b2c45d4SDenys Vlasenko 			err = move_addr_to_user(&address, err, usockaddr,
206889bddce5SStephen Hemminger 						usockaddr_len);
20696cb153caSBenjamin LaHaise 		fput_light(sock->file, fput_needed);
20701da177e4SLinus Torvalds 	}
20711da177e4SLinus Torvalds 	return err;
20721da177e4SLinus Torvalds }
20731da177e4SLinus Torvalds 
2074b21c8f83SDominik Brodowski SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
2075b21c8f83SDominik Brodowski 		int __user *, usockaddr_len)
2076b21c8f83SDominik Brodowski {
2077b21c8f83SDominik Brodowski 	return __sys_getpeername(fd, usockaddr, usockaddr_len);
2078b21c8f83SDominik Brodowski }
2079b21c8f83SDominik Brodowski 
20801da177e4SLinus Torvalds /*
20811da177e4SLinus Torvalds  *	Send a datagram to a given address. We move the address into kernel
20821da177e4SLinus Torvalds  *	space and check the user space data area is readable before invoking
20831da177e4SLinus Torvalds  *	the protocol.
20841da177e4SLinus Torvalds  */
2085211b634bSDominik Brodowski int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags,
2086211b634bSDominik Brodowski 		 struct sockaddr __user *addr,  int addr_len)
20871da177e4SLinus Torvalds {
20881da177e4SLinus Torvalds 	struct socket *sock;
2089230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
20901da177e4SLinus Torvalds 	int err;
20911da177e4SLinus Torvalds 	struct msghdr msg;
20921da177e4SLinus Torvalds 	struct iovec iov;
20936cb153caSBenjamin LaHaise 	int fput_needed;
20941da177e4SLinus Torvalds 
2095602bd0e9SAl Viro 	err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
2096602bd0e9SAl Viro 	if (unlikely(err))
2097602bd0e9SAl Viro 		return err;
2098de0fa95cSPavel Emelyanov 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
2099de0fa95cSPavel Emelyanov 	if (!sock)
21004387ff75SDavid S. Miller 		goto out;
21016cb153caSBenjamin LaHaise 
21021da177e4SLinus Torvalds 	msg.msg_name = NULL;
21031da177e4SLinus Torvalds 	msg.msg_control = NULL;
21041da177e4SLinus Torvalds 	msg.msg_controllen = 0;
21051da177e4SLinus Torvalds 	msg.msg_namelen = 0;
21067c701d92SPavel Begunkov 	msg.msg_ubuf = NULL;
21076cb153caSBenjamin LaHaise 	if (addr) {
210843db362dSMaciej Żenczykowski 		err = move_addr_to_kernel(addr, addr_len, &address);
21091da177e4SLinus Torvalds 		if (err < 0)
21101da177e4SLinus Torvalds 			goto out_put;
2111230b1839SYOSHIFUJI Hideaki 		msg.msg_name = (struct sockaddr *)&address;
21121da177e4SLinus Torvalds 		msg.msg_namelen = addr_len;
21131da177e4SLinus Torvalds 	}
21141da177e4SLinus Torvalds 	if (sock->file->f_flags & O_NONBLOCK)
21151da177e4SLinus Torvalds 		flags |= MSG_DONTWAIT;
21161da177e4SLinus Torvalds 	msg.msg_flags = flags;
2117d8725c86SAl Viro 	err = sock_sendmsg(sock, &msg);
21181da177e4SLinus Torvalds 
21191da177e4SLinus Torvalds out_put:
2120de0fa95cSPavel Emelyanov 	fput_light(sock->file, fput_needed);
21214387ff75SDavid S. Miller out:
21221da177e4SLinus Torvalds 	return err;
21231da177e4SLinus Torvalds }
21241da177e4SLinus Torvalds 
2125211b634bSDominik Brodowski SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
2126211b634bSDominik Brodowski 		unsigned int, flags, struct sockaddr __user *, addr,
2127211b634bSDominik Brodowski 		int, addr_len)
2128211b634bSDominik Brodowski {
2129211b634bSDominik Brodowski 	return __sys_sendto(fd, buff, len, flags, addr, addr_len);
2130211b634bSDominik Brodowski }
2131211b634bSDominik Brodowski 
21321da177e4SLinus Torvalds /*
21331da177e4SLinus Torvalds  *	Send a datagram down a socket.
21341da177e4SLinus Torvalds  */
21351da177e4SLinus Torvalds 
21363e0fa65fSHeiko Carstens SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
213795c96174SEric Dumazet 		unsigned int, flags)
21381da177e4SLinus Torvalds {
2139211b634bSDominik Brodowski 	return __sys_sendto(fd, buff, len, flags, NULL, 0);
21401da177e4SLinus Torvalds }
21411da177e4SLinus Torvalds 
21421da177e4SLinus Torvalds /*
21431da177e4SLinus Torvalds  *	Receive a frame from the socket and optionally record the address of the
21441da177e4SLinus Torvalds  *	sender. We verify the buffers are writable and if needed move the
21451da177e4SLinus Torvalds  *	sender address from kernel to user space.
21461da177e4SLinus Torvalds  */
21477a09e1ebSDominik Brodowski int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags,
21487a09e1ebSDominik Brodowski 		   struct sockaddr __user *addr, int __user *addr_len)
21491da177e4SLinus Torvalds {
21501228b34cSEric Dumazet 	struct sockaddr_storage address;
21511228b34cSEric Dumazet 	struct msghdr msg = {
21521228b34cSEric Dumazet 		/* Save some cycles and don't copy the address if not needed */
21531228b34cSEric Dumazet 		.msg_name = addr ? (struct sockaddr *)&address : NULL,
21541228b34cSEric Dumazet 	};
21551da177e4SLinus Torvalds 	struct socket *sock;
21561da177e4SLinus Torvalds 	struct iovec iov;
21571da177e4SLinus Torvalds 	int err, err2;
21586cb153caSBenjamin LaHaise 	int fput_needed;
21591da177e4SLinus Torvalds 
2160602bd0e9SAl Viro 	err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
2161602bd0e9SAl Viro 	if (unlikely(err))
2162602bd0e9SAl Viro 		return err;
2163de0fa95cSPavel Emelyanov 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
21641da177e4SLinus Torvalds 	if (!sock)
2165de0fa95cSPavel Emelyanov 		goto out;
21661da177e4SLinus Torvalds 
21671da177e4SLinus Torvalds 	if (sock->file->f_flags & O_NONBLOCK)
21681da177e4SLinus Torvalds 		flags |= MSG_DONTWAIT;
21692da62906SAl Viro 	err = sock_recvmsg(sock, &msg, flags);
21701da177e4SLinus Torvalds 
217189bddce5SStephen Hemminger 	if (err >= 0 && addr != NULL) {
217243db362dSMaciej Żenczykowski 		err2 = move_addr_to_user(&address,
2173230b1839SYOSHIFUJI Hideaki 					 msg.msg_namelen, addr, addr_len);
21741da177e4SLinus Torvalds 		if (err2 < 0)
21751da177e4SLinus Torvalds 			err = err2;
21761da177e4SLinus Torvalds 	}
2177de0fa95cSPavel Emelyanov 
2178de0fa95cSPavel Emelyanov 	fput_light(sock->file, fput_needed);
21794387ff75SDavid S. Miller out:
21801da177e4SLinus Torvalds 	return err;
21811da177e4SLinus Torvalds }
21821da177e4SLinus Torvalds 
21837a09e1ebSDominik Brodowski SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
21847a09e1ebSDominik Brodowski 		unsigned int, flags, struct sockaddr __user *, addr,
21857a09e1ebSDominik Brodowski 		int __user *, addr_len)
21867a09e1ebSDominik Brodowski {
21877a09e1ebSDominik Brodowski 	return __sys_recvfrom(fd, ubuf, size, flags, addr, addr_len);
21887a09e1ebSDominik Brodowski }
21897a09e1ebSDominik Brodowski 
21901da177e4SLinus Torvalds /*
21911da177e4SLinus Torvalds  *	Receive a datagram from a socket.
21921da177e4SLinus Torvalds  */
21931da177e4SLinus Torvalds 
2194b7c0ddf5SJan Glauber SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
2195b7c0ddf5SJan Glauber 		unsigned int, flags)
21961da177e4SLinus Torvalds {
21977a09e1ebSDominik Brodowski 	return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
21981da177e4SLinus Torvalds }
21991da177e4SLinus Torvalds 
220083f0c10bSFlorian Westphal static bool sock_use_custom_sol_socket(const struct socket *sock)
220183f0c10bSFlorian Westphal {
2202*a5ef058dSPaolo Abeni 	return test_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags);
220383f0c10bSFlorian Westphal }
220483f0c10bSFlorian Westphal 
22051da177e4SLinus Torvalds /*
22061da177e4SLinus Torvalds  *	Set a socket option. Because we don't know the option lengths we have
22071da177e4SLinus Torvalds  *	to pass the user mode parameter for the protocols to sort out.
22081da177e4SLinus Torvalds  */
2209a7b75c5aSChristoph Hellwig int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval,
221055db9c0eSChristoph Hellwig 		int optlen)
22111da177e4SLinus Torvalds {
2212519a8a6cSChristoph Hellwig 	sockptr_t optval = USER_SOCKPTR(user_optval);
22130d01da6aSStanislav Fomichev 	char *kernel_optval = NULL;
22146cb153caSBenjamin LaHaise 	int err, fput_needed;
22151da177e4SLinus Torvalds 	struct socket *sock;
22161da177e4SLinus Torvalds 
22171da177e4SLinus Torvalds 	if (optlen < 0)
22181da177e4SLinus Torvalds 		return -EINVAL;
22191da177e4SLinus Torvalds 
222089bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
22214a367299SChristoph Hellwig 	if (!sock)
22224a367299SChristoph Hellwig 		return err;
22234a367299SChristoph Hellwig 
22241da177e4SLinus Torvalds 	err = security_socket_setsockopt(sock, level, optname);
22256cb153caSBenjamin LaHaise 	if (err)
22266cb153caSBenjamin LaHaise 		goto out_put;
22271da177e4SLinus Torvalds 
222855db9c0eSChristoph Hellwig 	if (!in_compat_syscall())
22294a367299SChristoph Hellwig 		err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname,
2230a7b75c5aSChristoph Hellwig 						     user_optval, &optlen,
223155db9c0eSChristoph Hellwig 						     &kernel_optval);
22324a367299SChristoph Hellwig 	if (err < 0)
22330d01da6aSStanislav Fomichev 		goto out_put;
22344a367299SChristoph Hellwig 	if (err > 0) {
22350d01da6aSStanislav Fomichev 		err = 0;
22360d01da6aSStanislav Fomichev 		goto out_put;
22370d01da6aSStanislav Fomichev 	}
22380d01da6aSStanislav Fomichev 
2239a7b75c5aSChristoph Hellwig 	if (kernel_optval)
2240a7b75c5aSChristoph Hellwig 		optval = KERNEL_SOCKPTR(kernel_optval);
224183f0c10bSFlorian Westphal 	if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock))
2242a7b75c5aSChristoph Hellwig 		err = sock_setsockopt(sock, level, optname, optval, optlen);
2243a44d9e72SChristoph Hellwig 	else if (unlikely(!sock->ops->setsockopt))
2244a44d9e72SChristoph Hellwig 		err = -EOPNOTSUPP;
22451da177e4SLinus Torvalds 	else
22464a367299SChristoph Hellwig 		err = sock->ops->setsockopt(sock, level, optname, optval,
224789bddce5SStephen Hemminger 					    optlen);
22480d01da6aSStanislav Fomichev 	kfree(kernel_optval);
22496cb153caSBenjamin LaHaise out_put:
22506cb153caSBenjamin LaHaise 	fput_light(sock->file, fput_needed);
22511da177e4SLinus Torvalds 	return err;
22521da177e4SLinus Torvalds }
22531da177e4SLinus Torvalds 
2254cc36dca0SDominik Brodowski SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
2255cc36dca0SDominik Brodowski 		char __user *, optval, int, optlen)
2256cc36dca0SDominik Brodowski {
2257cc36dca0SDominik Brodowski 	return __sys_setsockopt(fd, level, optname, optval, optlen);
2258cc36dca0SDominik Brodowski }
2259cc36dca0SDominik Brodowski 
22609cacf81fSStanislav Fomichev INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level,
22619cacf81fSStanislav Fomichev 							 int optname));
22629cacf81fSStanislav Fomichev 
22631da177e4SLinus Torvalds /*
22641da177e4SLinus Torvalds  *	Get a socket option. Because we don't know the option lengths we have
22651da177e4SLinus Torvalds  *	to pass a user mode parameter for the protocols to sort out.
22661da177e4SLinus Torvalds  */
226755db9c0eSChristoph Hellwig int __sys_getsockopt(int fd, int level, int optname, char __user *optval,
226855db9c0eSChristoph Hellwig 		int __user *optlen)
22691da177e4SLinus Torvalds {
22706cb153caSBenjamin LaHaise 	int err, fput_needed;
22711da177e4SLinus Torvalds 	struct socket *sock;
22720d01da6aSStanislav Fomichev 	int max_optlen;
22731da177e4SLinus Torvalds 
227489bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
2275d8a9b38fSChristoph Hellwig 	if (!sock)
2276d8a9b38fSChristoph Hellwig 		return err;
2277d8a9b38fSChristoph Hellwig 
22786cb153caSBenjamin LaHaise 	err = security_socket_getsockopt(sock, level, optname);
22796cb153caSBenjamin LaHaise 	if (err)
22806cb153caSBenjamin LaHaise 		goto out_put;
22811da177e4SLinus Torvalds 
228255db9c0eSChristoph Hellwig 	if (!in_compat_syscall())
22830d01da6aSStanislav Fomichev 		max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen);
22840d01da6aSStanislav Fomichev 
22851da177e4SLinus Torvalds 	if (level == SOL_SOCKET)
2286d8a9b38fSChristoph Hellwig 		err = sock_getsockopt(sock, level, optname, optval, optlen);
2287a44d9e72SChristoph Hellwig 	else if (unlikely(!sock->ops->getsockopt))
2288a44d9e72SChristoph Hellwig 		err = -EOPNOTSUPP;
22891da177e4SLinus Torvalds 	else
2290d8a9b38fSChristoph Hellwig 		err = sock->ops->getsockopt(sock, level, optname, optval,
229189bddce5SStephen Hemminger 					    optlen);
22920d01da6aSStanislav Fomichev 
229355db9c0eSChristoph Hellwig 	if (!in_compat_syscall())
229455db9c0eSChristoph Hellwig 		err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname,
229555db9c0eSChristoph Hellwig 						     optval, optlen, max_optlen,
229655db9c0eSChristoph Hellwig 						     err);
22976cb153caSBenjamin LaHaise out_put:
22986cb153caSBenjamin LaHaise 	fput_light(sock->file, fput_needed);
22991da177e4SLinus Torvalds 	return err;
23001da177e4SLinus Torvalds }
23011da177e4SLinus Torvalds 
230213a2d70eSDominik Brodowski SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
230313a2d70eSDominik Brodowski 		char __user *, optval, int __user *, optlen)
230413a2d70eSDominik Brodowski {
230513a2d70eSDominik Brodowski 	return __sys_getsockopt(fd, level, optname, optval, optlen);
230613a2d70eSDominik Brodowski }
230713a2d70eSDominik Brodowski 
23081da177e4SLinus Torvalds /*
23091da177e4SLinus Torvalds  *	Shutdown a socket.
23101da177e4SLinus Torvalds  */
23111da177e4SLinus Torvalds 
2312b713c195SJens Axboe int __sys_shutdown_sock(struct socket *sock, int how)
2313b713c195SJens Axboe {
2314b713c195SJens Axboe 	int err;
2315b713c195SJens Axboe 
2316b713c195SJens Axboe 	err = security_socket_shutdown(sock, how);
2317b713c195SJens Axboe 	if (!err)
2318b713c195SJens Axboe 		err = sock->ops->shutdown(sock, how);
2319b713c195SJens Axboe 
2320b713c195SJens Axboe 	return err;
2321b713c195SJens Axboe }
2322b713c195SJens Axboe 
2323005a1aeaSDominik Brodowski int __sys_shutdown(int fd, int how)
23241da177e4SLinus Torvalds {
23256cb153caSBenjamin LaHaise 	int err, fput_needed;
23261da177e4SLinus Torvalds 	struct socket *sock;
23271da177e4SLinus Torvalds 
232889bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
232989bddce5SStephen Hemminger 	if (sock != NULL) {
2330b713c195SJens Axboe 		err = __sys_shutdown_sock(sock, how);
23316cb153caSBenjamin LaHaise 		fput_light(sock->file, fput_needed);
23321da177e4SLinus Torvalds 	}
23331da177e4SLinus Torvalds 	return err;
23341da177e4SLinus Torvalds }
23351da177e4SLinus Torvalds 
2336005a1aeaSDominik Brodowski SYSCALL_DEFINE2(shutdown, int, fd, int, how)
2337005a1aeaSDominik Brodowski {
2338005a1aeaSDominik Brodowski 	return __sys_shutdown(fd, how);
2339005a1aeaSDominik Brodowski }
2340005a1aeaSDominik Brodowski 
23411da177e4SLinus Torvalds /* A couple of helpful macros for getting the address of the 32/64 bit
23421da177e4SLinus Torvalds  * fields which are the same type (int / unsigned) on our platforms.
23431da177e4SLinus Torvalds  */
23441da177e4SLinus Torvalds #define COMPAT_MSG(msg, member)	((MSG_CMSG_COMPAT & flags) ? &msg##_compat->member : &msg->member)
23451da177e4SLinus Torvalds #define COMPAT_NAMELEN(msg)	COMPAT_MSG(msg, msg_namelen)
23461da177e4SLinus Torvalds #define COMPAT_FLAGS(msg)	COMPAT_MSG(msg, msg_flags)
23471da177e4SLinus Torvalds 
2348c71d8ebeSTetsuo Handa struct used_address {
2349c71d8ebeSTetsuo Handa 	struct sockaddr_storage name;
2350c71d8ebeSTetsuo Handa 	unsigned int name_len;
2351c71d8ebeSTetsuo Handa };
2352c71d8ebeSTetsuo Handa 
23537fa875b8SDylan Yudaken int __copy_msghdr(struct msghdr *kmsg,
23547fa875b8SDylan Yudaken 		  struct user_msghdr *msg,
23557fa875b8SDylan Yudaken 		  struct sockaddr __user **save_addr)
23561661bf36SDan Carpenter {
235708adb7daSAl Viro 	ssize_t err;
235808adb7daSAl Viro 
23591f466e1fSChristoph Hellwig 	kmsg->msg_control_is_user = true;
23601228b34cSEric Dumazet 	kmsg->msg_get_inq = 0;
23617fa875b8SDylan Yudaken 	kmsg->msg_control_user = msg->msg_control;
23627fa875b8SDylan Yudaken 	kmsg->msg_controllen = msg->msg_controllen;
23637fa875b8SDylan Yudaken 	kmsg->msg_flags = msg->msg_flags;
2364ffb07550SAl Viro 
23657fa875b8SDylan Yudaken 	kmsg->msg_namelen = msg->msg_namelen;
23667fa875b8SDylan Yudaken 	if (!msg->msg_name)
23676a2a2b3aSAni Sinha 		kmsg->msg_namelen = 0;
23686a2a2b3aSAni Sinha 
2369dbb490b9SMatthew Leach 	if (kmsg->msg_namelen < 0)
2370dbb490b9SMatthew Leach 		return -EINVAL;
2371dbb490b9SMatthew Leach 
23721661bf36SDan Carpenter 	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
2373db31c55aSDan Carpenter 		kmsg->msg_namelen = sizeof(struct sockaddr_storage);
237408adb7daSAl Viro 
237508adb7daSAl Viro 	if (save_addr)
23767fa875b8SDylan Yudaken 		*save_addr = msg->msg_name;
237708adb7daSAl Viro 
23787fa875b8SDylan Yudaken 	if (msg->msg_name && kmsg->msg_namelen) {
237908adb7daSAl Viro 		if (!save_addr) {
23807fa875b8SDylan Yudaken 			err = move_addr_to_kernel(msg->msg_name,
2381864d9664SPaolo Abeni 						  kmsg->msg_namelen,
238208adb7daSAl Viro 						  kmsg->msg_name);
238308adb7daSAl Viro 			if (err < 0)
238408adb7daSAl Viro 				return err;
238508adb7daSAl Viro 		}
238608adb7daSAl Viro 	} else {
238708adb7daSAl Viro 		kmsg->msg_name = NULL;
238808adb7daSAl Viro 		kmsg->msg_namelen = 0;
238908adb7daSAl Viro 	}
239008adb7daSAl Viro 
23917fa875b8SDylan Yudaken 	if (msg->msg_iovlen > UIO_MAXIOV)
239208adb7daSAl Viro 		return -EMSGSIZE;
239308adb7daSAl Viro 
23940345f931Stadeusz.struk@intel.com 	kmsg->msg_iocb = NULL;
23957c701d92SPavel Begunkov 	kmsg->msg_ubuf = NULL;
23960a384abfSJens Axboe 	return 0;
23970a384abfSJens Axboe }
23980a384abfSJens Axboe 
23990a384abfSJens Axboe static int copy_msghdr_from_user(struct msghdr *kmsg,
24000a384abfSJens Axboe 				 struct user_msghdr __user *umsg,
24010a384abfSJens Axboe 				 struct sockaddr __user **save_addr,
24020a384abfSJens Axboe 				 struct iovec **iov)
24030a384abfSJens Axboe {
24040a384abfSJens Axboe 	struct user_msghdr msg;
24050a384abfSJens Axboe 	ssize_t err;
24060a384abfSJens Axboe 
24077fa875b8SDylan Yudaken 	if (copy_from_user(&msg, umsg, sizeof(*umsg)))
24087fa875b8SDylan Yudaken 		return -EFAULT;
24097fa875b8SDylan Yudaken 
24107fa875b8SDylan Yudaken 	err = __copy_msghdr(kmsg, &msg, save_addr);
24110a384abfSJens Axboe 	if (err)
24120a384abfSJens Axboe 		return err;
24130345f931Stadeusz.struk@intel.com 
241487e5e6daSJens Axboe 	err = import_iovec(save_addr ? READ : WRITE,
2415ffb07550SAl Viro 			    msg.msg_iov, msg.msg_iovlen,
2416da184284SAl Viro 			    UIO_FASTIOV, iov, &kmsg->msg_iter);
241787e5e6daSJens Axboe 	return err < 0 ? err : 0;
24181661bf36SDan Carpenter }
24191661bf36SDan Carpenter 
24204257c8caSJens Axboe static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys,
24214257c8caSJens Axboe 			   unsigned int flags, struct used_address *used_address,
242228a94d8fSTom Herbert 			   unsigned int allowed_msghdr_flags)
24231da177e4SLinus Torvalds {
2424b9d717a7SAlex Williamson 	unsigned char ctl[sizeof(struct cmsghdr) + 20]
2425846cc123SAmit Kushwaha 				__aligned(sizeof(__kernel_size_t));
2426b9d717a7SAlex Williamson 	/* 20 is size of ipv6_pktinfo */
24271da177e4SLinus Torvalds 	unsigned char *ctl_buf = ctl;
2428d8725c86SAl Viro 	int ctl_len;
242908adb7daSAl Viro 	ssize_t err;
24301da177e4SLinus Torvalds 
24311da177e4SLinus Torvalds 	err = -ENOBUFS;
24321da177e4SLinus Torvalds 
2433228e548eSAnton Blanchard 	if (msg_sys->msg_controllen > INT_MAX)
24344257c8caSJens Axboe 		goto out;
243528a94d8fSTom Herbert 	flags |= (msg_sys->msg_flags & allowed_msghdr_flags);
2436228e548eSAnton Blanchard 	ctl_len = msg_sys->msg_controllen;
24371da177e4SLinus Torvalds 	if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
243889bddce5SStephen Hemminger 		err =
2439228e548eSAnton Blanchard 		    cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
244089bddce5SStephen Hemminger 						     sizeof(ctl));
24411da177e4SLinus Torvalds 		if (err)
24424257c8caSJens Axboe 			goto out;
2443228e548eSAnton Blanchard 		ctl_buf = msg_sys->msg_control;
2444228e548eSAnton Blanchard 		ctl_len = msg_sys->msg_controllen;
24451da177e4SLinus Torvalds 	} else if (ctl_len) {
2446ac4340fcSDavid S. Miller 		BUILD_BUG_ON(sizeof(struct cmsghdr) !=
2447ac4340fcSDavid S. Miller 			     CMSG_ALIGN(sizeof(struct cmsghdr)));
244889bddce5SStephen Hemminger 		if (ctl_len > sizeof(ctl)) {
24491da177e4SLinus Torvalds 			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
24501da177e4SLinus Torvalds 			if (ctl_buf == NULL)
24514257c8caSJens Axboe 				goto out;
24521da177e4SLinus Torvalds 		}
24531da177e4SLinus Torvalds 		err = -EFAULT;
24541f466e1fSChristoph Hellwig 		if (copy_from_user(ctl_buf, msg_sys->msg_control_user, ctl_len))
24551da177e4SLinus Torvalds 			goto out_freectl;
2456228e548eSAnton Blanchard 		msg_sys->msg_control = ctl_buf;
24571f466e1fSChristoph Hellwig 		msg_sys->msg_control_is_user = false;
24581da177e4SLinus Torvalds 	}
2459228e548eSAnton Blanchard 	msg_sys->msg_flags = flags;
24601da177e4SLinus Torvalds 
24611da177e4SLinus Torvalds 	if (sock->file->f_flags & O_NONBLOCK)
2462228e548eSAnton Blanchard 		msg_sys->msg_flags |= MSG_DONTWAIT;
2463c71d8ebeSTetsuo Handa 	/*
2464c71d8ebeSTetsuo Handa 	 * If this is sendmmsg() and current destination address is same as
2465c71d8ebeSTetsuo Handa 	 * previously succeeded address, omit asking LSM's decision.
2466c71d8ebeSTetsuo Handa 	 * used_address->name_len is initialized to UINT_MAX so that the first
2467c71d8ebeSTetsuo Handa 	 * destination address never matches.
2468c71d8ebeSTetsuo Handa 	 */
2469bc909d9dSMathieu Desnoyers 	if (used_address && msg_sys->msg_name &&
2470bc909d9dSMathieu Desnoyers 	    used_address->name_len == msg_sys->msg_namelen &&
2471bc909d9dSMathieu Desnoyers 	    !memcmp(&used_address->name, msg_sys->msg_name,
2472c71d8ebeSTetsuo Handa 		    used_address->name_len)) {
2473d8725c86SAl Viro 		err = sock_sendmsg_nosec(sock, msg_sys);
2474c71d8ebeSTetsuo Handa 		goto out_freectl;
2475c71d8ebeSTetsuo Handa 	}
2476d8725c86SAl Viro 	err = sock_sendmsg(sock, msg_sys);
2477c71d8ebeSTetsuo Handa 	/*
2478c71d8ebeSTetsuo Handa 	 * If this is sendmmsg() and sending to current destination address was
2479c71d8ebeSTetsuo Handa 	 * successful, remember it.
2480c71d8ebeSTetsuo Handa 	 */
2481c71d8ebeSTetsuo Handa 	if (used_address && err >= 0) {
2482c71d8ebeSTetsuo Handa 		used_address->name_len = msg_sys->msg_namelen;
2483bc909d9dSMathieu Desnoyers 		if (msg_sys->msg_name)
2484bc909d9dSMathieu Desnoyers 			memcpy(&used_address->name, msg_sys->msg_name,
2485c71d8ebeSTetsuo Handa 			       used_address->name_len);
2486c71d8ebeSTetsuo Handa 	}
24871da177e4SLinus Torvalds 
24881da177e4SLinus Torvalds out_freectl:
24891da177e4SLinus Torvalds 	if (ctl_buf != ctl)
24901da177e4SLinus Torvalds 		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
24914257c8caSJens Axboe out:
24924257c8caSJens Axboe 	return err;
24934257c8caSJens Axboe }
24944257c8caSJens Axboe 
249503b1230cSJens Axboe int sendmsg_copy_msghdr(struct msghdr *msg,
24964257c8caSJens Axboe 			struct user_msghdr __user *umsg, unsigned flags,
24974257c8caSJens Axboe 			struct iovec **iov)
24984257c8caSJens Axboe {
24994257c8caSJens Axboe 	int err;
25004257c8caSJens Axboe 
25014257c8caSJens Axboe 	if (flags & MSG_CMSG_COMPAT) {
25024257c8caSJens Axboe 		struct compat_msghdr __user *msg_compat;
25034257c8caSJens Axboe 
25044257c8caSJens Axboe 		msg_compat = (struct compat_msghdr __user *) umsg;
25054257c8caSJens Axboe 		err = get_compat_msghdr(msg, msg_compat, NULL, iov);
25064257c8caSJens Axboe 	} else {
25074257c8caSJens Axboe 		err = copy_msghdr_from_user(msg, umsg, NULL, iov);
25084257c8caSJens Axboe 	}
25094257c8caSJens Axboe 	if (err < 0)
25104257c8caSJens Axboe 		return err;
25114257c8caSJens Axboe 
25124257c8caSJens Axboe 	return 0;
25134257c8caSJens Axboe }
25144257c8caSJens Axboe 
25154257c8caSJens Axboe static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
25164257c8caSJens Axboe 			 struct msghdr *msg_sys, unsigned int flags,
25174257c8caSJens Axboe 			 struct used_address *used_address,
25184257c8caSJens Axboe 			 unsigned int allowed_msghdr_flags)
25194257c8caSJens Axboe {
25204257c8caSJens Axboe 	struct sockaddr_storage address;
25214257c8caSJens Axboe 	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
25224257c8caSJens Axboe 	ssize_t err;
25234257c8caSJens Axboe 
25244257c8caSJens Axboe 	msg_sys->msg_name = &address;
25254257c8caSJens Axboe 
25264257c8caSJens Axboe 	err = sendmsg_copy_msghdr(msg_sys, msg, flags, &iov);
25274257c8caSJens Axboe 	if (err < 0)
25284257c8caSJens Axboe 		return err;
25294257c8caSJens Axboe 
25304257c8caSJens Axboe 	err = ____sys_sendmsg(sock, msg_sys, flags, used_address,
25314257c8caSJens Axboe 				allowed_msghdr_flags);
2532a74e9106SEric Dumazet 	kfree(iov);
2533228e548eSAnton Blanchard 	return err;
2534228e548eSAnton Blanchard }
2535228e548eSAnton Blanchard 
2536228e548eSAnton Blanchard /*
2537228e548eSAnton Blanchard  *	BSD sendmsg interface
2538228e548eSAnton Blanchard  */
253903b1230cSJens Axboe long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg,
25400fa03c62SJens Axboe 			unsigned int flags)
25410fa03c62SJens Axboe {
254203b1230cSJens Axboe 	return ____sys_sendmsg(sock, msg, flags, NULL, 0);
25430fa03c62SJens Axboe }
2544228e548eSAnton Blanchard 
2545e1834a32SDominik Brodowski long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
2546e1834a32SDominik Brodowski 		   bool forbid_cmsg_compat)
2547228e548eSAnton Blanchard {
2548228e548eSAnton Blanchard 	int fput_needed, err;
2549228e548eSAnton Blanchard 	struct msghdr msg_sys;
25501be374a0SAndy Lutomirski 	struct socket *sock;
2551228e548eSAnton Blanchard 
2552e1834a32SDominik Brodowski 	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
2553e1834a32SDominik Brodowski 		return -EINVAL;
2554e1834a32SDominik Brodowski 
25551be374a0SAndy Lutomirski 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
2556228e548eSAnton Blanchard 	if (!sock)
2557228e548eSAnton Blanchard 		goto out;
2558228e548eSAnton Blanchard 
255928a94d8fSTom Herbert 	err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0);
2560228e548eSAnton Blanchard 
25616cb153caSBenjamin LaHaise 	fput_light(sock->file, fput_needed);
25621da177e4SLinus Torvalds out:
25631da177e4SLinus Torvalds 	return err;
25641da177e4SLinus Torvalds }
25651da177e4SLinus Torvalds 
2566666547ffSAl Viro SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
2567a7526eb5SAndy Lutomirski {
2568e1834a32SDominik Brodowski 	return __sys_sendmsg(fd, msg, flags, true);
2569a7526eb5SAndy Lutomirski }
2570a7526eb5SAndy Lutomirski 
2571228e548eSAnton Blanchard /*
2572228e548eSAnton Blanchard  *	Linux sendmmsg interface
2573228e548eSAnton Blanchard  */
2574228e548eSAnton Blanchard 
2575228e548eSAnton Blanchard int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2576e1834a32SDominik Brodowski 		   unsigned int flags, bool forbid_cmsg_compat)
2577228e548eSAnton Blanchard {
2578228e548eSAnton Blanchard 	int fput_needed, err, datagrams;
2579228e548eSAnton Blanchard 	struct socket *sock;
2580228e548eSAnton Blanchard 	struct mmsghdr __user *entry;
2581228e548eSAnton Blanchard 	struct compat_mmsghdr __user *compat_entry;
2582228e548eSAnton Blanchard 	struct msghdr msg_sys;
2583c71d8ebeSTetsuo Handa 	struct used_address used_address;
2584f092276dSTom Herbert 	unsigned int oflags = flags;
2585228e548eSAnton Blanchard 
2586e1834a32SDominik Brodowski 	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
2587e1834a32SDominik Brodowski 		return -EINVAL;
2588e1834a32SDominik Brodowski 
258998382f41SAnton Blanchard 	if (vlen > UIO_MAXIOV)
259098382f41SAnton Blanchard 		vlen = UIO_MAXIOV;
2591228e548eSAnton Blanchard 
2592228e548eSAnton Blanchard 	datagrams = 0;
2593228e548eSAnton Blanchard 
2594228e548eSAnton Blanchard 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
2595228e548eSAnton Blanchard 	if (!sock)
2596228e548eSAnton Blanchard 		return err;
2597228e548eSAnton Blanchard 
2598c71d8ebeSTetsuo Handa 	used_address.name_len = UINT_MAX;
2599228e548eSAnton Blanchard 	entry = mmsg;
2600228e548eSAnton Blanchard 	compat_entry = (struct compat_mmsghdr __user *)mmsg;
2601728ffb86SAnton Blanchard 	err = 0;
2602f092276dSTom Herbert 	flags |= MSG_BATCH;
2603228e548eSAnton Blanchard 
2604228e548eSAnton Blanchard 	while (datagrams < vlen) {
2605f092276dSTom Herbert 		if (datagrams == vlen - 1)
2606f092276dSTom Herbert 			flags = oflags;
2607f092276dSTom Herbert 
2608228e548eSAnton Blanchard 		if (MSG_CMSG_COMPAT & flags) {
2609666547ffSAl Viro 			err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry,
261028a94d8fSTom Herbert 					     &msg_sys, flags, &used_address, MSG_EOR);
2611228e548eSAnton Blanchard 			if (err < 0)
2612228e548eSAnton Blanchard 				break;
2613228e548eSAnton Blanchard 			err = __put_user(err, &compat_entry->msg_len);
2614228e548eSAnton Blanchard 			++compat_entry;
2615228e548eSAnton Blanchard 		} else {
2616a7526eb5SAndy Lutomirski 			err = ___sys_sendmsg(sock,
2617666547ffSAl Viro 					     (struct user_msghdr __user *)entry,
261828a94d8fSTom Herbert 					     &msg_sys, flags, &used_address, MSG_EOR);
2619228e548eSAnton Blanchard 			if (err < 0)
2620228e548eSAnton Blanchard 				break;
2621228e548eSAnton Blanchard 			err = put_user(err, &entry->msg_len);
2622228e548eSAnton Blanchard 			++entry;
2623228e548eSAnton Blanchard 		}
2624228e548eSAnton Blanchard 
2625228e548eSAnton Blanchard 		if (err)
2626228e548eSAnton Blanchard 			break;
2627228e548eSAnton Blanchard 		++datagrams;
26283023898bSSoheil Hassas Yeganeh 		if (msg_data_left(&msg_sys))
26293023898bSSoheil Hassas Yeganeh 			break;
2630a78cb84cSEric Dumazet 		cond_resched();
2631228e548eSAnton Blanchard 	}
2632228e548eSAnton Blanchard 
2633228e548eSAnton Blanchard 	fput_light(sock->file, fput_needed);
2634228e548eSAnton Blanchard 
2635728ffb86SAnton Blanchard 	/* We only return an error if no datagrams were able to be sent */
2636728ffb86SAnton Blanchard 	if (datagrams != 0)
2637228e548eSAnton Blanchard 		return datagrams;
2638228e548eSAnton Blanchard 
2639228e548eSAnton Blanchard 	return err;
2640228e548eSAnton Blanchard }
2641228e548eSAnton Blanchard 
2642228e548eSAnton Blanchard SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
2643228e548eSAnton Blanchard 		unsigned int, vlen, unsigned int, flags)
2644228e548eSAnton Blanchard {
2645e1834a32SDominik Brodowski 	return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
2646228e548eSAnton Blanchard }
2647228e548eSAnton Blanchard 
264803b1230cSJens Axboe int recvmsg_copy_msghdr(struct msghdr *msg,
26494257c8caSJens Axboe 			struct user_msghdr __user *umsg, unsigned flags,
26504257c8caSJens Axboe 			struct sockaddr __user **uaddr,
26514257c8caSJens Axboe 			struct iovec **iov)
26524257c8caSJens Axboe {
26534257c8caSJens Axboe 	ssize_t err;
26544257c8caSJens Axboe 
26554257c8caSJens Axboe 	if (MSG_CMSG_COMPAT & flags) {
26564257c8caSJens Axboe 		struct compat_msghdr __user *msg_compat;
26574257c8caSJens Axboe 
26584257c8caSJens Axboe 		msg_compat = (struct compat_msghdr __user *) umsg;
26594257c8caSJens Axboe 		err = get_compat_msghdr(msg, msg_compat, uaddr, iov);
26604257c8caSJens Axboe 	} else {
26614257c8caSJens Axboe 		err = copy_msghdr_from_user(msg, umsg, uaddr, iov);
26624257c8caSJens Axboe 	}
26634257c8caSJens Axboe 	if (err < 0)
26644257c8caSJens Axboe 		return err;
26654257c8caSJens Axboe 
26664257c8caSJens Axboe 	return 0;
26674257c8caSJens Axboe }
26684257c8caSJens Axboe 
26694257c8caSJens Axboe static int ____sys_recvmsg(struct socket *sock, struct msghdr *msg_sys,
26704257c8caSJens Axboe 			   struct user_msghdr __user *msg,
26714257c8caSJens Axboe 			   struct sockaddr __user *uaddr,
26724257c8caSJens Axboe 			   unsigned int flags, int nosec)
26731da177e4SLinus Torvalds {
267489bddce5SStephen Hemminger 	struct compat_msghdr __user *msg_compat =
267589bddce5SStephen Hemminger 					(struct compat_msghdr __user *) msg;
26764257c8caSJens Axboe 	int __user *uaddr_len = COMPAT_NAMELEN(msg);
26774257c8caSJens Axboe 	struct sockaddr_storage addr;
26781da177e4SLinus Torvalds 	unsigned long cmsg_ptr;
26792da62906SAl Viro 	int len;
268008adb7daSAl Viro 	ssize_t err;
26811da177e4SLinus Torvalds 
268208adb7daSAl Viro 	msg_sys->msg_name = &addr;
2683a2e27255SArnaldo Carvalho de Melo 	cmsg_ptr = (unsigned long)msg_sys->msg_control;
2684a2e27255SArnaldo Carvalho de Melo 	msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
26851da177e4SLinus Torvalds 
2686f3d33426SHannes Frederic Sowa 	/* We assume all kernel code knows the size of sockaddr_storage */
2687f3d33426SHannes Frederic Sowa 	msg_sys->msg_namelen = 0;
2688f3d33426SHannes Frederic Sowa 
26891da177e4SLinus Torvalds 	if (sock->file->f_flags & O_NONBLOCK)
26901da177e4SLinus Torvalds 		flags |= MSG_DONTWAIT;
26911af66221SEric Dumazet 
26921af66221SEric Dumazet 	if (unlikely(nosec))
26931af66221SEric Dumazet 		err = sock_recvmsg_nosec(sock, msg_sys, flags);
26941af66221SEric Dumazet 	else
26951af66221SEric Dumazet 		err = sock_recvmsg(sock, msg_sys, flags);
26961af66221SEric Dumazet 
26971da177e4SLinus Torvalds 	if (err < 0)
26984257c8caSJens Axboe 		goto out;
26991da177e4SLinus Torvalds 	len = err;
27001da177e4SLinus Torvalds 
27011da177e4SLinus Torvalds 	if (uaddr != NULL) {
270243db362dSMaciej Żenczykowski 		err = move_addr_to_user(&addr,
2703a2e27255SArnaldo Carvalho de Melo 					msg_sys->msg_namelen, uaddr,
270489bddce5SStephen Hemminger 					uaddr_len);
27051da177e4SLinus Torvalds 		if (err < 0)
27064257c8caSJens Axboe 			goto out;
27071da177e4SLinus Torvalds 	}
2708a2e27255SArnaldo Carvalho de Melo 	err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
270937f7f421SDavid S. Miller 			 COMPAT_FLAGS(msg));
27101da177e4SLinus Torvalds 	if (err)
27114257c8caSJens Axboe 		goto out;
27121da177e4SLinus Torvalds 	if (MSG_CMSG_COMPAT & flags)
2713a2e27255SArnaldo Carvalho de Melo 		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
27141da177e4SLinus Torvalds 				 &msg_compat->msg_controllen);
27151da177e4SLinus Torvalds 	else
2716a2e27255SArnaldo Carvalho de Melo 		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
27171da177e4SLinus Torvalds 				 &msg->msg_controllen);
27181da177e4SLinus Torvalds 	if (err)
27194257c8caSJens Axboe 		goto out;
27201da177e4SLinus Torvalds 	err = len;
27214257c8caSJens Axboe out:
27224257c8caSJens Axboe 	return err;
27234257c8caSJens Axboe }
27241da177e4SLinus Torvalds 
27254257c8caSJens Axboe static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
27264257c8caSJens Axboe 			 struct msghdr *msg_sys, unsigned int flags, int nosec)
27274257c8caSJens Axboe {
27284257c8caSJens Axboe 	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
27294257c8caSJens Axboe 	/* user mode address pointers */
27304257c8caSJens Axboe 	struct sockaddr __user *uaddr;
27314257c8caSJens Axboe 	ssize_t err;
27324257c8caSJens Axboe 
27334257c8caSJens Axboe 	err = recvmsg_copy_msghdr(msg_sys, msg, flags, &uaddr, &iov);
27344257c8caSJens Axboe 	if (err < 0)
27354257c8caSJens Axboe 		return err;
27364257c8caSJens Axboe 
27374257c8caSJens Axboe 	err = ____sys_recvmsg(sock, msg_sys, msg, uaddr, flags, nosec);
2738a74e9106SEric Dumazet 	kfree(iov);
2739a2e27255SArnaldo Carvalho de Melo 	return err;
2740a2e27255SArnaldo Carvalho de Melo }
2741a2e27255SArnaldo Carvalho de Melo 
2742a2e27255SArnaldo Carvalho de Melo /*
2743a2e27255SArnaldo Carvalho de Melo  *	BSD recvmsg interface
2744a2e27255SArnaldo Carvalho de Melo  */
2745a2e27255SArnaldo Carvalho de Melo 
274603b1230cSJens Axboe long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
274703b1230cSJens Axboe 			struct user_msghdr __user *umsg,
274803b1230cSJens Axboe 			struct sockaddr __user *uaddr, unsigned int flags)
2749aa1fa28fSJens Axboe {
275003b1230cSJens Axboe 	return ____sys_recvmsg(sock, msg, umsg, uaddr, flags, 0);
2751aa1fa28fSJens Axboe }
2752aa1fa28fSJens Axboe 
2753e1834a32SDominik Brodowski long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
2754e1834a32SDominik Brodowski 		   bool forbid_cmsg_compat)
2755a2e27255SArnaldo Carvalho de Melo {
2756a2e27255SArnaldo Carvalho de Melo 	int fput_needed, err;
2757a2e27255SArnaldo Carvalho de Melo 	struct msghdr msg_sys;
27581be374a0SAndy Lutomirski 	struct socket *sock;
2759a2e27255SArnaldo Carvalho de Melo 
2760e1834a32SDominik Brodowski 	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
2761e1834a32SDominik Brodowski 		return -EINVAL;
2762e1834a32SDominik Brodowski 
27631be374a0SAndy Lutomirski 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
2764a2e27255SArnaldo Carvalho de Melo 	if (!sock)
2765a2e27255SArnaldo Carvalho de Melo 		goto out;
2766a2e27255SArnaldo Carvalho de Melo 
2767a7526eb5SAndy Lutomirski 	err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
2768a2e27255SArnaldo Carvalho de Melo 
27696cb153caSBenjamin LaHaise 	fput_light(sock->file, fput_needed);
27701da177e4SLinus Torvalds out:
27711da177e4SLinus Torvalds 	return err;
27721da177e4SLinus Torvalds }
27731da177e4SLinus Torvalds 
2774666547ffSAl Viro SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
2775a7526eb5SAndy Lutomirski 		unsigned int, flags)
2776a7526eb5SAndy Lutomirski {
2777e1834a32SDominik Brodowski 	return __sys_recvmsg(fd, msg, flags, true);
2778a7526eb5SAndy Lutomirski }
2779a7526eb5SAndy Lutomirski 
2780a2e27255SArnaldo Carvalho de Melo /*
2781a2e27255SArnaldo Carvalho de Melo  *     Linux recvmmsg interface
2782a2e27255SArnaldo Carvalho de Melo  */
27831da177e4SLinus Torvalds 
2784e11d4284SArnd Bergmann static int do_recvmmsg(int fd, struct mmsghdr __user *mmsg,
2785e11d4284SArnd Bergmann 			  unsigned int vlen, unsigned int flags,
2786e11d4284SArnd Bergmann 			  struct timespec64 *timeout)
2787a2e27255SArnaldo Carvalho de Melo {
2788a2e27255SArnaldo Carvalho de Melo 	int fput_needed, err, datagrams;
2789a2e27255SArnaldo Carvalho de Melo 	struct socket *sock;
2790a2e27255SArnaldo Carvalho de Melo 	struct mmsghdr __user *entry;
2791d7256d0eSJean-Mickael Guerin 	struct compat_mmsghdr __user *compat_entry;
2792a2e27255SArnaldo Carvalho de Melo 	struct msghdr msg_sys;
2793766b9f92SDeepa Dinamani 	struct timespec64 end_time;
2794766b9f92SDeepa Dinamani 	struct timespec64 timeout64;
2795a2e27255SArnaldo Carvalho de Melo 
2796a2e27255SArnaldo Carvalho de Melo 	if (timeout &&
2797a2e27255SArnaldo Carvalho de Melo 	    poll_select_set_timeout(&end_time, timeout->tv_sec,
2798a2e27255SArnaldo Carvalho de Melo 				    timeout->tv_nsec))
2799a2e27255SArnaldo Carvalho de Melo 		return -EINVAL;
2800a2e27255SArnaldo Carvalho de Melo 
2801a2e27255SArnaldo Carvalho de Melo 	datagrams = 0;
2802a2e27255SArnaldo Carvalho de Melo 
2803a2e27255SArnaldo Carvalho de Melo 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
2804a2e27255SArnaldo Carvalho de Melo 	if (!sock)
2805a2e27255SArnaldo Carvalho de Melo 		return err;
2806a2e27255SArnaldo Carvalho de Melo 
28077797dc41SSoheil Hassas Yeganeh 	if (likely(!(flags & MSG_ERRQUEUE))) {
2808a2e27255SArnaldo Carvalho de Melo 		err = sock_error(sock->sk);
2809e623a9e9SMaxime Jayat 		if (err) {
2810e623a9e9SMaxime Jayat 			datagrams = err;
2811a2e27255SArnaldo Carvalho de Melo 			goto out_put;
2812e623a9e9SMaxime Jayat 		}
28137797dc41SSoheil Hassas Yeganeh 	}
2814a2e27255SArnaldo Carvalho de Melo 
2815a2e27255SArnaldo Carvalho de Melo 	entry = mmsg;
2816d7256d0eSJean-Mickael Guerin 	compat_entry = (struct compat_mmsghdr __user *)mmsg;
2817a2e27255SArnaldo Carvalho de Melo 
2818a2e27255SArnaldo Carvalho de Melo 	while (datagrams < vlen) {
2819a2e27255SArnaldo Carvalho de Melo 		/*
2820a2e27255SArnaldo Carvalho de Melo 		 * No need to ask LSM for more than the first datagram.
2821a2e27255SArnaldo Carvalho de Melo 		 */
2822d7256d0eSJean-Mickael Guerin 		if (MSG_CMSG_COMPAT & flags) {
2823666547ffSAl Viro 			err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry,
2824b9eb8b87SAnton Blanchard 					     &msg_sys, flags & ~MSG_WAITFORONE,
2825b9eb8b87SAnton Blanchard 					     datagrams);
2826d7256d0eSJean-Mickael Guerin 			if (err < 0)
2827d7256d0eSJean-Mickael Guerin 				break;
2828d7256d0eSJean-Mickael Guerin 			err = __put_user(err, &compat_entry->msg_len);
2829d7256d0eSJean-Mickael Guerin 			++compat_entry;
2830d7256d0eSJean-Mickael Guerin 		} else {
2831a7526eb5SAndy Lutomirski 			err = ___sys_recvmsg(sock,
2832666547ffSAl Viro 					     (struct user_msghdr __user *)entry,
2833b9eb8b87SAnton Blanchard 					     &msg_sys, flags & ~MSG_WAITFORONE,
2834b9eb8b87SAnton Blanchard 					     datagrams);
2835a2e27255SArnaldo Carvalho de Melo 			if (err < 0)
2836a2e27255SArnaldo Carvalho de Melo 				break;
2837a2e27255SArnaldo Carvalho de Melo 			err = put_user(err, &entry->msg_len);
2838d7256d0eSJean-Mickael Guerin 			++entry;
2839d7256d0eSJean-Mickael Guerin 		}
2840d7256d0eSJean-Mickael Guerin 
2841a2e27255SArnaldo Carvalho de Melo 		if (err)
2842a2e27255SArnaldo Carvalho de Melo 			break;
2843a2e27255SArnaldo Carvalho de Melo 		++datagrams;
2844a2e27255SArnaldo Carvalho de Melo 
284571c5c159SBrandon L Black 		/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
284671c5c159SBrandon L Black 		if (flags & MSG_WAITFORONE)
284771c5c159SBrandon L Black 			flags |= MSG_DONTWAIT;
284871c5c159SBrandon L Black 
2849a2e27255SArnaldo Carvalho de Melo 		if (timeout) {
2850766b9f92SDeepa Dinamani 			ktime_get_ts64(&timeout64);
2851c2e6c856SArnd Bergmann 			*timeout = timespec64_sub(end_time, timeout64);
2852a2e27255SArnaldo Carvalho de Melo 			if (timeout->tv_sec < 0) {
2853a2e27255SArnaldo Carvalho de Melo 				timeout->tv_sec = timeout->tv_nsec = 0;
2854a2e27255SArnaldo Carvalho de Melo 				break;
2855a2e27255SArnaldo Carvalho de Melo 			}
2856a2e27255SArnaldo Carvalho de Melo 
2857a2e27255SArnaldo Carvalho de Melo 			/* Timeout, return less than vlen datagrams */
2858a2e27255SArnaldo Carvalho de Melo 			if (timeout->tv_nsec == 0 && timeout->tv_sec == 0)
2859a2e27255SArnaldo Carvalho de Melo 				break;
2860a2e27255SArnaldo Carvalho de Melo 		}
2861a2e27255SArnaldo Carvalho de Melo 
2862a2e27255SArnaldo Carvalho de Melo 		/* Out of band data, return right away */
2863a2e27255SArnaldo Carvalho de Melo 		if (msg_sys.msg_flags & MSG_OOB)
2864a2e27255SArnaldo Carvalho de Melo 			break;
2865a78cb84cSEric Dumazet 		cond_resched();
2866a2e27255SArnaldo Carvalho de Melo 	}
2867a2e27255SArnaldo Carvalho de Melo 
2868a2e27255SArnaldo Carvalho de Melo 	if (err == 0)
286934b88a68SArnaldo Carvalho de Melo 		goto out_put;
2870a2e27255SArnaldo Carvalho de Melo 
287134b88a68SArnaldo Carvalho de Melo 	if (datagrams == 0) {
287234b88a68SArnaldo Carvalho de Melo 		datagrams = err;
287334b88a68SArnaldo Carvalho de Melo 		goto out_put;
287434b88a68SArnaldo Carvalho de Melo 	}
287534b88a68SArnaldo Carvalho de Melo 
2876a2e27255SArnaldo Carvalho de Melo 	/*
2877a2e27255SArnaldo Carvalho de Melo 	 * We may return less entries than requested (vlen) if the
2878a2e27255SArnaldo Carvalho de Melo 	 * sock is non block and there aren't enough datagrams...
2879a2e27255SArnaldo Carvalho de Melo 	 */
2880a2e27255SArnaldo Carvalho de Melo 	if (err != -EAGAIN) {
2881a2e27255SArnaldo Carvalho de Melo 		/*
2882a2e27255SArnaldo Carvalho de Melo 		 * ... or  if recvmsg returns an error after we
2883a2e27255SArnaldo Carvalho de Melo 		 * received some datagrams, where we record the
2884a2e27255SArnaldo Carvalho de Melo 		 * error to return on the next call or if the
2885a2e27255SArnaldo Carvalho de Melo 		 * app asks about it using getsockopt(SO_ERROR).
2886a2e27255SArnaldo Carvalho de Melo 		 */
2887a2e27255SArnaldo Carvalho de Melo 		sock->sk->sk_err = -err;
2888a2e27255SArnaldo Carvalho de Melo 	}
288934b88a68SArnaldo Carvalho de Melo out_put:
289034b88a68SArnaldo Carvalho de Melo 	fput_light(sock->file, fput_needed);
2891a2e27255SArnaldo Carvalho de Melo 
2892a2e27255SArnaldo Carvalho de Melo 	return datagrams;
2893a2e27255SArnaldo Carvalho de Melo }
2894a2e27255SArnaldo Carvalho de Melo 
2895e11d4284SArnd Bergmann int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
28961255e269SDominik Brodowski 		   unsigned int vlen, unsigned int flags,
2897e11d4284SArnd Bergmann 		   struct __kernel_timespec __user *timeout,
2898e11d4284SArnd Bergmann 		   struct old_timespec32 __user *timeout32)
2899a2e27255SArnaldo Carvalho de Melo {
2900a2e27255SArnaldo Carvalho de Melo 	int datagrams;
2901c2e6c856SArnd Bergmann 	struct timespec64 timeout_sys;
2902a2e27255SArnaldo Carvalho de Melo 
2903e11d4284SArnd Bergmann 	if (timeout && get_timespec64(&timeout_sys, timeout))
2904a2e27255SArnaldo Carvalho de Melo 		return -EFAULT;
2905a2e27255SArnaldo Carvalho de Melo 
2906e11d4284SArnd Bergmann 	if (timeout32 && get_old_timespec32(&timeout_sys, timeout32))
2907e11d4284SArnd Bergmann 		return -EFAULT;
2908a2e27255SArnaldo Carvalho de Melo 
2909e11d4284SArnd Bergmann 	if (!timeout && !timeout32)
2910e11d4284SArnd Bergmann 		return do_recvmmsg(fd, mmsg, vlen, flags, NULL);
2911e11d4284SArnd Bergmann 
2912e11d4284SArnd Bergmann 	datagrams = do_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys);
2913e11d4284SArnd Bergmann 
2914e11d4284SArnd Bergmann 	if (datagrams <= 0)
2915e11d4284SArnd Bergmann 		return datagrams;
2916e11d4284SArnd Bergmann 
2917e11d4284SArnd Bergmann 	if (timeout && put_timespec64(&timeout_sys, timeout))
2918e11d4284SArnd Bergmann 		datagrams = -EFAULT;
2919e11d4284SArnd Bergmann 
2920e11d4284SArnd Bergmann 	if (timeout32 && put_old_timespec32(&timeout_sys, timeout32))
2921a2e27255SArnaldo Carvalho de Melo 		datagrams = -EFAULT;
2922a2e27255SArnaldo Carvalho de Melo 
2923a2e27255SArnaldo Carvalho de Melo 	return datagrams;
2924a2e27255SArnaldo Carvalho de Melo }
2925a2e27255SArnaldo Carvalho de Melo 
29261255e269SDominik Brodowski SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
29271255e269SDominik Brodowski 		unsigned int, vlen, unsigned int, flags,
2928c2e6c856SArnd Bergmann 		struct __kernel_timespec __user *, timeout)
29291255e269SDominik Brodowski {
2930e11d4284SArnd Bergmann 	if (flags & MSG_CMSG_COMPAT)
2931e11d4284SArnd Bergmann 		return -EINVAL;
2932e11d4284SArnd Bergmann 
2933e11d4284SArnd Bergmann 	return __sys_recvmmsg(fd, mmsg, vlen, flags, timeout, NULL);
29341255e269SDominik Brodowski }
29351255e269SDominik Brodowski 
2936e11d4284SArnd Bergmann #ifdef CONFIG_COMPAT_32BIT_TIME
2937e11d4284SArnd Bergmann SYSCALL_DEFINE5(recvmmsg_time32, int, fd, struct mmsghdr __user *, mmsg,
2938e11d4284SArnd Bergmann 		unsigned int, vlen, unsigned int, flags,
2939e11d4284SArnd Bergmann 		struct old_timespec32 __user *, timeout)
2940e11d4284SArnd Bergmann {
2941e11d4284SArnd Bergmann 	if (flags & MSG_CMSG_COMPAT)
2942e11d4284SArnd Bergmann 		return -EINVAL;
2943e11d4284SArnd Bergmann 
2944e11d4284SArnd Bergmann 	return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL, timeout);
2945e11d4284SArnd Bergmann }
2946e11d4284SArnd Bergmann #endif
2947e11d4284SArnd Bergmann 
2948a2e27255SArnaldo Carvalho de Melo #ifdef __ARCH_WANT_SYS_SOCKETCALL
29491da177e4SLinus Torvalds /* Argument list sizes for sys_socketcall */
29501da177e4SLinus Torvalds #define AL(x) ((x) * sizeof(unsigned long))
2951228e548eSAnton Blanchard static const unsigned char nargs[21] = {
295289bddce5SStephen Hemminger 	AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
29531da177e4SLinus Torvalds 	AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
2954aaca0bdcSUlrich Drepper 	AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
2955228e548eSAnton Blanchard 	AL(4), AL(5), AL(4)
295689bddce5SStephen Hemminger };
295789bddce5SStephen Hemminger 
29581da177e4SLinus Torvalds #undef AL
29591da177e4SLinus Torvalds 
29601da177e4SLinus Torvalds /*
29611da177e4SLinus Torvalds  *	System call vectors.
29621da177e4SLinus Torvalds  *
29631da177e4SLinus Torvalds  *	Argument checking cleaned up. Saved 20% in size.
29641da177e4SLinus Torvalds  *  This function doesn't need to set the kernel lock because
29651da177e4SLinus Torvalds  *  it is set by the callees.
29661da177e4SLinus Torvalds  */
29671da177e4SLinus Torvalds 
29683e0fa65fSHeiko Carstens SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
29691da177e4SLinus Torvalds {
29702950fa9dSChen Gang 	unsigned long a[AUDITSC_ARGS];
29711da177e4SLinus Torvalds 	unsigned long a0, a1;
29721da177e4SLinus Torvalds 	int err;
297347379052SArjan van de Ven 	unsigned int len;
29741da177e4SLinus Torvalds 
2975228e548eSAnton Blanchard 	if (call < 1 || call > SYS_SENDMMSG)
29761da177e4SLinus Torvalds 		return -EINVAL;
2977c8e8cd57SJeremy Cline 	call = array_index_nospec(call, SYS_SENDMMSG + 1);
29781da177e4SLinus Torvalds 
297947379052SArjan van de Ven 	len = nargs[call];
298047379052SArjan van de Ven 	if (len > sizeof(a))
298147379052SArjan van de Ven 		return -EINVAL;
298247379052SArjan van de Ven 
29831da177e4SLinus Torvalds 	/* copy_from_user should be SMP safe. */
298447379052SArjan van de Ven 	if (copy_from_user(a, args, len))
29851da177e4SLinus Torvalds 		return -EFAULT;
29861da177e4SLinus Torvalds 
29872950fa9dSChen Gang 	err = audit_socketcall(nargs[call] / sizeof(unsigned long), a);
29882950fa9dSChen Gang 	if (err)
29892950fa9dSChen Gang 		return err;
29903ec3b2fbSDavid Woodhouse 
29911da177e4SLinus Torvalds 	a0 = a[0];
29921da177e4SLinus Torvalds 	a1 = a[1];
29931da177e4SLinus Torvalds 
299489bddce5SStephen Hemminger 	switch (call) {
29951da177e4SLinus Torvalds 	case SYS_SOCKET:
29969d6a15c3SDominik Brodowski 		err = __sys_socket(a0, a1, a[2]);
29971da177e4SLinus Torvalds 		break;
29981da177e4SLinus Torvalds 	case SYS_BIND:
2999a87d35d8SDominik Brodowski 		err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
30001da177e4SLinus Torvalds 		break;
30011da177e4SLinus Torvalds 	case SYS_CONNECT:
30021387c2c2SDominik Brodowski 		err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
30031da177e4SLinus Torvalds 		break;
30041da177e4SLinus Torvalds 	case SYS_LISTEN:
300525e290eeSDominik Brodowski 		err = __sys_listen(a0, a1);
30061da177e4SLinus Torvalds 		break;
30071da177e4SLinus Torvalds 	case SYS_ACCEPT:
30084541e805SDominik Brodowski 		err = __sys_accept4(a0, (struct sockaddr __user *)a1,
3009aaca0bdcSUlrich Drepper 				    (int __user *)a[2], 0);
30101da177e4SLinus Torvalds 		break;
30111da177e4SLinus Torvalds 	case SYS_GETSOCKNAME:
301289bddce5SStephen Hemminger 		err =
30138882a107SDominik Brodowski 		    __sys_getsockname(a0, (struct sockaddr __user *)a1,
301489bddce5SStephen Hemminger 				      (int __user *)a[2]);
30151da177e4SLinus Torvalds 		break;
30161da177e4SLinus Torvalds 	case SYS_GETPEERNAME:
301789bddce5SStephen Hemminger 		err =
3018b21c8f83SDominik Brodowski 		    __sys_getpeername(a0, (struct sockaddr __user *)a1,
301989bddce5SStephen Hemminger 				      (int __user *)a[2]);
30201da177e4SLinus Torvalds 		break;
30211da177e4SLinus Torvalds 	case SYS_SOCKETPAIR:
30226debc8d8SDominik Brodowski 		err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
30231da177e4SLinus Torvalds 		break;
30241da177e4SLinus Torvalds 	case SYS_SEND:
3025f3bf896bSDominik Brodowski 		err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
3026f3bf896bSDominik Brodowski 				   NULL, 0);
30271da177e4SLinus Torvalds 		break;
30281da177e4SLinus Torvalds 	case SYS_SENDTO:
3029211b634bSDominik Brodowski 		err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
30301da177e4SLinus Torvalds 				   (struct sockaddr __user *)a[4], a[5]);
30311da177e4SLinus Torvalds 		break;
30321da177e4SLinus Torvalds 	case SYS_RECV:
3033d27e9afcSDominik Brodowski 		err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
3034d27e9afcSDominik Brodowski 				     NULL, NULL);
30351da177e4SLinus Torvalds 		break;
30361da177e4SLinus Torvalds 	case SYS_RECVFROM:
30377a09e1ebSDominik Brodowski 		err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
303889bddce5SStephen Hemminger 				     (struct sockaddr __user *)a[4],
303989bddce5SStephen Hemminger 				     (int __user *)a[5]);
30401da177e4SLinus Torvalds 		break;
30411da177e4SLinus Torvalds 	case SYS_SHUTDOWN:
3042005a1aeaSDominik Brodowski 		err = __sys_shutdown(a0, a1);
30431da177e4SLinus Torvalds 		break;
30441da177e4SLinus Torvalds 	case SYS_SETSOCKOPT:
3045cc36dca0SDominik Brodowski 		err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3],
3046cc36dca0SDominik Brodowski 				       a[4]);
30471da177e4SLinus Torvalds 		break;
30481da177e4SLinus Torvalds 	case SYS_GETSOCKOPT:
304989bddce5SStephen Hemminger 		err =
305013a2d70eSDominik Brodowski 		    __sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
305189bddce5SStephen Hemminger 				     (int __user *)a[4]);
30521da177e4SLinus Torvalds 		break;
30531da177e4SLinus Torvalds 	case SYS_SENDMSG:
3054e1834a32SDominik Brodowski 		err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1,
3055e1834a32SDominik Brodowski 				    a[2], true);
30561da177e4SLinus Torvalds 		break;
3057228e548eSAnton Blanchard 	case SYS_SENDMMSG:
3058e1834a32SDominik Brodowski 		err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2],
3059e1834a32SDominik Brodowski 				     a[3], true);
3060228e548eSAnton Blanchard 		break;
30611da177e4SLinus Torvalds 	case SYS_RECVMSG:
3062e1834a32SDominik Brodowski 		err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1,
3063e1834a32SDominik Brodowski 				    a[2], true);
30641da177e4SLinus Torvalds 		break;
3065a2e27255SArnaldo Carvalho de Melo 	case SYS_RECVMMSG:
30663ca47e95SArnd Bergmann 		if (IS_ENABLED(CONFIG_64BIT))
3067e11d4284SArnd Bergmann 			err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1,
3068e11d4284SArnd Bergmann 					     a[2], a[3],
3069e11d4284SArnd Bergmann 					     (struct __kernel_timespec __user *)a[4],
3070e11d4284SArnd Bergmann 					     NULL);
3071e11d4284SArnd Bergmann 		else
3072e11d4284SArnd Bergmann 			err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1,
3073e11d4284SArnd Bergmann 					     a[2], a[3], NULL,
3074e11d4284SArnd Bergmann 					     (struct old_timespec32 __user *)a[4]);
3075a2e27255SArnaldo Carvalho de Melo 		break;
3076de11defeSUlrich Drepper 	case SYS_ACCEPT4:
30774541e805SDominik Brodowski 		err = __sys_accept4(a0, (struct sockaddr __user *)a1,
3078de11defeSUlrich Drepper 				    (int __user *)a[2], a[3]);
3079aaca0bdcSUlrich Drepper 		break;
30801da177e4SLinus Torvalds 	default:
30811da177e4SLinus Torvalds 		err = -EINVAL;
30821da177e4SLinus Torvalds 		break;
30831da177e4SLinus Torvalds 	}
30841da177e4SLinus Torvalds 	return err;
30851da177e4SLinus Torvalds }
30861da177e4SLinus Torvalds 
30871da177e4SLinus Torvalds #endif				/* __ARCH_WANT_SYS_SOCKETCALL */
30881da177e4SLinus Torvalds 
308955737fdaSStephen Hemminger /**
309055737fdaSStephen Hemminger  *	sock_register - add a socket protocol handler
309155737fdaSStephen Hemminger  *	@ops: description of protocol
309255737fdaSStephen Hemminger  *
30931da177e4SLinus Torvalds  *	This function is called by a protocol handler that wants to
30941da177e4SLinus Torvalds  *	advertise its address family, and have it linked into the
3095e793c0f7SMasanari Iida  *	socket interface. The value ops->family corresponds to the
309655737fdaSStephen Hemminger  *	socket system call protocol family.
30971da177e4SLinus Torvalds  */
3098f0fd27d4SStephen Hemminger int sock_register(const struct net_proto_family *ops)
30991da177e4SLinus Torvalds {
31001da177e4SLinus Torvalds 	int err;
31011da177e4SLinus Torvalds 
31021da177e4SLinus Torvalds 	if (ops->family >= NPROTO) {
31033410f22eSYang Yingliang 		pr_crit("protocol %d >= NPROTO(%d)\n", ops->family, NPROTO);
31041da177e4SLinus Torvalds 		return -ENOBUFS;
31051da177e4SLinus Torvalds 	}
310655737fdaSStephen Hemminger 
310755737fdaSStephen Hemminger 	spin_lock(&net_family_lock);
3108190683a9SEric Dumazet 	if (rcu_dereference_protected(net_families[ops->family],
3109190683a9SEric Dumazet 				      lockdep_is_held(&net_family_lock)))
31101da177e4SLinus Torvalds 		err = -EEXIST;
311155737fdaSStephen Hemminger 	else {
3112cf778b00SEric Dumazet 		rcu_assign_pointer(net_families[ops->family], ops);
31131da177e4SLinus Torvalds 		err = 0;
31141da177e4SLinus Torvalds 	}
311555737fdaSStephen Hemminger 	spin_unlock(&net_family_lock);
311655737fdaSStephen Hemminger 
3117fe0bdbdeSYejune Deng 	pr_info("NET: Registered %s protocol family\n", pf_family_names[ops->family]);
31181da177e4SLinus Torvalds 	return err;
31191da177e4SLinus Torvalds }
3120c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_register);
31211da177e4SLinus Torvalds 
312255737fdaSStephen Hemminger /**
312355737fdaSStephen Hemminger  *	sock_unregister - remove a protocol handler
312455737fdaSStephen Hemminger  *	@family: protocol family to remove
312555737fdaSStephen Hemminger  *
31261da177e4SLinus Torvalds  *	This function is called by a protocol handler that wants to
31271da177e4SLinus Torvalds  *	remove its address family, and have it unlinked from the
312855737fdaSStephen Hemminger  *	new socket creation.
312955737fdaSStephen Hemminger  *
313055737fdaSStephen Hemminger  *	If protocol handler is a module, then it can use module reference
313155737fdaSStephen Hemminger  *	counts to protect against new references. If protocol handler is not
313255737fdaSStephen Hemminger  *	a module then it needs to provide its own protection in
313355737fdaSStephen Hemminger  *	the ops->create routine.
31341da177e4SLinus Torvalds  */
3135f0fd27d4SStephen Hemminger void sock_unregister(int family)
31361da177e4SLinus Torvalds {
3137f0fd27d4SStephen Hemminger 	BUG_ON(family < 0 || family >= NPROTO);
31381da177e4SLinus Torvalds 
313955737fdaSStephen Hemminger 	spin_lock(&net_family_lock);
3140a9b3cd7fSStephen Hemminger 	RCU_INIT_POINTER(net_families[family], NULL);
314155737fdaSStephen Hemminger 	spin_unlock(&net_family_lock);
314255737fdaSStephen Hemminger 
314355737fdaSStephen Hemminger 	synchronize_rcu();
314455737fdaSStephen Hemminger 
3145fe0bdbdeSYejune Deng 	pr_info("NET: Unregistered %s protocol family\n", pf_family_names[family]);
31461da177e4SLinus Torvalds }
3147c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_unregister);
31481da177e4SLinus Torvalds 
3149bf2ae2e4SXin Long bool sock_is_registered(int family)
3150bf2ae2e4SXin Long {
315166b51b0aSJeremy Cline 	return family < NPROTO && rcu_access_pointer(net_families[family]);
3152bf2ae2e4SXin Long }
3153bf2ae2e4SXin Long 
315477d76ea3SAndi Kleen static int __init sock_init(void)
31551da177e4SLinus Torvalds {
3156b3e19d92SNick Piggin 	int err;
31572ca794e5SEric W. Biederman 	/*
31582ca794e5SEric W. Biederman 	 *      Initialize the network sysctl infrastructure.
31592ca794e5SEric W. Biederman 	 */
31602ca794e5SEric W. Biederman 	err = net_sysctl_init();
31612ca794e5SEric W. Biederman 	if (err)
31622ca794e5SEric W. Biederman 		goto out;
3163b3e19d92SNick Piggin 
31641da177e4SLinus Torvalds 	/*
31651da177e4SLinus Torvalds 	 *      Initialize skbuff SLAB cache
31661da177e4SLinus Torvalds 	 */
31671da177e4SLinus Torvalds 	skb_init();
31681da177e4SLinus Torvalds 
31691da177e4SLinus Torvalds 	/*
31701da177e4SLinus Torvalds 	 *      Initialize the protocols module.
31711da177e4SLinus Torvalds 	 */
31721da177e4SLinus Torvalds 
31731da177e4SLinus Torvalds 	init_inodecache();
3174b3e19d92SNick Piggin 
3175b3e19d92SNick Piggin 	err = register_filesystem(&sock_fs_type);
3176b3e19d92SNick Piggin 	if (err)
317747260ba9SMiaohe Lin 		goto out;
31781da177e4SLinus Torvalds 	sock_mnt = kern_mount(&sock_fs_type);
3179b3e19d92SNick Piggin 	if (IS_ERR(sock_mnt)) {
3180b3e19d92SNick Piggin 		err = PTR_ERR(sock_mnt);
3181b3e19d92SNick Piggin 		goto out_mount;
3182b3e19d92SNick Piggin 	}
318377d76ea3SAndi Kleen 
318477d76ea3SAndi Kleen 	/* The real protocol initialization is performed in later initcalls.
31851da177e4SLinus Torvalds 	 */
31861da177e4SLinus Torvalds 
31871da177e4SLinus Torvalds #ifdef CONFIG_NETFILTER
31886d11cfdbSPablo Neira Ayuso 	err = netfilter_init();
31896d11cfdbSPablo Neira Ayuso 	if (err)
31906d11cfdbSPablo Neira Ayuso 		goto out;
31911da177e4SLinus Torvalds #endif
3192cbeb321aSDavid S. Miller 
3193408eccceSDaniel Borkmann 	ptp_classifier_init();
3194c1f19b51SRichard Cochran 
3195b3e19d92SNick Piggin out:
3196b3e19d92SNick Piggin 	return err;
3197b3e19d92SNick Piggin 
3198b3e19d92SNick Piggin out_mount:
3199b3e19d92SNick Piggin 	unregister_filesystem(&sock_fs_type);
3200b3e19d92SNick Piggin 	goto out;
32011da177e4SLinus Torvalds }
32021da177e4SLinus Torvalds 
320377d76ea3SAndi Kleen core_initcall(sock_init);	/* early initcall */
320477d76ea3SAndi Kleen 
32051da177e4SLinus Torvalds #ifdef CONFIG_PROC_FS
32061da177e4SLinus Torvalds void socket_seq_show(struct seq_file *seq)
32071da177e4SLinus Torvalds {
3208648845abSTonghao Zhang 	seq_printf(seq, "sockets: used %d\n",
3209648845abSTonghao Zhang 		   sock_inuse_get(seq->private));
32101da177e4SLinus Torvalds }
32111da177e4SLinus Torvalds #endif				/* CONFIG_PROC_FS */
32121da177e4SLinus Torvalds 
321329c49648SArnd Bergmann /* Handle the fact that while struct ifreq has the same *layout* on
321429c49648SArnd Bergmann  * 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data,
321529c49648SArnd Bergmann  * which are handled elsewhere, it still has different *size* due to
321629c49648SArnd Bergmann  * ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit,
321729c49648SArnd Bergmann  * resulting in struct ifreq being 32 and 40 bytes respectively).
321829c49648SArnd Bergmann  * As a result, if the struct happens to be at the end of a page and
321929c49648SArnd Bergmann  * the next page isn't readable/writable, we get a fault. To prevent
322029c49648SArnd Bergmann  * that, copy back and forth to the full size.
322129c49648SArnd Bergmann  */
322229c49648SArnd Bergmann int get_user_ifreq(struct ifreq *ifr, void __user **ifrdata, void __user *arg)
322329c49648SArnd Bergmann {
322429c49648SArnd Bergmann 	if (in_compat_syscall()) {
322529c49648SArnd Bergmann 		struct compat_ifreq *ifr32 = (struct compat_ifreq *)ifr;
322629c49648SArnd Bergmann 
322729c49648SArnd Bergmann 		memset(ifr, 0, sizeof(*ifr));
322829c49648SArnd Bergmann 		if (copy_from_user(ifr32, arg, sizeof(*ifr32)))
322929c49648SArnd Bergmann 			return -EFAULT;
323029c49648SArnd Bergmann 
323129c49648SArnd Bergmann 		if (ifrdata)
323229c49648SArnd Bergmann 			*ifrdata = compat_ptr(ifr32->ifr_data);
323329c49648SArnd Bergmann 
323429c49648SArnd Bergmann 		return 0;
323529c49648SArnd Bergmann 	}
323629c49648SArnd Bergmann 
323729c49648SArnd Bergmann 	if (copy_from_user(ifr, arg, sizeof(*ifr)))
323829c49648SArnd Bergmann 		return -EFAULT;
323929c49648SArnd Bergmann 
324029c49648SArnd Bergmann 	if (ifrdata)
324129c49648SArnd Bergmann 		*ifrdata = ifr->ifr_data;
324229c49648SArnd Bergmann 
324329c49648SArnd Bergmann 	return 0;
324429c49648SArnd Bergmann }
324529c49648SArnd Bergmann EXPORT_SYMBOL(get_user_ifreq);
324629c49648SArnd Bergmann 
324729c49648SArnd Bergmann int put_user_ifreq(struct ifreq *ifr, void __user *arg)
324829c49648SArnd Bergmann {
324929c49648SArnd Bergmann 	size_t size = sizeof(*ifr);
325029c49648SArnd Bergmann 
325129c49648SArnd Bergmann 	if (in_compat_syscall())
325229c49648SArnd Bergmann 		size = sizeof(struct compat_ifreq);
325329c49648SArnd Bergmann 
325429c49648SArnd Bergmann 	if (copy_to_user(arg, ifr, size))
325529c49648SArnd Bergmann 		return -EFAULT;
325629c49648SArnd Bergmann 
325729c49648SArnd Bergmann 	return 0;
325829c49648SArnd Bergmann }
325929c49648SArnd Bergmann EXPORT_SYMBOL(put_user_ifreq);
326029c49648SArnd Bergmann 
326189bbfc95SShaun Pereira #ifdef CONFIG_COMPAT
32627a50a240SArnd Bergmann static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
32637a50a240SArnd Bergmann {
32647a50a240SArnd Bergmann 	compat_uptr_t uptr32;
326544c02a2cSAl Viro 	struct ifreq ifr;
326644c02a2cSAl Viro 	void __user *saved;
326744c02a2cSAl Viro 	int err;
32687a50a240SArnd Bergmann 
326929c49648SArnd Bergmann 	if (get_user_ifreq(&ifr, NULL, uifr32))
32707a50a240SArnd Bergmann 		return -EFAULT;
32717a50a240SArnd Bergmann 
32727a50a240SArnd Bergmann 	if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
32737a50a240SArnd Bergmann 		return -EFAULT;
32747a50a240SArnd Bergmann 
327544c02a2cSAl Viro 	saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
327644c02a2cSAl Viro 	ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
32777a50a240SArnd Bergmann 
3278a554bf96SArnd Bergmann 	err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL, NULL);
327944c02a2cSAl Viro 	if (!err) {
328044c02a2cSAl Viro 		ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved;
328129c49648SArnd Bergmann 		if (put_user_ifreq(&ifr, uifr32))
328244c02a2cSAl Viro 			err = -EFAULT;
32837a50a240SArnd Bergmann 	}
32847a229387SArnd Bergmann 	return err;
32857a229387SArnd Bergmann }
32867a229387SArnd Bergmann 
3287590d4693SBen Hutchings /* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
3288590d4693SBen Hutchings static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
32896b96018bSArnd Bergmann 				 struct compat_ifreq __user *u_ifreq32)
32907a229387SArnd Bergmann {
329144c02a2cSAl Viro 	struct ifreq ifreq;
3292a554bf96SArnd Bergmann 	void __user *data;
32937a229387SArnd Bergmann 
3294d0efb162SPeter Collingbourne 	if (!is_socket_ioctl_cmd(cmd))
3295d0efb162SPeter Collingbourne 		return -ENOTTY;
3296a554bf96SArnd Bergmann 	if (get_user_ifreq(&ifreq, &data, u_ifreq32))
32977a229387SArnd Bergmann 		return -EFAULT;
3298a554bf96SArnd Bergmann 	ifreq.ifr_data = data;
32997a229387SArnd Bergmann 
3300a554bf96SArnd Bergmann 	return dev_ioctl(net, cmd, &ifreq, data, NULL);
33017a229387SArnd Bergmann }
33027a229387SArnd Bergmann 
33036b96018bSArnd Bergmann static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
33046b96018bSArnd Bergmann 			 unsigned int cmd, unsigned long arg)
33056b96018bSArnd Bergmann {
33066b96018bSArnd Bergmann 	void __user *argp = compat_ptr(arg);
33076b96018bSArnd Bergmann 	struct sock *sk = sock->sk;
33086b96018bSArnd Bergmann 	struct net *net = sock_net(sk);
33097a229387SArnd Bergmann 
33106b96018bSArnd Bergmann 	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
331188fc023fSArnd Bergmann 		return sock_ioctl(file, cmd, (unsigned long)argp);
33127a229387SArnd Bergmann 
33136b96018bSArnd Bergmann 	switch (cmd) {
33147a50a240SArnd Bergmann 	case SIOCWANDEV:
33157a50a240SArnd Bergmann 		return compat_siocwandev(net, argp);
33160768e170SArnd Bergmann 	case SIOCGSTAMP_OLD:
33170768e170SArnd Bergmann 	case SIOCGSTAMPNS_OLD:
3318c7cbdbf2SArnd Bergmann 		if (!sock->ops->gettstamp)
3319c7cbdbf2SArnd Bergmann 			return -ENOIOCTLCMD;
33200768e170SArnd Bergmann 		return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD,
3321c7cbdbf2SArnd Bergmann 					    !COMPAT_USE_64BIT_TIME);
3322c7cbdbf2SArnd Bergmann 
3323dd98d289SArnd Bergmann 	case SIOCETHTOOL:
3324590d4693SBen Hutchings 	case SIOCBONDSLAVEINFOQUERY:
3325590d4693SBen Hutchings 	case SIOCBONDINFOQUERY:
3326a2116ed2SArnd Bergmann 	case SIOCSHWTSTAMP:
3327fd468c74SBen Hutchings 	case SIOCGHWTSTAMP:
3328590d4693SBen Hutchings 		return compat_ifr_data_ioctl(net, cmd, argp);
33297a229387SArnd Bergmann 
33306b96018bSArnd Bergmann 	case FIOSETOWN:
33316b96018bSArnd Bergmann 	case SIOCSPGRP:
33326b96018bSArnd Bergmann 	case FIOGETOWN:
33336b96018bSArnd Bergmann 	case SIOCGPGRP:
33346b96018bSArnd Bergmann 	case SIOCBRADDBR:
33356b96018bSArnd Bergmann 	case SIOCBRDELBR:
33366b96018bSArnd Bergmann 	case SIOCGIFVLAN:
33376b96018bSArnd Bergmann 	case SIOCSIFVLAN:
3338c62cce2cSAndrey Vagin 	case SIOCGSKNS:
33390768e170SArnd Bergmann 	case SIOCGSTAMP_NEW:
33400768e170SArnd Bergmann 	case SIOCGSTAMPNS_NEW:
3341876f0bf9SArnd Bergmann 	case SIOCGIFCONF:
3342fd3a4590SRemi Pommarel 	case SIOCSIFBR:
3343fd3a4590SRemi Pommarel 	case SIOCGIFBR:
33446b96018bSArnd Bergmann 		return sock_ioctl(file, cmd, arg);
33456b96018bSArnd Bergmann 
33466b96018bSArnd Bergmann 	case SIOCGIFFLAGS:
33476b96018bSArnd Bergmann 	case SIOCSIFFLAGS:
3348709566d7SArnd Bergmann 	case SIOCGIFMAP:
3349709566d7SArnd Bergmann 	case SIOCSIFMAP:
33506b96018bSArnd Bergmann 	case SIOCGIFMETRIC:
33516b96018bSArnd Bergmann 	case SIOCSIFMETRIC:
33526b96018bSArnd Bergmann 	case SIOCGIFMTU:
33536b96018bSArnd Bergmann 	case SIOCSIFMTU:
33546b96018bSArnd Bergmann 	case SIOCGIFMEM:
33556b96018bSArnd Bergmann 	case SIOCSIFMEM:
33566b96018bSArnd Bergmann 	case SIOCGIFHWADDR:
33576b96018bSArnd Bergmann 	case SIOCSIFHWADDR:
33586b96018bSArnd Bergmann 	case SIOCADDMULTI:
33596b96018bSArnd Bergmann 	case SIOCDELMULTI:
33606b96018bSArnd Bergmann 	case SIOCGIFINDEX:
33616b96018bSArnd Bergmann 	case SIOCGIFADDR:
33626b96018bSArnd Bergmann 	case SIOCSIFADDR:
33636b96018bSArnd Bergmann 	case SIOCSIFHWBROADCAST:
33646b96018bSArnd Bergmann 	case SIOCDIFADDR:
33656b96018bSArnd Bergmann 	case SIOCGIFBRDADDR:
33666b96018bSArnd Bergmann 	case SIOCSIFBRDADDR:
33676b96018bSArnd Bergmann 	case SIOCGIFDSTADDR:
33686b96018bSArnd Bergmann 	case SIOCSIFDSTADDR:
33696b96018bSArnd Bergmann 	case SIOCGIFNETMASK:
33706b96018bSArnd Bergmann 	case SIOCSIFNETMASK:
33716b96018bSArnd Bergmann 	case SIOCSIFPFLAGS:
33726b96018bSArnd Bergmann 	case SIOCGIFPFLAGS:
33736b96018bSArnd Bergmann 	case SIOCGIFTXQLEN:
33746b96018bSArnd Bergmann 	case SIOCSIFTXQLEN:
33756b96018bSArnd Bergmann 	case SIOCBRADDIF:
33766b96018bSArnd Bergmann 	case SIOCBRDELIF:
3377c6c9fee3SJohannes Berg 	case SIOCGIFNAME:
33789177efd3SArnd Bergmann 	case SIOCSIFNAME:
33799177efd3SArnd Bergmann 	case SIOCGMIIPHY:
33809177efd3SArnd Bergmann 	case SIOCGMIIREG:
33819177efd3SArnd Bergmann 	case SIOCSMIIREG:
3382f92d4fc9SAl Viro 	case SIOCBONDENSLAVE:
3383f92d4fc9SAl Viro 	case SIOCBONDRELEASE:
3384f92d4fc9SAl Viro 	case SIOCBONDSETHWADDR:
3385f92d4fc9SAl Viro 	case SIOCBONDCHANGEACTIVE:
33866b96018bSArnd Bergmann 	case SIOCSARP:
33876b96018bSArnd Bergmann 	case SIOCGARP:
33886b96018bSArnd Bergmann 	case SIOCDARP:
3389c7dc504eSArnd Bergmann 	case SIOCOUTQ:
33909d7bf41fSArnd Bergmann 	case SIOCOUTQNSD:
33916b96018bSArnd Bergmann 	case SIOCATMARK:
339263ff03abSJohannes Berg 		return sock_do_ioctl(net, sock, cmd, arg);
33939177efd3SArnd Bergmann 	}
33949177efd3SArnd Bergmann 
33956b96018bSArnd Bergmann 	return -ENOIOCTLCMD;
33966b96018bSArnd Bergmann }
33977a229387SArnd Bergmann 
339895c96174SEric Dumazet static long compat_sock_ioctl(struct file *file, unsigned int cmd,
339989bbfc95SShaun Pereira 			      unsigned long arg)
340089bbfc95SShaun Pereira {
340189bbfc95SShaun Pereira 	struct socket *sock = file->private_data;
340289bbfc95SShaun Pereira 	int ret = -ENOIOCTLCMD;
340387de87d5SDavid S. Miller 	struct sock *sk;
340487de87d5SDavid S. Miller 	struct net *net;
340587de87d5SDavid S. Miller 
340687de87d5SDavid S. Miller 	sk = sock->sk;
340787de87d5SDavid S. Miller 	net = sock_net(sk);
340889bbfc95SShaun Pereira 
340989bbfc95SShaun Pereira 	if (sock->ops->compat_ioctl)
341089bbfc95SShaun Pereira 		ret = sock->ops->compat_ioctl(sock, cmd, arg);
341189bbfc95SShaun Pereira 
341287de87d5SDavid S. Miller 	if (ret == -ENOIOCTLCMD &&
341387de87d5SDavid S. Miller 	    (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
341487de87d5SDavid S. Miller 		ret = compat_wext_handle_ioctl(net, cmd, arg);
341587de87d5SDavid S. Miller 
34166b96018bSArnd Bergmann 	if (ret == -ENOIOCTLCMD)
34176b96018bSArnd Bergmann 		ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
34186b96018bSArnd Bergmann 
341989bbfc95SShaun Pereira 	return ret;
342089bbfc95SShaun Pereira }
342189bbfc95SShaun Pereira #endif
342289bbfc95SShaun Pereira 
34238a3c245cSPedro Tammela /**
34248a3c245cSPedro Tammela  *	kernel_bind - bind an address to a socket (kernel space)
34258a3c245cSPedro Tammela  *	@sock: socket
34268a3c245cSPedro Tammela  *	@addr: address
34278a3c245cSPedro Tammela  *	@addrlen: length of address
34288a3c245cSPedro Tammela  *
34298a3c245cSPedro Tammela  *	Returns 0 or an error.
34308a3c245cSPedro Tammela  */
34318a3c245cSPedro Tammela 
3432ac5a488eSSridhar Samudrala int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
3433ac5a488eSSridhar Samudrala {
3434ac5a488eSSridhar Samudrala 	return sock->ops->bind(sock, addr, addrlen);
3435ac5a488eSSridhar Samudrala }
3436c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_bind);
3437ac5a488eSSridhar Samudrala 
34388a3c245cSPedro Tammela /**
34398a3c245cSPedro Tammela  *	kernel_listen - move socket to listening state (kernel space)
34408a3c245cSPedro Tammela  *	@sock: socket
34418a3c245cSPedro Tammela  *	@backlog: pending connections queue size
34428a3c245cSPedro Tammela  *
34438a3c245cSPedro Tammela  *	Returns 0 or an error.
34448a3c245cSPedro Tammela  */
34458a3c245cSPedro Tammela 
3446ac5a488eSSridhar Samudrala int kernel_listen(struct socket *sock, int backlog)
3447ac5a488eSSridhar Samudrala {
3448ac5a488eSSridhar Samudrala 	return sock->ops->listen(sock, backlog);
3449ac5a488eSSridhar Samudrala }
3450c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_listen);
3451ac5a488eSSridhar Samudrala 
34528a3c245cSPedro Tammela /**
34538a3c245cSPedro Tammela  *	kernel_accept - accept a connection (kernel space)
34548a3c245cSPedro Tammela  *	@sock: listening socket
34558a3c245cSPedro Tammela  *	@newsock: new connected socket
34568a3c245cSPedro Tammela  *	@flags: flags
34578a3c245cSPedro Tammela  *
34588a3c245cSPedro Tammela  *	@flags must be SOCK_CLOEXEC, SOCK_NONBLOCK or 0.
34598a3c245cSPedro Tammela  *	If it fails, @newsock is guaranteed to be %NULL.
34608a3c245cSPedro Tammela  *	Returns 0 or an error.
34618a3c245cSPedro Tammela  */
34628a3c245cSPedro Tammela 
3463ac5a488eSSridhar Samudrala int kernel_accept(struct socket *sock, struct socket **newsock, int flags)
3464ac5a488eSSridhar Samudrala {
3465ac5a488eSSridhar Samudrala 	struct sock *sk = sock->sk;
3466ac5a488eSSridhar Samudrala 	int err;
3467ac5a488eSSridhar Samudrala 
3468ac5a488eSSridhar Samudrala 	err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol,
3469ac5a488eSSridhar Samudrala 			       newsock);
3470ac5a488eSSridhar Samudrala 	if (err < 0)
3471ac5a488eSSridhar Samudrala 		goto done;
3472ac5a488eSSridhar Samudrala 
3473cdfbabfbSDavid Howells 	err = sock->ops->accept(sock, *newsock, flags, true);
3474ac5a488eSSridhar Samudrala 	if (err < 0) {
3475ac5a488eSSridhar Samudrala 		sock_release(*newsock);
3476fa8705b0STony Battersby 		*newsock = NULL;
3477ac5a488eSSridhar Samudrala 		goto done;
3478ac5a488eSSridhar Samudrala 	}
3479ac5a488eSSridhar Samudrala 
3480ac5a488eSSridhar Samudrala 	(*newsock)->ops = sock->ops;
34811b08534eSWei Yongjun 	__module_get((*newsock)->ops->owner);
3482ac5a488eSSridhar Samudrala 
3483ac5a488eSSridhar Samudrala done:
3484ac5a488eSSridhar Samudrala 	return err;
3485ac5a488eSSridhar Samudrala }
3486c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_accept);
3487ac5a488eSSridhar Samudrala 
34888a3c245cSPedro Tammela /**
34898a3c245cSPedro Tammela  *	kernel_connect - connect a socket (kernel space)
34908a3c245cSPedro Tammela  *	@sock: socket
34918a3c245cSPedro Tammela  *	@addr: address
34928a3c245cSPedro Tammela  *	@addrlen: address length
34938a3c245cSPedro Tammela  *	@flags: flags (O_NONBLOCK, ...)
34948a3c245cSPedro Tammela  *
3495f1dcffccSLu Wei  *	For datagram sockets, @addr is the address to which datagrams are sent
34968a3c245cSPedro Tammela  *	by default, and the only address from which datagrams are received.
34978a3c245cSPedro Tammela  *	For stream sockets, attempts to connect to @addr.
34988a3c245cSPedro Tammela  *	Returns 0 or an error code.
34998a3c245cSPedro Tammela  */
35008a3c245cSPedro Tammela 
3501ac5a488eSSridhar Samudrala int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
3502ac5a488eSSridhar Samudrala 		   int flags)
3503ac5a488eSSridhar Samudrala {
3504ac5a488eSSridhar Samudrala 	return sock->ops->connect(sock, addr, addrlen, flags);
3505ac5a488eSSridhar Samudrala }
3506c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_connect);
3507ac5a488eSSridhar Samudrala 
35088a3c245cSPedro Tammela /**
35098a3c245cSPedro Tammela  *	kernel_getsockname - get the address which the socket is bound (kernel space)
35108a3c245cSPedro Tammela  *	@sock: socket
35118a3c245cSPedro Tammela  *	@addr: address holder
35128a3c245cSPedro Tammela  *
35138a3c245cSPedro Tammela  * 	Fills the @addr pointer with the address which the socket is bound.
35140fc95decSAlex Maydanik  *	Returns the length of the address in bytes or an error code.
35158a3c245cSPedro Tammela  */
35168a3c245cSPedro Tammela 
35179b2c45d4SDenys Vlasenko int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
3518ac5a488eSSridhar Samudrala {
35199b2c45d4SDenys Vlasenko 	return sock->ops->getname(sock, addr, 0);
3520ac5a488eSSridhar Samudrala }
3521c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_getsockname);
3522ac5a488eSSridhar Samudrala 
35238a3c245cSPedro Tammela /**
3524645f0897SMiaohe Lin  *	kernel_getpeername - get the address which the socket is connected (kernel space)
35258a3c245cSPedro Tammela  *	@sock: socket
35268a3c245cSPedro Tammela  *	@addr: address holder
35278a3c245cSPedro Tammela  *
35288a3c245cSPedro Tammela  * 	Fills the @addr pointer with the address which the socket is connected.
35290fc95decSAlex Maydanik  *	Returns the length of the address in bytes or an error code.
35308a3c245cSPedro Tammela  */
35318a3c245cSPedro Tammela 
35329b2c45d4SDenys Vlasenko int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
3533ac5a488eSSridhar Samudrala {
35349b2c45d4SDenys Vlasenko 	return sock->ops->getname(sock, addr, 1);
3535ac5a488eSSridhar Samudrala }
3536c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_getpeername);
3537ac5a488eSSridhar Samudrala 
35388a3c245cSPedro Tammela /**
35398a3c245cSPedro Tammela  *	kernel_sendpage - send a &page through a socket (kernel space)
35408a3c245cSPedro Tammela  *	@sock: socket
35418a3c245cSPedro Tammela  *	@page: page
35428a3c245cSPedro Tammela  *	@offset: page offset
35438a3c245cSPedro Tammela  *	@size: total size in bytes
35448a3c245cSPedro Tammela  *	@flags: flags (MSG_DONTWAIT, ...)
35458a3c245cSPedro Tammela  *
35468a3c245cSPedro Tammela  *	Returns the total amount sent in bytes or an error.
35478a3c245cSPedro Tammela  */
35488a3c245cSPedro Tammela 
3549ac5a488eSSridhar Samudrala int kernel_sendpage(struct socket *sock, struct page *page, int offset,
3550ac5a488eSSridhar Samudrala 		    size_t size, int flags)
3551ac5a488eSSridhar Samudrala {
35527b62d31dSColy Li 	if (sock->ops->sendpage) {
35537b62d31dSColy Li 		/* Warn in case the improper page to zero-copy send */
35547b62d31dSColy Li 		WARN_ONCE(!sendpage_ok(page), "improper page for zero-copy send");
3555ac5a488eSSridhar Samudrala 		return sock->ops->sendpage(sock, page, offset, size, flags);
35567b62d31dSColy Li 	}
3557ac5a488eSSridhar Samudrala 	return sock_no_sendpage(sock, page, offset, size, flags);
3558ac5a488eSSridhar Samudrala }
3559c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_sendpage);
3560ac5a488eSSridhar Samudrala 
35618a3c245cSPedro Tammela /**
35628a3c245cSPedro Tammela  *	kernel_sendpage_locked - send a &page through the locked sock (kernel space)
35638a3c245cSPedro Tammela  *	@sk: sock
35648a3c245cSPedro Tammela  *	@page: page
35658a3c245cSPedro Tammela  *	@offset: page offset
35668a3c245cSPedro Tammela  *	@size: total size in bytes
35678a3c245cSPedro Tammela  *	@flags: flags (MSG_DONTWAIT, ...)
35688a3c245cSPedro Tammela  *
35698a3c245cSPedro Tammela  *	Returns the total amount sent in bytes or an error.
35708a3c245cSPedro Tammela  *	Caller must hold @sk.
35718a3c245cSPedro Tammela  */
35728a3c245cSPedro Tammela 
3573306b13ebSTom Herbert int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset,
3574306b13ebSTom Herbert 			   size_t size, int flags)
3575306b13ebSTom Herbert {
3576306b13ebSTom Herbert 	struct socket *sock = sk->sk_socket;
3577306b13ebSTom Herbert 
3578306b13ebSTom Herbert 	if (sock->ops->sendpage_locked)
3579306b13ebSTom Herbert 		return sock->ops->sendpage_locked(sk, page, offset, size,
3580306b13ebSTom Herbert 						  flags);
3581306b13ebSTom Herbert 
3582306b13ebSTom Herbert 	return sock_no_sendpage_locked(sk, page, offset, size, flags);
3583306b13ebSTom Herbert }
3584306b13ebSTom Herbert EXPORT_SYMBOL(kernel_sendpage_locked);
3585306b13ebSTom Herbert 
35868a3c245cSPedro Tammela /**
3587645f0897SMiaohe Lin  *	kernel_sock_shutdown - shut down part of a full-duplex connection (kernel space)
35888a3c245cSPedro Tammela  *	@sock: socket
35898a3c245cSPedro Tammela  *	@how: connection part
35908a3c245cSPedro Tammela  *
35918a3c245cSPedro Tammela  *	Returns 0 or an error.
35928a3c245cSPedro Tammela  */
35938a3c245cSPedro Tammela 
359491cf45f0STrond Myklebust int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)
359591cf45f0STrond Myklebust {
359691cf45f0STrond Myklebust 	return sock->ops->shutdown(sock, how);
359791cf45f0STrond Myklebust }
359891cf45f0STrond Myklebust EXPORT_SYMBOL(kernel_sock_shutdown);
3599113c3075SR. Parameswaran 
36008a3c245cSPedro Tammela /**
36018a3c245cSPedro Tammela  *	kernel_sock_ip_overhead - returns the IP overhead imposed by a socket
36028a3c245cSPedro Tammela  *	@sk: socket
36038a3c245cSPedro Tammela  *
36048a3c245cSPedro Tammela  *	This routine returns the IP overhead imposed by a socket i.e.
3605113c3075SR. Parameswaran  *	the length of the underlying IP header, depending on whether
3606113c3075SR. Parameswaran  *	this is an IPv4 or IPv6 socket and the length from IP options turned
360757240d00SR. Parameswaran  *	on at the socket. Assumes that the caller has a lock on the socket.
3608113c3075SR. Parameswaran  */
36098a3c245cSPedro Tammela 
3610113c3075SR. Parameswaran u32 kernel_sock_ip_overhead(struct sock *sk)
3611113c3075SR. Parameswaran {
3612113c3075SR. Parameswaran 	struct inet_sock *inet;
3613113c3075SR. Parameswaran 	struct ip_options_rcu *opt;
3614113c3075SR. Parameswaran 	u32 overhead = 0;
3615113c3075SR. Parameswaran #if IS_ENABLED(CONFIG_IPV6)
3616113c3075SR. Parameswaran 	struct ipv6_pinfo *np;
3617113c3075SR. Parameswaran 	struct ipv6_txoptions *optv6 = NULL;
3618113c3075SR. Parameswaran #endif /* IS_ENABLED(CONFIG_IPV6) */
3619113c3075SR. Parameswaran 
3620113c3075SR. Parameswaran 	if (!sk)
3621113c3075SR. Parameswaran 		return overhead;
3622113c3075SR. Parameswaran 
3623113c3075SR. Parameswaran 	switch (sk->sk_family) {
3624113c3075SR. Parameswaran 	case AF_INET:
3625113c3075SR. Parameswaran 		inet = inet_sk(sk);
3626113c3075SR. Parameswaran 		overhead += sizeof(struct iphdr);
3627113c3075SR. Parameswaran 		opt = rcu_dereference_protected(inet->inet_opt,
3628614d79c0Sstephen hemminger 						sock_owned_by_user(sk));
3629113c3075SR. Parameswaran 		if (opt)
3630113c3075SR. Parameswaran 			overhead += opt->opt.optlen;
3631113c3075SR. Parameswaran 		return overhead;
3632113c3075SR. Parameswaran #if IS_ENABLED(CONFIG_IPV6)
3633113c3075SR. Parameswaran 	case AF_INET6:
3634113c3075SR. Parameswaran 		np = inet6_sk(sk);
3635113c3075SR. Parameswaran 		overhead += sizeof(struct ipv6hdr);
3636113c3075SR. Parameswaran 		if (np)
3637113c3075SR. Parameswaran 			optv6 = rcu_dereference_protected(np->opt,
3638614d79c0Sstephen hemminger 							  sock_owned_by_user(sk));
3639113c3075SR. Parameswaran 		if (optv6)
3640113c3075SR. Parameswaran 			overhead += (optv6->opt_flen + optv6->opt_nflen);
3641113c3075SR. Parameswaran 		return overhead;
3642113c3075SR. Parameswaran #endif /* IS_ENABLED(CONFIG_IPV6) */
3643113c3075SR. Parameswaran 	default: /* Returns 0 overhead if the socket is not ipv4 or ipv6 */
3644113c3075SR. Parameswaran 		return overhead;
3645113c3075SR. Parameswaran 	}
3646113c3075SR. Parameswaran }
3647113c3075SR. Parameswaran EXPORT_SYMBOL(kernel_sock_ip_overhead);
3648