xref: /openbmc/linux/net/socket.c (revision 9a8ad9ac)
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 
551da177e4SLinus Torvalds #include <linux/mm.h>
561da177e4SLinus Torvalds #include <linux/socket.h>
571da177e4SLinus Torvalds #include <linux/file.h>
581da177e4SLinus Torvalds #include <linux/net.h>
591da177e4SLinus Torvalds #include <linux/interrupt.h>
60aaca0bdcSUlrich Drepper #include <linux/thread_info.h>
6155737fdaSStephen Hemminger #include <linux/rcupdate.h>
621da177e4SLinus Torvalds #include <linux/netdevice.h>
631da177e4SLinus Torvalds #include <linux/proc_fs.h>
641da177e4SLinus Torvalds #include <linux/seq_file.h>
654a3e2f71SArjan van de Ven #include <linux/mutex.h>
661da177e4SLinus Torvalds #include <linux/if_bridge.h>
6720380731SArnaldo Carvalho de Melo #include <linux/if_frad.h>
6820380731SArnaldo Carvalho de Melo #include <linux/if_vlan.h>
69408eccceSDaniel Borkmann #include <linux/ptp_classify.h>
701da177e4SLinus Torvalds #include <linux/init.h>
711da177e4SLinus Torvalds #include <linux/poll.h>
721da177e4SLinus Torvalds #include <linux/cache.h>
731da177e4SLinus Torvalds #include <linux/module.h>
741da177e4SLinus Torvalds #include <linux/highmem.h>
751da177e4SLinus Torvalds #include <linux/mount.h>
76fba9be49SDavid Howells #include <linux/pseudo_fs.h>
771da177e4SLinus Torvalds #include <linux/security.h>
781da177e4SLinus Torvalds #include <linux/syscalls.h>
791da177e4SLinus Torvalds #include <linux/compat.h>
801da177e4SLinus Torvalds #include <linux/kmod.h>
813ec3b2fbSDavid Woodhouse #include <linux/audit.h>
82d86b5e0eSAdrian Bunk #include <linux/wireless.h>
831b8d7ae4SEric W. Biederman #include <linux/nsproxy.h>
841fd7317dSNick Black #include <linux/magic.h>
855a0e3ad6STejun Heo #include <linux/slab.h>
86600e1779SMasatake YAMATO #include <linux/xattr.h>
87c8e8cd57SJeremy Cline #include <linux/nospec.h>
888c3c447bSPaolo Abeni #include <linux/indirect_call_wrapper.h>
891da177e4SLinus Torvalds 
907c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
911da177e4SLinus Torvalds #include <asm/unistd.h>
921da177e4SLinus Torvalds 
931da177e4SLinus Torvalds #include <net/compat.h>
9487de87d5SDavid S. Miller #include <net/wext.h>
95f8451725SHerbert Xu #include <net/cls_cgroup.h>
961da177e4SLinus Torvalds 
971da177e4SLinus Torvalds #include <net/sock.h>
981da177e4SLinus Torvalds #include <linux/netfilter.h>
991da177e4SLinus Torvalds 
1006b96018bSArnd Bergmann #include <linux/if_tun.h>
1016b96018bSArnd Bergmann #include <linux/ipv6_route.h>
1026b96018bSArnd Bergmann #include <linux/route.h>
103c7dc504eSArnd Bergmann #include <linux/termios.h>
1046b96018bSArnd Bergmann #include <linux/sockios.h>
105076bb0c8SEliezer Tamir #include <net/busy_poll.h>
106f24b9be5SWillem de Bruijn #include <linux/errqueue.h>
10706021292SEliezer Tamir 
108e0d1095aSCong Wang #ifdef CONFIG_NET_RX_BUSY_POLL
10964b0dc51SEliezer Tamir unsigned int sysctl_net_busy_read __read_mostly;
11064b0dc51SEliezer Tamir unsigned int sysctl_net_busy_poll __read_mostly;
11106021292SEliezer Tamir #endif
1126b96018bSArnd Bergmann 
1138ae5e030SAl Viro static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to);
1148ae5e030SAl Viro static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from);
1151da177e4SLinus Torvalds static int sock_mmap(struct file *file, struct vm_area_struct *vma);
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds static int sock_close(struct inode *inode, struct file *file);
118a11e1d43SLinus Torvalds static __poll_t sock_poll(struct file *file,
119a11e1d43SLinus Torvalds 			      struct poll_table_struct *wait);
12089bddce5SStephen Hemminger static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
12189bbfc95SShaun Pereira #ifdef CONFIG_COMPAT
12289bbfc95SShaun Pereira static long compat_sock_ioctl(struct file *file,
12389bbfc95SShaun Pereira 			      unsigned int cmd, unsigned long arg);
12489bbfc95SShaun Pereira #endif
1251da177e4SLinus Torvalds static int sock_fasync(int fd, struct file *filp, int on);
1261da177e4SLinus Torvalds static ssize_t sock_sendpage(struct file *file, struct page *page,
1271da177e4SLinus Torvalds 			     int offset, size_t size, loff_t *ppos, int more);
1289c55e01cSJens Axboe static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
1299c55e01cSJens Axboe 				struct pipe_inode_info *pipe, size_t len,
1309c55e01cSJens Axboe 				unsigned int flags);
131542d3065SArnd Bergmann 
132542d3065SArnd Bergmann #ifdef CONFIG_PROC_FS
133542d3065SArnd Bergmann static void sock_show_fdinfo(struct seq_file *m, struct file *f)
134542d3065SArnd Bergmann {
135542d3065SArnd Bergmann 	struct socket *sock = f->private_data;
136542d3065SArnd Bergmann 
137542d3065SArnd Bergmann 	if (sock->ops->show_fdinfo)
138542d3065SArnd Bergmann 		sock->ops->show_fdinfo(m, sock);
139542d3065SArnd Bergmann }
140542d3065SArnd Bergmann #else
141542d3065SArnd Bergmann #define sock_show_fdinfo NULL
142542d3065SArnd Bergmann #endif
1431da177e4SLinus Torvalds 
1441da177e4SLinus Torvalds /*
1451da177e4SLinus Torvalds  *	Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
1461da177e4SLinus Torvalds  *	in the operation structures but are done directly via the socketcall() multiplexor.
1471da177e4SLinus Torvalds  */
1481da177e4SLinus Torvalds 
149da7071d7SArjan van de Ven static const struct file_operations socket_file_ops = {
1501da177e4SLinus Torvalds 	.owner =	THIS_MODULE,
1511da177e4SLinus Torvalds 	.llseek =	no_llseek,
1528ae5e030SAl Viro 	.read_iter =	sock_read_iter,
1538ae5e030SAl Viro 	.write_iter =	sock_write_iter,
1541da177e4SLinus Torvalds 	.poll =		sock_poll,
1551da177e4SLinus Torvalds 	.unlocked_ioctl = sock_ioctl,
15689bbfc95SShaun Pereira #ifdef CONFIG_COMPAT
15789bbfc95SShaun Pereira 	.compat_ioctl = compat_sock_ioctl,
15889bbfc95SShaun Pereira #endif
1591da177e4SLinus Torvalds 	.mmap =		sock_mmap,
1601da177e4SLinus Torvalds 	.release =	sock_close,
1611da177e4SLinus Torvalds 	.fasync =	sock_fasync,
1625274f052SJens Axboe 	.sendpage =	sock_sendpage,
1635274f052SJens Axboe 	.splice_write = generic_splice_sendpage,
1649c55e01cSJens Axboe 	.splice_read =	sock_splice_read,
165b4653342SKirill Tkhai 	.show_fdinfo =	sock_show_fdinfo,
1661da177e4SLinus Torvalds };
1671da177e4SLinus Torvalds 
1681da177e4SLinus Torvalds /*
1691da177e4SLinus Torvalds  *	The protocol list. Each protocol is registered in here.
1701da177e4SLinus Torvalds  */
1711da177e4SLinus Torvalds 
1721da177e4SLinus Torvalds static DEFINE_SPINLOCK(net_family_lock);
173190683a9SEric Dumazet static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
1741da177e4SLinus Torvalds 
1751da177e4SLinus Torvalds /*
17689bddce5SStephen Hemminger  * Support routines.
17789bddce5SStephen Hemminger  * Move socket addresses back and forth across the kernel/user
1781da177e4SLinus Torvalds  * divide and look after the messy bits.
1791da177e4SLinus Torvalds  */
1801da177e4SLinus Torvalds 
1811da177e4SLinus Torvalds /**
1821da177e4SLinus Torvalds  *	move_addr_to_kernel	-	copy a socket address into kernel space
1831da177e4SLinus Torvalds  *	@uaddr: Address in user space
1841da177e4SLinus Torvalds  *	@kaddr: Address in kernel space
1851da177e4SLinus Torvalds  *	@ulen: Length in user space
1861da177e4SLinus Torvalds  *
1871da177e4SLinus Torvalds  *	The address is copied into kernel space. If the provided address is
1881da177e4SLinus Torvalds  *	too long an error code of -EINVAL is returned. If the copy gives
1891da177e4SLinus Torvalds  *	invalid addresses -EFAULT is returned. On a success 0 is returned.
1901da177e4SLinus Torvalds  */
1911da177e4SLinus Torvalds 
19243db362dSMaciej Żenczykowski int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr)
1931da177e4SLinus Torvalds {
194230b1839SYOSHIFUJI Hideaki 	if (ulen < 0 || ulen > sizeof(struct sockaddr_storage))
1951da177e4SLinus Torvalds 		return -EINVAL;
1961da177e4SLinus Torvalds 	if (ulen == 0)
1971da177e4SLinus Torvalds 		return 0;
1981da177e4SLinus Torvalds 	if (copy_from_user(kaddr, uaddr, ulen))
1991da177e4SLinus Torvalds 		return -EFAULT;
2003ec3b2fbSDavid Woodhouse 	return audit_sockaddr(ulen, kaddr);
2011da177e4SLinus Torvalds }
2021da177e4SLinus Torvalds 
2031da177e4SLinus Torvalds /**
2041da177e4SLinus Torvalds  *	move_addr_to_user	-	copy an address to user space
2051da177e4SLinus Torvalds  *	@kaddr: kernel space address
2061da177e4SLinus Torvalds  *	@klen: length of address in kernel
2071da177e4SLinus Torvalds  *	@uaddr: user space address
2081da177e4SLinus Torvalds  *	@ulen: pointer to user length field
2091da177e4SLinus Torvalds  *
2101da177e4SLinus Torvalds  *	The value pointed to by ulen on entry is the buffer length available.
2111da177e4SLinus Torvalds  *	This is overwritten with the buffer space used. -EINVAL is returned
2121da177e4SLinus Torvalds  *	if an overlong buffer is specified or a negative buffer size. -EFAULT
2131da177e4SLinus Torvalds  *	is returned if either the buffer or the length field are not
2141da177e4SLinus Torvalds  *	accessible.
2151da177e4SLinus Torvalds  *	After copying the data up to the limit the user specifies, the true
2161da177e4SLinus Torvalds  *	length of the data is written over the length limit the user
2171da177e4SLinus Torvalds  *	specified. Zero is returned for a success.
2181da177e4SLinus Torvalds  */
2191da177e4SLinus Torvalds 
22043db362dSMaciej Żenczykowski static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
22111165f14Sstephen hemminger 			     void __user *uaddr, int __user *ulen)
2221da177e4SLinus Torvalds {
2231da177e4SLinus Torvalds 	int err;
2241da177e4SLinus Torvalds 	int len;
2251da177e4SLinus Torvalds 
22668c6beb3SHannes Frederic Sowa 	BUG_ON(klen > sizeof(struct sockaddr_storage));
22789bddce5SStephen Hemminger 	err = get_user(len, ulen);
22889bddce5SStephen Hemminger 	if (err)
2291da177e4SLinus Torvalds 		return err;
2301da177e4SLinus Torvalds 	if (len > klen)
2311da177e4SLinus Torvalds 		len = klen;
23268c6beb3SHannes Frederic Sowa 	if (len < 0)
2331da177e4SLinus Torvalds 		return -EINVAL;
23489bddce5SStephen Hemminger 	if (len) {
235d6fe3945SSteve Grubb 		if (audit_sockaddr(klen, kaddr))
236d6fe3945SSteve Grubb 			return -ENOMEM;
2371da177e4SLinus Torvalds 		if (copy_to_user(uaddr, kaddr, len))
2381da177e4SLinus Torvalds 			return -EFAULT;
2391da177e4SLinus Torvalds 	}
2401da177e4SLinus Torvalds 	/*
2411da177e4SLinus Torvalds 	 *      "fromlen shall refer to the value before truncation.."
2421da177e4SLinus Torvalds 	 *                      1003.1g
2431da177e4SLinus Torvalds 	 */
2441da177e4SLinus Torvalds 	return __put_user(klen, ulen);
2451da177e4SLinus Torvalds }
2461da177e4SLinus Torvalds 
24708009a76SAlexey Dobriyan static struct kmem_cache *sock_inode_cachep __ro_after_init;
2481da177e4SLinus Torvalds 
2491da177e4SLinus Torvalds static struct inode *sock_alloc_inode(struct super_block *sb)
2501da177e4SLinus Torvalds {
2511da177e4SLinus Torvalds 	struct socket_alloc *ei;
25289bddce5SStephen Hemminger 
253e94b1766SChristoph Lameter 	ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
2541da177e4SLinus Torvalds 	if (!ei)
2551da177e4SLinus Torvalds 		return NULL;
256333f7909SAl Viro 	init_waitqueue_head(&ei->socket.wq.wait);
257333f7909SAl Viro 	ei->socket.wq.fasync_list = NULL;
258333f7909SAl Viro 	ei->socket.wq.flags = 0;
2591da177e4SLinus Torvalds 
2601da177e4SLinus Torvalds 	ei->socket.state = SS_UNCONNECTED;
2611da177e4SLinus Torvalds 	ei->socket.flags = 0;
2621da177e4SLinus Torvalds 	ei->socket.ops = NULL;
2631da177e4SLinus Torvalds 	ei->socket.sk = NULL;
2641da177e4SLinus Torvalds 	ei->socket.file = NULL;
2651da177e4SLinus Torvalds 
2661da177e4SLinus Torvalds 	return &ei->vfs_inode;
2671da177e4SLinus Torvalds }
2681da177e4SLinus Torvalds 
2696d7855c5SAl Viro static void sock_free_inode(struct inode *inode)
2701da177e4SLinus Torvalds {
27143815482SEric Dumazet 	struct socket_alloc *ei;
27243815482SEric Dumazet 
27343815482SEric Dumazet 	ei = container_of(inode, struct socket_alloc, vfs_inode);
27443815482SEric Dumazet 	kmem_cache_free(sock_inode_cachep, ei);
2751da177e4SLinus Torvalds }
2761da177e4SLinus Torvalds 
27751cc5068SAlexey Dobriyan static void init_once(void *foo)
2781da177e4SLinus Torvalds {
2791da177e4SLinus Torvalds 	struct socket_alloc *ei = (struct socket_alloc *)foo;
2801da177e4SLinus Torvalds 
2811da177e4SLinus Torvalds 	inode_init_once(&ei->vfs_inode);
2821da177e4SLinus Torvalds }
2831da177e4SLinus Torvalds 
2841e911632Syuan linyu static void init_inodecache(void)
2851da177e4SLinus Torvalds {
2861da177e4SLinus Torvalds 	sock_inode_cachep = kmem_cache_create("sock_inode_cache",
2871da177e4SLinus Torvalds 					      sizeof(struct socket_alloc),
28889bddce5SStephen Hemminger 					      0,
28989bddce5SStephen Hemminger 					      (SLAB_HWCACHE_ALIGN |
29089bddce5SStephen Hemminger 					       SLAB_RECLAIM_ACCOUNT |
2915d097056SVladimir Davydov 					       SLAB_MEM_SPREAD | SLAB_ACCOUNT),
29220c2df83SPaul Mundt 					      init_once);
2931e911632Syuan linyu 	BUG_ON(sock_inode_cachep == NULL);
2941da177e4SLinus Torvalds }
2951da177e4SLinus Torvalds 
296b87221deSAlexey Dobriyan static const struct super_operations sockfs_ops = {
2971da177e4SLinus Torvalds 	.alloc_inode	= sock_alloc_inode,
2986d7855c5SAl Viro 	.free_inode	= sock_free_inode,
2991da177e4SLinus Torvalds 	.statfs		= simple_statfs,
3001da177e4SLinus Torvalds };
3011da177e4SLinus Torvalds 
302c23fbb6bSEric Dumazet /*
303c23fbb6bSEric Dumazet  * sockfs_dname() is called from d_path().
304c23fbb6bSEric Dumazet  */
305c23fbb6bSEric Dumazet static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
306c23fbb6bSEric Dumazet {
307c23fbb6bSEric Dumazet 	return dynamic_dname(dentry, buffer, buflen, "socket:[%lu]",
308c5ef6035SDavid Howells 				d_inode(dentry)->i_ino);
309c23fbb6bSEric Dumazet }
310c23fbb6bSEric Dumazet 
3113ba13d17SAl Viro static const struct dentry_operations sockfs_dentry_operations = {
312c23fbb6bSEric Dumazet 	.d_dname  = sockfs_dname,
3131da177e4SLinus Torvalds };
3141da177e4SLinus Torvalds 
315bba0bd31SAndreas Gruenbacher static int sockfs_xattr_get(const struct xattr_handler *handler,
316bba0bd31SAndreas Gruenbacher 			    struct dentry *dentry, struct inode *inode,
317bba0bd31SAndreas Gruenbacher 			    const char *suffix, void *value, size_t size)
318bba0bd31SAndreas Gruenbacher {
319bba0bd31SAndreas Gruenbacher 	if (value) {
320bba0bd31SAndreas Gruenbacher 		if (dentry->d_name.len + 1 > size)
321bba0bd31SAndreas Gruenbacher 			return -ERANGE;
322bba0bd31SAndreas Gruenbacher 		memcpy(value, dentry->d_name.name, dentry->d_name.len + 1);
323bba0bd31SAndreas Gruenbacher 	}
324bba0bd31SAndreas Gruenbacher 	return dentry->d_name.len + 1;
325bba0bd31SAndreas Gruenbacher }
326bba0bd31SAndreas Gruenbacher 
327bba0bd31SAndreas Gruenbacher #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
328bba0bd31SAndreas Gruenbacher #define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
329bba0bd31SAndreas Gruenbacher #define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
330bba0bd31SAndreas Gruenbacher 
331bba0bd31SAndreas Gruenbacher static const struct xattr_handler sockfs_xattr_handler = {
332bba0bd31SAndreas Gruenbacher 	.name = XATTR_NAME_SOCKPROTONAME,
333bba0bd31SAndreas Gruenbacher 	.get = sockfs_xattr_get,
334bba0bd31SAndreas Gruenbacher };
335bba0bd31SAndreas Gruenbacher 
3364a590153SAndreas Gruenbacher static int sockfs_security_xattr_set(const struct xattr_handler *handler,
3374a590153SAndreas Gruenbacher 				     struct dentry *dentry, struct inode *inode,
3384a590153SAndreas Gruenbacher 				     const char *suffix, const void *value,
3394a590153SAndreas Gruenbacher 				     size_t size, int flags)
3404a590153SAndreas Gruenbacher {
3414a590153SAndreas Gruenbacher 	/* Handled by LSM. */
3424a590153SAndreas Gruenbacher 	return -EAGAIN;
3434a590153SAndreas Gruenbacher }
3444a590153SAndreas Gruenbacher 
3454a590153SAndreas Gruenbacher static const struct xattr_handler sockfs_security_xattr_handler = {
3464a590153SAndreas Gruenbacher 	.prefix = XATTR_SECURITY_PREFIX,
3474a590153SAndreas Gruenbacher 	.set = sockfs_security_xattr_set,
3484a590153SAndreas Gruenbacher };
3494a590153SAndreas Gruenbacher 
350bba0bd31SAndreas Gruenbacher static const struct xattr_handler *sockfs_xattr_handlers[] = {
351bba0bd31SAndreas Gruenbacher 	&sockfs_xattr_handler,
3524a590153SAndreas Gruenbacher 	&sockfs_security_xattr_handler,
353bba0bd31SAndreas Gruenbacher 	NULL
354bba0bd31SAndreas Gruenbacher };
355bba0bd31SAndreas Gruenbacher 
356fba9be49SDavid Howells static int sockfs_init_fs_context(struct fs_context *fc)
357c74a1cbbSAl Viro {
358fba9be49SDavid Howells 	struct pseudo_fs_context *ctx = init_pseudo(fc, SOCKFS_MAGIC);
359fba9be49SDavid Howells 	if (!ctx)
360fba9be49SDavid Howells 		return -ENOMEM;
361fba9be49SDavid Howells 	ctx->ops = &sockfs_ops;
362fba9be49SDavid Howells 	ctx->dops = &sockfs_dentry_operations;
363fba9be49SDavid Howells 	ctx->xattr = sockfs_xattr_handlers;
364fba9be49SDavid Howells 	return 0;
365c74a1cbbSAl Viro }
366c74a1cbbSAl Viro 
367c74a1cbbSAl Viro static struct vfsmount *sock_mnt __read_mostly;
368c74a1cbbSAl Viro 
369c74a1cbbSAl Viro static struct file_system_type sock_fs_type = {
370c74a1cbbSAl Viro 	.name =		"sockfs",
371fba9be49SDavid Howells 	.init_fs_context = sockfs_init_fs_context,
372c74a1cbbSAl Viro 	.kill_sb =	kill_anon_super,
373c74a1cbbSAl Viro };
374c74a1cbbSAl Viro 
3751da177e4SLinus Torvalds /*
3761da177e4SLinus Torvalds  *	Obtains the first available file descriptor and sets it up for use.
3771da177e4SLinus Torvalds  *
37839d8c1b6SDavid S. Miller  *	These functions create file structures and maps them to fd space
37939d8c1b6SDavid S. Miller  *	of the current process. On success it returns file descriptor
3801da177e4SLinus Torvalds  *	and file struct implicitly stored in sock->file.
3811da177e4SLinus Torvalds  *	Note that another thread may close file descriptor before we return
3821da177e4SLinus Torvalds  *	from this function. We use the fact that now we do not refer
3831da177e4SLinus Torvalds  *	to socket after mapping. If one day we will need it, this
3841da177e4SLinus Torvalds  *	function will increment ref. count on file by 1.
3851da177e4SLinus Torvalds  *
3861da177e4SLinus Torvalds  *	In any case returned fd MAY BE not valid!
3871da177e4SLinus Torvalds  *	This race condition is unavoidable
3881da177e4SLinus Torvalds  *	with shared fd spaces, we cannot solve it inside kernel,
3891da177e4SLinus Torvalds  *	but we take care of internal coherence yet.
3901da177e4SLinus Torvalds  */
3911da177e4SLinus Torvalds 
3928a3c245cSPedro Tammela /**
3938a3c245cSPedro Tammela  *	sock_alloc_file - Bind a &socket to a &file
3948a3c245cSPedro Tammela  *	@sock: socket
3958a3c245cSPedro Tammela  *	@flags: file status flags
3968a3c245cSPedro Tammela  *	@dname: protocol name
3978a3c245cSPedro Tammela  *
3988a3c245cSPedro Tammela  *	Returns the &file bound with @sock, implicitly storing it
3998a3c245cSPedro Tammela  *	in sock->file. If dname is %NULL, sets to "".
4008a3c245cSPedro Tammela  *	On failure the return is a ERR pointer (see linux/err.h).
4018a3c245cSPedro Tammela  *	This function uses GFP_KERNEL internally.
4028a3c245cSPedro Tammela  */
4038a3c245cSPedro Tammela 
404aab174f0SLinus Torvalds struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)
4051da177e4SLinus Torvalds {
4067cbe66b6SAl Viro 	struct file *file;
4071da177e4SLinus Torvalds 
408d93aa9d8SAl Viro 	if (!dname)
409d93aa9d8SAl Viro 		dname = sock->sk ? sock->sk->sk_prot_creator->name : "";
41039d8c1b6SDavid S. Miller 
411d93aa9d8SAl Viro 	file = alloc_file_pseudo(SOCK_INODE(sock), sock_mnt, dname,
412d93aa9d8SAl Viro 				O_RDWR | (flags & O_NONBLOCK),
413cc3808f8SAl Viro 				&socket_file_ops);
414b5ffe634SViresh Kumar 	if (IS_ERR(file)) {
4158e1611e2SAl Viro 		sock_release(sock);
41639b65252SAnatol Pomozov 		return file;
417cc3808f8SAl Viro 	}
4181da177e4SLinus Torvalds 
4191da177e4SLinus Torvalds 	sock->file = file;
42007dc3f07SBenjamin LaHaise 	file->private_data = sock;
421d8e464ecSLinus Torvalds 	stream_open(SOCK_INODE(sock), file);
42228407630SAl Viro 	return file;
4231da177e4SLinus Torvalds }
42456b31d1cSAl Viro EXPORT_SYMBOL(sock_alloc_file);
4251da177e4SLinus Torvalds 
42656b31d1cSAl Viro static int sock_map_fd(struct socket *sock, int flags)
42739d8c1b6SDavid S. Miller {
42839d8c1b6SDavid S. Miller 	struct file *newfile;
42928407630SAl Viro 	int fd = get_unused_fd_flags(flags);
430ce4bb04cSAl Viro 	if (unlikely(fd < 0)) {
431ce4bb04cSAl Viro 		sock_release(sock);
4321da177e4SLinus Torvalds 		return fd;
433ce4bb04cSAl Viro 	}
4341da177e4SLinus Torvalds 
435aab174f0SLinus Torvalds 	newfile = sock_alloc_file(sock, flags, NULL);
4364546e44cSEnrico Weigelt 	if (!IS_ERR(newfile)) {
4371da177e4SLinus Torvalds 		fd_install(fd, newfile);
4381da177e4SLinus Torvalds 		return fd;
4391da177e4SLinus Torvalds 	}
44028407630SAl Viro 
44128407630SAl Viro 	put_unused_fd(fd);
44228407630SAl Viro 	return PTR_ERR(newfile);
4431da177e4SLinus Torvalds }
4441da177e4SLinus Torvalds 
4458a3c245cSPedro Tammela /**
4468a3c245cSPedro Tammela  *	sock_from_file - Return the &socket bounded to @file.
4478a3c245cSPedro Tammela  *	@file: file
4488a3c245cSPedro Tammela  *	@err: pointer to an error code return
4498a3c245cSPedro Tammela  *
4508a3c245cSPedro Tammela  *	On failure returns %NULL and assigns -ENOTSOCK to @err.
4518a3c245cSPedro Tammela  */
4528a3c245cSPedro Tammela 
453406a3c63SJohn Fastabend struct socket *sock_from_file(struct file *file, int *err)
4546cb153caSBenjamin LaHaise {
4556cb153caSBenjamin LaHaise 	if (file->f_op == &socket_file_ops)
4566cb153caSBenjamin LaHaise 		return file->private_data;	/* set in sock_map_fd */
4576cb153caSBenjamin LaHaise 
4586cb153caSBenjamin LaHaise 	*err = -ENOTSOCK;
4596cb153caSBenjamin LaHaise 	return NULL;
4606cb153caSBenjamin LaHaise }
461406a3c63SJohn Fastabend EXPORT_SYMBOL(sock_from_file);
4626cb153caSBenjamin LaHaise 
4631da177e4SLinus Torvalds /**
4641da177e4SLinus Torvalds  *	sockfd_lookup - Go from a file number to its socket slot
4651da177e4SLinus Torvalds  *	@fd: file handle
4661da177e4SLinus Torvalds  *	@err: pointer to an error code return
4671da177e4SLinus Torvalds  *
4681da177e4SLinus Torvalds  *	The file handle passed in is locked and the socket it is bound
469241c4667SRosen, Rami  *	to is returned. If an error occurs the err pointer is overwritten
4701da177e4SLinus Torvalds  *	with a negative errno code and NULL is returned. The function checks
4711da177e4SLinus Torvalds  *	for both invalid handles and passing a handle which is not a socket.
4721da177e4SLinus Torvalds  *
4731da177e4SLinus Torvalds  *	On a success the socket object pointer is returned.
4741da177e4SLinus Torvalds  */
4751da177e4SLinus Torvalds 
4761da177e4SLinus Torvalds struct socket *sockfd_lookup(int fd, int *err)
4771da177e4SLinus Torvalds {
4781da177e4SLinus Torvalds 	struct file *file;
4791da177e4SLinus Torvalds 	struct socket *sock;
4801da177e4SLinus Torvalds 
48189bddce5SStephen Hemminger 	file = fget(fd);
48289bddce5SStephen Hemminger 	if (!file) {
4831da177e4SLinus Torvalds 		*err = -EBADF;
4841da177e4SLinus Torvalds 		return NULL;
4851da177e4SLinus Torvalds 	}
48689bddce5SStephen Hemminger 
4876cb153caSBenjamin LaHaise 	sock = sock_from_file(file, err);
4886cb153caSBenjamin LaHaise 	if (!sock)
4891da177e4SLinus Torvalds 		fput(file);
4906cb153caSBenjamin LaHaise 	return sock;
4911da177e4SLinus Torvalds }
492c6d409cfSEric Dumazet EXPORT_SYMBOL(sockfd_lookup);
4931da177e4SLinus Torvalds 
4946cb153caSBenjamin LaHaise static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
4956cb153caSBenjamin LaHaise {
49600e188efSAl Viro 	struct fd f = fdget(fd);
4976cb153caSBenjamin LaHaise 	struct socket *sock;
4986cb153caSBenjamin LaHaise 
4993672558cSHua Zhong 	*err = -EBADF;
50000e188efSAl Viro 	if (f.file) {
50100e188efSAl Viro 		sock = sock_from_file(f.file, err);
50200e188efSAl Viro 		if (likely(sock)) {
50300e188efSAl Viro 			*fput_needed = f.flags;
5041da177e4SLinus Torvalds 			return sock;
50500e188efSAl Viro 		}
50600e188efSAl Viro 		fdput(f);
5076cb153caSBenjamin LaHaise 	}
5086cb153caSBenjamin LaHaise 	return NULL;
5091da177e4SLinus Torvalds }
5101da177e4SLinus Torvalds 
511600e1779SMasatake YAMATO static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
512600e1779SMasatake YAMATO 				size_t size)
513600e1779SMasatake YAMATO {
514600e1779SMasatake YAMATO 	ssize_t len;
515600e1779SMasatake YAMATO 	ssize_t used = 0;
516600e1779SMasatake YAMATO 
517c5ef6035SDavid Howells 	len = security_inode_listsecurity(d_inode(dentry), buffer, size);
518600e1779SMasatake YAMATO 	if (len < 0)
519600e1779SMasatake YAMATO 		return len;
520600e1779SMasatake YAMATO 	used += len;
521600e1779SMasatake YAMATO 	if (buffer) {
522600e1779SMasatake YAMATO 		if (size < used)
523600e1779SMasatake YAMATO 			return -ERANGE;
524600e1779SMasatake YAMATO 		buffer += len;
525600e1779SMasatake YAMATO 	}
526600e1779SMasatake YAMATO 
527600e1779SMasatake YAMATO 	len = (XATTR_NAME_SOCKPROTONAME_LEN + 1);
528600e1779SMasatake YAMATO 	used += len;
529600e1779SMasatake YAMATO 	if (buffer) {
530600e1779SMasatake YAMATO 		if (size < used)
531600e1779SMasatake YAMATO 			return -ERANGE;
532600e1779SMasatake YAMATO 		memcpy(buffer, XATTR_NAME_SOCKPROTONAME, len);
533600e1779SMasatake YAMATO 		buffer += len;
534600e1779SMasatake YAMATO 	}
535600e1779SMasatake YAMATO 
536600e1779SMasatake YAMATO 	return used;
537600e1779SMasatake YAMATO }
538600e1779SMasatake YAMATO 
539dc647ec8STobias Klauser static int sockfs_setattr(struct dentry *dentry, struct iattr *iattr)
54086741ec2SLorenzo Colitti {
54186741ec2SLorenzo Colitti 	int err = simple_setattr(dentry, iattr);
54286741ec2SLorenzo Colitti 
543e1a3a60aSEric Biggers 	if (!err && (iattr->ia_valid & ATTR_UID)) {
54486741ec2SLorenzo Colitti 		struct socket *sock = SOCKET_I(d_inode(dentry));
54586741ec2SLorenzo Colitti 
5466d8c50dcSCong Wang 		if (sock->sk)
54786741ec2SLorenzo Colitti 			sock->sk->sk_uid = iattr->ia_uid;
5486d8c50dcSCong Wang 		else
5496d8c50dcSCong Wang 			err = -ENOENT;
55086741ec2SLorenzo Colitti 	}
55186741ec2SLorenzo Colitti 
55286741ec2SLorenzo Colitti 	return err;
55386741ec2SLorenzo Colitti }
55486741ec2SLorenzo Colitti 
555600e1779SMasatake YAMATO static const struct inode_operations sockfs_inode_ops = {
556600e1779SMasatake YAMATO 	.listxattr = sockfs_listxattr,
55786741ec2SLorenzo Colitti 	.setattr = sockfs_setattr,
558600e1779SMasatake YAMATO };
559600e1779SMasatake YAMATO 
5601da177e4SLinus Torvalds /**
5611da177e4SLinus Torvalds  *	sock_alloc - allocate a socket
5621da177e4SLinus Torvalds  *
5631da177e4SLinus Torvalds  *	Allocate a new inode and socket object. The two are bound together
5641da177e4SLinus Torvalds  *	and initialised. The socket is then returned. If we are out of inodes
5658a3c245cSPedro Tammela  *	NULL is returned. This functions uses GFP_KERNEL internally.
5661da177e4SLinus Torvalds  */
5671da177e4SLinus Torvalds 
568f4a00aacSTom Herbert struct socket *sock_alloc(void)
5691da177e4SLinus Torvalds {
5701da177e4SLinus Torvalds 	struct inode *inode;
5711da177e4SLinus Torvalds 	struct socket *sock;
5721da177e4SLinus Torvalds 
573a209dfc7SEric Dumazet 	inode = new_inode_pseudo(sock_mnt->mnt_sb);
5741da177e4SLinus Torvalds 	if (!inode)
5751da177e4SLinus Torvalds 		return NULL;
5761da177e4SLinus Torvalds 
5771da177e4SLinus Torvalds 	sock = SOCKET_I(inode);
5781da177e4SLinus Torvalds 
57985fe4025SChristoph Hellwig 	inode->i_ino = get_next_ino();
5801da177e4SLinus Torvalds 	inode->i_mode = S_IFSOCK | S_IRWXUGO;
5818192b0c4SDavid Howells 	inode->i_uid = current_fsuid();
5828192b0c4SDavid Howells 	inode->i_gid = current_fsgid();
583600e1779SMasatake YAMATO 	inode->i_op = &sockfs_inode_ops;
5841da177e4SLinus Torvalds 
5851da177e4SLinus Torvalds 	return sock;
5861da177e4SLinus Torvalds }
587f4a00aacSTom Herbert EXPORT_SYMBOL(sock_alloc);
5881da177e4SLinus Torvalds 
5896d8c50dcSCong Wang static void __sock_release(struct socket *sock, struct inode *inode)
5901da177e4SLinus Torvalds {
5911da177e4SLinus Torvalds 	if (sock->ops) {
5921da177e4SLinus Torvalds 		struct module *owner = sock->ops->owner;
5931da177e4SLinus Torvalds 
5946d8c50dcSCong Wang 		if (inode)
5956d8c50dcSCong Wang 			inode_lock(inode);
5961da177e4SLinus Torvalds 		sock->ops->release(sock);
597ff7b11aaSEric Biggers 		sock->sk = NULL;
5986d8c50dcSCong Wang 		if (inode)
5996d8c50dcSCong Wang 			inode_unlock(inode);
6001da177e4SLinus Torvalds 		sock->ops = NULL;
6011da177e4SLinus Torvalds 		module_put(owner);
6021da177e4SLinus Torvalds 	}
6031da177e4SLinus Torvalds 
604333f7909SAl Viro 	if (sock->wq.fasync_list)
6053410f22eSYang Yingliang 		pr_err("%s: fasync list not empty!\n", __func__);
6061da177e4SLinus Torvalds 
6071da177e4SLinus Torvalds 	if (!sock->file) {
6081da177e4SLinus Torvalds 		iput(SOCK_INODE(sock));
6091da177e4SLinus Torvalds 		return;
6101da177e4SLinus Torvalds 	}
6111da177e4SLinus Torvalds 	sock->file = NULL;
6121da177e4SLinus Torvalds }
6136d8c50dcSCong Wang 
6149a8ad9acSAndrew Lunn /**
6159a8ad9acSAndrew Lunn  *	sock_release - close a socket
6169a8ad9acSAndrew Lunn  *	@sock: socket to close
6179a8ad9acSAndrew Lunn  *
6189a8ad9acSAndrew Lunn  *	The socket is released from the protocol stack if it has a release
6199a8ad9acSAndrew Lunn  *	callback, and the inode is then released if the socket is bound to
6209a8ad9acSAndrew Lunn  *	an inode not a file.
6219a8ad9acSAndrew Lunn  */
6226d8c50dcSCong Wang void sock_release(struct socket *sock)
6236d8c50dcSCong Wang {
6246d8c50dcSCong Wang 	__sock_release(sock, NULL);
6256d8c50dcSCong Wang }
626c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_release);
6271da177e4SLinus Torvalds 
628c14ac945SSoheil Hassas Yeganeh void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags)
62920d49473SPatrick Ohly {
630140c55d4SEric Dumazet 	u8 flags = *tx_flags;
631140c55d4SEric Dumazet 
632c14ac945SSoheil Hassas Yeganeh 	if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE)
633140c55d4SEric Dumazet 		flags |= SKBTX_HW_TSTAMP;
634140c55d4SEric Dumazet 
635c14ac945SSoheil Hassas Yeganeh 	if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE)
636140c55d4SEric Dumazet 		flags |= SKBTX_SW_TSTAMP;
637140c55d4SEric Dumazet 
638c14ac945SSoheil Hassas Yeganeh 	if (tsflags & SOF_TIMESTAMPING_TX_SCHED)
639140c55d4SEric Dumazet 		flags |= SKBTX_SCHED_TSTAMP;
640140c55d4SEric Dumazet 
641140c55d4SEric Dumazet 	*tx_flags = flags;
64220d49473SPatrick Ohly }
64367cc0d40SWillem de Bruijn EXPORT_SYMBOL(__sock_tx_timestamp);
64420d49473SPatrick Ohly 
6458c3c447bSPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet_sendmsg(struct socket *, struct msghdr *,
6468c3c447bSPaolo Abeni 					   size_t));
647a648a592SPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet6_sendmsg(struct socket *, struct msghdr *,
648a648a592SPaolo Abeni 					    size_t));
649d8725c86SAl Viro static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
6501da177e4SLinus Torvalds {
651a648a592SPaolo Abeni 	int ret = INDIRECT_CALL_INET(sock->ops->sendmsg, inet6_sendmsg,
652a648a592SPaolo Abeni 				     inet_sendmsg, sock, msg,
653a648a592SPaolo Abeni 				     msg_data_left(msg));
654d8725c86SAl Viro 	BUG_ON(ret == -EIOCBQUEUED);
655d8725c86SAl Viro 	return ret;
6561da177e4SLinus Torvalds }
6570cf00c6fSGu Zheng 
65885806af0SRandy Dunlap /**
65985806af0SRandy Dunlap  *	sock_sendmsg - send a message through @sock
66085806af0SRandy Dunlap  *	@sock: socket
66185806af0SRandy Dunlap  *	@msg: message to send
66285806af0SRandy Dunlap  *
66385806af0SRandy Dunlap  *	Sends @msg through @sock, passing through LSM.
66485806af0SRandy Dunlap  *	Returns the number of bytes sent, or an error code.
66585806af0SRandy Dunlap  */
666d8725c86SAl Viro int sock_sendmsg(struct socket *sock, struct msghdr *msg)
6670cf00c6fSGu Zheng {
668d8725c86SAl Viro 	int err = security_socket_sendmsg(sock, msg,
66901e97e65SAl Viro 					  msg_data_left(msg));
6701b784140SYing Xue 
671d8725c86SAl Viro 	return err ?: sock_sendmsg_nosec(sock, msg);
6720cf00c6fSGu Zheng }
673c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_sendmsg);
6741da177e4SLinus Torvalds 
6758a3c245cSPedro Tammela /**
6768a3c245cSPedro Tammela  *	kernel_sendmsg - send a message through @sock (kernel-space)
6778a3c245cSPedro Tammela  *	@sock: socket
6788a3c245cSPedro Tammela  *	@msg: message header
6798a3c245cSPedro Tammela  *	@vec: kernel vec
6808a3c245cSPedro Tammela  *	@num: vec array length
6818a3c245cSPedro Tammela  *	@size: total message data size
6828a3c245cSPedro Tammela  *
6838a3c245cSPedro Tammela  *	Builds the message data with @vec and sends it through @sock.
6848a3c245cSPedro Tammela  *	Returns the number of bytes sent, or an error code.
6858a3c245cSPedro Tammela  */
6868a3c245cSPedro Tammela 
6871da177e4SLinus Torvalds int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
6881da177e4SLinus Torvalds 		   struct kvec *vec, size_t num, size_t size)
6891da177e4SLinus Torvalds {
690aa563d7bSDavid Howells 	iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size);
691d8725c86SAl Viro 	return sock_sendmsg(sock, msg);
6921da177e4SLinus Torvalds }
693c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_sendmsg);
6941da177e4SLinus Torvalds 
6958a3c245cSPedro Tammela /**
6968a3c245cSPedro Tammela  *	kernel_sendmsg_locked - send a message through @sock (kernel-space)
6978a3c245cSPedro Tammela  *	@sk: sock
6988a3c245cSPedro Tammela  *	@msg: message header
6998a3c245cSPedro Tammela  *	@vec: output s/g array
7008a3c245cSPedro Tammela  *	@num: output s/g array length
7018a3c245cSPedro Tammela  *	@size: total message data size
7028a3c245cSPedro Tammela  *
7038a3c245cSPedro Tammela  *	Builds the message data with @vec and sends it through @sock.
7048a3c245cSPedro Tammela  *	Returns the number of bytes sent, or an error code.
7058a3c245cSPedro Tammela  *	Caller must hold @sk.
7068a3c245cSPedro Tammela  */
7078a3c245cSPedro Tammela 
708306b13ebSTom Herbert int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg,
709306b13ebSTom Herbert 			  struct kvec *vec, size_t num, size_t size)
710306b13ebSTom Herbert {
711306b13ebSTom Herbert 	struct socket *sock = sk->sk_socket;
712306b13ebSTom Herbert 
713306b13ebSTom Herbert 	if (!sock->ops->sendmsg_locked)
714db5980d8SJohn Fastabend 		return sock_no_sendmsg_locked(sk, msg, size);
715306b13ebSTom Herbert 
716aa563d7bSDavid Howells 	iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size);
717306b13ebSTom Herbert 
718306b13ebSTom Herbert 	return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg));
719306b13ebSTom Herbert }
720306b13ebSTom Herbert EXPORT_SYMBOL(kernel_sendmsg_locked);
721306b13ebSTom Herbert 
7228605330aSSoheil Hassas Yeganeh static bool skb_is_err_queue(const struct sk_buff *skb)
7238605330aSSoheil Hassas Yeganeh {
7248605330aSSoheil Hassas Yeganeh 	/* pkt_type of skbs enqueued on the error queue are set to
7258605330aSSoheil Hassas Yeganeh 	 * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
7268605330aSSoheil Hassas Yeganeh 	 * in recvmsg, since skbs received on a local socket will never
7278605330aSSoheil Hassas Yeganeh 	 * have a pkt_type of PACKET_OUTGOING.
7288605330aSSoheil Hassas Yeganeh 	 */
7298605330aSSoheil Hassas Yeganeh 	return skb->pkt_type == PACKET_OUTGOING;
7308605330aSSoheil Hassas Yeganeh }
7318605330aSSoheil Hassas Yeganeh 
732b50a5c70SMiroslav Lichvar /* On transmit, software and hardware timestamps are returned independently.
733b50a5c70SMiroslav Lichvar  * As the two skb clones share the hardware timestamp, which may be updated
734b50a5c70SMiroslav Lichvar  * before the software timestamp is received, a hardware TX timestamp may be
735b50a5c70SMiroslav Lichvar  * returned only if there is no software TX timestamp. Ignore false software
736b50a5c70SMiroslav Lichvar  * timestamps, which may be made in the __sock_recv_timestamp() call when the
7377f1bc6e9SDeepa Dinamani  * option SO_TIMESTAMP_OLD(NS) is enabled on the socket, even when the skb has a
738b50a5c70SMiroslav Lichvar  * hardware timestamp.
739b50a5c70SMiroslav Lichvar  */
740b50a5c70SMiroslav Lichvar static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp)
741b50a5c70SMiroslav Lichvar {
742b50a5c70SMiroslav Lichvar 	return skb->tstamp && !false_tstamp && skb_is_err_queue(skb);
743b50a5c70SMiroslav Lichvar }
744b50a5c70SMiroslav Lichvar 
745aad9c8c4SMiroslav Lichvar static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb)
746aad9c8c4SMiroslav Lichvar {
747aad9c8c4SMiroslav Lichvar 	struct scm_ts_pktinfo ts_pktinfo;
748aad9c8c4SMiroslav Lichvar 	struct net_device *orig_dev;
749aad9c8c4SMiroslav Lichvar 
750aad9c8c4SMiroslav Lichvar 	if (!skb_mac_header_was_set(skb))
751aad9c8c4SMiroslav Lichvar 		return;
752aad9c8c4SMiroslav Lichvar 
753aad9c8c4SMiroslav Lichvar 	memset(&ts_pktinfo, 0, sizeof(ts_pktinfo));
754aad9c8c4SMiroslav Lichvar 
755aad9c8c4SMiroslav Lichvar 	rcu_read_lock();
756aad9c8c4SMiroslav Lichvar 	orig_dev = dev_get_by_napi_id(skb_napi_id(skb));
757aad9c8c4SMiroslav Lichvar 	if (orig_dev)
758aad9c8c4SMiroslav Lichvar 		ts_pktinfo.if_index = orig_dev->ifindex;
759aad9c8c4SMiroslav Lichvar 	rcu_read_unlock();
760aad9c8c4SMiroslav Lichvar 
761aad9c8c4SMiroslav Lichvar 	ts_pktinfo.pkt_length = skb->len - skb_mac_offset(skb);
762aad9c8c4SMiroslav Lichvar 	put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO,
763aad9c8c4SMiroslav Lichvar 		 sizeof(ts_pktinfo), &ts_pktinfo);
764aad9c8c4SMiroslav Lichvar }
765aad9c8c4SMiroslav Lichvar 
76692f37fd2SEric Dumazet /*
76792f37fd2SEric Dumazet  * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
76892f37fd2SEric Dumazet  */
76992f37fd2SEric Dumazet void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
77092f37fd2SEric Dumazet 	struct sk_buff *skb)
77192f37fd2SEric Dumazet {
77220d49473SPatrick Ohly 	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
773887feae3SDeepa Dinamani 	int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
7749718475eSDeepa Dinamani 	struct scm_timestamping_internal tss;
7759718475eSDeepa Dinamani 
776b50a5c70SMiroslav Lichvar 	int empty = 1, false_tstamp = 0;
77720d49473SPatrick Ohly 	struct skb_shared_hwtstamps *shhwtstamps =
77820d49473SPatrick Ohly 		skb_hwtstamps(skb);
77992f37fd2SEric Dumazet 
78020d49473SPatrick Ohly 	/* Race occurred between timestamp enabling and packet
78120d49473SPatrick Ohly 	   receiving.  Fill in the current time for now. */
782b50a5c70SMiroslav Lichvar 	if (need_software_tstamp && skb->tstamp == 0) {
78320d49473SPatrick Ohly 		__net_timestamp(skb);
784b50a5c70SMiroslav Lichvar 		false_tstamp = 1;
785b50a5c70SMiroslav Lichvar 	}
78620d49473SPatrick Ohly 
78720d49473SPatrick Ohly 	if (need_software_tstamp) {
78892f37fd2SEric Dumazet 		if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
789887feae3SDeepa Dinamani 			if (new_tstamp) {
790887feae3SDeepa Dinamani 				struct __kernel_sock_timeval tv;
791887feae3SDeepa Dinamani 
792887feae3SDeepa Dinamani 				skb_get_new_timestamp(skb, &tv);
793887feae3SDeepa Dinamani 				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
794887feae3SDeepa Dinamani 					 sizeof(tv), &tv);
795887feae3SDeepa Dinamani 			} else {
79613c6ee2aSDeepa Dinamani 				struct __kernel_old_timeval tv;
797887feae3SDeepa Dinamani 
79820d49473SPatrick Ohly 				skb_get_timestamp(skb, &tv);
7997f1bc6e9SDeepa Dinamani 				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
80020d49473SPatrick Ohly 					 sizeof(tv), &tv);
801887feae3SDeepa Dinamani 			}
802887feae3SDeepa Dinamani 		} else {
803887feae3SDeepa Dinamani 			if (new_tstamp) {
804887feae3SDeepa Dinamani 				struct __kernel_timespec ts;
805887feae3SDeepa Dinamani 
806887feae3SDeepa Dinamani 				skb_get_new_timestampns(skb, &ts);
807887feae3SDeepa Dinamani 				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
808887feae3SDeepa Dinamani 					 sizeof(ts), &ts);
80992f37fd2SEric Dumazet 			} else {
810df1b4ba9SArnd Bergmann 				struct __kernel_old_timespec ts;
811887feae3SDeepa Dinamani 
812f24b9be5SWillem de Bruijn 				skb_get_timestampns(skb, &ts);
8137f1bc6e9SDeepa Dinamani 				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
814f24b9be5SWillem de Bruijn 					 sizeof(ts), &ts);
81592f37fd2SEric Dumazet 			}
81692f37fd2SEric Dumazet 		}
817887feae3SDeepa Dinamani 	}
81892f37fd2SEric Dumazet 
819f24b9be5SWillem de Bruijn 	memset(&tss, 0, sizeof(tss));
820c199105dSWillem de Bruijn 	if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
8219718475eSDeepa Dinamani 	    ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
82220d49473SPatrick Ohly 		empty = 0;
8234d276eb6SWillem de Bruijn 	if (shhwtstamps &&
824b9f40e21SWillem de Bruijn 	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
825b50a5c70SMiroslav Lichvar 	    !skb_is_swtx_tstamp(skb, false_tstamp) &&
8269718475eSDeepa Dinamani 	    ktime_to_timespec64_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
82720d49473SPatrick Ohly 		empty = 0;
828aad9c8c4SMiroslav Lichvar 		if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
829aad9c8c4SMiroslav Lichvar 		    !skb_is_err_queue(skb))
830aad9c8c4SMiroslav Lichvar 			put_ts_pktinfo(msg, skb);
831aad9c8c4SMiroslav Lichvar 	}
8321c885808SFrancis Yan 	if (!empty) {
8339718475eSDeepa Dinamani 		if (sock_flag(sk, SOCK_TSTAMP_NEW))
8349718475eSDeepa Dinamani 			put_cmsg_scm_timestamping64(msg, &tss);
8359718475eSDeepa Dinamani 		else
8369718475eSDeepa Dinamani 			put_cmsg_scm_timestamping(msg, &tss);
8371c885808SFrancis Yan 
8388605330aSSoheil Hassas Yeganeh 		if (skb_is_err_queue(skb) && skb->len &&
8394ef1b286SSoheil Hassas Yeganeh 		    SKB_EXT_ERR(skb)->opt_stats)
8401c885808SFrancis Yan 			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS,
8411c885808SFrancis Yan 				 skb->len, skb->data);
8421c885808SFrancis Yan 	}
84320d49473SPatrick Ohly }
8447c81fd8bSArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
8457c81fd8bSArnaldo Carvalho de Melo 
8466e3e939fSJohannes Berg void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
8476e3e939fSJohannes Berg 	struct sk_buff *skb)
8486e3e939fSJohannes Berg {
8496e3e939fSJohannes Berg 	int ack;
8506e3e939fSJohannes Berg 
8516e3e939fSJohannes Berg 	if (!sock_flag(sk, SOCK_WIFI_STATUS))
8526e3e939fSJohannes Berg 		return;
8536e3e939fSJohannes Berg 	if (!skb->wifi_acked_valid)
8546e3e939fSJohannes Berg 		return;
8556e3e939fSJohannes Berg 
8566e3e939fSJohannes Berg 	ack = skb->wifi_acked;
8576e3e939fSJohannes Berg 
8586e3e939fSJohannes Berg 	put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack);
8596e3e939fSJohannes Berg }
8606e3e939fSJohannes Berg EXPORT_SYMBOL_GPL(__sock_recv_wifi_status);
8616e3e939fSJohannes Berg 
86211165f14Sstephen hemminger static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
86311165f14Sstephen hemminger 				   struct sk_buff *skb)
8643b885787SNeil Horman {
865744d5a3eSEyal Birger 	if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount)
8663b885787SNeil Horman 		put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
867744d5a3eSEyal Birger 			sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
8683b885787SNeil Horman }
8693b885787SNeil Horman 
870767dd033SEric Dumazet void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
8713b885787SNeil Horman 	struct sk_buff *skb)
8723b885787SNeil Horman {
8733b885787SNeil Horman 	sock_recv_timestamp(msg, sk, skb);
8743b885787SNeil Horman 	sock_recv_drops(msg, sk, skb);
8753b885787SNeil Horman }
876767dd033SEric Dumazet EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops);
8773b885787SNeil Horman 
8788c3c447bSPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *,
8798c3c447bSPaolo Abeni 					   size_t, int));
880a648a592SPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet6_recvmsg(struct socket *, struct msghdr *,
881a648a592SPaolo Abeni 					    size_t, int));
8821b784140SYing Xue static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
8831b784140SYing Xue 				     int flags)
884a2e27255SArnaldo Carvalho de Melo {
885a648a592SPaolo Abeni 	return INDIRECT_CALL_INET(sock->ops->recvmsg, inet6_recvmsg,
886a648a592SPaolo Abeni 				  inet_recvmsg, sock, msg, msg_data_left(msg),
887a648a592SPaolo Abeni 				  flags);
8882da62906SAl Viro }
889a2e27255SArnaldo Carvalho de Melo 
89085806af0SRandy Dunlap /**
89185806af0SRandy Dunlap  *	sock_recvmsg - receive a message from @sock
89285806af0SRandy Dunlap  *	@sock: socket
89385806af0SRandy Dunlap  *	@msg: message to receive
89485806af0SRandy Dunlap  *	@flags: message flags
89585806af0SRandy Dunlap  *
89685806af0SRandy Dunlap  *	Receives @msg from @sock, passing through LSM. Returns the total number
89785806af0SRandy Dunlap  *	of bytes received, or an error.
89885806af0SRandy Dunlap  */
8992da62906SAl Viro int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags)
9002da62906SAl Viro {
9012da62906SAl Viro 	int err = security_socket_recvmsg(sock, msg, msg_data_left(msg), flags);
9022da62906SAl Viro 
9032da62906SAl Viro 	return err ?: sock_recvmsg_nosec(sock, msg, flags);
9041da177e4SLinus Torvalds }
905c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_recvmsg);
9061da177e4SLinus Torvalds 
907c1249c0aSMartin Lucina /**
908c1249c0aSMartin Lucina  *	kernel_recvmsg - Receive a message from a socket (kernel space)
909c1249c0aSMartin Lucina  *	@sock: The socket to receive the message from
910c1249c0aSMartin Lucina  *	@msg: Received message
911c1249c0aSMartin Lucina  *	@vec: Input s/g array for message data
912c1249c0aSMartin Lucina  *	@num: Size of input s/g array
913c1249c0aSMartin Lucina  *	@size: Number of bytes to read
914c1249c0aSMartin Lucina  *	@flags: Message flags (MSG_DONTWAIT, etc...)
915c1249c0aSMartin Lucina  *
916c1249c0aSMartin Lucina  *	On return the msg structure contains the scatter/gather array passed in the
917c1249c0aSMartin Lucina  *	vec argument. The array is modified so that it consists of the unfilled
918c1249c0aSMartin Lucina  *	portion of the original array.
919c1249c0aSMartin Lucina  *
920c1249c0aSMartin Lucina  *	The returned value is the total number of bytes received, or an error.
921c1249c0aSMartin Lucina  */
9228a3c245cSPedro Tammela 
9231da177e4SLinus Torvalds int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
92489bddce5SStephen Hemminger 		   struct kvec *vec, size_t num, size_t size, int flags)
9251da177e4SLinus Torvalds {
9261f466e1fSChristoph Hellwig 	msg->msg_control_is_user = false;
927aa563d7bSDavid Howells 	iov_iter_kvec(&msg->msg_iter, READ, vec, num, size);
9281f466e1fSChristoph Hellwig 	return sock_recvmsg(sock, msg, flags);
9291da177e4SLinus Torvalds }
930c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_recvmsg);
9311da177e4SLinus Torvalds 
93220380731SArnaldo Carvalho de Melo static ssize_t sock_sendpage(struct file *file, struct page *page,
9331da177e4SLinus Torvalds 			     int offset, size_t size, loff_t *ppos, int more)
9341da177e4SLinus Torvalds {
9351da177e4SLinus Torvalds 	struct socket *sock;
9361da177e4SLinus Torvalds 	int flags;
9371da177e4SLinus Torvalds 
938b69aee04SEric Dumazet 	sock = file->private_data;
9391da177e4SLinus Torvalds 
94035f9c09fSEric Dumazet 	flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
94135f9c09fSEric Dumazet 	/* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */
94235f9c09fSEric Dumazet 	flags |= more;
9431da177e4SLinus Torvalds 
944e6949583SLinus Torvalds 	return kernel_sendpage(sock, page, offset, size, flags);
9451da177e4SLinus Torvalds }
9461da177e4SLinus Torvalds 
9479c55e01cSJens Axboe static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
9489c55e01cSJens Axboe 				struct pipe_inode_info *pipe, size_t len,
9499c55e01cSJens Axboe 				unsigned int flags)
9509c55e01cSJens Axboe {
9519c55e01cSJens Axboe 	struct socket *sock = file->private_data;
9529c55e01cSJens Axboe 
953997b37daSRémi Denis-Courmont 	if (unlikely(!sock->ops->splice_read))
95495506588SSlavomir Kaslev 		return generic_file_splice_read(file, ppos, pipe, len, flags);
955997b37daSRémi Denis-Courmont 
9569c55e01cSJens Axboe 	return sock->ops->splice_read(sock, ppos, pipe, len, flags);
9579c55e01cSJens Axboe }
9589c55e01cSJens Axboe 
9598ae5e030SAl Viro static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
960ce1d4d3eSChristoph Hellwig {
9616d652330SAl Viro 	struct file *file = iocb->ki_filp;
9626d652330SAl Viro 	struct socket *sock = file->private_data;
9630345f931Stadeusz.struk@intel.com 	struct msghdr msg = {.msg_iter = *to,
9640345f931Stadeusz.struk@intel.com 			     .msg_iocb = iocb};
9658ae5e030SAl Viro 	ssize_t res;
966ce1d4d3eSChristoph Hellwig 
967ebfcd895SJens Axboe 	if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT))
9688ae5e030SAl Viro 		msg.msg_flags = MSG_DONTWAIT;
9698ae5e030SAl Viro 
9708ae5e030SAl Viro 	if (iocb->ki_pos != 0)
971ce1d4d3eSChristoph Hellwig 		return -ESPIPE;
972027445c3SBadari Pulavarty 
97366ee59afSChristoph Hellwig 	if (!iov_iter_count(to))	/* Match SYS5 behaviour */
974ce1d4d3eSChristoph Hellwig 		return 0;
975ce1d4d3eSChristoph Hellwig 
9762da62906SAl Viro 	res = sock_recvmsg(sock, &msg, msg.msg_flags);
9778ae5e030SAl Viro 	*to = msg.msg_iter;
9788ae5e030SAl Viro 	return res;
979ce1d4d3eSChristoph Hellwig }
980ce1d4d3eSChristoph Hellwig 
9818ae5e030SAl Viro static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
9821da177e4SLinus Torvalds {
9836d652330SAl Viro 	struct file *file = iocb->ki_filp;
9846d652330SAl Viro 	struct socket *sock = file->private_data;
9850345f931Stadeusz.struk@intel.com 	struct msghdr msg = {.msg_iter = *from,
9860345f931Stadeusz.struk@intel.com 			     .msg_iocb = iocb};
9878ae5e030SAl Viro 	ssize_t res;
9881da177e4SLinus Torvalds 
9898ae5e030SAl Viro 	if (iocb->ki_pos != 0)
990ce1d4d3eSChristoph Hellwig 		return -ESPIPE;
991027445c3SBadari Pulavarty 
992ebfcd895SJens Axboe 	if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT))
9938ae5e030SAl Viro 		msg.msg_flags = MSG_DONTWAIT;
9948ae5e030SAl Viro 
9956d652330SAl Viro 	if (sock->type == SOCK_SEQPACKET)
9966d652330SAl Viro 		msg.msg_flags |= MSG_EOR;
9976d652330SAl Viro 
998d8725c86SAl Viro 	res = sock_sendmsg(sock, &msg);
9998ae5e030SAl Viro 	*from = msg.msg_iter;
10008ae5e030SAl Viro 	return res;
10011da177e4SLinus Torvalds }
10021da177e4SLinus Torvalds 
10031da177e4SLinus Torvalds /*
10041da177e4SLinus Torvalds  * Atomic setting of ioctl hooks to avoid race
10051da177e4SLinus Torvalds  * with module unload.
10061da177e4SLinus Torvalds  */
10071da177e4SLinus Torvalds 
10084a3e2f71SArjan van de Ven static DEFINE_MUTEX(br_ioctl_mutex);
1009c6d409cfSEric Dumazet static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg);
10101da177e4SLinus Torvalds 
1011881d966bSEric W. Biederman void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
10121da177e4SLinus Torvalds {
10134a3e2f71SArjan van de Ven 	mutex_lock(&br_ioctl_mutex);
10141da177e4SLinus Torvalds 	br_ioctl_hook = hook;
10154a3e2f71SArjan van de Ven 	mutex_unlock(&br_ioctl_mutex);
10161da177e4SLinus Torvalds }
10171da177e4SLinus Torvalds EXPORT_SYMBOL(brioctl_set);
10181da177e4SLinus Torvalds 
10194a3e2f71SArjan van de Ven static DEFINE_MUTEX(vlan_ioctl_mutex);
1020881d966bSEric W. Biederman static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
10211da177e4SLinus Torvalds 
1022881d966bSEric W. Biederman void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
10231da177e4SLinus Torvalds {
10244a3e2f71SArjan van de Ven 	mutex_lock(&vlan_ioctl_mutex);
10251da177e4SLinus Torvalds 	vlan_ioctl_hook = hook;
10264a3e2f71SArjan van de Ven 	mutex_unlock(&vlan_ioctl_mutex);
10271da177e4SLinus Torvalds }
10281da177e4SLinus Torvalds EXPORT_SYMBOL(vlan_ioctl_set);
10291da177e4SLinus Torvalds 
10304a3e2f71SArjan van de Ven static DEFINE_MUTEX(dlci_ioctl_mutex);
10311da177e4SLinus Torvalds static int (*dlci_ioctl_hook) (unsigned int, void __user *);
10321da177e4SLinus Torvalds 
10331da177e4SLinus Torvalds void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
10341da177e4SLinus Torvalds {
10354a3e2f71SArjan van de Ven 	mutex_lock(&dlci_ioctl_mutex);
10361da177e4SLinus Torvalds 	dlci_ioctl_hook = hook;
10374a3e2f71SArjan van de Ven 	mutex_unlock(&dlci_ioctl_mutex);
10381da177e4SLinus Torvalds }
10391da177e4SLinus Torvalds EXPORT_SYMBOL(dlci_ioctl_set);
10401da177e4SLinus Torvalds 
10416b96018bSArnd Bergmann static long sock_do_ioctl(struct net *net, struct socket *sock,
104263ff03abSJohannes Berg 			  unsigned int cmd, unsigned long arg)
10436b96018bSArnd Bergmann {
10446b96018bSArnd Bergmann 	int err;
10456b96018bSArnd Bergmann 	void __user *argp = (void __user *)arg;
10466b96018bSArnd Bergmann 
10476b96018bSArnd Bergmann 	err = sock->ops->ioctl(sock, cmd, arg);
10486b96018bSArnd Bergmann 
10496b96018bSArnd Bergmann 	/*
10506b96018bSArnd Bergmann 	 * If this ioctl is unknown try to hand it down
10516b96018bSArnd Bergmann 	 * to the NIC driver.
10526b96018bSArnd Bergmann 	 */
105336fd633eSAl Viro 	if (err != -ENOIOCTLCMD)
10546b96018bSArnd Bergmann 		return err;
10556b96018bSArnd Bergmann 
105636fd633eSAl Viro 	if (cmd == SIOCGIFCONF) {
105736fd633eSAl Viro 		struct ifconf ifc;
105836fd633eSAl Viro 		if (copy_from_user(&ifc, argp, sizeof(struct ifconf)))
105936fd633eSAl Viro 			return -EFAULT;
106036fd633eSAl Viro 		rtnl_lock();
106136fd633eSAl Viro 		err = dev_ifconf(net, &ifc, sizeof(struct ifreq));
106236fd633eSAl Viro 		rtnl_unlock();
106336fd633eSAl Viro 		if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf)))
106436fd633eSAl Viro 			err = -EFAULT;
106544c02a2cSAl Viro 	} else {
106644c02a2cSAl Viro 		struct ifreq ifr;
106744c02a2cSAl Viro 		bool need_copyout;
106863ff03abSJohannes Berg 		if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
106944c02a2cSAl Viro 			return -EFAULT;
107044c02a2cSAl Viro 		err = dev_ioctl(net, cmd, &ifr, &need_copyout);
107144c02a2cSAl Viro 		if (!err && need_copyout)
107263ff03abSJohannes Berg 			if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
107344c02a2cSAl Viro 				return -EFAULT;
107436fd633eSAl Viro 	}
10756b96018bSArnd Bergmann 	return err;
10766b96018bSArnd Bergmann }
10776b96018bSArnd Bergmann 
10781da177e4SLinus Torvalds /*
10791da177e4SLinus Torvalds  *	With an ioctl, arg may well be a user mode pointer, but we don't know
10801da177e4SLinus Torvalds  *	what to do with it - that's up to the protocol still.
10811da177e4SLinus Torvalds  */
10821da177e4SLinus Torvalds 
10838a3c245cSPedro Tammela /**
10848a3c245cSPedro Tammela  *	get_net_ns - increment the refcount of the network namespace
10858a3c245cSPedro Tammela  *	@ns: common namespace (net)
10868a3c245cSPedro Tammela  *
10878a3c245cSPedro Tammela  *	Returns the net's common namespace.
10888a3c245cSPedro Tammela  */
10898a3c245cSPedro Tammela 
1090d8d211a2SKirill Tkhai struct ns_common *get_net_ns(struct ns_common *ns)
1091c62cce2cSAndrey Vagin {
1092c62cce2cSAndrey Vagin 	return &get_net(container_of(ns, struct net, ns))->ns;
1093c62cce2cSAndrey Vagin }
1094d8d211a2SKirill Tkhai EXPORT_SYMBOL_GPL(get_net_ns);
1095c62cce2cSAndrey Vagin 
10961da177e4SLinus Torvalds static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
10971da177e4SLinus Torvalds {
10981da177e4SLinus Torvalds 	struct socket *sock;
1099881d966bSEric W. Biederman 	struct sock *sk;
11001da177e4SLinus Torvalds 	void __user *argp = (void __user *)arg;
11011da177e4SLinus Torvalds 	int pid, err;
1102881d966bSEric W. Biederman 	struct net *net;
11031da177e4SLinus Torvalds 
1104b69aee04SEric Dumazet 	sock = file->private_data;
1105881d966bSEric W. Biederman 	sk = sock->sk;
11063b1e0a65SYOSHIFUJI Hideaki 	net = sock_net(sk);
110744c02a2cSAl Viro 	if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) {
110844c02a2cSAl Viro 		struct ifreq ifr;
110944c02a2cSAl Viro 		bool need_copyout;
111044c02a2cSAl Viro 		if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
111144c02a2cSAl Viro 			return -EFAULT;
111244c02a2cSAl Viro 		err = dev_ioctl(net, cmd, &ifr, &need_copyout);
111344c02a2cSAl Viro 		if (!err && need_copyout)
111444c02a2cSAl Viro 			if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
111544c02a2cSAl Viro 				return -EFAULT;
11161da177e4SLinus Torvalds 	} else
11173d23e349SJohannes Berg #ifdef CONFIG_WEXT_CORE
11181da177e4SLinus Torvalds 	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
1119b1b0c245SAl Viro 		err = wext_handle_ioctl(net, cmd, argp);
11201da177e4SLinus Torvalds 	} else
11213d23e349SJohannes Berg #endif
11221da177e4SLinus Torvalds 		switch (cmd) {
11231da177e4SLinus Torvalds 		case FIOSETOWN:
11241da177e4SLinus Torvalds 		case SIOCSPGRP:
11251da177e4SLinus Torvalds 			err = -EFAULT;
11261da177e4SLinus Torvalds 			if (get_user(pid, (int __user *)argp))
11271da177e4SLinus Torvalds 				break;
1128393cc3f5SJiri Slaby 			err = f_setown(sock->file, pid, 1);
11291da177e4SLinus Torvalds 			break;
11301da177e4SLinus Torvalds 		case FIOGETOWN:
11311da177e4SLinus Torvalds 		case SIOCGPGRP:
1132609d7fa9SEric W. Biederman 			err = put_user(f_getown(sock->file),
113389bddce5SStephen Hemminger 				       (int __user *)argp);
11341da177e4SLinus Torvalds 			break;
11351da177e4SLinus Torvalds 		case SIOCGIFBR:
11361da177e4SLinus Torvalds 		case SIOCSIFBR:
11371da177e4SLinus Torvalds 		case SIOCBRADDBR:
11381da177e4SLinus Torvalds 		case SIOCBRDELBR:
11391da177e4SLinus Torvalds 			err = -ENOPKG;
11401da177e4SLinus Torvalds 			if (!br_ioctl_hook)
11411da177e4SLinus Torvalds 				request_module("bridge");
11421da177e4SLinus Torvalds 
11434a3e2f71SArjan van de Ven 			mutex_lock(&br_ioctl_mutex);
11441da177e4SLinus Torvalds 			if (br_ioctl_hook)
1145881d966bSEric W. Biederman 				err = br_ioctl_hook(net, cmd, argp);
11464a3e2f71SArjan van de Ven 			mutex_unlock(&br_ioctl_mutex);
11471da177e4SLinus Torvalds 			break;
11481da177e4SLinus Torvalds 		case SIOCGIFVLAN:
11491da177e4SLinus Torvalds 		case SIOCSIFVLAN:
11501da177e4SLinus Torvalds 			err = -ENOPKG;
11511da177e4SLinus Torvalds 			if (!vlan_ioctl_hook)
11521da177e4SLinus Torvalds 				request_module("8021q");
11531da177e4SLinus Torvalds 
11544a3e2f71SArjan van de Ven 			mutex_lock(&vlan_ioctl_mutex);
11551da177e4SLinus Torvalds 			if (vlan_ioctl_hook)
1156881d966bSEric W. Biederman 				err = vlan_ioctl_hook(net, argp);
11574a3e2f71SArjan van de Ven 			mutex_unlock(&vlan_ioctl_mutex);
11581da177e4SLinus Torvalds 			break;
11591da177e4SLinus Torvalds 		case SIOCADDDLCI:
11601da177e4SLinus Torvalds 		case SIOCDELDLCI:
11611da177e4SLinus Torvalds 			err = -ENOPKG;
11621da177e4SLinus Torvalds 			if (!dlci_ioctl_hook)
11631da177e4SLinus Torvalds 				request_module("dlci");
11641da177e4SLinus Torvalds 
11654a3e2f71SArjan van de Ven 			mutex_lock(&dlci_ioctl_mutex);
11667512cbf6SPavel Emelyanov 			if (dlci_ioctl_hook)
11671da177e4SLinus Torvalds 				err = dlci_ioctl_hook(cmd, argp);
11684a3e2f71SArjan van de Ven 			mutex_unlock(&dlci_ioctl_mutex);
11691da177e4SLinus Torvalds 			break;
1170c62cce2cSAndrey Vagin 		case SIOCGSKNS:
1171c62cce2cSAndrey Vagin 			err = -EPERM;
1172c62cce2cSAndrey Vagin 			if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1173c62cce2cSAndrey Vagin 				break;
1174c62cce2cSAndrey Vagin 
1175c62cce2cSAndrey Vagin 			err = open_related_ns(&net->ns, get_net_ns);
1176c62cce2cSAndrey Vagin 			break;
11770768e170SArnd Bergmann 		case SIOCGSTAMP_OLD:
11780768e170SArnd Bergmann 		case SIOCGSTAMPNS_OLD:
1179c7cbdbf2SArnd Bergmann 			if (!sock->ops->gettstamp) {
1180c7cbdbf2SArnd Bergmann 				err = -ENOIOCTLCMD;
1181c7cbdbf2SArnd Bergmann 				break;
1182c7cbdbf2SArnd Bergmann 			}
1183c7cbdbf2SArnd Bergmann 			err = sock->ops->gettstamp(sock, argp,
11840768e170SArnd Bergmann 						   cmd == SIOCGSTAMP_OLD,
11850768e170SArnd Bergmann 						   !IS_ENABLED(CONFIG_64BIT));
118660747828SGustavo A. R. Silva 			break;
11870768e170SArnd Bergmann 		case SIOCGSTAMP_NEW:
11880768e170SArnd Bergmann 		case SIOCGSTAMPNS_NEW:
11890768e170SArnd Bergmann 			if (!sock->ops->gettstamp) {
11900768e170SArnd Bergmann 				err = -ENOIOCTLCMD;
11910768e170SArnd Bergmann 				break;
11920768e170SArnd Bergmann 			}
11930768e170SArnd Bergmann 			err = sock->ops->gettstamp(sock, argp,
11940768e170SArnd Bergmann 						   cmd == SIOCGSTAMP_NEW,
11950768e170SArnd Bergmann 						   false);
1196c7cbdbf2SArnd Bergmann 			break;
11971da177e4SLinus Torvalds 		default:
119863ff03abSJohannes Berg 			err = sock_do_ioctl(net, sock, cmd, arg);
11991da177e4SLinus Torvalds 			break;
12001da177e4SLinus Torvalds 		}
12011da177e4SLinus Torvalds 	return err;
12021da177e4SLinus Torvalds }
12031da177e4SLinus Torvalds 
12048a3c245cSPedro Tammela /**
12058a3c245cSPedro Tammela  *	sock_create_lite - creates a socket
12068a3c245cSPedro Tammela  *	@family: protocol family (AF_INET, ...)
12078a3c245cSPedro Tammela  *	@type: communication type (SOCK_STREAM, ...)
12088a3c245cSPedro Tammela  *	@protocol: protocol (0, ...)
12098a3c245cSPedro Tammela  *	@res: new socket
12108a3c245cSPedro Tammela  *
12118a3c245cSPedro Tammela  *	Creates a new socket and assigns it to @res, passing through LSM.
12128a3c245cSPedro Tammela  *	The new socket initialization is not complete, see kernel_accept().
12138a3c245cSPedro Tammela  *	Returns 0 or an error. On failure @res is set to %NULL.
12148a3c245cSPedro Tammela  *	This function internally uses GFP_KERNEL.
12158a3c245cSPedro Tammela  */
12168a3c245cSPedro Tammela 
12171da177e4SLinus Torvalds int sock_create_lite(int family, int type, int protocol, struct socket **res)
12181da177e4SLinus Torvalds {
12191da177e4SLinus Torvalds 	int err;
12201da177e4SLinus Torvalds 	struct socket *sock = NULL;
12211da177e4SLinus Torvalds 
12221da177e4SLinus Torvalds 	err = security_socket_create(family, type, protocol, 1);
12231da177e4SLinus Torvalds 	if (err)
12241da177e4SLinus Torvalds 		goto out;
12251da177e4SLinus Torvalds 
12261da177e4SLinus Torvalds 	sock = sock_alloc();
12271da177e4SLinus Torvalds 	if (!sock) {
12281da177e4SLinus Torvalds 		err = -ENOMEM;
12291da177e4SLinus Torvalds 		goto out;
12301da177e4SLinus Torvalds 	}
12311da177e4SLinus Torvalds 
12321da177e4SLinus Torvalds 	sock->type = type;
12337420ed23SVenkat Yekkirala 	err = security_socket_post_create(sock, family, type, protocol, 1);
12347420ed23SVenkat Yekkirala 	if (err)
12357420ed23SVenkat Yekkirala 		goto out_release;
12367420ed23SVenkat Yekkirala 
12371da177e4SLinus Torvalds out:
12381da177e4SLinus Torvalds 	*res = sock;
12391da177e4SLinus Torvalds 	return err;
12407420ed23SVenkat Yekkirala out_release:
12417420ed23SVenkat Yekkirala 	sock_release(sock);
12427420ed23SVenkat Yekkirala 	sock = NULL;
12437420ed23SVenkat Yekkirala 	goto out;
12441da177e4SLinus Torvalds }
1245c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_create_lite);
12461da177e4SLinus Torvalds 
12471da177e4SLinus Torvalds /* No kernel lock held - perfect */
1248ade994f4SAl Viro static __poll_t sock_poll(struct file *file, poll_table *wait)
12491da177e4SLinus Torvalds {
12503cafb376SChristoph Hellwig 	struct socket *sock = file->private_data;
1251a331de3bSChristoph Hellwig 	__poll_t events = poll_requested_events(wait), flag = 0;
12521da177e4SLinus Torvalds 
1253e88958e6SChristoph Hellwig 	if (!sock->ops->poll)
1254e88958e6SChristoph Hellwig 		return 0;
1255f641f13bSChristoph Hellwig 
1256a331de3bSChristoph Hellwig 	if (sk_can_busy_loop(sock->sk)) {
1257f641f13bSChristoph Hellwig 		/* poll once if requested by the syscall */
1258a331de3bSChristoph Hellwig 		if (events & POLL_BUSY_LOOP)
1259f641f13bSChristoph Hellwig 			sk_busy_loop(sock->sk, 1);
1260a331de3bSChristoph Hellwig 
1261a331de3bSChristoph Hellwig 		/* if this socket can poll_ll, tell the system call */
1262a331de3bSChristoph Hellwig 		flag = POLL_BUSY_LOOP;
1263a331de3bSChristoph Hellwig 	}
1264a331de3bSChristoph Hellwig 
1265a331de3bSChristoph Hellwig 	return sock->ops->poll(file, sock, wait) | flag;
12661da177e4SLinus Torvalds }
12671da177e4SLinus Torvalds 
12681da177e4SLinus Torvalds static int sock_mmap(struct file *file, struct vm_area_struct *vma)
12691da177e4SLinus Torvalds {
1270b69aee04SEric Dumazet 	struct socket *sock = file->private_data;
12711da177e4SLinus Torvalds 
12721da177e4SLinus Torvalds 	return sock->ops->mmap(file, sock, vma);
12731da177e4SLinus Torvalds }
12741da177e4SLinus Torvalds 
127520380731SArnaldo Carvalho de Melo static int sock_close(struct inode *inode, struct file *filp)
12761da177e4SLinus Torvalds {
12776d8c50dcSCong Wang 	__sock_release(SOCKET_I(inode), inode);
12781da177e4SLinus Torvalds 	return 0;
12791da177e4SLinus Torvalds }
12801da177e4SLinus Torvalds 
12811da177e4SLinus Torvalds /*
12821da177e4SLinus Torvalds  *	Update the socket async list
12831da177e4SLinus Torvalds  *
12841da177e4SLinus Torvalds  *	Fasync_list locking strategy.
12851da177e4SLinus Torvalds  *
12861da177e4SLinus Torvalds  *	1. fasync_list is modified only under process context socket lock
12871da177e4SLinus Torvalds  *	   i.e. under semaphore.
12881da177e4SLinus Torvalds  *	2. fasync_list is used under read_lock(&sk->sk_callback_lock)
1289989a2979SEric Dumazet  *	   or under socket lock
12901da177e4SLinus Torvalds  */
12911da177e4SLinus Torvalds 
12921da177e4SLinus Torvalds static int sock_fasync(int fd, struct file *filp, int on)
12931da177e4SLinus Torvalds {
1294989a2979SEric Dumazet 	struct socket *sock = filp->private_data;
1295989a2979SEric Dumazet 	struct sock *sk = sock->sk;
1296333f7909SAl Viro 	struct socket_wq *wq = &sock->wq;
12971da177e4SLinus Torvalds 
1298989a2979SEric Dumazet 	if (sk == NULL)
12991da177e4SLinus Torvalds 		return -EINVAL;
13001da177e4SLinus Torvalds 
13011da177e4SLinus Torvalds 	lock_sock(sk);
1302eaefd110SEric Dumazet 	fasync_helper(fd, filp, on, &wq->fasync_list);
13031da177e4SLinus Torvalds 
1304eaefd110SEric Dumazet 	if (!wq->fasync_list)
1305bcdce719SEric Dumazet 		sock_reset_flag(sk, SOCK_FASYNC);
1306989a2979SEric Dumazet 	else
1307989a2979SEric Dumazet 		sock_set_flag(sk, SOCK_FASYNC);
13081da177e4SLinus Torvalds 
1309989a2979SEric Dumazet 	release_sock(sk);
13101da177e4SLinus Torvalds 	return 0;
13111da177e4SLinus Torvalds }
13121da177e4SLinus Torvalds 
1313ceb5d58bSEric Dumazet /* This function may be called only under rcu_lock */
13141da177e4SLinus Torvalds 
1315ceb5d58bSEric Dumazet int sock_wake_async(struct socket_wq *wq, int how, int band)
13161da177e4SLinus Torvalds {
1317ceb5d58bSEric Dumazet 	if (!wq || !wq->fasync_list)
1318ceb5d58bSEric Dumazet 		return -1;
131943815482SEric Dumazet 
132089bddce5SStephen Hemminger 	switch (how) {
13218d8ad9d7SPavel Emelyanov 	case SOCK_WAKE_WAITD:
1322ceb5d58bSEric Dumazet 		if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags))
13231da177e4SLinus Torvalds 			break;
13241da177e4SLinus Torvalds 		goto call_kill;
13258d8ad9d7SPavel Emelyanov 	case SOCK_WAKE_SPACE:
1326ceb5d58bSEric Dumazet 		if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags))
13271da177e4SLinus Torvalds 			break;
13281da177e4SLinus Torvalds 		/* fall through */
13298d8ad9d7SPavel Emelyanov 	case SOCK_WAKE_IO:
13301da177e4SLinus Torvalds call_kill:
133143815482SEric Dumazet 		kill_fasync(&wq->fasync_list, SIGIO, band);
13321da177e4SLinus Torvalds 		break;
13338d8ad9d7SPavel Emelyanov 	case SOCK_WAKE_URG:
133443815482SEric Dumazet 		kill_fasync(&wq->fasync_list, SIGURG, band);
13351da177e4SLinus Torvalds 	}
1336ceb5d58bSEric Dumazet 
13371da177e4SLinus Torvalds 	return 0;
13381da177e4SLinus Torvalds }
1339c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_wake_async);
13401da177e4SLinus Torvalds 
13418a3c245cSPedro Tammela /**
13428a3c245cSPedro Tammela  *	__sock_create - creates a socket
13438a3c245cSPedro Tammela  *	@net: net namespace
13448a3c245cSPedro Tammela  *	@family: protocol family (AF_INET, ...)
13458a3c245cSPedro Tammela  *	@type: communication type (SOCK_STREAM, ...)
13468a3c245cSPedro Tammela  *	@protocol: protocol (0, ...)
13478a3c245cSPedro Tammela  *	@res: new socket
13488a3c245cSPedro Tammela  *	@kern: boolean for kernel space sockets
13498a3c245cSPedro Tammela  *
13508a3c245cSPedro Tammela  *	Creates a new socket and assigns it to @res, passing through LSM.
13518a3c245cSPedro Tammela  *	Returns 0 or an error. On failure @res is set to %NULL. @kern must
13528a3c245cSPedro Tammela  *	be set to true if the socket resides in kernel space.
13538a3c245cSPedro Tammela  *	This function internally uses GFP_KERNEL.
13548a3c245cSPedro Tammela  */
13558a3c245cSPedro Tammela 
1356721db93aSPavel Emelyanov int __sock_create(struct net *net, int family, int type, int protocol,
135789bddce5SStephen Hemminger 			 struct socket **res, int kern)
13581da177e4SLinus Torvalds {
13591da177e4SLinus Torvalds 	int err;
13601da177e4SLinus Torvalds 	struct socket *sock;
136155737fdaSStephen Hemminger 	const struct net_proto_family *pf;
13621da177e4SLinus Torvalds 
13631da177e4SLinus Torvalds 	/*
13641da177e4SLinus Torvalds 	 *      Check protocol is in range
13651da177e4SLinus Torvalds 	 */
13661da177e4SLinus Torvalds 	if (family < 0 || family >= NPROTO)
13671da177e4SLinus Torvalds 		return -EAFNOSUPPORT;
13681da177e4SLinus Torvalds 	if (type < 0 || type >= SOCK_MAX)
13691da177e4SLinus Torvalds 		return -EINVAL;
13701da177e4SLinus Torvalds 
13711da177e4SLinus Torvalds 	/* Compatibility.
13721da177e4SLinus Torvalds 
13731da177e4SLinus Torvalds 	   This uglymoron is moved from INET layer to here to avoid
13741da177e4SLinus Torvalds 	   deadlock in module load.
13751da177e4SLinus Torvalds 	 */
13761da177e4SLinus Torvalds 	if (family == PF_INET && type == SOCK_PACKET) {
1377f3c98690Sliping.zhang 		pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)\n",
137889bddce5SStephen Hemminger 			     current->comm);
13791da177e4SLinus Torvalds 		family = PF_PACKET;
13801da177e4SLinus Torvalds 	}
13811da177e4SLinus Torvalds 
13821da177e4SLinus Torvalds 	err = security_socket_create(family, type, protocol, kern);
13831da177e4SLinus Torvalds 	if (err)
13841da177e4SLinus Torvalds 		return err;
13851da177e4SLinus Torvalds 
138655737fdaSStephen Hemminger 	/*
138755737fdaSStephen Hemminger 	 *	Allocate the socket and allow the family to set things up. if
138855737fdaSStephen Hemminger 	 *	the protocol is 0, the family is instructed to select an appropriate
138955737fdaSStephen Hemminger 	 *	default.
139055737fdaSStephen Hemminger 	 */
139155737fdaSStephen Hemminger 	sock = sock_alloc();
139255737fdaSStephen Hemminger 	if (!sock) {
1393e87cc472SJoe Perches 		net_warn_ratelimited("socket: no more sockets\n");
139455737fdaSStephen Hemminger 		return -ENFILE;	/* Not exactly a match, but its the
139555737fdaSStephen Hemminger 				   closest posix thing */
139655737fdaSStephen Hemminger 	}
139755737fdaSStephen Hemminger 
139855737fdaSStephen Hemminger 	sock->type = type;
139955737fdaSStephen Hemminger 
140095a5afcaSJohannes Berg #ifdef CONFIG_MODULES
14011da177e4SLinus Torvalds 	/* Attempt to load a protocol module if the find failed.
14021da177e4SLinus Torvalds 	 *
14031da177e4SLinus Torvalds 	 * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
14041da177e4SLinus Torvalds 	 * requested real, full-featured networking support upon configuration.
14051da177e4SLinus Torvalds 	 * Otherwise module support will break!
14061da177e4SLinus Torvalds 	 */
1407190683a9SEric Dumazet 	if (rcu_access_pointer(net_families[family]) == NULL)
14081da177e4SLinus Torvalds 		request_module("net-pf-%d", family);
14091da177e4SLinus Torvalds #endif
14101da177e4SLinus Torvalds 
141155737fdaSStephen Hemminger 	rcu_read_lock();
141255737fdaSStephen Hemminger 	pf = rcu_dereference(net_families[family]);
14131da177e4SLinus Torvalds 	err = -EAFNOSUPPORT;
141455737fdaSStephen Hemminger 	if (!pf)
141555737fdaSStephen Hemminger 		goto out_release;
14161da177e4SLinus Torvalds 
14171da177e4SLinus Torvalds 	/*
14181da177e4SLinus Torvalds 	 * We will call the ->create function, that possibly is in a loadable
14191da177e4SLinus Torvalds 	 * module, so we have to bump that loadable module refcnt first.
14201da177e4SLinus Torvalds 	 */
142155737fdaSStephen Hemminger 	if (!try_module_get(pf->owner))
14221da177e4SLinus Torvalds 		goto out_release;
14231da177e4SLinus Torvalds 
142455737fdaSStephen Hemminger 	/* Now protected by module ref count */
142555737fdaSStephen Hemminger 	rcu_read_unlock();
142655737fdaSStephen Hemminger 
14273f378b68SEric Paris 	err = pf->create(net, sock, protocol, kern);
142855737fdaSStephen Hemminger 	if (err < 0)
14291da177e4SLinus Torvalds 		goto out_module_put;
1430a79af59eSFrank Filz 
14311da177e4SLinus Torvalds 	/*
14321da177e4SLinus Torvalds 	 * Now to bump the refcnt of the [loadable] module that owns this
14331da177e4SLinus Torvalds 	 * socket at sock_release time we decrement its refcnt.
14341da177e4SLinus Torvalds 	 */
143555737fdaSStephen Hemminger 	if (!try_module_get(sock->ops->owner))
143655737fdaSStephen Hemminger 		goto out_module_busy;
143755737fdaSStephen Hemminger 
14381da177e4SLinus Torvalds 	/*
14391da177e4SLinus Torvalds 	 * Now that we're done with the ->create function, the [loadable]
14401da177e4SLinus Torvalds 	 * module can have its refcnt decremented
14411da177e4SLinus Torvalds 	 */
144255737fdaSStephen Hemminger 	module_put(pf->owner);
14437420ed23SVenkat Yekkirala 	err = security_socket_post_create(sock, family, type, protocol, kern);
14447420ed23SVenkat Yekkirala 	if (err)
14453b185525SHerbert Xu 		goto out_sock_release;
144655737fdaSStephen Hemminger 	*res = sock;
14471da177e4SLinus Torvalds 
144855737fdaSStephen Hemminger 	return 0;
144955737fdaSStephen Hemminger 
145055737fdaSStephen Hemminger out_module_busy:
145155737fdaSStephen Hemminger 	err = -EAFNOSUPPORT;
14521da177e4SLinus Torvalds out_module_put:
145355737fdaSStephen Hemminger 	sock->ops = NULL;
145455737fdaSStephen Hemminger 	module_put(pf->owner);
145555737fdaSStephen Hemminger out_sock_release:
14561da177e4SLinus Torvalds 	sock_release(sock);
145755737fdaSStephen Hemminger 	return err;
145855737fdaSStephen Hemminger 
145955737fdaSStephen Hemminger out_release:
146055737fdaSStephen Hemminger 	rcu_read_unlock();
146155737fdaSStephen Hemminger 	goto out_sock_release;
14621da177e4SLinus Torvalds }
1463721db93aSPavel Emelyanov EXPORT_SYMBOL(__sock_create);
14641da177e4SLinus Torvalds 
14658a3c245cSPedro Tammela /**
14668a3c245cSPedro Tammela  *	sock_create - creates a socket
14678a3c245cSPedro Tammela  *	@family: protocol family (AF_INET, ...)
14688a3c245cSPedro Tammela  *	@type: communication type (SOCK_STREAM, ...)
14698a3c245cSPedro Tammela  *	@protocol: protocol (0, ...)
14708a3c245cSPedro Tammela  *	@res: new socket
14718a3c245cSPedro Tammela  *
14728a3c245cSPedro Tammela  *	A wrapper around __sock_create().
14738a3c245cSPedro Tammela  *	Returns 0 or an error. This function internally uses GFP_KERNEL.
14748a3c245cSPedro Tammela  */
14758a3c245cSPedro Tammela 
14761da177e4SLinus Torvalds int sock_create(int family, int type, int protocol, struct socket **res)
14771da177e4SLinus Torvalds {
14781b8d7ae4SEric W. Biederman 	return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
14791da177e4SLinus Torvalds }
1480c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_create);
14811da177e4SLinus Torvalds 
14828a3c245cSPedro Tammela /**
14838a3c245cSPedro Tammela  *	sock_create_kern - creates a socket (kernel space)
14848a3c245cSPedro Tammela  *	@net: net namespace
14858a3c245cSPedro Tammela  *	@family: protocol family (AF_INET, ...)
14868a3c245cSPedro Tammela  *	@type: communication type (SOCK_STREAM, ...)
14878a3c245cSPedro Tammela  *	@protocol: protocol (0, ...)
14888a3c245cSPedro Tammela  *	@res: new socket
14898a3c245cSPedro Tammela  *
14908a3c245cSPedro Tammela  *	A wrapper around __sock_create().
14918a3c245cSPedro Tammela  *	Returns 0 or an error. This function internally uses GFP_KERNEL.
14928a3c245cSPedro Tammela  */
14938a3c245cSPedro Tammela 
1494eeb1bd5cSEric W. Biederman int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
14951da177e4SLinus Torvalds {
1496eeb1bd5cSEric W. Biederman 	return __sock_create(net, family, type, protocol, res, 1);
14971da177e4SLinus Torvalds }
1498c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_create_kern);
14991da177e4SLinus Torvalds 
15009d6a15c3SDominik Brodowski int __sys_socket(int family, int type, int protocol)
15011da177e4SLinus Torvalds {
15021da177e4SLinus Torvalds 	int retval;
15031da177e4SLinus Torvalds 	struct socket *sock;
1504a677a039SUlrich Drepper 	int flags;
1505a677a039SUlrich Drepper 
1506e38b36f3SUlrich Drepper 	/* Check the SOCK_* constants for consistency.  */
1507e38b36f3SUlrich Drepper 	BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC);
1508e38b36f3SUlrich Drepper 	BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK);
1509e38b36f3SUlrich Drepper 	BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK);
1510e38b36f3SUlrich Drepper 	BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK);
1511e38b36f3SUlrich Drepper 
1512a677a039SUlrich Drepper 	flags = type & ~SOCK_TYPE_MASK;
151377d27200SUlrich Drepper 	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
1514a677a039SUlrich Drepper 		return -EINVAL;
1515a677a039SUlrich Drepper 	type &= SOCK_TYPE_MASK;
15161da177e4SLinus Torvalds 
1517aaca0bdcSUlrich Drepper 	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1518aaca0bdcSUlrich Drepper 		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1519aaca0bdcSUlrich Drepper 
15201da177e4SLinus Torvalds 	retval = sock_create(family, type, protocol, &sock);
15211da177e4SLinus Torvalds 	if (retval < 0)
15221da177e4SLinus Torvalds 		return retval;
15231da177e4SLinus Torvalds 
15248e1611e2SAl Viro 	return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
15251da177e4SLinus Torvalds }
15261da177e4SLinus Torvalds 
15279d6a15c3SDominik Brodowski SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
15289d6a15c3SDominik Brodowski {
15299d6a15c3SDominik Brodowski 	return __sys_socket(family, type, protocol);
15309d6a15c3SDominik Brodowski }
15319d6a15c3SDominik Brodowski 
15321da177e4SLinus Torvalds /*
15331da177e4SLinus Torvalds  *	Create a pair of connected sockets.
15341da177e4SLinus Torvalds  */
15351da177e4SLinus Torvalds 
15366debc8d8SDominik Brodowski int __sys_socketpair(int family, int type, int protocol, int __user *usockvec)
15371da177e4SLinus Torvalds {
15381da177e4SLinus Torvalds 	struct socket *sock1, *sock2;
15391da177e4SLinus Torvalds 	int fd1, fd2, err;
1540db349509SAl Viro 	struct file *newfile1, *newfile2;
1541a677a039SUlrich Drepper 	int flags;
1542a677a039SUlrich Drepper 
1543a677a039SUlrich Drepper 	flags = type & ~SOCK_TYPE_MASK;
154477d27200SUlrich Drepper 	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
1545a677a039SUlrich Drepper 		return -EINVAL;
1546a677a039SUlrich Drepper 	type &= SOCK_TYPE_MASK;
15471da177e4SLinus Torvalds 
1548aaca0bdcSUlrich Drepper 	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1549aaca0bdcSUlrich Drepper 		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1550aaca0bdcSUlrich Drepper 
15511da177e4SLinus Torvalds 	/*
1552016a266bSAl Viro 	 * reserve descriptors and make sure we won't fail
1553016a266bSAl Viro 	 * to return them to userland.
1554016a266bSAl Viro 	 */
1555016a266bSAl Viro 	fd1 = get_unused_fd_flags(flags);
1556016a266bSAl Viro 	if (unlikely(fd1 < 0))
1557016a266bSAl Viro 		return fd1;
1558016a266bSAl Viro 
1559016a266bSAl Viro 	fd2 = get_unused_fd_flags(flags);
1560016a266bSAl Viro 	if (unlikely(fd2 < 0)) {
1561016a266bSAl Viro 		put_unused_fd(fd1);
1562016a266bSAl Viro 		return fd2;
1563016a266bSAl Viro 	}
1564016a266bSAl Viro 
1565016a266bSAl Viro 	err = put_user(fd1, &usockvec[0]);
1566016a266bSAl Viro 	if (err)
1567016a266bSAl Viro 		goto out;
1568016a266bSAl Viro 
1569016a266bSAl Viro 	err = put_user(fd2, &usockvec[1]);
1570016a266bSAl Viro 	if (err)
1571016a266bSAl Viro 		goto out;
1572016a266bSAl Viro 
1573016a266bSAl Viro 	/*
15741da177e4SLinus Torvalds 	 * Obtain the first socket and check if the underlying protocol
15751da177e4SLinus Torvalds 	 * supports the socketpair call.
15761da177e4SLinus Torvalds 	 */
15771da177e4SLinus Torvalds 
15781da177e4SLinus Torvalds 	err = sock_create(family, type, protocol, &sock1);
1579016a266bSAl Viro 	if (unlikely(err < 0))
15801da177e4SLinus Torvalds 		goto out;
15811da177e4SLinus Torvalds 
15821da177e4SLinus Torvalds 	err = sock_create(family, type, protocol, &sock2);
1583016a266bSAl Viro 	if (unlikely(err < 0)) {
1584016a266bSAl Viro 		sock_release(sock1);
1585016a266bSAl Viro 		goto out;
1586bf3c23d1SDavid S. Miller 	}
1587d73aa286SYann Droneaud 
1588d47cd945SDavid Herrmann 	err = security_socket_socketpair(sock1, sock2);
1589d47cd945SDavid Herrmann 	if (unlikely(err)) {
1590d47cd945SDavid Herrmann 		sock_release(sock2);
1591d47cd945SDavid Herrmann 		sock_release(sock1);
1592d47cd945SDavid Herrmann 		goto out;
1593d47cd945SDavid Herrmann 	}
1594d47cd945SDavid Herrmann 
1595016a266bSAl Viro 	err = sock1->ops->socketpair(sock1, sock2);
1596016a266bSAl Viro 	if (unlikely(err < 0)) {
1597016a266bSAl Viro 		sock_release(sock2);
1598016a266bSAl Viro 		sock_release(sock1);
1599016a266bSAl Viro 		goto out;
160028407630SAl Viro 	}
160128407630SAl Viro 
1602aab174f0SLinus Torvalds 	newfile1 = sock_alloc_file(sock1, flags, NULL);
1603b5ffe634SViresh Kumar 	if (IS_ERR(newfile1)) {
160428407630SAl Viro 		err = PTR_ERR(newfile1);
1605016a266bSAl Viro 		sock_release(sock2);
1606016a266bSAl Viro 		goto out;
160728407630SAl Viro 	}
160828407630SAl Viro 
1609aab174f0SLinus Torvalds 	newfile2 = sock_alloc_file(sock2, flags, NULL);
161028407630SAl Viro 	if (IS_ERR(newfile2)) {
161128407630SAl Viro 		err = PTR_ERR(newfile2);
1612016a266bSAl Viro 		fput(newfile1);
1613016a266bSAl Viro 		goto out;
1614db349509SAl Viro 	}
1615db349509SAl Viro 
1616157cf649SAl Viro 	audit_fd_pair(fd1, fd2);
1617d73aa286SYann Droneaud 
1618db349509SAl Viro 	fd_install(fd1, newfile1);
1619db349509SAl Viro 	fd_install(fd2, newfile2);
16201da177e4SLinus Torvalds 	return 0;
16211da177e4SLinus Torvalds 
16221da177e4SLinus Torvalds out:
1623016a266bSAl Viro 	put_unused_fd(fd2);
1624016a266bSAl Viro 	put_unused_fd(fd1);
16251da177e4SLinus Torvalds 	return err;
16261da177e4SLinus Torvalds }
16271da177e4SLinus Torvalds 
16286debc8d8SDominik Brodowski SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
16296debc8d8SDominik Brodowski 		int __user *, usockvec)
16306debc8d8SDominik Brodowski {
16316debc8d8SDominik Brodowski 	return __sys_socketpair(family, type, protocol, usockvec);
16326debc8d8SDominik Brodowski }
16336debc8d8SDominik Brodowski 
16341da177e4SLinus Torvalds /*
16351da177e4SLinus Torvalds  *	Bind a name to a socket. Nothing much to do here since it's
16361da177e4SLinus Torvalds  *	the protocol's responsibility to handle the local address.
16371da177e4SLinus Torvalds  *
16381da177e4SLinus Torvalds  *	We move the socket address to kernel space before we call
16391da177e4SLinus Torvalds  *	the protocol layer (having also checked the address is ok).
16401da177e4SLinus Torvalds  */
16411da177e4SLinus Torvalds 
1642a87d35d8SDominik Brodowski int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
16431da177e4SLinus Torvalds {
16441da177e4SLinus Torvalds 	struct socket *sock;
1645230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
16466cb153caSBenjamin LaHaise 	int err, fput_needed;
16471da177e4SLinus Torvalds 
164889bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
164989bddce5SStephen Hemminger 	if (sock) {
165043db362dSMaciej Żenczykowski 		err = move_addr_to_kernel(umyaddr, addrlen, &address);
1651068b88ccSJakub Sitnicki 		if (!err) {
165289bddce5SStephen Hemminger 			err = security_socket_bind(sock,
1653230b1839SYOSHIFUJI Hideaki 						   (struct sockaddr *)&address,
165489bddce5SStephen Hemminger 						   addrlen);
16556cb153caSBenjamin LaHaise 			if (!err)
16566cb153caSBenjamin LaHaise 				err = sock->ops->bind(sock,
165789bddce5SStephen Hemminger 						      (struct sockaddr *)
1658230b1839SYOSHIFUJI Hideaki 						      &address, addrlen);
16591da177e4SLinus Torvalds 		}
16606cb153caSBenjamin LaHaise 		fput_light(sock->file, fput_needed);
16611da177e4SLinus Torvalds 	}
16621da177e4SLinus Torvalds 	return err;
16631da177e4SLinus Torvalds }
16641da177e4SLinus Torvalds 
1665a87d35d8SDominik Brodowski SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
1666a87d35d8SDominik Brodowski {
1667a87d35d8SDominik Brodowski 	return __sys_bind(fd, umyaddr, addrlen);
1668a87d35d8SDominik Brodowski }
1669a87d35d8SDominik Brodowski 
16701da177e4SLinus Torvalds /*
16711da177e4SLinus Torvalds  *	Perform a listen. Basically, we allow the protocol to do anything
16721da177e4SLinus Torvalds  *	necessary for a listen, and if that works, we mark the socket as
16731da177e4SLinus Torvalds  *	ready for listening.
16741da177e4SLinus Torvalds  */
16751da177e4SLinus Torvalds 
167625e290eeSDominik Brodowski int __sys_listen(int fd, int backlog)
16771da177e4SLinus Torvalds {
16781da177e4SLinus Torvalds 	struct socket *sock;
16796cb153caSBenjamin LaHaise 	int err, fput_needed;
1680b8e1f9b5SPavel Emelyanov 	int somaxconn;
16811da177e4SLinus Torvalds 
168289bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
168389bddce5SStephen Hemminger 	if (sock) {
16848efa6e93SPavel Emelyanov 		somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
168595c96174SEric Dumazet 		if ((unsigned int)backlog > somaxconn)
1686b8e1f9b5SPavel Emelyanov 			backlog = somaxconn;
16871da177e4SLinus Torvalds 
16881da177e4SLinus Torvalds 		err = security_socket_listen(sock, backlog);
16896cb153caSBenjamin LaHaise 		if (!err)
16901da177e4SLinus Torvalds 			err = sock->ops->listen(sock, backlog);
16916cb153caSBenjamin LaHaise 
16926cb153caSBenjamin LaHaise 		fput_light(sock->file, fput_needed);
16931da177e4SLinus Torvalds 	}
16941da177e4SLinus Torvalds 	return err;
16951da177e4SLinus Torvalds }
16961da177e4SLinus Torvalds 
169725e290eeSDominik Brodowski SYSCALL_DEFINE2(listen, int, fd, int, backlog)
169825e290eeSDominik Brodowski {
169925e290eeSDominik Brodowski 	return __sys_listen(fd, backlog);
170025e290eeSDominik Brodowski }
170125e290eeSDominik Brodowski 
1702de2ea4b6SJens Axboe int __sys_accept4_file(struct file *file, unsigned file_flags,
1703de2ea4b6SJens Axboe 		       struct sockaddr __user *upeer_sockaddr,
170409952e3eSJens Axboe 		       int __user *upeer_addrlen, int flags,
170509952e3eSJens Axboe 		       unsigned long nofile)
17061da177e4SLinus Torvalds {
17071da177e4SLinus Torvalds 	struct socket *sock, *newsock;
170839d8c1b6SDavid S. Miller 	struct file *newfile;
1709de2ea4b6SJens Axboe 	int err, len, newfd;
1710230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
17111da177e4SLinus Torvalds 
171277d27200SUlrich Drepper 	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
1713aaca0bdcSUlrich Drepper 		return -EINVAL;
1714aaca0bdcSUlrich Drepper 
1715aaca0bdcSUlrich Drepper 	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1716aaca0bdcSUlrich Drepper 		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1717aaca0bdcSUlrich Drepper 
1718de2ea4b6SJens Axboe 	sock = sock_from_file(file, &err);
17191da177e4SLinus Torvalds 	if (!sock)
17201da177e4SLinus Torvalds 		goto out;
17211da177e4SLinus Torvalds 
17221da177e4SLinus Torvalds 	err = -ENFILE;
1723c6d409cfSEric Dumazet 	newsock = sock_alloc();
1724c6d409cfSEric Dumazet 	if (!newsock)
1725de2ea4b6SJens Axboe 		goto out;
17261da177e4SLinus Torvalds 
17271da177e4SLinus Torvalds 	newsock->type = sock->type;
17281da177e4SLinus Torvalds 	newsock->ops = sock->ops;
17291da177e4SLinus Torvalds 
17301da177e4SLinus Torvalds 	/*
17311da177e4SLinus Torvalds 	 * We don't need try_module_get here, as the listening socket (sock)
17321da177e4SLinus Torvalds 	 * has the protocol module (sock->ops->owner) held.
17331da177e4SLinus Torvalds 	 */
17341da177e4SLinus Torvalds 	__module_get(newsock->ops->owner);
17351da177e4SLinus Torvalds 
173609952e3eSJens Axboe 	newfd = __get_unused_fd_flags(flags, nofile);
173739d8c1b6SDavid S. Miller 	if (unlikely(newfd < 0)) {
173839d8c1b6SDavid S. Miller 		err = newfd;
17399a1875e6SDavid S. Miller 		sock_release(newsock);
1740de2ea4b6SJens Axboe 		goto out;
174139d8c1b6SDavid S. Miller 	}
1742aab174f0SLinus Torvalds 	newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
1743b5ffe634SViresh Kumar 	if (IS_ERR(newfile)) {
174428407630SAl Viro 		err = PTR_ERR(newfile);
174528407630SAl Viro 		put_unused_fd(newfd);
1746de2ea4b6SJens Axboe 		goto out;
174728407630SAl Viro 	}
174839d8c1b6SDavid S. Miller 
1749a79af59eSFrank Filz 	err = security_socket_accept(sock, newsock);
1750a79af59eSFrank Filz 	if (err)
175139d8c1b6SDavid S. Miller 		goto out_fd;
1752a79af59eSFrank Filz 
1753de2ea4b6SJens Axboe 	err = sock->ops->accept(sock, newsock, sock->file->f_flags | file_flags,
1754de2ea4b6SJens Axboe 					false);
17551da177e4SLinus Torvalds 	if (err < 0)
175639d8c1b6SDavid S. Miller 		goto out_fd;
17571da177e4SLinus Torvalds 
17581da177e4SLinus Torvalds 	if (upeer_sockaddr) {
17599b2c45d4SDenys Vlasenko 		len = newsock->ops->getname(newsock,
17609b2c45d4SDenys Vlasenko 					(struct sockaddr *)&address, 2);
17619b2c45d4SDenys Vlasenko 		if (len < 0) {
17621da177e4SLinus Torvalds 			err = -ECONNABORTED;
176339d8c1b6SDavid S. Miller 			goto out_fd;
17641da177e4SLinus Torvalds 		}
176543db362dSMaciej Żenczykowski 		err = move_addr_to_user(&address,
1766230b1839SYOSHIFUJI Hideaki 					len, upeer_sockaddr, upeer_addrlen);
17671da177e4SLinus Torvalds 		if (err < 0)
176839d8c1b6SDavid S. Miller 			goto out_fd;
17691da177e4SLinus Torvalds 	}
17701da177e4SLinus Torvalds 
17711da177e4SLinus Torvalds 	/* File flags are not inherited via accept() unlike another OSes. */
17721da177e4SLinus Torvalds 
177339d8c1b6SDavid S. Miller 	fd_install(newfd, newfile);
177439d8c1b6SDavid S. Miller 	err = newfd;
17751da177e4SLinus Torvalds out:
17761da177e4SLinus Torvalds 	return err;
177739d8c1b6SDavid S. Miller out_fd:
17789606a216SDavid S. Miller 	fput(newfile);
177939d8c1b6SDavid S. Miller 	put_unused_fd(newfd);
1780de2ea4b6SJens Axboe 	goto out;
1781de2ea4b6SJens Axboe 
1782de2ea4b6SJens Axboe }
1783de2ea4b6SJens Axboe 
1784de2ea4b6SJens Axboe /*
1785de2ea4b6SJens Axboe  *	For accept, we attempt to create a new socket, set up the link
1786de2ea4b6SJens Axboe  *	with the client, wake up the client, then return the new
1787de2ea4b6SJens Axboe  *	connected fd. We collect the address of the connector in kernel
1788de2ea4b6SJens Axboe  *	space and move it to user at the very end. This is unclean because
1789de2ea4b6SJens Axboe  *	we open the socket then return an error.
1790de2ea4b6SJens Axboe  *
1791de2ea4b6SJens Axboe  *	1003.1g adds the ability to recvmsg() to query connection pending
1792de2ea4b6SJens Axboe  *	status to recvmsg. We need to add that support in a way thats
1793de2ea4b6SJens Axboe  *	clean when we restructure accept also.
1794de2ea4b6SJens Axboe  */
1795de2ea4b6SJens Axboe 
1796de2ea4b6SJens Axboe int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
1797de2ea4b6SJens Axboe 		  int __user *upeer_addrlen, int flags)
1798de2ea4b6SJens Axboe {
1799de2ea4b6SJens Axboe 	int ret = -EBADF;
1800de2ea4b6SJens Axboe 	struct fd f;
1801de2ea4b6SJens Axboe 
1802de2ea4b6SJens Axboe 	f = fdget(fd);
1803de2ea4b6SJens Axboe 	if (f.file) {
1804de2ea4b6SJens Axboe 		ret = __sys_accept4_file(f.file, 0, upeer_sockaddr,
180509952e3eSJens Axboe 						upeer_addrlen, flags,
180609952e3eSJens Axboe 						rlimit(RLIMIT_NOFILE));
1807de2ea4b6SJens Axboe 		if (f.flags)
1808de2ea4b6SJens Axboe 			fput(f.file);
1809de2ea4b6SJens Axboe 	}
1810de2ea4b6SJens Axboe 
1811de2ea4b6SJens Axboe 	return ret;
18121da177e4SLinus Torvalds }
18131da177e4SLinus Torvalds 
18144541e805SDominik Brodowski SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
18154541e805SDominik Brodowski 		int __user *, upeer_addrlen, int, flags)
18164541e805SDominik Brodowski {
18174541e805SDominik Brodowski 	return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, flags);
18184541e805SDominik Brodowski }
18194541e805SDominik Brodowski 
182020f37034SHeiko Carstens SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
182120f37034SHeiko Carstens 		int __user *, upeer_addrlen)
1822aaca0bdcSUlrich Drepper {
18234541e805SDominik Brodowski 	return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
1824aaca0bdcSUlrich Drepper }
1825aaca0bdcSUlrich Drepper 
18261da177e4SLinus Torvalds /*
18271da177e4SLinus Torvalds  *	Attempt to connect to a socket with the server address.  The address
18281da177e4SLinus Torvalds  *	is in user space so we verify it is OK and move it to kernel space.
18291da177e4SLinus Torvalds  *
18301da177e4SLinus Torvalds  *	For 1003.1g we need to add clean support for a bind to AF_UNSPEC to
18311da177e4SLinus Torvalds  *	break bindings
18321da177e4SLinus Torvalds  *
18331da177e4SLinus Torvalds  *	NOTE: 1003.1g draft 6.3 is broken with respect to AX.25/NetROM and
18341da177e4SLinus Torvalds  *	other SEQPACKET protocols that take time to connect() as it doesn't
18351da177e4SLinus Torvalds  *	include the -EINPROGRESS status for such sockets.
18361da177e4SLinus Torvalds  */
18371da177e4SLinus Torvalds 
1838f499a021SJens Axboe int __sys_connect_file(struct file *file, struct sockaddr_storage *address,
1839bd3ded31SJens Axboe 		       int addrlen, int file_flags)
18401da177e4SLinus Torvalds {
18411da177e4SLinus Torvalds 	struct socket *sock;
1842bd3ded31SJens Axboe 	int err;
18431da177e4SLinus Torvalds 
1844bd3ded31SJens Axboe 	sock = sock_from_file(file, &err);
18451da177e4SLinus Torvalds 	if (!sock)
18461da177e4SLinus Torvalds 		goto out;
18471da177e4SLinus Torvalds 
184889bddce5SStephen Hemminger 	err =
1849f499a021SJens Axboe 	    security_socket_connect(sock, (struct sockaddr *)address, addrlen);
18501da177e4SLinus Torvalds 	if (err)
1851bd3ded31SJens Axboe 		goto out;
18521da177e4SLinus Torvalds 
1853f499a021SJens Axboe 	err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen,
1854bd3ded31SJens Axboe 				 sock->file->f_flags | file_flags);
18551da177e4SLinus Torvalds out:
18561da177e4SLinus Torvalds 	return err;
18571da177e4SLinus Torvalds }
18581da177e4SLinus Torvalds 
1859bd3ded31SJens Axboe int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
1860bd3ded31SJens Axboe {
1861bd3ded31SJens Axboe 	int ret = -EBADF;
1862bd3ded31SJens Axboe 	struct fd f;
1863bd3ded31SJens Axboe 
1864bd3ded31SJens Axboe 	f = fdget(fd);
1865bd3ded31SJens Axboe 	if (f.file) {
1866f499a021SJens Axboe 		struct sockaddr_storage address;
1867f499a021SJens Axboe 
1868f499a021SJens Axboe 		ret = move_addr_to_kernel(uservaddr, addrlen, &address);
1869f499a021SJens Axboe 		if (!ret)
1870f499a021SJens Axboe 			ret = __sys_connect_file(f.file, &address, addrlen, 0);
1871bd3ded31SJens Axboe 		if (f.flags)
1872bd3ded31SJens Axboe 			fput(f.file);
1873bd3ded31SJens Axboe 	}
1874bd3ded31SJens Axboe 
1875bd3ded31SJens Axboe 	return ret;
1876bd3ded31SJens Axboe }
1877bd3ded31SJens Axboe 
18781387c2c2SDominik Brodowski SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
18791387c2c2SDominik Brodowski 		int, addrlen)
18801387c2c2SDominik Brodowski {
18811387c2c2SDominik Brodowski 	return __sys_connect(fd, uservaddr, addrlen);
18821387c2c2SDominik Brodowski }
18831387c2c2SDominik Brodowski 
18841da177e4SLinus Torvalds /*
18851da177e4SLinus Torvalds  *	Get the local address ('name') of a socket object. Move the obtained
18861da177e4SLinus Torvalds  *	name to user space.
18871da177e4SLinus Torvalds  */
18881da177e4SLinus Torvalds 
18898882a107SDominik Brodowski int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
18908882a107SDominik Brodowski 		      int __user *usockaddr_len)
18911da177e4SLinus Torvalds {
18921da177e4SLinus Torvalds 	struct socket *sock;
1893230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
18949b2c45d4SDenys Vlasenko 	int err, fput_needed;
18951da177e4SLinus Torvalds 
18966cb153caSBenjamin LaHaise 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
18971da177e4SLinus Torvalds 	if (!sock)
18981da177e4SLinus Torvalds 		goto out;
18991da177e4SLinus Torvalds 
19001da177e4SLinus Torvalds 	err = security_socket_getsockname(sock);
19011da177e4SLinus Torvalds 	if (err)
19021da177e4SLinus Torvalds 		goto out_put;
19031da177e4SLinus Torvalds 
19049b2c45d4SDenys Vlasenko 	err = sock->ops->getname(sock, (struct sockaddr *)&address, 0);
19059b2c45d4SDenys Vlasenko 	if (err < 0)
19061da177e4SLinus Torvalds 		goto out_put;
19079b2c45d4SDenys Vlasenko         /* "err" is actually length in this case */
19089b2c45d4SDenys Vlasenko 	err = move_addr_to_user(&address, err, usockaddr, usockaddr_len);
19091da177e4SLinus Torvalds 
19101da177e4SLinus Torvalds out_put:
19116cb153caSBenjamin LaHaise 	fput_light(sock->file, fput_needed);
19121da177e4SLinus Torvalds out:
19131da177e4SLinus Torvalds 	return err;
19141da177e4SLinus Torvalds }
19151da177e4SLinus Torvalds 
19168882a107SDominik Brodowski SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
19178882a107SDominik Brodowski 		int __user *, usockaddr_len)
19188882a107SDominik Brodowski {
19198882a107SDominik Brodowski 	return __sys_getsockname(fd, usockaddr, usockaddr_len);
19208882a107SDominik Brodowski }
19218882a107SDominik Brodowski 
19221da177e4SLinus Torvalds /*
19231da177e4SLinus Torvalds  *	Get the remote address ('name') of a socket object. Move the obtained
19241da177e4SLinus Torvalds  *	name to user space.
19251da177e4SLinus Torvalds  */
19261da177e4SLinus Torvalds 
1927b21c8f83SDominik Brodowski int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
1928b21c8f83SDominik Brodowski 		      int __user *usockaddr_len)
19291da177e4SLinus Torvalds {
19301da177e4SLinus Torvalds 	struct socket *sock;
1931230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
19329b2c45d4SDenys Vlasenko 	int err, fput_needed;
19331da177e4SLinus Torvalds 
193489bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
193589bddce5SStephen Hemminger 	if (sock != NULL) {
19361da177e4SLinus Torvalds 		err = security_socket_getpeername(sock);
19371da177e4SLinus Torvalds 		if (err) {
19386cb153caSBenjamin LaHaise 			fput_light(sock->file, fput_needed);
19391da177e4SLinus Torvalds 			return err;
19401da177e4SLinus Torvalds 		}
19411da177e4SLinus Torvalds 
19429b2c45d4SDenys Vlasenko 		err = sock->ops->getname(sock, (struct sockaddr *)&address, 1);
19439b2c45d4SDenys Vlasenko 		if (err >= 0)
19449b2c45d4SDenys Vlasenko 			/* "err" is actually length in this case */
19459b2c45d4SDenys Vlasenko 			err = move_addr_to_user(&address, err, usockaddr,
194689bddce5SStephen Hemminger 						usockaddr_len);
19476cb153caSBenjamin LaHaise 		fput_light(sock->file, fput_needed);
19481da177e4SLinus Torvalds 	}
19491da177e4SLinus Torvalds 	return err;
19501da177e4SLinus Torvalds }
19511da177e4SLinus Torvalds 
1952b21c8f83SDominik Brodowski SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
1953b21c8f83SDominik Brodowski 		int __user *, usockaddr_len)
1954b21c8f83SDominik Brodowski {
1955b21c8f83SDominik Brodowski 	return __sys_getpeername(fd, usockaddr, usockaddr_len);
1956b21c8f83SDominik Brodowski }
1957b21c8f83SDominik Brodowski 
19581da177e4SLinus Torvalds /*
19591da177e4SLinus Torvalds  *	Send a datagram to a given address. We move the address into kernel
19601da177e4SLinus Torvalds  *	space and check the user space data area is readable before invoking
19611da177e4SLinus Torvalds  *	the protocol.
19621da177e4SLinus Torvalds  */
1963211b634bSDominik Brodowski int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags,
1964211b634bSDominik Brodowski 		 struct sockaddr __user *addr,  int addr_len)
19651da177e4SLinus Torvalds {
19661da177e4SLinus Torvalds 	struct socket *sock;
1967230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
19681da177e4SLinus Torvalds 	int err;
19691da177e4SLinus Torvalds 	struct msghdr msg;
19701da177e4SLinus Torvalds 	struct iovec iov;
19716cb153caSBenjamin LaHaise 	int fput_needed;
19721da177e4SLinus Torvalds 
1973602bd0e9SAl Viro 	err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
1974602bd0e9SAl Viro 	if (unlikely(err))
1975602bd0e9SAl Viro 		return err;
1976de0fa95cSPavel Emelyanov 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1977de0fa95cSPavel Emelyanov 	if (!sock)
19784387ff75SDavid S. Miller 		goto out;
19796cb153caSBenjamin LaHaise 
19801da177e4SLinus Torvalds 	msg.msg_name = NULL;
19811da177e4SLinus Torvalds 	msg.msg_control = NULL;
19821da177e4SLinus Torvalds 	msg.msg_controllen = 0;
19831da177e4SLinus Torvalds 	msg.msg_namelen = 0;
19846cb153caSBenjamin LaHaise 	if (addr) {
198543db362dSMaciej Żenczykowski 		err = move_addr_to_kernel(addr, addr_len, &address);
19861da177e4SLinus Torvalds 		if (err < 0)
19871da177e4SLinus Torvalds 			goto out_put;
1988230b1839SYOSHIFUJI Hideaki 		msg.msg_name = (struct sockaddr *)&address;
19891da177e4SLinus Torvalds 		msg.msg_namelen = addr_len;
19901da177e4SLinus Torvalds 	}
19911da177e4SLinus Torvalds 	if (sock->file->f_flags & O_NONBLOCK)
19921da177e4SLinus Torvalds 		flags |= MSG_DONTWAIT;
19931da177e4SLinus Torvalds 	msg.msg_flags = flags;
1994d8725c86SAl Viro 	err = sock_sendmsg(sock, &msg);
19951da177e4SLinus Torvalds 
19961da177e4SLinus Torvalds out_put:
1997de0fa95cSPavel Emelyanov 	fput_light(sock->file, fput_needed);
19984387ff75SDavid S. Miller out:
19991da177e4SLinus Torvalds 	return err;
20001da177e4SLinus Torvalds }
20011da177e4SLinus Torvalds 
2002211b634bSDominik Brodowski SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
2003211b634bSDominik Brodowski 		unsigned int, flags, struct sockaddr __user *, addr,
2004211b634bSDominik Brodowski 		int, addr_len)
2005211b634bSDominik Brodowski {
2006211b634bSDominik Brodowski 	return __sys_sendto(fd, buff, len, flags, addr, addr_len);
2007211b634bSDominik Brodowski }
2008211b634bSDominik Brodowski 
20091da177e4SLinus Torvalds /*
20101da177e4SLinus Torvalds  *	Send a datagram down a socket.
20111da177e4SLinus Torvalds  */
20121da177e4SLinus Torvalds 
20133e0fa65fSHeiko Carstens SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
201495c96174SEric Dumazet 		unsigned int, flags)
20151da177e4SLinus Torvalds {
2016211b634bSDominik Brodowski 	return __sys_sendto(fd, buff, len, flags, NULL, 0);
20171da177e4SLinus Torvalds }
20181da177e4SLinus Torvalds 
20191da177e4SLinus Torvalds /*
20201da177e4SLinus Torvalds  *	Receive a frame from the socket and optionally record the address of the
20211da177e4SLinus Torvalds  *	sender. We verify the buffers are writable and if needed move the
20221da177e4SLinus Torvalds  *	sender address from kernel to user space.
20231da177e4SLinus Torvalds  */
20247a09e1ebSDominik Brodowski int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags,
20257a09e1ebSDominik Brodowski 		   struct sockaddr __user *addr, int __user *addr_len)
20261da177e4SLinus Torvalds {
20271da177e4SLinus Torvalds 	struct socket *sock;
20281da177e4SLinus Torvalds 	struct iovec iov;
20291da177e4SLinus Torvalds 	struct msghdr msg;
2030230b1839SYOSHIFUJI Hideaki 	struct sockaddr_storage address;
20311da177e4SLinus Torvalds 	int err, err2;
20326cb153caSBenjamin LaHaise 	int fput_needed;
20331da177e4SLinus Torvalds 
2034602bd0e9SAl Viro 	err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
2035602bd0e9SAl Viro 	if (unlikely(err))
2036602bd0e9SAl Viro 		return err;
2037de0fa95cSPavel Emelyanov 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
20381da177e4SLinus Torvalds 	if (!sock)
2039de0fa95cSPavel Emelyanov 		goto out;
20401da177e4SLinus Torvalds 
20411da177e4SLinus Torvalds 	msg.msg_control = NULL;
20421da177e4SLinus Torvalds 	msg.msg_controllen = 0;
2043f3d33426SHannes Frederic Sowa 	/* Save some cycles and don't copy the address if not needed */
2044f3d33426SHannes Frederic Sowa 	msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
2045f3d33426SHannes Frederic Sowa 	/* We assume all kernel code knows the size of sockaddr_storage */
2046f3d33426SHannes Frederic Sowa 	msg.msg_namelen = 0;
2047130ed5d1Stadeusz.struk@intel.com 	msg.msg_iocb = NULL;
20489f138fa6SAlexander Potapenko 	msg.msg_flags = 0;
20491da177e4SLinus Torvalds 	if (sock->file->f_flags & O_NONBLOCK)
20501da177e4SLinus Torvalds 		flags |= MSG_DONTWAIT;
20512da62906SAl Viro 	err = sock_recvmsg(sock, &msg, flags);
20521da177e4SLinus Torvalds 
205389bddce5SStephen Hemminger 	if (err >= 0 && addr != NULL) {
205443db362dSMaciej Żenczykowski 		err2 = move_addr_to_user(&address,
2055230b1839SYOSHIFUJI Hideaki 					 msg.msg_namelen, addr, addr_len);
20561da177e4SLinus Torvalds 		if (err2 < 0)
20571da177e4SLinus Torvalds 			err = err2;
20581da177e4SLinus Torvalds 	}
2059de0fa95cSPavel Emelyanov 
2060de0fa95cSPavel Emelyanov 	fput_light(sock->file, fput_needed);
20614387ff75SDavid S. Miller out:
20621da177e4SLinus Torvalds 	return err;
20631da177e4SLinus Torvalds }
20641da177e4SLinus Torvalds 
20657a09e1ebSDominik Brodowski SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
20667a09e1ebSDominik Brodowski 		unsigned int, flags, struct sockaddr __user *, addr,
20677a09e1ebSDominik Brodowski 		int __user *, addr_len)
20687a09e1ebSDominik Brodowski {
20697a09e1ebSDominik Brodowski 	return __sys_recvfrom(fd, ubuf, size, flags, addr, addr_len);
20707a09e1ebSDominik Brodowski }
20717a09e1ebSDominik Brodowski 
20721da177e4SLinus Torvalds /*
20731da177e4SLinus Torvalds  *	Receive a datagram from a socket.
20741da177e4SLinus Torvalds  */
20751da177e4SLinus Torvalds 
2076b7c0ddf5SJan Glauber SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
2077b7c0ddf5SJan Glauber 		unsigned int, flags)
20781da177e4SLinus Torvalds {
20797a09e1ebSDominik Brodowski 	return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
20801da177e4SLinus Torvalds }
20811da177e4SLinus Torvalds 
208283f0c10bSFlorian Westphal static bool sock_use_custom_sol_socket(const struct socket *sock)
208383f0c10bSFlorian Westphal {
208483f0c10bSFlorian Westphal 	const struct sock *sk = sock->sk;
208583f0c10bSFlorian Westphal 
208683f0c10bSFlorian Westphal 	/* Use sock->ops->setsockopt() for MPTCP */
208783f0c10bSFlorian Westphal 	return IS_ENABLED(CONFIG_MPTCP) &&
208883f0c10bSFlorian Westphal 	       sk->sk_protocol == IPPROTO_MPTCP &&
208983f0c10bSFlorian Westphal 	       sk->sk_type == SOCK_STREAM &&
209083f0c10bSFlorian Westphal 	       (sk->sk_family == AF_INET || sk->sk_family == AF_INET6);
209183f0c10bSFlorian Westphal }
209283f0c10bSFlorian Westphal 
20931da177e4SLinus Torvalds /*
20941da177e4SLinus Torvalds  *	Set a socket option. Because we don't know the option lengths we have
20951da177e4SLinus Torvalds  *	to pass the user mode parameter for the protocols to sort out.
20961da177e4SLinus Torvalds  */
20971da177e4SLinus Torvalds 
2098cc36dca0SDominik Brodowski static int __sys_setsockopt(int fd, int level, int optname,
2099cc36dca0SDominik Brodowski 			    char __user *optval, int optlen)
21001da177e4SLinus Torvalds {
21010d01da6aSStanislav Fomichev 	mm_segment_t oldfs = get_fs();
21020d01da6aSStanislav Fomichev 	char *kernel_optval = NULL;
21036cb153caSBenjamin LaHaise 	int err, fput_needed;
21041da177e4SLinus Torvalds 	struct socket *sock;
21051da177e4SLinus Torvalds 
21061da177e4SLinus Torvalds 	if (optlen < 0)
21071da177e4SLinus Torvalds 		return -EINVAL;
21081da177e4SLinus Torvalds 
210989bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
211089bddce5SStephen Hemminger 	if (sock != NULL) {
21111da177e4SLinus Torvalds 		err = security_socket_setsockopt(sock, level, optname);
21126cb153caSBenjamin LaHaise 		if (err)
21136cb153caSBenjamin LaHaise 			goto out_put;
21141da177e4SLinus Torvalds 
21150d01da6aSStanislav Fomichev 		err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level,
21160d01da6aSStanislav Fomichev 						     &optname, optval, &optlen,
21170d01da6aSStanislav Fomichev 						     &kernel_optval);
21180d01da6aSStanislav Fomichev 
21190d01da6aSStanislav Fomichev 		if (err < 0) {
21200d01da6aSStanislav Fomichev 			goto out_put;
21210d01da6aSStanislav Fomichev 		} else if (err > 0) {
21220d01da6aSStanislav Fomichev 			err = 0;
21230d01da6aSStanislav Fomichev 			goto out_put;
21240d01da6aSStanislav Fomichev 		}
21250d01da6aSStanislav Fomichev 
21260d01da6aSStanislav Fomichev 		if (kernel_optval) {
21270d01da6aSStanislav Fomichev 			set_fs(KERNEL_DS);
21280d01da6aSStanislav Fomichev 			optval = (char __user __force *)kernel_optval;
21290d01da6aSStanislav Fomichev 		}
21300d01da6aSStanislav Fomichev 
213183f0c10bSFlorian Westphal 		if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock))
213289bddce5SStephen Hemminger 			err =
213389bddce5SStephen Hemminger 			    sock_setsockopt(sock, level, optname, optval,
213489bddce5SStephen Hemminger 					    optlen);
21351da177e4SLinus Torvalds 		else
213689bddce5SStephen Hemminger 			err =
213789bddce5SStephen Hemminger 			    sock->ops->setsockopt(sock, level, optname, optval,
213889bddce5SStephen Hemminger 						  optlen);
21390d01da6aSStanislav Fomichev 
21400d01da6aSStanislav Fomichev 		if (kernel_optval) {
21410d01da6aSStanislav Fomichev 			set_fs(oldfs);
21420d01da6aSStanislav Fomichev 			kfree(kernel_optval);
21430d01da6aSStanislav Fomichev 		}
21446cb153caSBenjamin LaHaise out_put:
21456cb153caSBenjamin LaHaise 		fput_light(sock->file, fput_needed);
21461da177e4SLinus Torvalds 	}
21471da177e4SLinus Torvalds 	return err;
21481da177e4SLinus Torvalds }
21491da177e4SLinus Torvalds 
2150cc36dca0SDominik Brodowski SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
2151cc36dca0SDominik Brodowski 		char __user *, optval, int, optlen)
2152cc36dca0SDominik Brodowski {
2153cc36dca0SDominik Brodowski 	return __sys_setsockopt(fd, level, optname, optval, optlen);
2154cc36dca0SDominik Brodowski }
2155cc36dca0SDominik Brodowski 
21561da177e4SLinus Torvalds /*
21571da177e4SLinus Torvalds  *	Get a socket option. Because we don't know the option lengths we have
21581da177e4SLinus Torvalds  *	to pass a user mode parameter for the protocols to sort out.
21591da177e4SLinus Torvalds  */
21601da177e4SLinus Torvalds 
216113a2d70eSDominik Brodowski static int __sys_getsockopt(int fd, int level, int optname,
216213a2d70eSDominik Brodowski 			    char __user *optval, int __user *optlen)
21631da177e4SLinus Torvalds {
21646cb153caSBenjamin LaHaise 	int err, fput_needed;
21651da177e4SLinus Torvalds 	struct socket *sock;
21660d01da6aSStanislav Fomichev 	int max_optlen;
21671da177e4SLinus Torvalds 
216889bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
216989bddce5SStephen Hemminger 	if (sock != NULL) {
21706cb153caSBenjamin LaHaise 		err = security_socket_getsockopt(sock, level, optname);
21716cb153caSBenjamin LaHaise 		if (err)
21726cb153caSBenjamin LaHaise 			goto out_put;
21731da177e4SLinus Torvalds 
21740d01da6aSStanislav Fomichev 		max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen);
21750d01da6aSStanislav Fomichev 
21761da177e4SLinus Torvalds 		if (level == SOL_SOCKET)
217789bddce5SStephen Hemminger 			err =
217889bddce5SStephen Hemminger 			    sock_getsockopt(sock, level, optname, optval,
217989bddce5SStephen Hemminger 					    optlen);
21801da177e4SLinus Torvalds 		else
218189bddce5SStephen Hemminger 			err =
218289bddce5SStephen Hemminger 			    sock->ops->getsockopt(sock, level, optname, optval,
218389bddce5SStephen Hemminger 						  optlen);
21840d01da6aSStanislav Fomichev 
21850d01da6aSStanislav Fomichev 		err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname,
21860d01da6aSStanislav Fomichev 						     optval, optlen,
21870d01da6aSStanislav Fomichev 						     max_optlen, err);
21886cb153caSBenjamin LaHaise out_put:
21896cb153caSBenjamin LaHaise 		fput_light(sock->file, fput_needed);
21901da177e4SLinus Torvalds 	}
21911da177e4SLinus Torvalds 	return err;
21921da177e4SLinus Torvalds }
21931da177e4SLinus Torvalds 
219413a2d70eSDominik Brodowski SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
219513a2d70eSDominik Brodowski 		char __user *, optval, int __user *, optlen)
219613a2d70eSDominik Brodowski {
219713a2d70eSDominik Brodowski 	return __sys_getsockopt(fd, level, optname, optval, optlen);
219813a2d70eSDominik Brodowski }
219913a2d70eSDominik Brodowski 
22001da177e4SLinus Torvalds /*
22011da177e4SLinus Torvalds  *	Shutdown a socket.
22021da177e4SLinus Torvalds  */
22031da177e4SLinus Torvalds 
2204005a1aeaSDominik Brodowski int __sys_shutdown(int fd, int how)
22051da177e4SLinus Torvalds {
22066cb153caSBenjamin LaHaise 	int err, fput_needed;
22071da177e4SLinus Torvalds 	struct socket *sock;
22081da177e4SLinus Torvalds 
220989bddce5SStephen Hemminger 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
221089bddce5SStephen Hemminger 	if (sock != NULL) {
22111da177e4SLinus Torvalds 		err = security_socket_shutdown(sock, how);
22126cb153caSBenjamin LaHaise 		if (!err)
22131da177e4SLinus Torvalds 			err = sock->ops->shutdown(sock, how);
22146cb153caSBenjamin LaHaise 		fput_light(sock->file, fput_needed);
22151da177e4SLinus Torvalds 	}
22161da177e4SLinus Torvalds 	return err;
22171da177e4SLinus Torvalds }
22181da177e4SLinus Torvalds 
2219005a1aeaSDominik Brodowski SYSCALL_DEFINE2(shutdown, int, fd, int, how)
2220005a1aeaSDominik Brodowski {
2221005a1aeaSDominik Brodowski 	return __sys_shutdown(fd, how);
2222005a1aeaSDominik Brodowski }
2223005a1aeaSDominik Brodowski 
22241da177e4SLinus Torvalds /* A couple of helpful macros for getting the address of the 32/64 bit
22251da177e4SLinus Torvalds  * fields which are the same type (int / unsigned) on our platforms.
22261da177e4SLinus Torvalds  */
22271da177e4SLinus Torvalds #define COMPAT_MSG(msg, member)	((MSG_CMSG_COMPAT & flags) ? &msg##_compat->member : &msg->member)
22281da177e4SLinus Torvalds #define COMPAT_NAMELEN(msg)	COMPAT_MSG(msg, msg_namelen)
22291da177e4SLinus Torvalds #define COMPAT_FLAGS(msg)	COMPAT_MSG(msg, msg_flags)
22301da177e4SLinus Torvalds 
2231c71d8ebeSTetsuo Handa struct used_address {
2232c71d8ebeSTetsuo Handa 	struct sockaddr_storage name;
2233c71d8ebeSTetsuo Handa 	unsigned int name_len;
2234c71d8ebeSTetsuo Handa };
2235c71d8ebeSTetsuo Handa 
22360a384abfSJens Axboe int __copy_msghdr_from_user(struct msghdr *kmsg,
223708adb7daSAl Viro 			    struct user_msghdr __user *umsg,
223808adb7daSAl Viro 			    struct sockaddr __user **save_addr,
22390a384abfSJens Axboe 			    struct iovec __user **uiov, size_t *nsegs)
22401661bf36SDan Carpenter {
2241ffb07550SAl Viro 	struct user_msghdr msg;
224208adb7daSAl Viro 	ssize_t err;
224308adb7daSAl Viro 
2244ffb07550SAl Viro 	if (copy_from_user(&msg, umsg, sizeof(*umsg)))
22451661bf36SDan Carpenter 		return -EFAULT;
2246dbb490b9SMatthew Leach 
22471f466e1fSChristoph Hellwig 	kmsg->msg_control_is_user = true;
22481f466e1fSChristoph Hellwig 	kmsg->msg_control_user = msg.msg_control;
2249ffb07550SAl Viro 	kmsg->msg_controllen = msg.msg_controllen;
2250ffb07550SAl Viro 	kmsg->msg_flags = msg.msg_flags;
2251ffb07550SAl Viro 
2252ffb07550SAl Viro 	kmsg->msg_namelen = msg.msg_namelen;
2253ffb07550SAl Viro 	if (!msg.msg_name)
22546a2a2b3aSAni Sinha 		kmsg->msg_namelen = 0;
22556a2a2b3aSAni Sinha 
2256dbb490b9SMatthew Leach 	if (kmsg->msg_namelen < 0)
2257dbb490b9SMatthew Leach 		return -EINVAL;
2258dbb490b9SMatthew Leach 
22591661bf36SDan Carpenter 	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
2260db31c55aSDan Carpenter 		kmsg->msg_namelen = sizeof(struct sockaddr_storage);
226108adb7daSAl Viro 
226208adb7daSAl Viro 	if (save_addr)
2263ffb07550SAl Viro 		*save_addr = msg.msg_name;
226408adb7daSAl Viro 
2265ffb07550SAl Viro 	if (msg.msg_name && kmsg->msg_namelen) {
226608adb7daSAl Viro 		if (!save_addr) {
2267864d9664SPaolo Abeni 			err = move_addr_to_kernel(msg.msg_name,
2268864d9664SPaolo Abeni 						  kmsg->msg_namelen,
226908adb7daSAl Viro 						  kmsg->msg_name);
227008adb7daSAl Viro 			if (err < 0)
227108adb7daSAl Viro 				return err;
227208adb7daSAl Viro 		}
227308adb7daSAl Viro 	} else {
227408adb7daSAl Viro 		kmsg->msg_name = NULL;
227508adb7daSAl Viro 		kmsg->msg_namelen = 0;
227608adb7daSAl Viro 	}
227708adb7daSAl Viro 
2278ffb07550SAl Viro 	if (msg.msg_iovlen > UIO_MAXIOV)
227908adb7daSAl Viro 		return -EMSGSIZE;
228008adb7daSAl Viro 
22810345f931Stadeusz.struk@intel.com 	kmsg->msg_iocb = NULL;
22820a384abfSJens Axboe 	*uiov = msg.msg_iov;
22830a384abfSJens Axboe 	*nsegs = msg.msg_iovlen;
22840a384abfSJens Axboe 	return 0;
22850a384abfSJens Axboe }
22860a384abfSJens Axboe 
22870a384abfSJens Axboe static int copy_msghdr_from_user(struct msghdr *kmsg,
22880a384abfSJens Axboe 				 struct user_msghdr __user *umsg,
22890a384abfSJens Axboe 				 struct sockaddr __user **save_addr,
22900a384abfSJens Axboe 				 struct iovec **iov)
22910a384abfSJens Axboe {
22920a384abfSJens Axboe 	struct user_msghdr msg;
22930a384abfSJens Axboe 	ssize_t err;
22940a384abfSJens Axboe 
22950a384abfSJens Axboe 	err = __copy_msghdr_from_user(kmsg, umsg, save_addr, &msg.msg_iov,
22960a384abfSJens Axboe 					&msg.msg_iovlen);
22970a384abfSJens Axboe 	if (err)
22980a384abfSJens Axboe 		return err;
22990345f931Stadeusz.struk@intel.com 
230087e5e6daSJens Axboe 	err = import_iovec(save_addr ? READ : WRITE,
2301ffb07550SAl Viro 			    msg.msg_iov, msg.msg_iovlen,
2302da184284SAl Viro 			    UIO_FASTIOV, iov, &kmsg->msg_iter);
230387e5e6daSJens Axboe 	return err < 0 ? err : 0;
23041661bf36SDan Carpenter }
23051661bf36SDan Carpenter 
23064257c8caSJens Axboe static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys,
23074257c8caSJens Axboe 			   unsigned int flags, struct used_address *used_address,
230828a94d8fSTom Herbert 			   unsigned int allowed_msghdr_flags)
23091da177e4SLinus Torvalds {
2310b9d717a7SAlex Williamson 	unsigned char ctl[sizeof(struct cmsghdr) + 20]
2311846cc123SAmit Kushwaha 				__aligned(sizeof(__kernel_size_t));
2312b9d717a7SAlex Williamson 	/* 20 is size of ipv6_pktinfo */
23131da177e4SLinus Torvalds 	unsigned char *ctl_buf = ctl;
2314d8725c86SAl Viro 	int ctl_len;
231508adb7daSAl Viro 	ssize_t err;
23161da177e4SLinus Torvalds 
23171da177e4SLinus Torvalds 	err = -ENOBUFS;
23181da177e4SLinus Torvalds 
2319228e548eSAnton Blanchard 	if (msg_sys->msg_controllen > INT_MAX)
23204257c8caSJens Axboe 		goto out;
232128a94d8fSTom Herbert 	flags |= (msg_sys->msg_flags & allowed_msghdr_flags);
2322228e548eSAnton Blanchard 	ctl_len = msg_sys->msg_controllen;
23231da177e4SLinus Torvalds 	if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
232489bddce5SStephen Hemminger 		err =
2325228e548eSAnton Blanchard 		    cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
232689bddce5SStephen Hemminger 						     sizeof(ctl));
23271da177e4SLinus Torvalds 		if (err)
23284257c8caSJens Axboe 			goto out;
2329228e548eSAnton Blanchard 		ctl_buf = msg_sys->msg_control;
2330228e548eSAnton Blanchard 		ctl_len = msg_sys->msg_controllen;
23311da177e4SLinus Torvalds 	} else if (ctl_len) {
2332ac4340fcSDavid S. Miller 		BUILD_BUG_ON(sizeof(struct cmsghdr) !=
2333ac4340fcSDavid S. Miller 			     CMSG_ALIGN(sizeof(struct cmsghdr)));
233489bddce5SStephen Hemminger 		if (ctl_len > sizeof(ctl)) {
23351da177e4SLinus Torvalds 			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
23361da177e4SLinus Torvalds 			if (ctl_buf == NULL)
23374257c8caSJens Axboe 				goto out;
23381da177e4SLinus Torvalds 		}
23391da177e4SLinus Torvalds 		err = -EFAULT;
23401f466e1fSChristoph Hellwig 		if (copy_from_user(ctl_buf, msg_sys->msg_control_user, ctl_len))
23411da177e4SLinus Torvalds 			goto out_freectl;
2342228e548eSAnton Blanchard 		msg_sys->msg_control = ctl_buf;
23431f466e1fSChristoph Hellwig 		msg_sys->msg_control_is_user = false;
23441da177e4SLinus Torvalds 	}
2345228e548eSAnton Blanchard 	msg_sys->msg_flags = flags;
23461da177e4SLinus Torvalds 
23471da177e4SLinus Torvalds 	if (sock->file->f_flags & O_NONBLOCK)
2348228e548eSAnton Blanchard 		msg_sys->msg_flags |= MSG_DONTWAIT;
2349c71d8ebeSTetsuo Handa 	/*
2350c71d8ebeSTetsuo Handa 	 * If this is sendmmsg() and current destination address is same as
2351c71d8ebeSTetsuo Handa 	 * previously succeeded address, omit asking LSM's decision.
2352c71d8ebeSTetsuo Handa 	 * used_address->name_len is initialized to UINT_MAX so that the first
2353c71d8ebeSTetsuo Handa 	 * destination address never matches.
2354c71d8ebeSTetsuo Handa 	 */
2355bc909d9dSMathieu Desnoyers 	if (used_address && msg_sys->msg_name &&
2356bc909d9dSMathieu Desnoyers 	    used_address->name_len == msg_sys->msg_namelen &&
2357bc909d9dSMathieu Desnoyers 	    !memcmp(&used_address->name, msg_sys->msg_name,
2358c71d8ebeSTetsuo Handa 		    used_address->name_len)) {
2359d8725c86SAl Viro 		err = sock_sendmsg_nosec(sock, msg_sys);
2360c71d8ebeSTetsuo Handa 		goto out_freectl;
2361c71d8ebeSTetsuo Handa 	}
2362d8725c86SAl Viro 	err = sock_sendmsg(sock, msg_sys);
2363c71d8ebeSTetsuo Handa 	/*
2364c71d8ebeSTetsuo Handa 	 * If this is sendmmsg() and sending to current destination address was
2365c71d8ebeSTetsuo Handa 	 * successful, remember it.
2366c71d8ebeSTetsuo Handa 	 */
2367c71d8ebeSTetsuo Handa 	if (used_address && err >= 0) {
2368c71d8ebeSTetsuo Handa 		used_address->name_len = msg_sys->msg_namelen;
2369bc909d9dSMathieu Desnoyers 		if (msg_sys->msg_name)
2370bc909d9dSMathieu Desnoyers 			memcpy(&used_address->name, msg_sys->msg_name,
2371c71d8ebeSTetsuo Handa 			       used_address->name_len);
2372c71d8ebeSTetsuo Handa 	}
23731da177e4SLinus Torvalds 
23741da177e4SLinus Torvalds out_freectl:
23751da177e4SLinus Torvalds 	if (ctl_buf != ctl)
23761da177e4SLinus Torvalds 		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
23774257c8caSJens Axboe out:
23784257c8caSJens Axboe 	return err;
23794257c8caSJens Axboe }
23804257c8caSJens Axboe 
238103b1230cSJens Axboe int sendmsg_copy_msghdr(struct msghdr *msg,
23824257c8caSJens Axboe 			struct user_msghdr __user *umsg, unsigned flags,
23834257c8caSJens Axboe 			struct iovec **iov)
23844257c8caSJens Axboe {
23854257c8caSJens Axboe 	int err;
23864257c8caSJens Axboe 
23874257c8caSJens Axboe 	if (flags & MSG_CMSG_COMPAT) {
23884257c8caSJens Axboe 		struct compat_msghdr __user *msg_compat;
23894257c8caSJens Axboe 
23904257c8caSJens Axboe 		msg_compat = (struct compat_msghdr __user *) umsg;
23914257c8caSJens Axboe 		err = get_compat_msghdr(msg, msg_compat, NULL, iov);
23924257c8caSJens Axboe 	} else {
23934257c8caSJens Axboe 		err = copy_msghdr_from_user(msg, umsg, NULL, iov);
23944257c8caSJens Axboe 	}
23954257c8caSJens Axboe 	if (err < 0)
23964257c8caSJens Axboe 		return err;
23974257c8caSJens Axboe 
23984257c8caSJens Axboe 	return 0;
23994257c8caSJens Axboe }
24004257c8caSJens Axboe 
24014257c8caSJens Axboe static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
24024257c8caSJens Axboe 			 struct msghdr *msg_sys, unsigned int flags,
24034257c8caSJens Axboe 			 struct used_address *used_address,
24044257c8caSJens Axboe 			 unsigned int allowed_msghdr_flags)
24054257c8caSJens Axboe {
24064257c8caSJens Axboe 	struct sockaddr_storage address;
24074257c8caSJens Axboe 	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
24084257c8caSJens Axboe 	ssize_t err;
24094257c8caSJens Axboe 
24104257c8caSJens Axboe 	msg_sys->msg_name = &address;
24114257c8caSJens Axboe 
24124257c8caSJens Axboe 	err = sendmsg_copy_msghdr(msg_sys, msg, flags, &iov);
24134257c8caSJens Axboe 	if (err < 0)
24144257c8caSJens Axboe 		return err;
24154257c8caSJens Axboe 
24164257c8caSJens Axboe 	err = ____sys_sendmsg(sock, msg_sys, flags, used_address,
24174257c8caSJens Axboe 				allowed_msghdr_flags);
2418a74e9106SEric Dumazet 	kfree(iov);
2419228e548eSAnton Blanchard 	return err;
2420228e548eSAnton Blanchard }
2421228e548eSAnton Blanchard 
2422228e548eSAnton Blanchard /*
2423228e548eSAnton Blanchard  *	BSD sendmsg interface
2424228e548eSAnton Blanchard  */
242503b1230cSJens Axboe long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg,
24260fa03c62SJens Axboe 			unsigned int flags)
24270fa03c62SJens Axboe {
2428d69e0779SJens Axboe 	/* disallow ancillary data requests from this path */
242903b1230cSJens Axboe 	if (msg->msg_control || msg->msg_controllen)
243003b1230cSJens Axboe 		return -EINVAL;
2431d69e0779SJens Axboe 
243203b1230cSJens Axboe 	return ____sys_sendmsg(sock, msg, flags, NULL, 0);
24330fa03c62SJens Axboe }
2434228e548eSAnton Blanchard 
2435e1834a32SDominik Brodowski long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
2436e1834a32SDominik Brodowski 		   bool forbid_cmsg_compat)
2437228e548eSAnton Blanchard {
2438228e548eSAnton Blanchard 	int fput_needed, err;
2439228e548eSAnton Blanchard 	struct msghdr msg_sys;
24401be374a0SAndy Lutomirski 	struct socket *sock;
2441228e548eSAnton Blanchard 
2442e1834a32SDominik Brodowski 	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
2443e1834a32SDominik Brodowski 		return -EINVAL;
2444e1834a32SDominik Brodowski 
24451be374a0SAndy Lutomirski 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
2446228e548eSAnton Blanchard 	if (!sock)
2447228e548eSAnton Blanchard 		goto out;
2448228e548eSAnton Blanchard 
244928a94d8fSTom Herbert 	err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0);
2450228e548eSAnton Blanchard 
24516cb153caSBenjamin LaHaise 	fput_light(sock->file, fput_needed);
24521da177e4SLinus Torvalds out:
24531da177e4SLinus Torvalds 	return err;
24541da177e4SLinus Torvalds }
24551da177e4SLinus Torvalds 
2456666547ffSAl Viro SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
2457a7526eb5SAndy Lutomirski {
2458e1834a32SDominik Brodowski 	return __sys_sendmsg(fd, msg, flags, true);
2459a7526eb5SAndy Lutomirski }
2460a7526eb5SAndy Lutomirski 
2461228e548eSAnton Blanchard /*
2462228e548eSAnton Blanchard  *	Linux sendmmsg interface
2463228e548eSAnton Blanchard  */
2464228e548eSAnton Blanchard 
2465228e548eSAnton Blanchard int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2466e1834a32SDominik Brodowski 		   unsigned int flags, bool forbid_cmsg_compat)
2467228e548eSAnton Blanchard {
2468228e548eSAnton Blanchard 	int fput_needed, err, datagrams;
2469228e548eSAnton Blanchard 	struct socket *sock;
2470228e548eSAnton Blanchard 	struct mmsghdr __user *entry;
2471228e548eSAnton Blanchard 	struct compat_mmsghdr __user *compat_entry;
2472228e548eSAnton Blanchard 	struct msghdr msg_sys;
2473c71d8ebeSTetsuo Handa 	struct used_address used_address;
2474f092276dSTom Herbert 	unsigned int oflags = flags;
2475228e548eSAnton Blanchard 
2476e1834a32SDominik Brodowski 	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
2477e1834a32SDominik Brodowski 		return -EINVAL;
2478e1834a32SDominik Brodowski 
247998382f41SAnton Blanchard 	if (vlen > UIO_MAXIOV)
248098382f41SAnton Blanchard 		vlen = UIO_MAXIOV;
2481228e548eSAnton Blanchard 
2482228e548eSAnton Blanchard 	datagrams = 0;
2483228e548eSAnton Blanchard 
2484228e548eSAnton Blanchard 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
2485228e548eSAnton Blanchard 	if (!sock)
2486228e548eSAnton Blanchard 		return err;
2487228e548eSAnton Blanchard 
2488c71d8ebeSTetsuo Handa 	used_address.name_len = UINT_MAX;
2489228e548eSAnton Blanchard 	entry = mmsg;
2490228e548eSAnton Blanchard 	compat_entry = (struct compat_mmsghdr __user *)mmsg;
2491728ffb86SAnton Blanchard 	err = 0;
2492f092276dSTom Herbert 	flags |= MSG_BATCH;
2493228e548eSAnton Blanchard 
2494228e548eSAnton Blanchard 	while (datagrams < vlen) {
2495f092276dSTom Herbert 		if (datagrams == vlen - 1)
2496f092276dSTom Herbert 			flags = oflags;
2497f092276dSTom Herbert 
2498228e548eSAnton Blanchard 		if (MSG_CMSG_COMPAT & flags) {
2499666547ffSAl Viro 			err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry,
250028a94d8fSTom Herbert 					     &msg_sys, flags, &used_address, MSG_EOR);
2501228e548eSAnton Blanchard 			if (err < 0)
2502228e548eSAnton Blanchard 				break;
2503228e548eSAnton Blanchard 			err = __put_user(err, &compat_entry->msg_len);
2504228e548eSAnton Blanchard 			++compat_entry;
2505228e548eSAnton Blanchard 		} else {
2506a7526eb5SAndy Lutomirski 			err = ___sys_sendmsg(sock,
2507666547ffSAl Viro 					     (struct user_msghdr __user *)entry,
250828a94d8fSTom Herbert 					     &msg_sys, flags, &used_address, MSG_EOR);
2509228e548eSAnton Blanchard 			if (err < 0)
2510228e548eSAnton Blanchard 				break;
2511228e548eSAnton Blanchard 			err = put_user(err, &entry->msg_len);
2512228e548eSAnton Blanchard 			++entry;
2513228e548eSAnton Blanchard 		}
2514228e548eSAnton Blanchard 
2515228e548eSAnton Blanchard 		if (err)
2516228e548eSAnton Blanchard 			break;
2517228e548eSAnton Blanchard 		++datagrams;
25183023898bSSoheil Hassas Yeganeh 		if (msg_data_left(&msg_sys))
25193023898bSSoheil Hassas Yeganeh 			break;
2520a78cb84cSEric Dumazet 		cond_resched();
2521228e548eSAnton Blanchard 	}
2522228e548eSAnton Blanchard 
2523228e548eSAnton Blanchard 	fput_light(sock->file, fput_needed);
2524228e548eSAnton Blanchard 
2525728ffb86SAnton Blanchard 	/* We only return an error if no datagrams were able to be sent */
2526728ffb86SAnton Blanchard 	if (datagrams != 0)
2527228e548eSAnton Blanchard 		return datagrams;
2528228e548eSAnton Blanchard 
2529228e548eSAnton Blanchard 	return err;
2530228e548eSAnton Blanchard }
2531228e548eSAnton Blanchard 
2532228e548eSAnton Blanchard SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
2533228e548eSAnton Blanchard 		unsigned int, vlen, unsigned int, flags)
2534228e548eSAnton Blanchard {
2535e1834a32SDominik Brodowski 	return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
2536228e548eSAnton Blanchard }
2537228e548eSAnton Blanchard 
253803b1230cSJens Axboe int recvmsg_copy_msghdr(struct msghdr *msg,
25394257c8caSJens Axboe 			struct user_msghdr __user *umsg, unsigned flags,
25404257c8caSJens Axboe 			struct sockaddr __user **uaddr,
25414257c8caSJens Axboe 			struct iovec **iov)
25424257c8caSJens Axboe {
25434257c8caSJens Axboe 	ssize_t err;
25444257c8caSJens Axboe 
25454257c8caSJens Axboe 	if (MSG_CMSG_COMPAT & flags) {
25464257c8caSJens Axboe 		struct compat_msghdr __user *msg_compat;
25474257c8caSJens Axboe 
25484257c8caSJens Axboe 		msg_compat = (struct compat_msghdr __user *) umsg;
25494257c8caSJens Axboe 		err = get_compat_msghdr(msg, msg_compat, uaddr, iov);
25504257c8caSJens Axboe 	} else {
25514257c8caSJens Axboe 		err = copy_msghdr_from_user(msg, umsg, uaddr, iov);
25524257c8caSJens Axboe 	}
25534257c8caSJens Axboe 	if (err < 0)
25544257c8caSJens Axboe 		return err;
25554257c8caSJens Axboe 
25564257c8caSJens Axboe 	return 0;
25574257c8caSJens Axboe }
25584257c8caSJens Axboe 
25594257c8caSJens Axboe static int ____sys_recvmsg(struct socket *sock, struct msghdr *msg_sys,
25604257c8caSJens Axboe 			   struct user_msghdr __user *msg,
25614257c8caSJens Axboe 			   struct sockaddr __user *uaddr,
25624257c8caSJens Axboe 			   unsigned int flags, int nosec)
25631da177e4SLinus Torvalds {
256489bddce5SStephen Hemminger 	struct compat_msghdr __user *msg_compat =
256589bddce5SStephen Hemminger 					(struct compat_msghdr __user *) msg;
25664257c8caSJens Axboe 	int __user *uaddr_len = COMPAT_NAMELEN(msg);
25674257c8caSJens Axboe 	struct sockaddr_storage addr;
25681da177e4SLinus Torvalds 	unsigned long cmsg_ptr;
25692da62906SAl Viro 	int len;
257008adb7daSAl Viro 	ssize_t err;
25711da177e4SLinus Torvalds 
257208adb7daSAl Viro 	msg_sys->msg_name = &addr;
2573a2e27255SArnaldo Carvalho de Melo 	cmsg_ptr = (unsigned long)msg_sys->msg_control;
2574a2e27255SArnaldo Carvalho de Melo 	msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
25751da177e4SLinus Torvalds 
2576f3d33426SHannes Frederic Sowa 	/* We assume all kernel code knows the size of sockaddr_storage */
2577f3d33426SHannes Frederic Sowa 	msg_sys->msg_namelen = 0;
2578f3d33426SHannes Frederic Sowa 
25791da177e4SLinus Torvalds 	if (sock->file->f_flags & O_NONBLOCK)
25801da177e4SLinus Torvalds 		flags |= MSG_DONTWAIT;
25811af66221SEric Dumazet 
25821af66221SEric Dumazet 	if (unlikely(nosec))
25831af66221SEric Dumazet 		err = sock_recvmsg_nosec(sock, msg_sys, flags);
25841af66221SEric Dumazet 	else
25851af66221SEric Dumazet 		err = sock_recvmsg(sock, msg_sys, flags);
25861af66221SEric Dumazet 
25871da177e4SLinus Torvalds 	if (err < 0)
25884257c8caSJens Axboe 		goto out;
25891da177e4SLinus Torvalds 	len = err;
25901da177e4SLinus Torvalds 
25911da177e4SLinus Torvalds 	if (uaddr != NULL) {
259243db362dSMaciej Żenczykowski 		err = move_addr_to_user(&addr,
2593a2e27255SArnaldo Carvalho de Melo 					msg_sys->msg_namelen, uaddr,
259489bddce5SStephen Hemminger 					uaddr_len);
25951da177e4SLinus Torvalds 		if (err < 0)
25964257c8caSJens Axboe 			goto out;
25971da177e4SLinus Torvalds 	}
2598a2e27255SArnaldo Carvalho de Melo 	err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
259937f7f421SDavid S. Miller 			 COMPAT_FLAGS(msg));
26001da177e4SLinus Torvalds 	if (err)
26014257c8caSJens Axboe 		goto out;
26021da177e4SLinus Torvalds 	if (MSG_CMSG_COMPAT & flags)
2603a2e27255SArnaldo Carvalho de Melo 		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
26041da177e4SLinus Torvalds 				 &msg_compat->msg_controllen);
26051da177e4SLinus Torvalds 	else
2606a2e27255SArnaldo Carvalho de Melo 		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
26071da177e4SLinus Torvalds 				 &msg->msg_controllen);
26081da177e4SLinus Torvalds 	if (err)
26094257c8caSJens Axboe 		goto out;
26101da177e4SLinus Torvalds 	err = len;
26114257c8caSJens Axboe out:
26124257c8caSJens Axboe 	return err;
26134257c8caSJens Axboe }
26141da177e4SLinus Torvalds 
26154257c8caSJens Axboe static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
26164257c8caSJens Axboe 			 struct msghdr *msg_sys, unsigned int flags, int nosec)
26174257c8caSJens Axboe {
26184257c8caSJens Axboe 	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
26194257c8caSJens Axboe 	/* user mode address pointers */
26204257c8caSJens Axboe 	struct sockaddr __user *uaddr;
26214257c8caSJens Axboe 	ssize_t err;
26224257c8caSJens Axboe 
26234257c8caSJens Axboe 	err = recvmsg_copy_msghdr(msg_sys, msg, flags, &uaddr, &iov);
26244257c8caSJens Axboe 	if (err < 0)
26254257c8caSJens Axboe 		return err;
26264257c8caSJens Axboe 
26274257c8caSJens Axboe 	err = ____sys_recvmsg(sock, msg_sys, msg, uaddr, flags, nosec);
2628a74e9106SEric Dumazet 	kfree(iov);
2629a2e27255SArnaldo Carvalho de Melo 	return err;
2630a2e27255SArnaldo Carvalho de Melo }
2631a2e27255SArnaldo Carvalho de Melo 
2632a2e27255SArnaldo Carvalho de Melo /*
2633a2e27255SArnaldo Carvalho de Melo  *	BSD recvmsg interface
2634a2e27255SArnaldo Carvalho de Melo  */
2635a2e27255SArnaldo Carvalho de Melo 
263603b1230cSJens Axboe long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
263703b1230cSJens Axboe 			struct user_msghdr __user *umsg,
263803b1230cSJens Axboe 			struct sockaddr __user *uaddr, unsigned int flags)
2639aa1fa28fSJens Axboe {
2640d69e0779SJens Axboe 	/* disallow ancillary data requests from this path */
264103b1230cSJens Axboe 	if (msg->msg_control || msg->msg_controllen)
264203b1230cSJens Axboe 		return -EINVAL;
2643d69e0779SJens Axboe 
264403b1230cSJens Axboe 	return ____sys_recvmsg(sock, msg, umsg, uaddr, flags, 0);
2645aa1fa28fSJens Axboe }
2646aa1fa28fSJens Axboe 
2647e1834a32SDominik Brodowski long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
2648e1834a32SDominik Brodowski 		   bool forbid_cmsg_compat)
2649a2e27255SArnaldo Carvalho de Melo {
2650a2e27255SArnaldo Carvalho de Melo 	int fput_needed, err;
2651a2e27255SArnaldo Carvalho de Melo 	struct msghdr msg_sys;
26521be374a0SAndy Lutomirski 	struct socket *sock;
2653a2e27255SArnaldo Carvalho de Melo 
2654e1834a32SDominik Brodowski 	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
2655e1834a32SDominik Brodowski 		return -EINVAL;
2656e1834a32SDominik Brodowski 
26571be374a0SAndy Lutomirski 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
2658a2e27255SArnaldo Carvalho de Melo 	if (!sock)
2659a2e27255SArnaldo Carvalho de Melo 		goto out;
2660a2e27255SArnaldo Carvalho de Melo 
2661a7526eb5SAndy Lutomirski 	err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
2662a2e27255SArnaldo Carvalho de Melo 
26636cb153caSBenjamin LaHaise 	fput_light(sock->file, fput_needed);
26641da177e4SLinus Torvalds out:
26651da177e4SLinus Torvalds 	return err;
26661da177e4SLinus Torvalds }
26671da177e4SLinus Torvalds 
2668666547ffSAl Viro SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
2669a7526eb5SAndy Lutomirski 		unsigned int, flags)
2670a7526eb5SAndy Lutomirski {
2671e1834a32SDominik Brodowski 	return __sys_recvmsg(fd, msg, flags, true);
2672a7526eb5SAndy Lutomirski }
2673a7526eb5SAndy Lutomirski 
2674a2e27255SArnaldo Carvalho de Melo /*
2675a2e27255SArnaldo Carvalho de Melo  *     Linux recvmmsg interface
2676a2e27255SArnaldo Carvalho de Melo  */
26771da177e4SLinus Torvalds 
2678e11d4284SArnd Bergmann static int do_recvmmsg(int fd, struct mmsghdr __user *mmsg,
2679e11d4284SArnd Bergmann 			  unsigned int vlen, unsigned int flags,
2680e11d4284SArnd Bergmann 			  struct timespec64 *timeout)
2681a2e27255SArnaldo Carvalho de Melo {
2682a2e27255SArnaldo Carvalho de Melo 	int fput_needed, err, datagrams;
2683a2e27255SArnaldo Carvalho de Melo 	struct socket *sock;
2684a2e27255SArnaldo Carvalho de Melo 	struct mmsghdr __user *entry;
2685d7256d0eSJean-Mickael Guerin 	struct compat_mmsghdr __user *compat_entry;
2686a2e27255SArnaldo Carvalho de Melo 	struct msghdr msg_sys;
2687766b9f92SDeepa Dinamani 	struct timespec64 end_time;
2688766b9f92SDeepa Dinamani 	struct timespec64 timeout64;
2689a2e27255SArnaldo Carvalho de Melo 
2690a2e27255SArnaldo Carvalho de Melo 	if (timeout &&
2691a2e27255SArnaldo Carvalho de Melo 	    poll_select_set_timeout(&end_time, timeout->tv_sec,
2692a2e27255SArnaldo Carvalho de Melo 				    timeout->tv_nsec))
2693a2e27255SArnaldo Carvalho de Melo 		return -EINVAL;
2694a2e27255SArnaldo Carvalho de Melo 
2695a2e27255SArnaldo Carvalho de Melo 	datagrams = 0;
2696a2e27255SArnaldo Carvalho de Melo 
2697a2e27255SArnaldo Carvalho de Melo 	sock = sockfd_lookup_light(fd, &err, &fput_needed);
2698a2e27255SArnaldo Carvalho de Melo 	if (!sock)
2699a2e27255SArnaldo Carvalho de Melo 		return err;
2700a2e27255SArnaldo Carvalho de Melo 
27017797dc41SSoheil Hassas Yeganeh 	if (likely(!(flags & MSG_ERRQUEUE))) {
2702a2e27255SArnaldo Carvalho de Melo 		err = sock_error(sock->sk);
2703e623a9e9SMaxime Jayat 		if (err) {
2704e623a9e9SMaxime Jayat 			datagrams = err;
2705a2e27255SArnaldo Carvalho de Melo 			goto out_put;
2706e623a9e9SMaxime Jayat 		}
27077797dc41SSoheil Hassas Yeganeh 	}
2708a2e27255SArnaldo Carvalho de Melo 
2709a2e27255SArnaldo Carvalho de Melo 	entry = mmsg;
2710d7256d0eSJean-Mickael Guerin 	compat_entry = (struct compat_mmsghdr __user *)mmsg;
2711a2e27255SArnaldo Carvalho de Melo 
2712a2e27255SArnaldo Carvalho de Melo 	while (datagrams < vlen) {
2713a2e27255SArnaldo Carvalho de Melo 		/*
2714a2e27255SArnaldo Carvalho de Melo 		 * No need to ask LSM for more than the first datagram.
2715a2e27255SArnaldo Carvalho de Melo 		 */
2716d7256d0eSJean-Mickael Guerin 		if (MSG_CMSG_COMPAT & flags) {
2717666547ffSAl Viro 			err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry,
2718b9eb8b87SAnton Blanchard 					     &msg_sys, flags & ~MSG_WAITFORONE,
2719b9eb8b87SAnton Blanchard 					     datagrams);
2720d7256d0eSJean-Mickael Guerin 			if (err < 0)
2721d7256d0eSJean-Mickael Guerin 				break;
2722d7256d0eSJean-Mickael Guerin 			err = __put_user(err, &compat_entry->msg_len);
2723d7256d0eSJean-Mickael Guerin 			++compat_entry;
2724d7256d0eSJean-Mickael Guerin 		} else {
2725a7526eb5SAndy Lutomirski 			err = ___sys_recvmsg(sock,
2726666547ffSAl Viro 					     (struct user_msghdr __user *)entry,
2727b9eb8b87SAnton Blanchard 					     &msg_sys, flags & ~MSG_WAITFORONE,
2728b9eb8b87SAnton Blanchard 					     datagrams);
2729a2e27255SArnaldo Carvalho de Melo 			if (err < 0)
2730a2e27255SArnaldo Carvalho de Melo 				break;
2731a2e27255SArnaldo Carvalho de Melo 			err = put_user(err, &entry->msg_len);
2732d7256d0eSJean-Mickael Guerin 			++entry;
2733d7256d0eSJean-Mickael Guerin 		}
2734d7256d0eSJean-Mickael Guerin 
2735a2e27255SArnaldo Carvalho de Melo 		if (err)
2736a2e27255SArnaldo Carvalho de Melo 			break;
2737a2e27255SArnaldo Carvalho de Melo 		++datagrams;
2738a2e27255SArnaldo Carvalho de Melo 
273971c5c159SBrandon L Black 		/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
274071c5c159SBrandon L Black 		if (flags & MSG_WAITFORONE)
274171c5c159SBrandon L Black 			flags |= MSG_DONTWAIT;
274271c5c159SBrandon L Black 
2743a2e27255SArnaldo Carvalho de Melo 		if (timeout) {
2744766b9f92SDeepa Dinamani 			ktime_get_ts64(&timeout64);
2745c2e6c856SArnd Bergmann 			*timeout = timespec64_sub(end_time, timeout64);
2746a2e27255SArnaldo Carvalho de Melo 			if (timeout->tv_sec < 0) {
2747a2e27255SArnaldo Carvalho de Melo 				timeout->tv_sec = timeout->tv_nsec = 0;
2748a2e27255SArnaldo Carvalho de Melo 				break;
2749a2e27255SArnaldo Carvalho de Melo 			}
2750a2e27255SArnaldo Carvalho de Melo 
2751a2e27255SArnaldo Carvalho de Melo 			/* Timeout, return less than vlen datagrams */
2752a2e27255SArnaldo Carvalho de Melo 			if (timeout->tv_nsec == 0 && timeout->tv_sec == 0)
2753a2e27255SArnaldo Carvalho de Melo 				break;
2754a2e27255SArnaldo Carvalho de Melo 		}
2755a2e27255SArnaldo Carvalho de Melo 
2756a2e27255SArnaldo Carvalho de Melo 		/* Out of band data, return right away */
2757a2e27255SArnaldo Carvalho de Melo 		if (msg_sys.msg_flags & MSG_OOB)
2758a2e27255SArnaldo Carvalho de Melo 			break;
2759a78cb84cSEric Dumazet 		cond_resched();
2760a2e27255SArnaldo Carvalho de Melo 	}
2761a2e27255SArnaldo Carvalho de Melo 
2762a2e27255SArnaldo Carvalho de Melo 	if (err == 0)
276334b88a68SArnaldo Carvalho de Melo 		goto out_put;
2764a2e27255SArnaldo Carvalho de Melo 
276534b88a68SArnaldo Carvalho de Melo 	if (datagrams == 0) {
276634b88a68SArnaldo Carvalho de Melo 		datagrams = err;
276734b88a68SArnaldo Carvalho de Melo 		goto out_put;
276834b88a68SArnaldo Carvalho de Melo 	}
276934b88a68SArnaldo Carvalho de Melo 
2770a2e27255SArnaldo Carvalho de Melo 	/*
2771a2e27255SArnaldo Carvalho de Melo 	 * We may return less entries than requested (vlen) if the
2772a2e27255SArnaldo Carvalho de Melo 	 * sock is non block and there aren't enough datagrams...
2773a2e27255SArnaldo Carvalho de Melo 	 */
2774a2e27255SArnaldo Carvalho de Melo 	if (err != -EAGAIN) {
2775a2e27255SArnaldo Carvalho de Melo 		/*
2776a2e27255SArnaldo Carvalho de Melo 		 * ... or  if recvmsg returns an error after we
2777a2e27255SArnaldo Carvalho de Melo 		 * received some datagrams, where we record the
2778a2e27255SArnaldo Carvalho de Melo 		 * error to return on the next call or if the
2779a2e27255SArnaldo Carvalho de Melo 		 * app asks about it using getsockopt(SO_ERROR).
2780a2e27255SArnaldo Carvalho de Melo 		 */
2781a2e27255SArnaldo Carvalho de Melo 		sock->sk->sk_err = -err;
2782a2e27255SArnaldo Carvalho de Melo 	}
278334b88a68SArnaldo Carvalho de Melo out_put:
278434b88a68SArnaldo Carvalho de Melo 	fput_light(sock->file, fput_needed);
2785a2e27255SArnaldo Carvalho de Melo 
2786a2e27255SArnaldo Carvalho de Melo 	return datagrams;
2787a2e27255SArnaldo Carvalho de Melo }
2788a2e27255SArnaldo Carvalho de Melo 
2789e11d4284SArnd Bergmann int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
27901255e269SDominik Brodowski 		   unsigned int vlen, unsigned int flags,
2791e11d4284SArnd Bergmann 		   struct __kernel_timespec __user *timeout,
2792e11d4284SArnd Bergmann 		   struct old_timespec32 __user *timeout32)
2793a2e27255SArnaldo Carvalho de Melo {
2794a2e27255SArnaldo Carvalho de Melo 	int datagrams;
2795c2e6c856SArnd Bergmann 	struct timespec64 timeout_sys;
2796a2e27255SArnaldo Carvalho de Melo 
2797e11d4284SArnd Bergmann 	if (timeout && get_timespec64(&timeout_sys, timeout))
2798a2e27255SArnaldo Carvalho de Melo 		return -EFAULT;
2799a2e27255SArnaldo Carvalho de Melo 
2800e11d4284SArnd Bergmann 	if (timeout32 && get_old_timespec32(&timeout_sys, timeout32))
2801e11d4284SArnd Bergmann 		return -EFAULT;
2802a2e27255SArnaldo Carvalho de Melo 
2803e11d4284SArnd Bergmann 	if (!timeout && !timeout32)
2804e11d4284SArnd Bergmann 		return do_recvmmsg(fd, mmsg, vlen, flags, NULL);
2805e11d4284SArnd Bergmann 
2806e11d4284SArnd Bergmann 	datagrams = do_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys);
2807e11d4284SArnd Bergmann 
2808e11d4284SArnd Bergmann 	if (datagrams <= 0)
2809e11d4284SArnd Bergmann 		return datagrams;
2810e11d4284SArnd Bergmann 
2811e11d4284SArnd Bergmann 	if (timeout && put_timespec64(&timeout_sys, timeout))
2812e11d4284SArnd Bergmann 		datagrams = -EFAULT;
2813e11d4284SArnd Bergmann 
2814e11d4284SArnd Bergmann 	if (timeout32 && put_old_timespec32(&timeout_sys, timeout32))
2815a2e27255SArnaldo Carvalho de Melo 		datagrams = -EFAULT;
2816a2e27255SArnaldo Carvalho de Melo 
2817a2e27255SArnaldo Carvalho de Melo 	return datagrams;
2818a2e27255SArnaldo Carvalho de Melo }
2819a2e27255SArnaldo Carvalho de Melo 
28201255e269SDominik Brodowski SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
28211255e269SDominik Brodowski 		unsigned int, vlen, unsigned int, flags,
2822c2e6c856SArnd Bergmann 		struct __kernel_timespec __user *, timeout)
28231255e269SDominik Brodowski {
2824e11d4284SArnd Bergmann 	if (flags & MSG_CMSG_COMPAT)
2825e11d4284SArnd Bergmann 		return -EINVAL;
2826e11d4284SArnd Bergmann 
2827e11d4284SArnd Bergmann 	return __sys_recvmmsg(fd, mmsg, vlen, flags, timeout, NULL);
28281255e269SDominik Brodowski }
28291255e269SDominik Brodowski 
2830e11d4284SArnd Bergmann #ifdef CONFIG_COMPAT_32BIT_TIME
2831e11d4284SArnd Bergmann SYSCALL_DEFINE5(recvmmsg_time32, int, fd, struct mmsghdr __user *, mmsg,
2832e11d4284SArnd Bergmann 		unsigned int, vlen, unsigned int, flags,
2833e11d4284SArnd Bergmann 		struct old_timespec32 __user *, timeout)
2834e11d4284SArnd Bergmann {
2835e11d4284SArnd Bergmann 	if (flags & MSG_CMSG_COMPAT)
2836e11d4284SArnd Bergmann 		return -EINVAL;
2837e11d4284SArnd Bergmann 
2838e11d4284SArnd Bergmann 	return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL, timeout);
2839e11d4284SArnd Bergmann }
2840e11d4284SArnd Bergmann #endif
2841e11d4284SArnd Bergmann 
2842a2e27255SArnaldo Carvalho de Melo #ifdef __ARCH_WANT_SYS_SOCKETCALL
28431da177e4SLinus Torvalds /* Argument list sizes for sys_socketcall */
28441da177e4SLinus Torvalds #define AL(x) ((x) * sizeof(unsigned long))
2845228e548eSAnton Blanchard static const unsigned char nargs[21] = {
284689bddce5SStephen Hemminger 	AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
28471da177e4SLinus Torvalds 	AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
2848aaca0bdcSUlrich Drepper 	AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
2849228e548eSAnton Blanchard 	AL(4), AL(5), AL(4)
285089bddce5SStephen Hemminger };
285189bddce5SStephen Hemminger 
28521da177e4SLinus Torvalds #undef AL
28531da177e4SLinus Torvalds 
28541da177e4SLinus Torvalds /*
28551da177e4SLinus Torvalds  *	System call vectors.
28561da177e4SLinus Torvalds  *
28571da177e4SLinus Torvalds  *	Argument checking cleaned up. Saved 20% in size.
28581da177e4SLinus Torvalds  *  This function doesn't need to set the kernel lock because
28591da177e4SLinus Torvalds  *  it is set by the callees.
28601da177e4SLinus Torvalds  */
28611da177e4SLinus Torvalds 
28623e0fa65fSHeiko Carstens SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
28631da177e4SLinus Torvalds {
28642950fa9dSChen Gang 	unsigned long a[AUDITSC_ARGS];
28651da177e4SLinus Torvalds 	unsigned long a0, a1;
28661da177e4SLinus Torvalds 	int err;
286747379052SArjan van de Ven 	unsigned int len;
28681da177e4SLinus Torvalds 
2869228e548eSAnton Blanchard 	if (call < 1 || call > SYS_SENDMMSG)
28701da177e4SLinus Torvalds 		return -EINVAL;
2871c8e8cd57SJeremy Cline 	call = array_index_nospec(call, SYS_SENDMMSG + 1);
28721da177e4SLinus Torvalds 
287347379052SArjan van de Ven 	len = nargs[call];
287447379052SArjan van de Ven 	if (len > sizeof(a))
287547379052SArjan van de Ven 		return -EINVAL;
287647379052SArjan van de Ven 
28771da177e4SLinus Torvalds 	/* copy_from_user should be SMP safe. */
287847379052SArjan van de Ven 	if (copy_from_user(a, args, len))
28791da177e4SLinus Torvalds 		return -EFAULT;
28801da177e4SLinus Torvalds 
28812950fa9dSChen Gang 	err = audit_socketcall(nargs[call] / sizeof(unsigned long), a);
28822950fa9dSChen Gang 	if (err)
28832950fa9dSChen Gang 		return err;
28843ec3b2fbSDavid Woodhouse 
28851da177e4SLinus Torvalds 	a0 = a[0];
28861da177e4SLinus Torvalds 	a1 = a[1];
28871da177e4SLinus Torvalds 
288889bddce5SStephen Hemminger 	switch (call) {
28891da177e4SLinus Torvalds 	case SYS_SOCKET:
28909d6a15c3SDominik Brodowski 		err = __sys_socket(a0, a1, a[2]);
28911da177e4SLinus Torvalds 		break;
28921da177e4SLinus Torvalds 	case SYS_BIND:
2893a87d35d8SDominik Brodowski 		err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
28941da177e4SLinus Torvalds 		break;
28951da177e4SLinus Torvalds 	case SYS_CONNECT:
28961387c2c2SDominik Brodowski 		err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
28971da177e4SLinus Torvalds 		break;
28981da177e4SLinus Torvalds 	case SYS_LISTEN:
289925e290eeSDominik Brodowski 		err = __sys_listen(a0, a1);
29001da177e4SLinus Torvalds 		break;
29011da177e4SLinus Torvalds 	case SYS_ACCEPT:
29024541e805SDominik Brodowski 		err = __sys_accept4(a0, (struct sockaddr __user *)a1,
2903aaca0bdcSUlrich Drepper 				    (int __user *)a[2], 0);
29041da177e4SLinus Torvalds 		break;
29051da177e4SLinus Torvalds 	case SYS_GETSOCKNAME:
290689bddce5SStephen Hemminger 		err =
29078882a107SDominik Brodowski 		    __sys_getsockname(a0, (struct sockaddr __user *)a1,
290889bddce5SStephen Hemminger 				      (int __user *)a[2]);
29091da177e4SLinus Torvalds 		break;
29101da177e4SLinus Torvalds 	case SYS_GETPEERNAME:
291189bddce5SStephen Hemminger 		err =
2912b21c8f83SDominik Brodowski 		    __sys_getpeername(a0, (struct sockaddr __user *)a1,
291389bddce5SStephen Hemminger 				      (int __user *)a[2]);
29141da177e4SLinus Torvalds 		break;
29151da177e4SLinus Torvalds 	case SYS_SOCKETPAIR:
29166debc8d8SDominik Brodowski 		err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
29171da177e4SLinus Torvalds 		break;
29181da177e4SLinus Torvalds 	case SYS_SEND:
2919f3bf896bSDominik Brodowski 		err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
2920f3bf896bSDominik Brodowski 				   NULL, 0);
29211da177e4SLinus Torvalds 		break;
29221da177e4SLinus Torvalds 	case SYS_SENDTO:
2923211b634bSDominik Brodowski 		err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
29241da177e4SLinus Torvalds 				   (struct sockaddr __user *)a[4], a[5]);
29251da177e4SLinus Torvalds 		break;
29261da177e4SLinus Torvalds 	case SYS_RECV:
2927d27e9afcSDominik Brodowski 		err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
2928d27e9afcSDominik Brodowski 				     NULL, NULL);
29291da177e4SLinus Torvalds 		break;
29301da177e4SLinus Torvalds 	case SYS_RECVFROM:
29317a09e1ebSDominik Brodowski 		err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
293289bddce5SStephen Hemminger 				     (struct sockaddr __user *)a[4],
293389bddce5SStephen Hemminger 				     (int __user *)a[5]);
29341da177e4SLinus Torvalds 		break;
29351da177e4SLinus Torvalds 	case SYS_SHUTDOWN:
2936005a1aeaSDominik Brodowski 		err = __sys_shutdown(a0, a1);
29371da177e4SLinus Torvalds 		break;
29381da177e4SLinus Torvalds 	case SYS_SETSOCKOPT:
2939cc36dca0SDominik Brodowski 		err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3],
2940cc36dca0SDominik Brodowski 				       a[4]);
29411da177e4SLinus Torvalds 		break;
29421da177e4SLinus Torvalds 	case SYS_GETSOCKOPT:
294389bddce5SStephen Hemminger 		err =
294413a2d70eSDominik Brodowski 		    __sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
294589bddce5SStephen Hemminger 				     (int __user *)a[4]);
29461da177e4SLinus Torvalds 		break;
29471da177e4SLinus Torvalds 	case SYS_SENDMSG:
2948e1834a32SDominik Brodowski 		err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1,
2949e1834a32SDominik Brodowski 				    a[2], true);
29501da177e4SLinus Torvalds 		break;
2951228e548eSAnton Blanchard 	case SYS_SENDMMSG:
2952e1834a32SDominik Brodowski 		err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2],
2953e1834a32SDominik Brodowski 				     a[3], true);
2954228e548eSAnton Blanchard 		break;
29551da177e4SLinus Torvalds 	case SYS_RECVMSG:
2956e1834a32SDominik Brodowski 		err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1,
2957e1834a32SDominik Brodowski 				    a[2], true);
29581da177e4SLinus Torvalds 		break;
2959a2e27255SArnaldo Carvalho de Melo 	case SYS_RECVMMSG:
29603ca47e95SArnd Bergmann 		if (IS_ENABLED(CONFIG_64BIT))
2961e11d4284SArnd Bergmann 			err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1,
2962e11d4284SArnd Bergmann 					     a[2], a[3],
2963e11d4284SArnd Bergmann 					     (struct __kernel_timespec __user *)a[4],
2964e11d4284SArnd Bergmann 					     NULL);
2965e11d4284SArnd Bergmann 		else
2966e11d4284SArnd Bergmann 			err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1,
2967e11d4284SArnd Bergmann 					     a[2], a[3], NULL,
2968e11d4284SArnd Bergmann 					     (struct old_timespec32 __user *)a[4]);
2969a2e27255SArnaldo Carvalho de Melo 		break;
2970de11defeSUlrich Drepper 	case SYS_ACCEPT4:
29714541e805SDominik Brodowski 		err = __sys_accept4(a0, (struct sockaddr __user *)a1,
2972de11defeSUlrich Drepper 				    (int __user *)a[2], a[3]);
2973aaca0bdcSUlrich Drepper 		break;
29741da177e4SLinus Torvalds 	default:
29751da177e4SLinus Torvalds 		err = -EINVAL;
29761da177e4SLinus Torvalds 		break;
29771da177e4SLinus Torvalds 	}
29781da177e4SLinus Torvalds 	return err;
29791da177e4SLinus Torvalds }
29801da177e4SLinus Torvalds 
29811da177e4SLinus Torvalds #endif				/* __ARCH_WANT_SYS_SOCKETCALL */
29821da177e4SLinus Torvalds 
298355737fdaSStephen Hemminger /**
298455737fdaSStephen Hemminger  *	sock_register - add a socket protocol handler
298555737fdaSStephen Hemminger  *	@ops: description of protocol
298655737fdaSStephen Hemminger  *
29871da177e4SLinus Torvalds  *	This function is called by a protocol handler that wants to
29881da177e4SLinus Torvalds  *	advertise its address family, and have it linked into the
2989e793c0f7SMasanari Iida  *	socket interface. The value ops->family corresponds to the
299055737fdaSStephen Hemminger  *	socket system call protocol family.
29911da177e4SLinus Torvalds  */
2992f0fd27d4SStephen Hemminger int sock_register(const struct net_proto_family *ops)
29931da177e4SLinus Torvalds {
29941da177e4SLinus Torvalds 	int err;
29951da177e4SLinus Torvalds 
29961da177e4SLinus Torvalds 	if (ops->family >= NPROTO) {
29973410f22eSYang Yingliang 		pr_crit("protocol %d >= NPROTO(%d)\n", ops->family, NPROTO);
29981da177e4SLinus Torvalds 		return -ENOBUFS;
29991da177e4SLinus Torvalds 	}
300055737fdaSStephen Hemminger 
300155737fdaSStephen Hemminger 	spin_lock(&net_family_lock);
3002190683a9SEric Dumazet 	if (rcu_dereference_protected(net_families[ops->family],
3003190683a9SEric Dumazet 				      lockdep_is_held(&net_family_lock)))
30041da177e4SLinus Torvalds 		err = -EEXIST;
300555737fdaSStephen Hemminger 	else {
3006cf778b00SEric Dumazet 		rcu_assign_pointer(net_families[ops->family], ops);
30071da177e4SLinus Torvalds 		err = 0;
30081da177e4SLinus Torvalds 	}
300955737fdaSStephen Hemminger 	spin_unlock(&net_family_lock);
301055737fdaSStephen Hemminger 
30113410f22eSYang Yingliang 	pr_info("NET: Registered protocol family %d\n", ops->family);
30121da177e4SLinus Torvalds 	return err;
30131da177e4SLinus Torvalds }
3014c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_register);
30151da177e4SLinus Torvalds 
301655737fdaSStephen Hemminger /**
301755737fdaSStephen Hemminger  *	sock_unregister - remove a protocol handler
301855737fdaSStephen Hemminger  *	@family: protocol family to remove
301955737fdaSStephen Hemminger  *
30201da177e4SLinus Torvalds  *	This function is called by a protocol handler that wants to
30211da177e4SLinus Torvalds  *	remove its address family, and have it unlinked from the
302255737fdaSStephen Hemminger  *	new socket creation.
302355737fdaSStephen Hemminger  *
302455737fdaSStephen Hemminger  *	If protocol handler is a module, then it can use module reference
302555737fdaSStephen Hemminger  *	counts to protect against new references. If protocol handler is not
302655737fdaSStephen Hemminger  *	a module then it needs to provide its own protection in
302755737fdaSStephen Hemminger  *	the ops->create routine.
30281da177e4SLinus Torvalds  */
3029f0fd27d4SStephen Hemminger void sock_unregister(int family)
30301da177e4SLinus Torvalds {
3031f0fd27d4SStephen Hemminger 	BUG_ON(family < 0 || family >= NPROTO);
30321da177e4SLinus Torvalds 
303355737fdaSStephen Hemminger 	spin_lock(&net_family_lock);
3034a9b3cd7fSStephen Hemminger 	RCU_INIT_POINTER(net_families[family], NULL);
303555737fdaSStephen Hemminger 	spin_unlock(&net_family_lock);
303655737fdaSStephen Hemminger 
303755737fdaSStephen Hemminger 	synchronize_rcu();
303855737fdaSStephen Hemminger 
30393410f22eSYang Yingliang 	pr_info("NET: Unregistered protocol family %d\n", family);
30401da177e4SLinus Torvalds }
3041c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_unregister);
30421da177e4SLinus Torvalds 
3043bf2ae2e4SXin Long bool sock_is_registered(int family)
3044bf2ae2e4SXin Long {
304566b51b0aSJeremy Cline 	return family < NPROTO && rcu_access_pointer(net_families[family]);
3046bf2ae2e4SXin Long }
3047bf2ae2e4SXin Long 
304877d76ea3SAndi Kleen static int __init sock_init(void)
30491da177e4SLinus Torvalds {
3050b3e19d92SNick Piggin 	int err;
30512ca794e5SEric W. Biederman 	/*
30522ca794e5SEric W. Biederman 	 *      Initialize the network sysctl infrastructure.
30532ca794e5SEric W. Biederman 	 */
30542ca794e5SEric W. Biederman 	err = net_sysctl_init();
30552ca794e5SEric W. Biederman 	if (err)
30562ca794e5SEric W. Biederman 		goto out;
3057b3e19d92SNick Piggin 
30581da177e4SLinus Torvalds 	/*
30591da177e4SLinus Torvalds 	 *      Initialize skbuff SLAB cache
30601da177e4SLinus Torvalds 	 */
30611da177e4SLinus Torvalds 	skb_init();
30621da177e4SLinus Torvalds 
30631da177e4SLinus Torvalds 	/*
30641da177e4SLinus Torvalds 	 *      Initialize the protocols module.
30651da177e4SLinus Torvalds 	 */
30661da177e4SLinus Torvalds 
30671da177e4SLinus Torvalds 	init_inodecache();
3068b3e19d92SNick Piggin 
3069b3e19d92SNick Piggin 	err = register_filesystem(&sock_fs_type);
3070b3e19d92SNick Piggin 	if (err)
3071b3e19d92SNick Piggin 		goto out_fs;
30721da177e4SLinus Torvalds 	sock_mnt = kern_mount(&sock_fs_type);
3073b3e19d92SNick Piggin 	if (IS_ERR(sock_mnt)) {
3074b3e19d92SNick Piggin 		err = PTR_ERR(sock_mnt);
3075b3e19d92SNick Piggin 		goto out_mount;
3076b3e19d92SNick Piggin 	}
307777d76ea3SAndi Kleen 
307877d76ea3SAndi Kleen 	/* The real protocol initialization is performed in later initcalls.
30791da177e4SLinus Torvalds 	 */
30801da177e4SLinus Torvalds 
30811da177e4SLinus Torvalds #ifdef CONFIG_NETFILTER
30826d11cfdbSPablo Neira Ayuso 	err = netfilter_init();
30836d11cfdbSPablo Neira Ayuso 	if (err)
30846d11cfdbSPablo Neira Ayuso 		goto out;
30851da177e4SLinus Torvalds #endif
3086cbeb321aSDavid S. Miller 
3087408eccceSDaniel Borkmann 	ptp_classifier_init();
3088c1f19b51SRichard Cochran 
3089b3e19d92SNick Piggin out:
3090b3e19d92SNick Piggin 	return err;
3091b3e19d92SNick Piggin 
3092b3e19d92SNick Piggin out_mount:
3093b3e19d92SNick Piggin 	unregister_filesystem(&sock_fs_type);
3094b3e19d92SNick Piggin out_fs:
3095b3e19d92SNick Piggin 	goto out;
30961da177e4SLinus Torvalds }
30971da177e4SLinus Torvalds 
309877d76ea3SAndi Kleen core_initcall(sock_init);	/* early initcall */
309977d76ea3SAndi Kleen 
31001da177e4SLinus Torvalds #ifdef CONFIG_PROC_FS
31011da177e4SLinus Torvalds void socket_seq_show(struct seq_file *seq)
31021da177e4SLinus Torvalds {
3103648845abSTonghao Zhang 	seq_printf(seq, "sockets: used %d\n",
3104648845abSTonghao Zhang 		   sock_inuse_get(seq->private));
31051da177e4SLinus Torvalds }
31061da177e4SLinus Torvalds #endif				/* CONFIG_PROC_FS */
31071da177e4SLinus Torvalds 
310889bbfc95SShaun Pereira #ifdef CONFIG_COMPAT
310936fd633eSAl Viro static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
31107a229387SArnd Bergmann {
31116b96018bSArnd Bergmann 	struct compat_ifconf ifc32;
31127a229387SArnd Bergmann 	struct ifconf ifc;
31137a229387SArnd Bergmann 	int err;
31147a229387SArnd Bergmann 
31156b96018bSArnd Bergmann 	if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
31167a229387SArnd Bergmann 		return -EFAULT;
31177a229387SArnd Bergmann 
311836fd633eSAl Viro 	ifc.ifc_len = ifc32.ifc_len;
311936fd633eSAl Viro 	ifc.ifc_req = compat_ptr(ifc32.ifcbuf);
31207a229387SArnd Bergmann 
312136fd633eSAl Viro 	rtnl_lock();
312236fd633eSAl Viro 	err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq));
312336fd633eSAl Viro 	rtnl_unlock();
31247a229387SArnd Bergmann 	if (err)
31257a229387SArnd Bergmann 		return err;
31267a229387SArnd Bergmann 
312736fd633eSAl Viro 	ifc32.ifc_len = ifc.ifc_len;
31286b96018bSArnd Bergmann 	if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
31297a229387SArnd Bergmann 		return -EFAULT;
31307a229387SArnd Bergmann 
31317a229387SArnd Bergmann 	return 0;
31327a229387SArnd Bergmann }
31337a229387SArnd Bergmann 
31346b96018bSArnd Bergmann static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
31357a229387SArnd Bergmann {
31363a7da39dSBen Hutchings 	struct compat_ethtool_rxnfc __user *compat_rxnfc;
31373a7da39dSBen Hutchings 	bool convert_in = false, convert_out = false;
313844c02a2cSAl Viro 	size_t buf_size = 0;
313944c02a2cSAl Viro 	struct ethtool_rxnfc __user *rxnfc = NULL;
314044c02a2cSAl Viro 	struct ifreq ifr;
31413a7da39dSBen Hutchings 	u32 rule_cnt = 0, actual_rule_cnt;
31423a7da39dSBen Hutchings 	u32 ethcmd;
31437a229387SArnd Bergmann 	u32 data;
31443a7da39dSBen Hutchings 	int ret;
31457a229387SArnd Bergmann 
31467a229387SArnd Bergmann 	if (get_user(data, &ifr32->ifr_ifru.ifru_data))
31477a229387SArnd Bergmann 		return -EFAULT;
31487a229387SArnd Bergmann 
31493a7da39dSBen Hutchings 	compat_rxnfc = compat_ptr(data);
31503a7da39dSBen Hutchings 
31513a7da39dSBen Hutchings 	if (get_user(ethcmd, &compat_rxnfc->cmd))
31527a229387SArnd Bergmann 		return -EFAULT;
31537a229387SArnd Bergmann 
31543a7da39dSBen Hutchings 	/* Most ethtool structures are defined without padding.
31553a7da39dSBen Hutchings 	 * Unfortunately struct ethtool_rxnfc is an exception.
31563a7da39dSBen Hutchings 	 */
31573a7da39dSBen Hutchings 	switch (ethcmd) {
31583a7da39dSBen Hutchings 	default:
31593a7da39dSBen Hutchings 		break;
31603a7da39dSBen Hutchings 	case ETHTOOL_GRXCLSRLALL:
31613a7da39dSBen Hutchings 		/* Buffer size is variable */
31623a7da39dSBen Hutchings 		if (get_user(rule_cnt, &compat_rxnfc->rule_cnt))
31633a7da39dSBen Hutchings 			return -EFAULT;
31643a7da39dSBen Hutchings 		if (rule_cnt > KMALLOC_MAX_SIZE / sizeof(u32))
31653a7da39dSBen Hutchings 			return -ENOMEM;
31663a7da39dSBen Hutchings 		buf_size += rule_cnt * sizeof(u32);
31673a7da39dSBen Hutchings 		/* fall through */
31683a7da39dSBen Hutchings 	case ETHTOOL_GRXRINGS:
31693a7da39dSBen Hutchings 	case ETHTOOL_GRXCLSRLCNT:
31703a7da39dSBen Hutchings 	case ETHTOOL_GRXCLSRULE:
317155664f32SBen Hutchings 	case ETHTOOL_SRXCLSRLINS:
31723a7da39dSBen Hutchings 		convert_out = true;
31733a7da39dSBen Hutchings 		/* fall through */
31743a7da39dSBen Hutchings 	case ETHTOOL_SRXCLSRLDEL:
31753a7da39dSBen Hutchings 		buf_size += sizeof(struct ethtool_rxnfc);
31763a7da39dSBen Hutchings 		convert_in = true;
317744c02a2cSAl Viro 		rxnfc = compat_alloc_user_space(buf_size);
31783a7da39dSBen Hutchings 		break;
31793a7da39dSBen Hutchings 	}
31803a7da39dSBen Hutchings 
318144c02a2cSAl Viro 	if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ))
31823a7da39dSBen Hutchings 		return -EFAULT;
31833a7da39dSBen Hutchings 
318444c02a2cSAl Viro 	ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc;
31853a7da39dSBen Hutchings 
31863a7da39dSBen Hutchings 	if (convert_in) {
3187127fe533SAlexander Duyck 		/* We expect there to be holes between fs.m_ext and
31883a7da39dSBen Hutchings 		 * fs.ring_cookie and at the end of fs, but nowhere else.
31893a7da39dSBen Hutchings 		 */
3190127fe533SAlexander Duyck 		BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) +
3191127fe533SAlexander Duyck 			     sizeof(compat_rxnfc->fs.m_ext) !=
3192127fe533SAlexander Duyck 			     offsetof(struct ethtool_rxnfc, fs.m_ext) +
3193127fe533SAlexander Duyck 			     sizeof(rxnfc->fs.m_ext));
31943a7da39dSBen Hutchings 		BUILD_BUG_ON(
31953a7da39dSBen Hutchings 			offsetof(struct compat_ethtool_rxnfc, fs.location) -
31963a7da39dSBen Hutchings 			offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) !=
31973a7da39dSBen Hutchings 			offsetof(struct ethtool_rxnfc, fs.location) -
31983a7da39dSBen Hutchings 			offsetof(struct ethtool_rxnfc, fs.ring_cookie));
31993a7da39dSBen Hutchings 
32003a7da39dSBen Hutchings 		if (copy_in_user(rxnfc, compat_rxnfc,
3201954b1244SStephen Hemminger 				 (void __user *)(&rxnfc->fs.m_ext + 1) -
3202954b1244SStephen Hemminger 				 (void __user *)rxnfc) ||
32033a7da39dSBen Hutchings 		    copy_in_user(&rxnfc->fs.ring_cookie,
32043a7da39dSBen Hutchings 				 &compat_rxnfc->fs.ring_cookie,
3205954b1244SStephen Hemminger 				 (void __user *)(&rxnfc->fs.location + 1) -
3206b6168562SWenwen Wang 				 (void __user *)&rxnfc->fs.ring_cookie))
3207b6168562SWenwen Wang 			return -EFAULT;
3208b6168562SWenwen Wang 		if (ethcmd == ETHTOOL_GRXCLSRLALL) {
3209b6168562SWenwen Wang 			if (put_user(rule_cnt, &rxnfc->rule_cnt))
3210b6168562SWenwen Wang 				return -EFAULT;
3211b6168562SWenwen Wang 		} else if (copy_in_user(&rxnfc->rule_cnt,
3212b6168562SWenwen Wang 					&compat_rxnfc->rule_cnt,
32133a7da39dSBen Hutchings 					sizeof(rxnfc->rule_cnt)))
32143a7da39dSBen Hutchings 			return -EFAULT;
32153a7da39dSBen Hutchings 	}
32163a7da39dSBen Hutchings 
321744c02a2cSAl Viro 	ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL);
32183a7da39dSBen Hutchings 	if (ret)
32193a7da39dSBen Hutchings 		return ret;
32203a7da39dSBen Hutchings 
32213a7da39dSBen Hutchings 	if (convert_out) {
32223a7da39dSBen Hutchings 		if (copy_in_user(compat_rxnfc, rxnfc,
3223954b1244SStephen Hemminger 				 (const void __user *)(&rxnfc->fs.m_ext + 1) -
3224954b1244SStephen Hemminger 				 (const void __user *)rxnfc) ||
32253a7da39dSBen Hutchings 		    copy_in_user(&compat_rxnfc->fs.ring_cookie,
32263a7da39dSBen Hutchings 				 &rxnfc->fs.ring_cookie,
3227954b1244SStephen Hemminger 				 (const void __user *)(&rxnfc->fs.location + 1) -
3228954b1244SStephen Hemminger 				 (const void __user *)&rxnfc->fs.ring_cookie) ||
32293a7da39dSBen Hutchings 		    copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt,
32303a7da39dSBen Hutchings 				 sizeof(rxnfc->rule_cnt)))
32313a7da39dSBen Hutchings 			return -EFAULT;
32323a7da39dSBen Hutchings 
32333a7da39dSBen Hutchings 		if (ethcmd == ETHTOOL_GRXCLSRLALL) {
32343a7da39dSBen Hutchings 			/* As an optimisation, we only copy the actual
32353a7da39dSBen Hutchings 			 * number of rules that the underlying
32363a7da39dSBen Hutchings 			 * function returned.  Since Mallory might
32373a7da39dSBen Hutchings 			 * change the rule count in user memory, we
32383a7da39dSBen Hutchings 			 * check that it is less than the rule count
32393a7da39dSBen Hutchings 			 * originally given (as the user buffer size),
32403a7da39dSBen Hutchings 			 * which has been range-checked.
32413a7da39dSBen Hutchings 			 */
32423a7da39dSBen Hutchings 			if (get_user(actual_rule_cnt, &rxnfc->rule_cnt))
32433a7da39dSBen Hutchings 				return -EFAULT;
32443a7da39dSBen Hutchings 			if (actual_rule_cnt < rule_cnt)
32453a7da39dSBen Hutchings 				rule_cnt = actual_rule_cnt;
32463a7da39dSBen Hutchings 			if (copy_in_user(&compat_rxnfc->rule_locs[0],
32473a7da39dSBen Hutchings 					 &rxnfc->rule_locs[0],
32483a7da39dSBen Hutchings 					 rule_cnt * sizeof(u32)))
32493a7da39dSBen Hutchings 				return -EFAULT;
32503a7da39dSBen Hutchings 		}
32513a7da39dSBen Hutchings 	}
32523a7da39dSBen Hutchings 
32533a7da39dSBen Hutchings 	return 0;
32547a229387SArnd Bergmann }
32557a229387SArnd Bergmann 
32567a50a240SArnd Bergmann static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
32577a50a240SArnd Bergmann {
32587a50a240SArnd Bergmann 	compat_uptr_t uptr32;
325944c02a2cSAl Viro 	struct ifreq ifr;
326044c02a2cSAl Viro 	void __user *saved;
326144c02a2cSAl Viro 	int err;
32627a50a240SArnd Bergmann 
326344c02a2cSAl Viro 	if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq)))
32647a50a240SArnd Bergmann 		return -EFAULT;
32657a50a240SArnd Bergmann 
32667a50a240SArnd Bergmann 	if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
32677a50a240SArnd Bergmann 		return -EFAULT;
32687a50a240SArnd Bergmann 
326944c02a2cSAl Viro 	saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
327044c02a2cSAl Viro 	ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
32717a50a240SArnd Bergmann 
327244c02a2cSAl Viro 	err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL);
327344c02a2cSAl Viro 	if (!err) {
327444c02a2cSAl Viro 		ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved;
327544c02a2cSAl Viro 		if (copy_to_user(uifr32, &ifr, sizeof(struct compat_ifreq)))
327644c02a2cSAl Viro 			err = -EFAULT;
32777a50a240SArnd Bergmann 	}
32787a229387SArnd Bergmann 	return err;
32797a229387SArnd Bergmann }
32807a229387SArnd Bergmann 
3281590d4693SBen Hutchings /* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
3282590d4693SBen Hutchings static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
32836b96018bSArnd Bergmann 				 struct compat_ifreq __user *u_ifreq32)
32847a229387SArnd Bergmann {
328544c02a2cSAl Viro 	struct ifreq ifreq;
32867a229387SArnd Bergmann 	u32 data32;
32877a229387SArnd Bergmann 
328844c02a2cSAl Viro 	if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ))
32897a229387SArnd Bergmann 		return -EFAULT;
329044c02a2cSAl Viro 	if (get_user(data32, &u_ifreq32->ifr_data))
32917a229387SArnd Bergmann 		return -EFAULT;
329244c02a2cSAl Viro 	ifreq.ifr_data = compat_ptr(data32);
32937a229387SArnd Bergmann 
329444c02a2cSAl Viro 	return dev_ioctl(net, cmd, &ifreq, NULL);
3295a2116ed2SArnd Bergmann }
3296a2116ed2SArnd Bergmann 
329737ac39bdSJohannes Berg static int compat_ifreq_ioctl(struct net *net, struct socket *sock,
329837ac39bdSJohannes Berg 			      unsigned int cmd,
329937ac39bdSJohannes Berg 			      struct compat_ifreq __user *uifr32)
330037ac39bdSJohannes Berg {
330137ac39bdSJohannes Berg 	struct ifreq __user *uifr;
330237ac39bdSJohannes Berg 	int err;
330337ac39bdSJohannes Berg 
330437ac39bdSJohannes Berg 	/* Handle the fact that while struct ifreq has the same *layout* on
330537ac39bdSJohannes Berg 	 * 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data,
330637ac39bdSJohannes Berg 	 * which are handled elsewhere, it still has different *size* due to
330737ac39bdSJohannes Berg 	 * ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit,
330837ac39bdSJohannes Berg 	 * resulting in struct ifreq being 32 and 40 bytes respectively).
330937ac39bdSJohannes Berg 	 * As a result, if the struct happens to be at the end of a page and
331037ac39bdSJohannes Berg 	 * the next page isn't readable/writable, we get a fault. To prevent
331137ac39bdSJohannes Berg 	 * that, copy back and forth to the full size.
331237ac39bdSJohannes Berg 	 */
331337ac39bdSJohannes Berg 
331437ac39bdSJohannes Berg 	uifr = compat_alloc_user_space(sizeof(*uifr));
331537ac39bdSJohannes Berg 	if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
331637ac39bdSJohannes Berg 		return -EFAULT;
331737ac39bdSJohannes Berg 
331837ac39bdSJohannes Berg 	err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
331937ac39bdSJohannes Berg 
332037ac39bdSJohannes Berg 	if (!err) {
332137ac39bdSJohannes Berg 		switch (cmd) {
332237ac39bdSJohannes Berg 		case SIOCGIFFLAGS:
332337ac39bdSJohannes Berg 		case SIOCGIFMETRIC:
332437ac39bdSJohannes Berg 		case SIOCGIFMTU:
332537ac39bdSJohannes Berg 		case SIOCGIFMEM:
332637ac39bdSJohannes Berg 		case SIOCGIFHWADDR:
332737ac39bdSJohannes Berg 		case SIOCGIFINDEX:
332837ac39bdSJohannes Berg 		case SIOCGIFADDR:
332937ac39bdSJohannes Berg 		case SIOCGIFBRDADDR:
333037ac39bdSJohannes Berg 		case SIOCGIFDSTADDR:
333137ac39bdSJohannes Berg 		case SIOCGIFNETMASK:
333237ac39bdSJohannes Berg 		case SIOCGIFPFLAGS:
333337ac39bdSJohannes Berg 		case SIOCGIFTXQLEN:
333437ac39bdSJohannes Berg 		case SIOCGMIIPHY:
333537ac39bdSJohannes Berg 		case SIOCGMIIREG:
3336c6c9fee3SJohannes Berg 		case SIOCGIFNAME:
333737ac39bdSJohannes Berg 			if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
333837ac39bdSJohannes Berg 				err = -EFAULT;
333937ac39bdSJohannes Berg 			break;
334037ac39bdSJohannes Berg 		}
334137ac39bdSJohannes Berg 	}
334237ac39bdSJohannes Berg 	return err;
334337ac39bdSJohannes Berg }
334437ac39bdSJohannes Berg 
3345a2116ed2SArnd Bergmann static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
3346a2116ed2SArnd Bergmann 			struct compat_ifreq __user *uifr32)
3347a2116ed2SArnd Bergmann {
3348a2116ed2SArnd Bergmann 	struct ifreq ifr;
3349a2116ed2SArnd Bergmann 	struct compat_ifmap __user *uifmap32;
3350a2116ed2SArnd Bergmann 	int err;
3351a2116ed2SArnd Bergmann 
3352a2116ed2SArnd Bergmann 	uifmap32 = &uifr32->ifr_ifru.ifru_map;
3353a2116ed2SArnd Bergmann 	err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
33543ddc5b46SMathieu Desnoyers 	err |= get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
33553ddc5b46SMathieu Desnoyers 	err |= get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
33563ddc5b46SMathieu Desnoyers 	err |= get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
33573ddc5b46SMathieu Desnoyers 	err |= get_user(ifr.ifr_map.irq, &uifmap32->irq);
33583ddc5b46SMathieu Desnoyers 	err |= get_user(ifr.ifr_map.dma, &uifmap32->dma);
33593ddc5b46SMathieu Desnoyers 	err |= get_user(ifr.ifr_map.port, &uifmap32->port);
3360a2116ed2SArnd Bergmann 	if (err)
3361a2116ed2SArnd Bergmann 		return -EFAULT;
3362a2116ed2SArnd Bergmann 
336344c02a2cSAl Viro 	err = dev_ioctl(net, cmd, &ifr, NULL);
3364a2116ed2SArnd Bergmann 
3365a2116ed2SArnd Bergmann 	if (cmd == SIOCGIFMAP && !err) {
33667a229387SArnd Bergmann 		err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
33673ddc5b46SMathieu Desnoyers 		err |= put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
33683ddc5b46SMathieu Desnoyers 		err |= put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
33693ddc5b46SMathieu Desnoyers 		err |= put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
33703ddc5b46SMathieu Desnoyers 		err |= put_user(ifr.ifr_map.irq, &uifmap32->irq);
33713ddc5b46SMathieu Desnoyers 		err |= put_user(ifr.ifr_map.dma, &uifmap32->dma);
33723ddc5b46SMathieu Desnoyers 		err |= put_user(ifr.ifr_map.port, &uifmap32->port);
33737a229387SArnd Bergmann 		if (err)
33747a229387SArnd Bergmann 			err = -EFAULT;
33757a229387SArnd Bergmann 	}
33767a229387SArnd Bergmann 	return err;
33777a229387SArnd Bergmann }
33787a229387SArnd Bergmann 
33797a229387SArnd Bergmann /* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
33807a229387SArnd Bergmann  * for some operations; this forces use of the newer bridge-utils that
338125985edcSLucas De Marchi  * use compatible ioctls
33827a229387SArnd Bergmann  */
33836b96018bSArnd Bergmann static int old_bridge_ioctl(compat_ulong_t __user *argp)
33847a229387SArnd Bergmann {
33856b96018bSArnd Bergmann 	compat_ulong_t tmp;
33867a229387SArnd Bergmann 
33876b96018bSArnd Bergmann 	if (get_user(tmp, argp))
33887a229387SArnd Bergmann 		return -EFAULT;
33897a229387SArnd Bergmann 	if (tmp == BRCTL_GET_VERSION)
33907a229387SArnd Bergmann 		return BRCTL_VERSION + 1;
33917a229387SArnd Bergmann 	return -EINVAL;
33927a229387SArnd Bergmann }
33937a229387SArnd Bergmann 
33946b96018bSArnd Bergmann static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
33956b96018bSArnd Bergmann 			 unsigned int cmd, unsigned long arg)
33966b96018bSArnd Bergmann {
33976b96018bSArnd Bergmann 	void __user *argp = compat_ptr(arg);
33986b96018bSArnd Bergmann 	struct sock *sk = sock->sk;
33996b96018bSArnd Bergmann 	struct net *net = sock_net(sk);
34007a229387SArnd Bergmann 
34016b96018bSArnd Bergmann 	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
3402590d4693SBen Hutchings 		return compat_ifr_data_ioctl(net, cmd, argp);
34037a229387SArnd Bergmann 
34046b96018bSArnd Bergmann 	switch (cmd) {
34056b96018bSArnd Bergmann 	case SIOCSIFBR:
34066b96018bSArnd Bergmann 	case SIOCGIFBR:
34076b96018bSArnd Bergmann 		return old_bridge_ioctl(argp);
34086b96018bSArnd Bergmann 	case SIOCGIFCONF:
340936fd633eSAl Viro 		return compat_dev_ifconf(net, argp);
34106b96018bSArnd Bergmann 	case SIOCETHTOOL:
34116b96018bSArnd Bergmann 		return ethtool_ioctl(net, argp);
34127a50a240SArnd Bergmann 	case SIOCWANDEV:
34137a50a240SArnd Bergmann 		return compat_siocwandev(net, argp);
3414a2116ed2SArnd Bergmann 	case SIOCGIFMAP:
3415a2116ed2SArnd Bergmann 	case SIOCSIFMAP:
3416a2116ed2SArnd Bergmann 		return compat_sioc_ifmap(net, cmd, argp);
34170768e170SArnd Bergmann 	case SIOCGSTAMP_OLD:
34180768e170SArnd Bergmann 	case SIOCGSTAMPNS_OLD:
3419c7cbdbf2SArnd Bergmann 		if (!sock->ops->gettstamp)
3420c7cbdbf2SArnd Bergmann 			return -ENOIOCTLCMD;
34210768e170SArnd Bergmann 		return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD,
3422c7cbdbf2SArnd Bergmann 					    !COMPAT_USE_64BIT_TIME);
3423c7cbdbf2SArnd Bergmann 
3424590d4693SBen Hutchings 	case SIOCBONDSLAVEINFOQUERY:
3425590d4693SBen Hutchings 	case SIOCBONDINFOQUERY:
3426a2116ed2SArnd Bergmann 	case SIOCSHWTSTAMP:
3427fd468c74SBen Hutchings 	case SIOCGHWTSTAMP:
3428590d4693SBen Hutchings 		return compat_ifr_data_ioctl(net, cmd, argp);
34297a229387SArnd Bergmann 
34306b96018bSArnd Bergmann 	case FIOSETOWN:
34316b96018bSArnd Bergmann 	case SIOCSPGRP:
34326b96018bSArnd Bergmann 	case FIOGETOWN:
34336b96018bSArnd Bergmann 	case SIOCGPGRP:
34346b96018bSArnd Bergmann 	case SIOCBRADDBR:
34356b96018bSArnd Bergmann 	case SIOCBRDELBR:
34366b96018bSArnd Bergmann 	case SIOCGIFVLAN:
34376b96018bSArnd Bergmann 	case SIOCSIFVLAN:
34386b96018bSArnd Bergmann 	case SIOCADDDLCI:
34396b96018bSArnd Bergmann 	case SIOCDELDLCI:
3440c62cce2cSAndrey Vagin 	case SIOCGSKNS:
34410768e170SArnd Bergmann 	case SIOCGSTAMP_NEW:
34420768e170SArnd Bergmann 	case SIOCGSTAMPNS_NEW:
34436b96018bSArnd Bergmann 		return sock_ioctl(file, cmd, arg);
34446b96018bSArnd Bergmann 
34456b96018bSArnd Bergmann 	case SIOCGIFFLAGS:
34466b96018bSArnd Bergmann 	case SIOCSIFFLAGS:
34476b96018bSArnd Bergmann 	case SIOCGIFMETRIC:
34486b96018bSArnd Bergmann 	case SIOCSIFMETRIC:
34496b96018bSArnd Bergmann 	case SIOCGIFMTU:
34506b96018bSArnd Bergmann 	case SIOCSIFMTU:
34516b96018bSArnd Bergmann 	case SIOCGIFMEM:
34526b96018bSArnd Bergmann 	case SIOCSIFMEM:
34536b96018bSArnd Bergmann 	case SIOCGIFHWADDR:
34546b96018bSArnd Bergmann 	case SIOCSIFHWADDR:
34556b96018bSArnd Bergmann 	case SIOCADDMULTI:
34566b96018bSArnd Bergmann 	case SIOCDELMULTI:
34576b96018bSArnd Bergmann 	case SIOCGIFINDEX:
34586b96018bSArnd Bergmann 	case SIOCGIFADDR:
34596b96018bSArnd Bergmann 	case SIOCSIFADDR:
34606b96018bSArnd Bergmann 	case SIOCSIFHWBROADCAST:
34616b96018bSArnd Bergmann 	case SIOCDIFADDR:
34626b96018bSArnd Bergmann 	case SIOCGIFBRDADDR:
34636b96018bSArnd Bergmann 	case SIOCSIFBRDADDR:
34646b96018bSArnd Bergmann 	case SIOCGIFDSTADDR:
34656b96018bSArnd Bergmann 	case SIOCSIFDSTADDR:
34666b96018bSArnd Bergmann 	case SIOCGIFNETMASK:
34676b96018bSArnd Bergmann 	case SIOCSIFNETMASK:
34686b96018bSArnd Bergmann 	case SIOCSIFPFLAGS:
34696b96018bSArnd Bergmann 	case SIOCGIFPFLAGS:
34706b96018bSArnd Bergmann 	case SIOCGIFTXQLEN:
34716b96018bSArnd Bergmann 	case SIOCSIFTXQLEN:
34726b96018bSArnd Bergmann 	case SIOCBRADDIF:
34736b96018bSArnd Bergmann 	case SIOCBRDELIF:
3474c6c9fee3SJohannes Berg 	case SIOCGIFNAME:
34759177efd3SArnd Bergmann 	case SIOCSIFNAME:
34769177efd3SArnd Bergmann 	case SIOCGMIIPHY:
34779177efd3SArnd Bergmann 	case SIOCGMIIREG:
34789177efd3SArnd Bergmann 	case SIOCSMIIREG:
3479f92d4fc9SAl Viro 	case SIOCBONDENSLAVE:
3480f92d4fc9SAl Viro 	case SIOCBONDRELEASE:
3481f92d4fc9SAl Viro 	case SIOCBONDSETHWADDR:
3482f92d4fc9SAl Viro 	case SIOCBONDCHANGEACTIVE:
348337ac39bdSJohannes Berg 		return compat_ifreq_ioctl(net, sock, cmd, argp);
348437ac39bdSJohannes Berg 
34856b96018bSArnd Bergmann 	case SIOCSARP:
34866b96018bSArnd Bergmann 	case SIOCGARP:
34876b96018bSArnd Bergmann 	case SIOCDARP:
3488c7dc504eSArnd Bergmann 	case SIOCOUTQ:
34899d7bf41fSArnd Bergmann 	case SIOCOUTQNSD:
34906b96018bSArnd Bergmann 	case SIOCATMARK:
349163ff03abSJohannes Berg 		return sock_do_ioctl(net, sock, cmd, arg);
34929177efd3SArnd Bergmann 	}
34939177efd3SArnd Bergmann 
34946b96018bSArnd Bergmann 	return -ENOIOCTLCMD;
34956b96018bSArnd Bergmann }
34967a229387SArnd Bergmann 
349795c96174SEric Dumazet static long compat_sock_ioctl(struct file *file, unsigned int cmd,
349889bbfc95SShaun Pereira 			      unsigned long arg)
349989bbfc95SShaun Pereira {
350089bbfc95SShaun Pereira 	struct socket *sock = file->private_data;
350189bbfc95SShaun Pereira 	int ret = -ENOIOCTLCMD;
350287de87d5SDavid S. Miller 	struct sock *sk;
350387de87d5SDavid S. Miller 	struct net *net;
350487de87d5SDavid S. Miller 
350587de87d5SDavid S. Miller 	sk = sock->sk;
350687de87d5SDavid S. Miller 	net = sock_net(sk);
350789bbfc95SShaun Pereira 
350889bbfc95SShaun Pereira 	if (sock->ops->compat_ioctl)
350989bbfc95SShaun Pereira 		ret = sock->ops->compat_ioctl(sock, cmd, arg);
351089bbfc95SShaun Pereira 
351187de87d5SDavid S. Miller 	if (ret == -ENOIOCTLCMD &&
351287de87d5SDavid S. Miller 	    (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
351387de87d5SDavid S. Miller 		ret = compat_wext_handle_ioctl(net, cmd, arg);
351487de87d5SDavid S. Miller 
35156b96018bSArnd Bergmann 	if (ret == -ENOIOCTLCMD)
35166b96018bSArnd Bergmann 		ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
35176b96018bSArnd Bergmann 
351889bbfc95SShaun Pereira 	return ret;
351989bbfc95SShaun Pereira }
352089bbfc95SShaun Pereira #endif
352189bbfc95SShaun Pereira 
35228a3c245cSPedro Tammela /**
35238a3c245cSPedro Tammela  *	kernel_bind - bind an address to a socket (kernel space)
35248a3c245cSPedro Tammela  *	@sock: socket
35258a3c245cSPedro Tammela  *	@addr: address
35268a3c245cSPedro Tammela  *	@addrlen: length of address
35278a3c245cSPedro Tammela  *
35288a3c245cSPedro Tammela  *	Returns 0 or an error.
35298a3c245cSPedro Tammela  */
35308a3c245cSPedro Tammela 
3531ac5a488eSSridhar Samudrala int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
3532ac5a488eSSridhar Samudrala {
3533ac5a488eSSridhar Samudrala 	return sock->ops->bind(sock, addr, addrlen);
3534ac5a488eSSridhar Samudrala }
3535c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_bind);
3536ac5a488eSSridhar Samudrala 
35378a3c245cSPedro Tammela /**
35388a3c245cSPedro Tammela  *	kernel_listen - move socket to listening state (kernel space)
35398a3c245cSPedro Tammela  *	@sock: socket
35408a3c245cSPedro Tammela  *	@backlog: pending connections queue size
35418a3c245cSPedro Tammela  *
35428a3c245cSPedro Tammela  *	Returns 0 or an error.
35438a3c245cSPedro Tammela  */
35448a3c245cSPedro Tammela 
3545ac5a488eSSridhar Samudrala int kernel_listen(struct socket *sock, int backlog)
3546ac5a488eSSridhar Samudrala {
3547ac5a488eSSridhar Samudrala 	return sock->ops->listen(sock, backlog);
3548ac5a488eSSridhar Samudrala }
3549c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_listen);
3550ac5a488eSSridhar Samudrala 
35518a3c245cSPedro Tammela /**
35528a3c245cSPedro Tammela  *	kernel_accept - accept a connection (kernel space)
35538a3c245cSPedro Tammela  *	@sock: listening socket
35548a3c245cSPedro Tammela  *	@newsock: new connected socket
35558a3c245cSPedro Tammela  *	@flags: flags
35568a3c245cSPedro Tammela  *
35578a3c245cSPedro Tammela  *	@flags must be SOCK_CLOEXEC, SOCK_NONBLOCK or 0.
35588a3c245cSPedro Tammela  *	If it fails, @newsock is guaranteed to be %NULL.
35598a3c245cSPedro Tammela  *	Returns 0 or an error.
35608a3c245cSPedro Tammela  */
35618a3c245cSPedro Tammela 
3562ac5a488eSSridhar Samudrala int kernel_accept(struct socket *sock, struct socket **newsock, int flags)
3563ac5a488eSSridhar Samudrala {
3564ac5a488eSSridhar Samudrala 	struct sock *sk = sock->sk;
3565ac5a488eSSridhar Samudrala 	int err;
3566ac5a488eSSridhar Samudrala 
3567ac5a488eSSridhar Samudrala 	err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol,
3568ac5a488eSSridhar Samudrala 			       newsock);
3569ac5a488eSSridhar Samudrala 	if (err < 0)
3570ac5a488eSSridhar Samudrala 		goto done;
3571ac5a488eSSridhar Samudrala 
3572cdfbabfbSDavid Howells 	err = sock->ops->accept(sock, *newsock, flags, true);
3573ac5a488eSSridhar Samudrala 	if (err < 0) {
3574ac5a488eSSridhar Samudrala 		sock_release(*newsock);
3575fa8705b0STony Battersby 		*newsock = NULL;
3576ac5a488eSSridhar Samudrala 		goto done;
3577ac5a488eSSridhar Samudrala 	}
3578ac5a488eSSridhar Samudrala 
3579ac5a488eSSridhar Samudrala 	(*newsock)->ops = sock->ops;
35801b08534eSWei Yongjun 	__module_get((*newsock)->ops->owner);
3581ac5a488eSSridhar Samudrala 
3582ac5a488eSSridhar Samudrala done:
3583ac5a488eSSridhar Samudrala 	return err;
3584ac5a488eSSridhar Samudrala }
3585c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_accept);
3586ac5a488eSSridhar Samudrala 
35878a3c245cSPedro Tammela /**
35888a3c245cSPedro Tammela  *	kernel_connect - connect a socket (kernel space)
35898a3c245cSPedro Tammela  *	@sock: socket
35908a3c245cSPedro Tammela  *	@addr: address
35918a3c245cSPedro Tammela  *	@addrlen: address length
35928a3c245cSPedro Tammela  *	@flags: flags (O_NONBLOCK, ...)
35938a3c245cSPedro Tammela  *
35948a3c245cSPedro Tammela  *	For datagram sockets, @addr is the addres to which datagrams are sent
35958a3c245cSPedro Tammela  *	by default, and the only address from which datagrams are received.
35968a3c245cSPedro Tammela  *	For stream sockets, attempts to connect to @addr.
35978a3c245cSPedro Tammela  *	Returns 0 or an error code.
35988a3c245cSPedro Tammela  */
35998a3c245cSPedro Tammela 
3600ac5a488eSSridhar Samudrala int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
3601ac5a488eSSridhar Samudrala 		   int flags)
3602ac5a488eSSridhar Samudrala {
3603ac5a488eSSridhar Samudrala 	return sock->ops->connect(sock, addr, addrlen, flags);
3604ac5a488eSSridhar Samudrala }
3605c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_connect);
3606ac5a488eSSridhar Samudrala 
36078a3c245cSPedro Tammela /**
36088a3c245cSPedro Tammela  *	kernel_getsockname - get the address which the socket is bound (kernel space)
36098a3c245cSPedro Tammela  *	@sock: socket
36108a3c245cSPedro Tammela  *	@addr: address holder
36118a3c245cSPedro Tammela  *
36128a3c245cSPedro Tammela  * 	Fills the @addr pointer with the address which the socket is bound.
36138a3c245cSPedro Tammela  *	Returns 0 or an error code.
36148a3c245cSPedro Tammela  */
36158a3c245cSPedro Tammela 
36169b2c45d4SDenys Vlasenko int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
3617ac5a488eSSridhar Samudrala {
36189b2c45d4SDenys Vlasenko 	return sock->ops->getname(sock, addr, 0);
3619ac5a488eSSridhar Samudrala }
3620c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_getsockname);
3621ac5a488eSSridhar Samudrala 
36228a3c245cSPedro Tammela /**
36238a3c245cSPedro Tammela  *	kernel_peername - get the address which the socket is connected (kernel space)
36248a3c245cSPedro Tammela  *	@sock: socket
36258a3c245cSPedro Tammela  *	@addr: address holder
36268a3c245cSPedro Tammela  *
36278a3c245cSPedro Tammela  * 	Fills the @addr pointer with the address which the socket is connected.
36288a3c245cSPedro Tammela  *	Returns 0 or an error code.
36298a3c245cSPedro Tammela  */
36308a3c245cSPedro Tammela 
36319b2c45d4SDenys Vlasenko int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
3632ac5a488eSSridhar Samudrala {
36339b2c45d4SDenys Vlasenko 	return sock->ops->getname(sock, addr, 1);
3634ac5a488eSSridhar Samudrala }
3635c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_getpeername);
3636ac5a488eSSridhar Samudrala 
36378a3c245cSPedro Tammela /**
36388a3c245cSPedro Tammela  *	kernel_sendpage - send a &page through a socket (kernel space)
36398a3c245cSPedro Tammela  *	@sock: socket
36408a3c245cSPedro Tammela  *	@page: page
36418a3c245cSPedro Tammela  *	@offset: page offset
36428a3c245cSPedro Tammela  *	@size: total size in bytes
36438a3c245cSPedro Tammela  *	@flags: flags (MSG_DONTWAIT, ...)
36448a3c245cSPedro Tammela  *
36458a3c245cSPedro Tammela  *	Returns the total amount sent in bytes or an error.
36468a3c245cSPedro Tammela  */
36478a3c245cSPedro Tammela 
3648ac5a488eSSridhar Samudrala int kernel_sendpage(struct socket *sock, struct page *page, int offset,
3649ac5a488eSSridhar Samudrala 		    size_t size, int flags)
3650ac5a488eSSridhar Samudrala {
3651ac5a488eSSridhar Samudrala 	if (sock->ops->sendpage)
3652ac5a488eSSridhar Samudrala 		return sock->ops->sendpage(sock, page, offset, size, flags);
3653ac5a488eSSridhar Samudrala 
3654ac5a488eSSridhar Samudrala 	return sock_no_sendpage(sock, page, offset, size, flags);
3655ac5a488eSSridhar Samudrala }
3656c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_sendpage);
3657ac5a488eSSridhar Samudrala 
36588a3c245cSPedro Tammela /**
36598a3c245cSPedro Tammela  *	kernel_sendpage_locked - send a &page through the locked sock (kernel space)
36608a3c245cSPedro Tammela  *	@sk: sock
36618a3c245cSPedro Tammela  *	@page: page
36628a3c245cSPedro Tammela  *	@offset: page offset
36638a3c245cSPedro Tammela  *	@size: total size in bytes
36648a3c245cSPedro Tammela  *	@flags: flags (MSG_DONTWAIT, ...)
36658a3c245cSPedro Tammela  *
36668a3c245cSPedro Tammela  *	Returns the total amount sent in bytes or an error.
36678a3c245cSPedro Tammela  *	Caller must hold @sk.
36688a3c245cSPedro Tammela  */
36698a3c245cSPedro Tammela 
3670306b13ebSTom Herbert int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset,
3671306b13ebSTom Herbert 			   size_t size, int flags)
3672306b13ebSTom Herbert {
3673306b13ebSTom Herbert 	struct socket *sock = sk->sk_socket;
3674306b13ebSTom Herbert 
3675306b13ebSTom Herbert 	if (sock->ops->sendpage_locked)
3676306b13ebSTom Herbert 		return sock->ops->sendpage_locked(sk, page, offset, size,
3677306b13ebSTom Herbert 						  flags);
3678306b13ebSTom Herbert 
3679306b13ebSTom Herbert 	return sock_no_sendpage_locked(sk, page, offset, size, flags);
3680306b13ebSTom Herbert }
3681306b13ebSTom Herbert EXPORT_SYMBOL(kernel_sendpage_locked);
3682306b13ebSTom Herbert 
36838a3c245cSPedro Tammela /**
36848a3c245cSPedro Tammela  *	kernel_shutdown - shut down part of a full-duplex connection (kernel space)
36858a3c245cSPedro Tammela  *	@sock: socket
36868a3c245cSPedro Tammela  *	@how: connection part
36878a3c245cSPedro Tammela  *
36888a3c245cSPedro Tammela  *	Returns 0 or an error.
36898a3c245cSPedro Tammela  */
36908a3c245cSPedro Tammela 
369191cf45f0STrond Myklebust int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)
369291cf45f0STrond Myklebust {
369391cf45f0STrond Myklebust 	return sock->ops->shutdown(sock, how);
369491cf45f0STrond Myklebust }
369591cf45f0STrond Myklebust EXPORT_SYMBOL(kernel_sock_shutdown);
3696113c3075SR. Parameswaran 
36978a3c245cSPedro Tammela /**
36988a3c245cSPedro Tammela  *	kernel_sock_ip_overhead - returns the IP overhead imposed by a socket
36998a3c245cSPedro Tammela  *	@sk: socket
37008a3c245cSPedro Tammela  *
37018a3c245cSPedro Tammela  *	This routine returns the IP overhead imposed by a socket i.e.
3702113c3075SR. Parameswaran  *	the length of the underlying IP header, depending on whether
3703113c3075SR. Parameswaran  *	this is an IPv4 or IPv6 socket and the length from IP options turned
370457240d00SR. Parameswaran  *	on at the socket. Assumes that the caller has a lock on the socket.
3705113c3075SR. Parameswaran  */
37068a3c245cSPedro Tammela 
3707113c3075SR. Parameswaran u32 kernel_sock_ip_overhead(struct sock *sk)
3708113c3075SR. Parameswaran {
3709113c3075SR. Parameswaran 	struct inet_sock *inet;
3710113c3075SR. Parameswaran 	struct ip_options_rcu *opt;
3711113c3075SR. Parameswaran 	u32 overhead = 0;
3712113c3075SR. Parameswaran #if IS_ENABLED(CONFIG_IPV6)
3713113c3075SR. Parameswaran 	struct ipv6_pinfo *np;
3714113c3075SR. Parameswaran 	struct ipv6_txoptions *optv6 = NULL;
3715113c3075SR. Parameswaran #endif /* IS_ENABLED(CONFIG_IPV6) */
3716113c3075SR. Parameswaran 
3717113c3075SR. Parameswaran 	if (!sk)
3718113c3075SR. Parameswaran 		return overhead;
3719113c3075SR. Parameswaran 
3720113c3075SR. Parameswaran 	switch (sk->sk_family) {
3721113c3075SR. Parameswaran 	case AF_INET:
3722113c3075SR. Parameswaran 		inet = inet_sk(sk);
3723113c3075SR. Parameswaran 		overhead += sizeof(struct iphdr);
3724113c3075SR. Parameswaran 		opt = rcu_dereference_protected(inet->inet_opt,
3725614d79c0Sstephen hemminger 						sock_owned_by_user(sk));
3726113c3075SR. Parameswaran 		if (opt)
3727113c3075SR. Parameswaran 			overhead += opt->opt.optlen;
3728113c3075SR. Parameswaran 		return overhead;
3729113c3075SR. Parameswaran #if IS_ENABLED(CONFIG_IPV6)
3730113c3075SR. Parameswaran 	case AF_INET6:
3731113c3075SR. Parameswaran 		np = inet6_sk(sk);
3732113c3075SR. Parameswaran 		overhead += sizeof(struct ipv6hdr);
3733113c3075SR. Parameswaran 		if (np)
3734113c3075SR. Parameswaran 			optv6 = rcu_dereference_protected(np->opt,
3735614d79c0Sstephen hemminger 							  sock_owned_by_user(sk));
3736113c3075SR. Parameswaran 		if (optv6)
3737113c3075SR. Parameswaran 			overhead += (optv6->opt_flen + optv6->opt_nflen);
3738113c3075SR. Parameswaran 		return overhead;
3739113c3075SR. Parameswaran #endif /* IS_ENABLED(CONFIG_IPV6) */
3740113c3075SR. Parameswaran 	default: /* Returns 0 overhead if the socket is not ipv4 or ipv6 */
3741113c3075SR. Parameswaran 		return overhead;
3742113c3075SR. Parameswaran 	}
3743113c3075SR. Parameswaran }
3744113c3075SR. Parameswaran EXPORT_SYMBOL(kernel_sock_ip_overhead);
3745