12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * NET An implementation of the SOCKET network access protocol. 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Version: @(#)socket.c 1.1.93 18/02/95 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * Authors: Orest Zborowski, <obz@Kodak.COM> 802c30a84SJesper Juhl * Ross Biro 91da177e4SLinus Torvalds * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds * Fixes: 121da177e4SLinus Torvalds * Anonymous : NOTSOCK/BADF cleanup. Error fix in 131da177e4SLinus Torvalds * shutdown() 141da177e4SLinus Torvalds * Alan Cox : verify_area() fixes 151da177e4SLinus Torvalds * Alan Cox : Removed DDI 161da177e4SLinus Torvalds * Jonathan Kamens : SOCK_DGRAM reconnect bug 171da177e4SLinus Torvalds * Alan Cox : Moved a load of checks to the very 181da177e4SLinus Torvalds * top level. 191da177e4SLinus Torvalds * Alan Cox : Move address structures to/from user 201da177e4SLinus Torvalds * mode above the protocol layers. 211da177e4SLinus Torvalds * Rob Janssen : Allow 0 length sends. 221da177e4SLinus Torvalds * Alan Cox : Asynchronous I/O support (cribbed from the 231da177e4SLinus Torvalds * tty drivers). 241da177e4SLinus Torvalds * Niibe Yutaka : Asynchronous I/O for writes (4.4BSD style) 251da177e4SLinus Torvalds * Jeff Uphoff : Made max number of sockets command-line 261da177e4SLinus Torvalds * configurable. 271da177e4SLinus Torvalds * Matti Aarnio : Made the number of sockets dynamic, 281da177e4SLinus Torvalds * to be allocated when needed, and mr. 291da177e4SLinus Torvalds * Uphoff's max is used as max to be 301da177e4SLinus Torvalds * allowed to allocate. 311da177e4SLinus Torvalds * Linus : Argh. removed all the socket allocation 321da177e4SLinus Torvalds * altogether: it's in the inode now. 331da177e4SLinus Torvalds * Alan Cox : Made sock_alloc()/sock_release() public 341da177e4SLinus Torvalds * for NetROM and future kernel nfsd type 351da177e4SLinus Torvalds * stuff. 361da177e4SLinus Torvalds * Alan Cox : sendmsg/recvmsg basics. 371da177e4SLinus Torvalds * Tom Dyas : Export net symbols. 381da177e4SLinus Torvalds * Marcin Dalecki : Fixed problems with CONFIG_NET="n". 391da177e4SLinus Torvalds * Alan Cox : Added thread locking to sys_* calls 401da177e4SLinus Torvalds * for sockets. May have errors at the 411da177e4SLinus Torvalds * moment. 421da177e4SLinus Torvalds * Kevin Buhr : Fixed the dumb errors in the above. 431da177e4SLinus Torvalds * Andi Kleen : Some small cleanups, optimizations, 441da177e4SLinus Torvalds * and fixed a copy_from_user() bug. 451da177e4SLinus Torvalds * Tigran Aivazian : sys_send(args) calls sys_sendto(args, NULL, 0) 461da177e4SLinus Torvalds * Tigran Aivazian : Made listen(2) backlog sanity checks 471da177e4SLinus Torvalds * protocol-independent 481da177e4SLinus Torvalds * 491da177e4SLinus Torvalds * This module is effectively the top level interface to the BSD socket 501da177e4SLinus Torvalds * paradigm. 511da177e4SLinus Torvalds * 521da177e4SLinus Torvalds * Based upon Swansea University Computer Society NET3.039 531da177e4SLinus Torvalds */ 541da177e4SLinus Torvalds 55aef2fedaSJakub Kicinski #include <linux/bpf-cgroup.h> 56cc69837fSJakub Kicinski #include <linux/ethtool.h> 571da177e4SLinus Torvalds #include <linux/mm.h> 581da177e4SLinus Torvalds #include <linux/socket.h> 591da177e4SLinus Torvalds #include <linux/file.h> 601da177e4SLinus Torvalds #include <linux/net.h> 611da177e4SLinus Torvalds #include <linux/interrupt.h> 62aaca0bdcSUlrich Drepper #include <linux/thread_info.h> 6355737fdaSStephen Hemminger #include <linux/rcupdate.h> 641da177e4SLinus Torvalds #include <linux/netdevice.h> 651da177e4SLinus Torvalds #include <linux/proc_fs.h> 661da177e4SLinus Torvalds #include <linux/seq_file.h> 674a3e2f71SArjan van de Ven #include <linux/mutex.h> 681da177e4SLinus Torvalds #include <linux/if_bridge.h> 6920380731SArnaldo Carvalho de Melo #include <linux/if_vlan.h> 70408eccceSDaniel Borkmann #include <linux/ptp_classify.h> 711da177e4SLinus Torvalds #include <linux/init.h> 721da177e4SLinus Torvalds #include <linux/poll.h> 731da177e4SLinus Torvalds #include <linux/cache.h> 741da177e4SLinus Torvalds #include <linux/module.h> 751da177e4SLinus Torvalds #include <linux/highmem.h> 761da177e4SLinus Torvalds #include <linux/mount.h> 77fba9be49SDavid Howells #include <linux/pseudo_fs.h> 781da177e4SLinus Torvalds #include <linux/security.h> 791da177e4SLinus Torvalds #include <linux/syscalls.h> 801da177e4SLinus Torvalds #include <linux/compat.h> 811da177e4SLinus Torvalds #include <linux/kmod.h> 823ec3b2fbSDavid Woodhouse #include <linux/audit.h> 83d86b5e0eSAdrian Bunk #include <linux/wireless.h> 841b8d7ae4SEric W. Biederman #include <linux/nsproxy.h> 851fd7317dSNick Black #include <linux/magic.h> 865a0e3ad6STejun Heo #include <linux/slab.h> 87600e1779SMasatake YAMATO #include <linux/xattr.h> 88c8e8cd57SJeremy Cline #include <linux/nospec.h> 898c3c447bSPaolo Abeni #include <linux/indirect_call_wrapper.h> 901da177e4SLinus Torvalds 917c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 921da177e4SLinus Torvalds #include <asm/unistd.h> 931da177e4SLinus Torvalds 941da177e4SLinus Torvalds #include <net/compat.h> 9587de87d5SDavid S. Miller #include <net/wext.h> 96f8451725SHerbert Xu #include <net/cls_cgroup.h> 971da177e4SLinus Torvalds 981da177e4SLinus Torvalds #include <net/sock.h> 991da177e4SLinus Torvalds #include <linux/netfilter.h> 1001da177e4SLinus Torvalds 1016b96018bSArnd Bergmann #include <linux/if_tun.h> 1026b96018bSArnd Bergmann #include <linux/ipv6_route.h> 1036b96018bSArnd Bergmann #include <linux/route.h> 104c7dc504eSArnd Bergmann #include <linux/termios.h> 1056b96018bSArnd Bergmann #include <linux/sockios.h> 106076bb0c8SEliezer Tamir #include <net/busy_poll.h> 107f24b9be5SWillem de Bruijn #include <linux/errqueue.h> 108d7c08826SYangbo Lu #include <linux/ptp_clock_kernel.h> 10906021292SEliezer Tamir 110e0d1095aSCong Wang #ifdef CONFIG_NET_RX_BUSY_POLL 11164b0dc51SEliezer Tamir unsigned int sysctl_net_busy_read __read_mostly; 11264b0dc51SEliezer Tamir unsigned int sysctl_net_busy_poll __read_mostly; 11306021292SEliezer Tamir #endif 1146b96018bSArnd Bergmann 1158ae5e030SAl Viro static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to); 1168ae5e030SAl Viro static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from); 1171da177e4SLinus Torvalds static int sock_mmap(struct file *file, struct vm_area_struct *vma); 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds static int sock_close(struct inode *inode, struct file *file); 120a11e1d43SLinus Torvalds static __poll_t sock_poll(struct file *file, 121a11e1d43SLinus Torvalds struct poll_table_struct *wait); 12289bddce5SStephen Hemminger static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 12389bbfc95SShaun Pereira #ifdef CONFIG_COMPAT 12489bbfc95SShaun Pereira static long compat_sock_ioctl(struct file *file, 12589bbfc95SShaun Pereira unsigned int cmd, unsigned long arg); 12689bbfc95SShaun Pereira #endif 1271da177e4SLinus Torvalds static int sock_fasync(int fd, struct file *filp, int on); 1281da177e4SLinus Torvalds static ssize_t sock_sendpage(struct file *file, struct page *page, 1291da177e4SLinus Torvalds int offset, size_t size, loff_t *ppos, int more); 1309c55e01cSJens Axboe static ssize_t sock_splice_read(struct file *file, loff_t *ppos, 1319c55e01cSJens Axboe struct pipe_inode_info *pipe, size_t len, 1329c55e01cSJens Axboe unsigned int flags); 133542d3065SArnd Bergmann 134542d3065SArnd Bergmann #ifdef CONFIG_PROC_FS 135542d3065SArnd Bergmann static void sock_show_fdinfo(struct seq_file *m, struct file *f) 136542d3065SArnd Bergmann { 137542d3065SArnd Bergmann struct socket *sock = f->private_data; 138542d3065SArnd Bergmann 139542d3065SArnd Bergmann if (sock->ops->show_fdinfo) 140542d3065SArnd Bergmann sock->ops->show_fdinfo(m, sock); 141542d3065SArnd Bergmann } 142542d3065SArnd Bergmann #else 143542d3065SArnd Bergmann #define sock_show_fdinfo NULL 144542d3065SArnd Bergmann #endif 1451da177e4SLinus Torvalds 1461da177e4SLinus Torvalds /* 1471da177e4SLinus Torvalds * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear 1481da177e4SLinus Torvalds * in the operation structures but are done directly via the socketcall() multiplexor. 1491da177e4SLinus Torvalds */ 1501da177e4SLinus Torvalds 151da7071d7SArjan van de Ven static const struct file_operations socket_file_ops = { 1521da177e4SLinus Torvalds .owner = THIS_MODULE, 1531da177e4SLinus Torvalds .llseek = no_llseek, 1548ae5e030SAl Viro .read_iter = sock_read_iter, 1558ae5e030SAl Viro .write_iter = sock_write_iter, 1561da177e4SLinus Torvalds .poll = sock_poll, 1571da177e4SLinus Torvalds .unlocked_ioctl = sock_ioctl, 15889bbfc95SShaun Pereira #ifdef CONFIG_COMPAT 15989bbfc95SShaun Pereira .compat_ioctl = compat_sock_ioctl, 16089bbfc95SShaun Pereira #endif 1611da177e4SLinus Torvalds .mmap = sock_mmap, 1621da177e4SLinus Torvalds .release = sock_close, 1631da177e4SLinus Torvalds .fasync = sock_fasync, 1645274f052SJens Axboe .sendpage = sock_sendpage, 1655274f052SJens Axboe .splice_write = generic_splice_sendpage, 1669c55e01cSJens Axboe .splice_read = sock_splice_read, 167b4653342SKirill Tkhai .show_fdinfo = sock_show_fdinfo, 1681da177e4SLinus Torvalds }; 1691da177e4SLinus Torvalds 170fe0bdbdeSYejune Deng static const char * const pf_family_names[] = { 171fe0bdbdeSYejune Deng [PF_UNSPEC] = "PF_UNSPEC", 172fe0bdbdeSYejune Deng [PF_UNIX] = "PF_UNIX/PF_LOCAL", 173fe0bdbdeSYejune Deng [PF_INET] = "PF_INET", 174fe0bdbdeSYejune Deng [PF_AX25] = "PF_AX25", 175fe0bdbdeSYejune Deng [PF_IPX] = "PF_IPX", 176fe0bdbdeSYejune Deng [PF_APPLETALK] = "PF_APPLETALK", 177fe0bdbdeSYejune Deng [PF_NETROM] = "PF_NETROM", 178fe0bdbdeSYejune Deng [PF_BRIDGE] = "PF_BRIDGE", 179fe0bdbdeSYejune Deng [PF_ATMPVC] = "PF_ATMPVC", 180fe0bdbdeSYejune Deng [PF_X25] = "PF_X25", 181fe0bdbdeSYejune Deng [PF_INET6] = "PF_INET6", 182fe0bdbdeSYejune Deng [PF_ROSE] = "PF_ROSE", 183fe0bdbdeSYejune Deng [PF_DECnet] = "PF_DECnet", 184fe0bdbdeSYejune Deng [PF_NETBEUI] = "PF_NETBEUI", 185fe0bdbdeSYejune Deng [PF_SECURITY] = "PF_SECURITY", 186fe0bdbdeSYejune Deng [PF_KEY] = "PF_KEY", 187fe0bdbdeSYejune Deng [PF_NETLINK] = "PF_NETLINK/PF_ROUTE", 188fe0bdbdeSYejune Deng [PF_PACKET] = "PF_PACKET", 189fe0bdbdeSYejune Deng [PF_ASH] = "PF_ASH", 190fe0bdbdeSYejune Deng [PF_ECONET] = "PF_ECONET", 191fe0bdbdeSYejune Deng [PF_ATMSVC] = "PF_ATMSVC", 192fe0bdbdeSYejune Deng [PF_RDS] = "PF_RDS", 193fe0bdbdeSYejune Deng [PF_SNA] = "PF_SNA", 194fe0bdbdeSYejune Deng [PF_IRDA] = "PF_IRDA", 195fe0bdbdeSYejune Deng [PF_PPPOX] = "PF_PPPOX", 196fe0bdbdeSYejune Deng [PF_WANPIPE] = "PF_WANPIPE", 197fe0bdbdeSYejune Deng [PF_LLC] = "PF_LLC", 198fe0bdbdeSYejune Deng [PF_IB] = "PF_IB", 199fe0bdbdeSYejune Deng [PF_MPLS] = "PF_MPLS", 200fe0bdbdeSYejune Deng [PF_CAN] = "PF_CAN", 201fe0bdbdeSYejune Deng [PF_TIPC] = "PF_TIPC", 202fe0bdbdeSYejune Deng [PF_BLUETOOTH] = "PF_BLUETOOTH", 203fe0bdbdeSYejune Deng [PF_IUCV] = "PF_IUCV", 204fe0bdbdeSYejune Deng [PF_RXRPC] = "PF_RXRPC", 205fe0bdbdeSYejune Deng [PF_ISDN] = "PF_ISDN", 206fe0bdbdeSYejune Deng [PF_PHONET] = "PF_PHONET", 207fe0bdbdeSYejune Deng [PF_IEEE802154] = "PF_IEEE802154", 208fe0bdbdeSYejune Deng [PF_CAIF] = "PF_CAIF", 209fe0bdbdeSYejune Deng [PF_ALG] = "PF_ALG", 210fe0bdbdeSYejune Deng [PF_NFC] = "PF_NFC", 211fe0bdbdeSYejune Deng [PF_VSOCK] = "PF_VSOCK", 212fe0bdbdeSYejune Deng [PF_KCM] = "PF_KCM", 213fe0bdbdeSYejune Deng [PF_QIPCRTR] = "PF_QIPCRTR", 214fe0bdbdeSYejune Deng [PF_SMC] = "PF_SMC", 215fe0bdbdeSYejune Deng [PF_XDP] = "PF_XDP", 216bc49d816SJeremy Kerr [PF_MCTP] = "PF_MCTP", 217fe0bdbdeSYejune Deng }; 218fe0bdbdeSYejune Deng 2191da177e4SLinus Torvalds /* 2201da177e4SLinus Torvalds * The protocol list. Each protocol is registered in here. 2211da177e4SLinus Torvalds */ 2221da177e4SLinus Torvalds 2231da177e4SLinus Torvalds static DEFINE_SPINLOCK(net_family_lock); 224190683a9SEric Dumazet static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly; 2251da177e4SLinus Torvalds 2261da177e4SLinus Torvalds /* 22789bddce5SStephen Hemminger * Support routines. 22889bddce5SStephen Hemminger * Move socket addresses back and forth across the kernel/user 2291da177e4SLinus Torvalds * divide and look after the messy bits. 2301da177e4SLinus Torvalds */ 2311da177e4SLinus Torvalds 2321da177e4SLinus Torvalds /** 2331da177e4SLinus Torvalds * move_addr_to_kernel - copy a socket address into kernel space 2341da177e4SLinus Torvalds * @uaddr: Address in user space 2351da177e4SLinus Torvalds * @kaddr: Address in kernel space 2361da177e4SLinus Torvalds * @ulen: Length in user space 2371da177e4SLinus Torvalds * 2381da177e4SLinus Torvalds * The address is copied into kernel space. If the provided address is 2391da177e4SLinus Torvalds * too long an error code of -EINVAL is returned. If the copy gives 2401da177e4SLinus Torvalds * invalid addresses -EFAULT is returned. On a success 0 is returned. 2411da177e4SLinus Torvalds */ 2421da177e4SLinus Torvalds 24343db362dSMaciej Żenczykowski int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr) 2441da177e4SLinus Torvalds { 245230b1839SYOSHIFUJI Hideaki if (ulen < 0 || ulen > sizeof(struct sockaddr_storage)) 2461da177e4SLinus Torvalds return -EINVAL; 2471da177e4SLinus Torvalds if (ulen == 0) 2481da177e4SLinus Torvalds return 0; 2491da177e4SLinus Torvalds if (copy_from_user(kaddr, uaddr, ulen)) 2501da177e4SLinus Torvalds return -EFAULT; 2513ec3b2fbSDavid Woodhouse return audit_sockaddr(ulen, kaddr); 2521da177e4SLinus Torvalds } 2531da177e4SLinus Torvalds 2541da177e4SLinus Torvalds /** 2551da177e4SLinus Torvalds * move_addr_to_user - copy an address to user space 2561da177e4SLinus Torvalds * @kaddr: kernel space address 2571da177e4SLinus Torvalds * @klen: length of address in kernel 2581da177e4SLinus Torvalds * @uaddr: user space address 2591da177e4SLinus Torvalds * @ulen: pointer to user length field 2601da177e4SLinus Torvalds * 2611da177e4SLinus Torvalds * The value pointed to by ulen on entry is the buffer length available. 2621da177e4SLinus Torvalds * This is overwritten with the buffer space used. -EINVAL is returned 2631da177e4SLinus Torvalds * if an overlong buffer is specified or a negative buffer size. -EFAULT 2641da177e4SLinus Torvalds * is returned if either the buffer or the length field are not 2651da177e4SLinus Torvalds * accessible. 2661da177e4SLinus Torvalds * After copying the data up to the limit the user specifies, the true 2671da177e4SLinus Torvalds * length of the data is written over the length limit the user 2681da177e4SLinus Torvalds * specified. Zero is returned for a success. 2691da177e4SLinus Torvalds */ 2701da177e4SLinus Torvalds 27143db362dSMaciej Żenczykowski static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen, 27211165f14Sstephen hemminger void __user *uaddr, int __user *ulen) 2731da177e4SLinus Torvalds { 2741da177e4SLinus Torvalds int err; 2751da177e4SLinus Torvalds int len; 2761da177e4SLinus Torvalds 27768c6beb3SHannes Frederic Sowa BUG_ON(klen > sizeof(struct sockaddr_storage)); 27889bddce5SStephen Hemminger err = get_user(len, ulen); 27989bddce5SStephen Hemminger if (err) 2801da177e4SLinus Torvalds return err; 2811da177e4SLinus Torvalds if (len > klen) 2821da177e4SLinus Torvalds len = klen; 28368c6beb3SHannes Frederic Sowa if (len < 0) 2841da177e4SLinus Torvalds return -EINVAL; 28589bddce5SStephen Hemminger if (len) { 286d6fe3945SSteve Grubb if (audit_sockaddr(klen, kaddr)) 287d6fe3945SSteve Grubb return -ENOMEM; 2881da177e4SLinus Torvalds if (copy_to_user(uaddr, kaddr, len)) 2891da177e4SLinus Torvalds return -EFAULT; 2901da177e4SLinus Torvalds } 2911da177e4SLinus Torvalds /* 2921da177e4SLinus Torvalds * "fromlen shall refer to the value before truncation.." 2931da177e4SLinus Torvalds * 1003.1g 2941da177e4SLinus Torvalds */ 2951da177e4SLinus Torvalds return __put_user(klen, ulen); 2961da177e4SLinus Torvalds } 2971da177e4SLinus Torvalds 29808009a76SAlexey Dobriyan static struct kmem_cache *sock_inode_cachep __ro_after_init; 2991da177e4SLinus Torvalds 3001da177e4SLinus Torvalds static struct inode *sock_alloc_inode(struct super_block *sb) 3011da177e4SLinus Torvalds { 3021da177e4SLinus Torvalds struct socket_alloc *ei; 30389bddce5SStephen Hemminger 304fd60b288SMuchun Song ei = alloc_inode_sb(sb, sock_inode_cachep, GFP_KERNEL); 3051da177e4SLinus Torvalds if (!ei) 3061da177e4SLinus Torvalds return NULL; 307333f7909SAl Viro init_waitqueue_head(&ei->socket.wq.wait); 308333f7909SAl Viro ei->socket.wq.fasync_list = NULL; 309333f7909SAl Viro ei->socket.wq.flags = 0; 3101da177e4SLinus Torvalds 3111da177e4SLinus Torvalds ei->socket.state = SS_UNCONNECTED; 3121da177e4SLinus Torvalds ei->socket.flags = 0; 3131da177e4SLinus Torvalds ei->socket.ops = NULL; 3141da177e4SLinus Torvalds ei->socket.sk = NULL; 3151da177e4SLinus Torvalds ei->socket.file = NULL; 3161da177e4SLinus Torvalds 3171da177e4SLinus Torvalds return &ei->vfs_inode; 3181da177e4SLinus Torvalds } 3191da177e4SLinus Torvalds 3206d7855c5SAl Viro static void sock_free_inode(struct inode *inode) 3211da177e4SLinus Torvalds { 32243815482SEric Dumazet struct socket_alloc *ei; 32343815482SEric Dumazet 32443815482SEric Dumazet ei = container_of(inode, struct socket_alloc, vfs_inode); 32543815482SEric Dumazet kmem_cache_free(sock_inode_cachep, ei); 3261da177e4SLinus Torvalds } 3271da177e4SLinus Torvalds 32851cc5068SAlexey Dobriyan static void init_once(void *foo) 3291da177e4SLinus Torvalds { 3301da177e4SLinus Torvalds struct socket_alloc *ei = (struct socket_alloc *)foo; 3311da177e4SLinus Torvalds 3321da177e4SLinus Torvalds inode_init_once(&ei->vfs_inode); 3331da177e4SLinus Torvalds } 3341da177e4SLinus Torvalds 3351e911632Syuan linyu static void init_inodecache(void) 3361da177e4SLinus Torvalds { 3371da177e4SLinus Torvalds sock_inode_cachep = kmem_cache_create("sock_inode_cache", 3381da177e4SLinus Torvalds sizeof(struct socket_alloc), 33989bddce5SStephen Hemminger 0, 34089bddce5SStephen Hemminger (SLAB_HWCACHE_ALIGN | 34189bddce5SStephen Hemminger SLAB_RECLAIM_ACCOUNT | 3425d097056SVladimir Davydov SLAB_MEM_SPREAD | SLAB_ACCOUNT), 34320c2df83SPaul Mundt init_once); 3441e911632Syuan linyu BUG_ON(sock_inode_cachep == NULL); 3451da177e4SLinus Torvalds } 3461da177e4SLinus Torvalds 347b87221deSAlexey Dobriyan static const struct super_operations sockfs_ops = { 3481da177e4SLinus Torvalds .alloc_inode = sock_alloc_inode, 3496d7855c5SAl Viro .free_inode = sock_free_inode, 3501da177e4SLinus Torvalds .statfs = simple_statfs, 3511da177e4SLinus Torvalds }; 3521da177e4SLinus Torvalds 353c23fbb6bSEric Dumazet /* 354c23fbb6bSEric Dumazet * sockfs_dname() is called from d_path(). 355c23fbb6bSEric Dumazet */ 356c23fbb6bSEric Dumazet static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen) 357c23fbb6bSEric Dumazet { 3580f60d288SAl Viro return dynamic_dname(buffer, buflen, "socket:[%lu]", 359c5ef6035SDavid Howells d_inode(dentry)->i_ino); 360c23fbb6bSEric Dumazet } 361c23fbb6bSEric Dumazet 3623ba13d17SAl Viro static const struct dentry_operations sockfs_dentry_operations = { 363c23fbb6bSEric Dumazet .d_dname = sockfs_dname, 3641da177e4SLinus Torvalds }; 3651da177e4SLinus Torvalds 366bba0bd31SAndreas Gruenbacher static int sockfs_xattr_get(const struct xattr_handler *handler, 367bba0bd31SAndreas Gruenbacher struct dentry *dentry, struct inode *inode, 368bba0bd31SAndreas Gruenbacher const char *suffix, void *value, size_t size) 369bba0bd31SAndreas Gruenbacher { 370bba0bd31SAndreas Gruenbacher if (value) { 371bba0bd31SAndreas Gruenbacher if (dentry->d_name.len + 1 > size) 372bba0bd31SAndreas Gruenbacher return -ERANGE; 373bba0bd31SAndreas Gruenbacher memcpy(value, dentry->d_name.name, dentry->d_name.len + 1); 374bba0bd31SAndreas Gruenbacher } 375bba0bd31SAndreas Gruenbacher return dentry->d_name.len + 1; 376bba0bd31SAndreas Gruenbacher } 377bba0bd31SAndreas Gruenbacher 378bba0bd31SAndreas Gruenbacher #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname" 379bba0bd31SAndreas Gruenbacher #define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX) 380bba0bd31SAndreas Gruenbacher #define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1) 381bba0bd31SAndreas Gruenbacher 382bba0bd31SAndreas Gruenbacher static const struct xattr_handler sockfs_xattr_handler = { 383bba0bd31SAndreas Gruenbacher .name = XATTR_NAME_SOCKPROTONAME, 384bba0bd31SAndreas Gruenbacher .get = sockfs_xattr_get, 385bba0bd31SAndreas Gruenbacher }; 386bba0bd31SAndreas Gruenbacher 3874a590153SAndreas Gruenbacher static int sockfs_security_xattr_set(const struct xattr_handler *handler, 388e65ce2a5SChristian Brauner struct user_namespace *mnt_userns, 3894a590153SAndreas Gruenbacher struct dentry *dentry, struct inode *inode, 3904a590153SAndreas Gruenbacher const char *suffix, const void *value, 3914a590153SAndreas Gruenbacher size_t size, int flags) 3924a590153SAndreas Gruenbacher { 3934a590153SAndreas Gruenbacher /* Handled by LSM. */ 3944a590153SAndreas Gruenbacher return -EAGAIN; 3954a590153SAndreas Gruenbacher } 3964a590153SAndreas Gruenbacher 3974a590153SAndreas Gruenbacher static const struct xattr_handler sockfs_security_xattr_handler = { 3984a590153SAndreas Gruenbacher .prefix = XATTR_SECURITY_PREFIX, 3994a590153SAndreas Gruenbacher .set = sockfs_security_xattr_set, 4004a590153SAndreas Gruenbacher }; 4014a590153SAndreas Gruenbacher 402bba0bd31SAndreas Gruenbacher static const struct xattr_handler *sockfs_xattr_handlers[] = { 403bba0bd31SAndreas Gruenbacher &sockfs_xattr_handler, 4044a590153SAndreas Gruenbacher &sockfs_security_xattr_handler, 405bba0bd31SAndreas Gruenbacher NULL 406bba0bd31SAndreas Gruenbacher }; 407bba0bd31SAndreas Gruenbacher 408fba9be49SDavid Howells static int sockfs_init_fs_context(struct fs_context *fc) 409c74a1cbbSAl Viro { 410fba9be49SDavid Howells struct pseudo_fs_context *ctx = init_pseudo(fc, SOCKFS_MAGIC); 411fba9be49SDavid Howells if (!ctx) 412fba9be49SDavid Howells return -ENOMEM; 413fba9be49SDavid Howells ctx->ops = &sockfs_ops; 414fba9be49SDavid Howells ctx->dops = &sockfs_dentry_operations; 415fba9be49SDavid Howells ctx->xattr = sockfs_xattr_handlers; 416fba9be49SDavid Howells return 0; 417c74a1cbbSAl Viro } 418c74a1cbbSAl Viro 419c74a1cbbSAl Viro static struct vfsmount *sock_mnt __read_mostly; 420c74a1cbbSAl Viro 421c74a1cbbSAl Viro static struct file_system_type sock_fs_type = { 422c74a1cbbSAl Viro .name = "sockfs", 423fba9be49SDavid Howells .init_fs_context = sockfs_init_fs_context, 424c74a1cbbSAl Viro .kill_sb = kill_anon_super, 425c74a1cbbSAl Viro }; 426c74a1cbbSAl Viro 4271da177e4SLinus Torvalds /* 4281da177e4SLinus Torvalds * Obtains the first available file descriptor and sets it up for use. 4291da177e4SLinus Torvalds * 43039d8c1b6SDavid S. Miller * These functions create file structures and maps them to fd space 43139d8c1b6SDavid S. Miller * of the current process. On success it returns file descriptor 4321da177e4SLinus Torvalds * and file struct implicitly stored in sock->file. 4331da177e4SLinus Torvalds * Note that another thread may close file descriptor before we return 4341da177e4SLinus Torvalds * from this function. We use the fact that now we do not refer 4351da177e4SLinus Torvalds * to socket after mapping. If one day we will need it, this 4361da177e4SLinus Torvalds * function will increment ref. count on file by 1. 4371da177e4SLinus Torvalds * 4381da177e4SLinus Torvalds * In any case returned fd MAY BE not valid! 4391da177e4SLinus Torvalds * This race condition is unavoidable 4401da177e4SLinus Torvalds * with shared fd spaces, we cannot solve it inside kernel, 4411da177e4SLinus Torvalds * but we take care of internal coherence yet. 4421da177e4SLinus Torvalds */ 4431da177e4SLinus Torvalds 4448a3c245cSPedro Tammela /** 4458a3c245cSPedro Tammela * sock_alloc_file - Bind a &socket to a &file 4468a3c245cSPedro Tammela * @sock: socket 4478a3c245cSPedro Tammela * @flags: file status flags 4488a3c245cSPedro Tammela * @dname: protocol name 4498a3c245cSPedro Tammela * 4508a3c245cSPedro Tammela * Returns the &file bound with @sock, implicitly storing it 4518a3c245cSPedro Tammela * in sock->file. If dname is %NULL, sets to "". 4528a3c245cSPedro Tammela * On failure the return is a ERR pointer (see linux/err.h). 4538a3c245cSPedro Tammela * This function uses GFP_KERNEL internally. 4548a3c245cSPedro Tammela */ 4558a3c245cSPedro Tammela 456aab174f0SLinus Torvalds struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) 4571da177e4SLinus Torvalds { 4587cbe66b6SAl Viro struct file *file; 4591da177e4SLinus Torvalds 460d93aa9d8SAl Viro if (!dname) 461d93aa9d8SAl Viro dname = sock->sk ? sock->sk->sk_prot_creator->name : ""; 46239d8c1b6SDavid S. Miller 463d93aa9d8SAl Viro file = alloc_file_pseudo(SOCK_INODE(sock), sock_mnt, dname, 464d93aa9d8SAl Viro O_RDWR | (flags & O_NONBLOCK), 465cc3808f8SAl Viro &socket_file_ops); 466b5ffe634SViresh Kumar if (IS_ERR(file)) { 4678e1611e2SAl Viro sock_release(sock); 46839b65252SAnatol Pomozov return file; 469cc3808f8SAl Viro } 4701da177e4SLinus Torvalds 4711da177e4SLinus Torvalds sock->file = file; 47207dc3f07SBenjamin LaHaise file->private_data = sock; 473d8e464ecSLinus Torvalds stream_open(SOCK_INODE(sock), file); 47428407630SAl Viro return file; 4751da177e4SLinus Torvalds } 47656b31d1cSAl Viro EXPORT_SYMBOL(sock_alloc_file); 4771da177e4SLinus Torvalds 47856b31d1cSAl Viro static int sock_map_fd(struct socket *sock, int flags) 47939d8c1b6SDavid S. Miller { 48039d8c1b6SDavid S. Miller struct file *newfile; 48128407630SAl Viro int fd = get_unused_fd_flags(flags); 482ce4bb04cSAl Viro if (unlikely(fd < 0)) { 483ce4bb04cSAl Viro sock_release(sock); 4841da177e4SLinus Torvalds return fd; 485ce4bb04cSAl Viro } 4861da177e4SLinus Torvalds 487aab174f0SLinus Torvalds newfile = sock_alloc_file(sock, flags, NULL); 4884546e44cSEnrico Weigelt if (!IS_ERR(newfile)) { 4891da177e4SLinus Torvalds fd_install(fd, newfile); 4901da177e4SLinus Torvalds return fd; 4911da177e4SLinus Torvalds } 49228407630SAl Viro 49328407630SAl Viro put_unused_fd(fd); 49428407630SAl Viro return PTR_ERR(newfile); 4951da177e4SLinus Torvalds } 4961da177e4SLinus Torvalds 4978a3c245cSPedro Tammela /** 4988a3c245cSPedro Tammela * sock_from_file - Return the &socket bounded to @file. 4998a3c245cSPedro Tammela * @file: file 5008a3c245cSPedro Tammela * 501dba4a925SFlorent Revest * On failure returns %NULL. 5028a3c245cSPedro Tammela */ 5038a3c245cSPedro Tammela 504dba4a925SFlorent Revest struct socket *sock_from_file(struct file *file) 5056cb153caSBenjamin LaHaise { 5066cb153caSBenjamin LaHaise if (file->f_op == &socket_file_ops) 507da214a47SJens Axboe return file->private_data; /* set in sock_alloc_file */ 5086cb153caSBenjamin LaHaise 5096cb153caSBenjamin LaHaise return NULL; 5106cb153caSBenjamin LaHaise } 511406a3c63SJohn Fastabend EXPORT_SYMBOL(sock_from_file); 5126cb153caSBenjamin LaHaise 5131da177e4SLinus Torvalds /** 5141da177e4SLinus Torvalds * sockfd_lookup - Go from a file number to its socket slot 5151da177e4SLinus Torvalds * @fd: file handle 5161da177e4SLinus Torvalds * @err: pointer to an error code return 5171da177e4SLinus Torvalds * 5181da177e4SLinus Torvalds * The file handle passed in is locked and the socket it is bound 519241c4667SRosen, Rami * to is returned. If an error occurs the err pointer is overwritten 5201da177e4SLinus Torvalds * with a negative errno code and NULL is returned. The function checks 5211da177e4SLinus Torvalds * for both invalid handles and passing a handle which is not a socket. 5221da177e4SLinus Torvalds * 5231da177e4SLinus Torvalds * On a success the socket object pointer is returned. 5241da177e4SLinus Torvalds */ 5251da177e4SLinus Torvalds 5261da177e4SLinus Torvalds struct socket *sockfd_lookup(int fd, int *err) 5271da177e4SLinus Torvalds { 5281da177e4SLinus Torvalds struct file *file; 5291da177e4SLinus Torvalds struct socket *sock; 5301da177e4SLinus Torvalds 53189bddce5SStephen Hemminger file = fget(fd); 53289bddce5SStephen Hemminger if (!file) { 5331da177e4SLinus Torvalds *err = -EBADF; 5341da177e4SLinus Torvalds return NULL; 5351da177e4SLinus Torvalds } 53689bddce5SStephen Hemminger 537dba4a925SFlorent Revest sock = sock_from_file(file); 538dba4a925SFlorent Revest if (!sock) { 539dba4a925SFlorent Revest *err = -ENOTSOCK; 5401da177e4SLinus Torvalds fput(file); 541dba4a925SFlorent Revest } 5426cb153caSBenjamin LaHaise return sock; 5431da177e4SLinus Torvalds } 544c6d409cfSEric Dumazet EXPORT_SYMBOL(sockfd_lookup); 5451da177e4SLinus Torvalds 5466cb153caSBenjamin LaHaise static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) 5476cb153caSBenjamin LaHaise { 54800e188efSAl Viro struct fd f = fdget(fd); 5496cb153caSBenjamin LaHaise struct socket *sock; 5506cb153caSBenjamin LaHaise 5513672558cSHua Zhong *err = -EBADF; 55200e188efSAl Viro if (f.file) { 553dba4a925SFlorent Revest sock = sock_from_file(f.file); 55400e188efSAl Viro if (likely(sock)) { 555ce787a5aSMiaohe Lin *fput_needed = f.flags & FDPUT_FPUT; 5561da177e4SLinus Torvalds return sock; 55700e188efSAl Viro } 558dba4a925SFlorent Revest *err = -ENOTSOCK; 55900e188efSAl Viro fdput(f); 5606cb153caSBenjamin LaHaise } 5616cb153caSBenjamin LaHaise return NULL; 5621da177e4SLinus Torvalds } 5631da177e4SLinus Torvalds 564600e1779SMasatake YAMATO static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer, 565600e1779SMasatake YAMATO size_t size) 566600e1779SMasatake YAMATO { 567600e1779SMasatake YAMATO ssize_t len; 568600e1779SMasatake YAMATO ssize_t used = 0; 569600e1779SMasatake YAMATO 570c5ef6035SDavid Howells len = security_inode_listsecurity(d_inode(dentry), buffer, size); 571600e1779SMasatake YAMATO if (len < 0) 572600e1779SMasatake YAMATO return len; 573600e1779SMasatake YAMATO used += len; 574600e1779SMasatake YAMATO if (buffer) { 575600e1779SMasatake YAMATO if (size < used) 576600e1779SMasatake YAMATO return -ERANGE; 577600e1779SMasatake YAMATO buffer += len; 578600e1779SMasatake YAMATO } 579600e1779SMasatake YAMATO 580600e1779SMasatake YAMATO len = (XATTR_NAME_SOCKPROTONAME_LEN + 1); 581600e1779SMasatake YAMATO used += len; 582600e1779SMasatake YAMATO if (buffer) { 583600e1779SMasatake YAMATO if (size < used) 584600e1779SMasatake YAMATO return -ERANGE; 585600e1779SMasatake YAMATO memcpy(buffer, XATTR_NAME_SOCKPROTONAME, len); 586600e1779SMasatake YAMATO buffer += len; 587600e1779SMasatake YAMATO } 588600e1779SMasatake YAMATO 589600e1779SMasatake YAMATO return used; 590600e1779SMasatake YAMATO } 591600e1779SMasatake YAMATO 592549c7297SChristian Brauner static int sockfs_setattr(struct user_namespace *mnt_userns, 593549c7297SChristian Brauner struct dentry *dentry, struct iattr *iattr) 59486741ec2SLorenzo Colitti { 595549c7297SChristian Brauner int err = simple_setattr(&init_user_ns, dentry, iattr); 59686741ec2SLorenzo Colitti 597e1a3a60aSEric Biggers if (!err && (iattr->ia_valid & ATTR_UID)) { 59886741ec2SLorenzo Colitti struct socket *sock = SOCKET_I(d_inode(dentry)); 59986741ec2SLorenzo Colitti 6006d8c50dcSCong Wang if (sock->sk) 60186741ec2SLorenzo Colitti sock->sk->sk_uid = iattr->ia_uid; 6026d8c50dcSCong Wang else 6036d8c50dcSCong Wang err = -ENOENT; 60486741ec2SLorenzo Colitti } 60586741ec2SLorenzo Colitti 60686741ec2SLorenzo Colitti return err; 60786741ec2SLorenzo Colitti } 60886741ec2SLorenzo Colitti 609600e1779SMasatake YAMATO static const struct inode_operations sockfs_inode_ops = { 610600e1779SMasatake YAMATO .listxattr = sockfs_listxattr, 61186741ec2SLorenzo Colitti .setattr = sockfs_setattr, 612600e1779SMasatake YAMATO }; 613600e1779SMasatake YAMATO 6141da177e4SLinus Torvalds /** 6151da177e4SLinus Torvalds * sock_alloc - allocate a socket 6161da177e4SLinus Torvalds * 6171da177e4SLinus Torvalds * Allocate a new inode and socket object. The two are bound together 6181da177e4SLinus Torvalds * and initialised. The socket is then returned. If we are out of inodes 6198a3c245cSPedro Tammela * NULL is returned. This functions uses GFP_KERNEL internally. 6201da177e4SLinus Torvalds */ 6211da177e4SLinus Torvalds 622f4a00aacSTom Herbert struct socket *sock_alloc(void) 6231da177e4SLinus Torvalds { 6241da177e4SLinus Torvalds struct inode *inode; 6251da177e4SLinus Torvalds struct socket *sock; 6261da177e4SLinus Torvalds 627a209dfc7SEric Dumazet inode = new_inode_pseudo(sock_mnt->mnt_sb); 6281da177e4SLinus Torvalds if (!inode) 6291da177e4SLinus Torvalds return NULL; 6301da177e4SLinus Torvalds 6311da177e4SLinus Torvalds sock = SOCKET_I(inode); 6321da177e4SLinus Torvalds 63385fe4025SChristoph Hellwig inode->i_ino = get_next_ino(); 6341da177e4SLinus Torvalds inode->i_mode = S_IFSOCK | S_IRWXUGO; 6358192b0c4SDavid Howells inode->i_uid = current_fsuid(); 6368192b0c4SDavid Howells inode->i_gid = current_fsgid(); 637600e1779SMasatake YAMATO inode->i_op = &sockfs_inode_ops; 6381da177e4SLinus Torvalds 6391da177e4SLinus Torvalds return sock; 6401da177e4SLinus Torvalds } 641f4a00aacSTom Herbert EXPORT_SYMBOL(sock_alloc); 6421da177e4SLinus Torvalds 6436d8c50dcSCong Wang static void __sock_release(struct socket *sock, struct inode *inode) 6441da177e4SLinus Torvalds { 6451da177e4SLinus Torvalds if (sock->ops) { 6461da177e4SLinus Torvalds struct module *owner = sock->ops->owner; 6471da177e4SLinus Torvalds 6486d8c50dcSCong Wang if (inode) 6496d8c50dcSCong Wang inode_lock(inode); 6501da177e4SLinus Torvalds sock->ops->release(sock); 651ff7b11aaSEric Biggers sock->sk = NULL; 6526d8c50dcSCong Wang if (inode) 6536d8c50dcSCong Wang inode_unlock(inode); 6541da177e4SLinus Torvalds sock->ops = NULL; 6551da177e4SLinus Torvalds module_put(owner); 6561da177e4SLinus Torvalds } 6571da177e4SLinus Torvalds 658333f7909SAl Viro if (sock->wq.fasync_list) 6593410f22eSYang Yingliang pr_err("%s: fasync list not empty!\n", __func__); 6601da177e4SLinus Torvalds 6611da177e4SLinus Torvalds if (!sock->file) { 6621da177e4SLinus Torvalds iput(SOCK_INODE(sock)); 6631da177e4SLinus Torvalds return; 6641da177e4SLinus Torvalds } 6651da177e4SLinus Torvalds sock->file = NULL; 6661da177e4SLinus Torvalds } 6676d8c50dcSCong Wang 6689a8ad9acSAndrew Lunn /** 6699a8ad9acSAndrew Lunn * sock_release - close a socket 6709a8ad9acSAndrew Lunn * @sock: socket to close 6719a8ad9acSAndrew Lunn * 6729a8ad9acSAndrew Lunn * The socket is released from the protocol stack if it has a release 6739a8ad9acSAndrew Lunn * callback, and the inode is then released if the socket is bound to 6749a8ad9acSAndrew Lunn * an inode not a file. 6759a8ad9acSAndrew Lunn */ 6766d8c50dcSCong Wang void sock_release(struct socket *sock) 6776d8c50dcSCong Wang { 6786d8c50dcSCong Wang __sock_release(sock, NULL); 6796d8c50dcSCong Wang } 680c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_release); 6811da177e4SLinus Torvalds 682c14ac945SSoheil Hassas Yeganeh void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags) 68320d49473SPatrick Ohly { 684140c55d4SEric Dumazet u8 flags = *tx_flags; 685140c55d4SEric Dumazet 68651eb7492SGerhard Engleder if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE) { 687140c55d4SEric Dumazet flags |= SKBTX_HW_TSTAMP; 688140c55d4SEric Dumazet 68951eb7492SGerhard Engleder /* PTP hardware clocks can provide a free running cycle counter 69051eb7492SGerhard Engleder * as a time base for virtual clocks. Tell driver to use the 69151eb7492SGerhard Engleder * free running cycle counter for timestamp if socket is bound 69251eb7492SGerhard Engleder * to virtual clock. 69351eb7492SGerhard Engleder */ 69451eb7492SGerhard Engleder if (tsflags & SOF_TIMESTAMPING_BIND_PHC) 69551eb7492SGerhard Engleder flags |= SKBTX_HW_TSTAMP_USE_CYCLES; 69651eb7492SGerhard Engleder } 69751eb7492SGerhard Engleder 698c14ac945SSoheil Hassas Yeganeh if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE) 699140c55d4SEric Dumazet flags |= SKBTX_SW_TSTAMP; 700140c55d4SEric Dumazet 701c14ac945SSoheil Hassas Yeganeh if (tsflags & SOF_TIMESTAMPING_TX_SCHED) 702140c55d4SEric Dumazet flags |= SKBTX_SCHED_TSTAMP; 703140c55d4SEric Dumazet 704140c55d4SEric Dumazet *tx_flags = flags; 70520d49473SPatrick Ohly } 70667cc0d40SWillem de Bruijn EXPORT_SYMBOL(__sock_tx_timestamp); 70720d49473SPatrick Ohly 7088c3c447bSPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet_sendmsg(struct socket *, struct msghdr *, 7098c3c447bSPaolo Abeni size_t)); 710a648a592SPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet6_sendmsg(struct socket *, struct msghdr *, 711a648a592SPaolo Abeni size_t)); 712d8725c86SAl Viro static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg) 7131da177e4SLinus Torvalds { 714a648a592SPaolo Abeni int ret = INDIRECT_CALL_INET(sock->ops->sendmsg, inet6_sendmsg, 715a648a592SPaolo Abeni inet_sendmsg, sock, msg, 716a648a592SPaolo Abeni msg_data_left(msg)); 717d8725c86SAl Viro BUG_ON(ret == -EIOCBQUEUED); 718d8725c86SAl Viro return ret; 7191da177e4SLinus Torvalds } 7200cf00c6fSGu Zheng 72185806af0SRandy Dunlap /** 72285806af0SRandy Dunlap * sock_sendmsg - send a message through @sock 72385806af0SRandy Dunlap * @sock: socket 72485806af0SRandy Dunlap * @msg: message to send 72585806af0SRandy Dunlap * 72685806af0SRandy Dunlap * Sends @msg through @sock, passing through LSM. 72785806af0SRandy Dunlap * Returns the number of bytes sent, or an error code. 72885806af0SRandy Dunlap */ 729d8725c86SAl Viro int sock_sendmsg(struct socket *sock, struct msghdr *msg) 7300cf00c6fSGu Zheng { 731d8725c86SAl Viro int err = security_socket_sendmsg(sock, msg, 73201e97e65SAl Viro msg_data_left(msg)); 7331b784140SYing Xue 734d8725c86SAl Viro return err ?: sock_sendmsg_nosec(sock, msg); 7350cf00c6fSGu Zheng } 736c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_sendmsg); 7371da177e4SLinus Torvalds 7388a3c245cSPedro Tammela /** 7398a3c245cSPedro Tammela * kernel_sendmsg - send a message through @sock (kernel-space) 7408a3c245cSPedro Tammela * @sock: socket 7418a3c245cSPedro Tammela * @msg: message header 7428a3c245cSPedro Tammela * @vec: kernel vec 7438a3c245cSPedro Tammela * @num: vec array length 7448a3c245cSPedro Tammela * @size: total message data size 7458a3c245cSPedro Tammela * 7468a3c245cSPedro Tammela * Builds the message data with @vec and sends it through @sock. 7478a3c245cSPedro Tammela * Returns the number of bytes sent, or an error code. 7488a3c245cSPedro Tammela */ 7498a3c245cSPedro Tammela 7501da177e4SLinus Torvalds int kernel_sendmsg(struct socket *sock, struct msghdr *msg, 7511da177e4SLinus Torvalds struct kvec *vec, size_t num, size_t size) 7521da177e4SLinus Torvalds { 753*de4eda9dSAl Viro iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, num, size); 754d8725c86SAl Viro return sock_sendmsg(sock, msg); 7551da177e4SLinus Torvalds } 756c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_sendmsg); 7571da177e4SLinus Torvalds 7588a3c245cSPedro Tammela /** 7598a3c245cSPedro Tammela * kernel_sendmsg_locked - send a message through @sock (kernel-space) 7608a3c245cSPedro Tammela * @sk: sock 7618a3c245cSPedro Tammela * @msg: message header 7628a3c245cSPedro Tammela * @vec: output s/g array 7638a3c245cSPedro Tammela * @num: output s/g array length 7648a3c245cSPedro Tammela * @size: total message data size 7658a3c245cSPedro Tammela * 7668a3c245cSPedro Tammela * Builds the message data with @vec and sends it through @sock. 7678a3c245cSPedro Tammela * Returns the number of bytes sent, or an error code. 7688a3c245cSPedro Tammela * Caller must hold @sk. 7698a3c245cSPedro Tammela */ 7708a3c245cSPedro Tammela 771306b13ebSTom Herbert int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg, 772306b13ebSTom Herbert struct kvec *vec, size_t num, size_t size) 773306b13ebSTom Herbert { 774306b13ebSTom Herbert struct socket *sock = sk->sk_socket; 775306b13ebSTom Herbert 776306b13ebSTom Herbert if (!sock->ops->sendmsg_locked) 777db5980d8SJohn Fastabend return sock_no_sendmsg_locked(sk, msg, size); 778306b13ebSTom Herbert 779*de4eda9dSAl Viro iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, num, size); 780306b13ebSTom Herbert 781306b13ebSTom Herbert return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg)); 782306b13ebSTom Herbert } 783306b13ebSTom Herbert EXPORT_SYMBOL(kernel_sendmsg_locked); 784306b13ebSTom Herbert 7858605330aSSoheil Hassas Yeganeh static bool skb_is_err_queue(const struct sk_buff *skb) 7868605330aSSoheil Hassas Yeganeh { 7878605330aSSoheil Hassas Yeganeh /* pkt_type of skbs enqueued on the error queue are set to 7888605330aSSoheil Hassas Yeganeh * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do 7898605330aSSoheil Hassas Yeganeh * in recvmsg, since skbs received on a local socket will never 7908605330aSSoheil Hassas Yeganeh * have a pkt_type of PACKET_OUTGOING. 7918605330aSSoheil Hassas Yeganeh */ 7928605330aSSoheil Hassas Yeganeh return skb->pkt_type == PACKET_OUTGOING; 7938605330aSSoheil Hassas Yeganeh } 7948605330aSSoheil Hassas Yeganeh 795b50a5c70SMiroslav Lichvar /* On transmit, software and hardware timestamps are returned independently. 796b50a5c70SMiroslav Lichvar * As the two skb clones share the hardware timestamp, which may be updated 797b50a5c70SMiroslav Lichvar * before the software timestamp is received, a hardware TX timestamp may be 798b50a5c70SMiroslav Lichvar * returned only if there is no software TX timestamp. Ignore false software 799b50a5c70SMiroslav Lichvar * timestamps, which may be made in the __sock_recv_timestamp() call when the 8007f1bc6e9SDeepa Dinamani * option SO_TIMESTAMP_OLD(NS) is enabled on the socket, even when the skb has a 801b50a5c70SMiroslav Lichvar * hardware timestamp. 802b50a5c70SMiroslav Lichvar */ 803b50a5c70SMiroslav Lichvar static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp) 804b50a5c70SMiroslav Lichvar { 805b50a5c70SMiroslav Lichvar return skb->tstamp && !false_tstamp && skb_is_err_queue(skb); 806b50a5c70SMiroslav Lichvar } 807b50a5c70SMiroslav Lichvar 80897dc7cd9SGerhard Engleder static ktime_t get_timestamp(struct sock *sk, struct sk_buff *skb, int *if_index) 80997dc7cd9SGerhard Engleder { 81097dc7cd9SGerhard Engleder bool cycles = sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC; 81197dc7cd9SGerhard Engleder struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); 81297dc7cd9SGerhard Engleder struct net_device *orig_dev; 81397dc7cd9SGerhard Engleder ktime_t hwtstamp; 81497dc7cd9SGerhard Engleder 81597dc7cd9SGerhard Engleder rcu_read_lock(); 81697dc7cd9SGerhard Engleder orig_dev = dev_get_by_napi_id(skb_napi_id(skb)); 81797dc7cd9SGerhard Engleder if (orig_dev) { 81897dc7cd9SGerhard Engleder *if_index = orig_dev->ifindex; 81997dc7cd9SGerhard Engleder hwtstamp = netdev_get_tstamp(orig_dev, shhwtstamps, cycles); 82097dc7cd9SGerhard Engleder } else { 82197dc7cd9SGerhard Engleder hwtstamp = shhwtstamps->hwtstamp; 82297dc7cd9SGerhard Engleder } 82397dc7cd9SGerhard Engleder rcu_read_unlock(); 82497dc7cd9SGerhard Engleder 82597dc7cd9SGerhard Engleder return hwtstamp; 82697dc7cd9SGerhard Engleder } 82797dc7cd9SGerhard Engleder 82897dc7cd9SGerhard Engleder static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb, 82997dc7cd9SGerhard Engleder int if_index) 830aad9c8c4SMiroslav Lichvar { 831aad9c8c4SMiroslav Lichvar struct scm_ts_pktinfo ts_pktinfo; 832aad9c8c4SMiroslav Lichvar struct net_device *orig_dev; 833aad9c8c4SMiroslav Lichvar 834aad9c8c4SMiroslav Lichvar if (!skb_mac_header_was_set(skb)) 835aad9c8c4SMiroslav Lichvar return; 836aad9c8c4SMiroslav Lichvar 837aad9c8c4SMiroslav Lichvar memset(&ts_pktinfo, 0, sizeof(ts_pktinfo)); 838aad9c8c4SMiroslav Lichvar 83997dc7cd9SGerhard Engleder if (!if_index) { 840aad9c8c4SMiroslav Lichvar rcu_read_lock(); 841aad9c8c4SMiroslav Lichvar orig_dev = dev_get_by_napi_id(skb_napi_id(skb)); 842aad9c8c4SMiroslav Lichvar if (orig_dev) 84397dc7cd9SGerhard Engleder if_index = orig_dev->ifindex; 844aad9c8c4SMiroslav Lichvar rcu_read_unlock(); 84597dc7cd9SGerhard Engleder } 84697dc7cd9SGerhard Engleder ts_pktinfo.if_index = if_index; 847aad9c8c4SMiroslav Lichvar 848aad9c8c4SMiroslav Lichvar ts_pktinfo.pkt_length = skb->len - skb_mac_offset(skb); 849aad9c8c4SMiroslav Lichvar put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO, 850aad9c8c4SMiroslav Lichvar sizeof(ts_pktinfo), &ts_pktinfo); 851aad9c8c4SMiroslav Lichvar } 852aad9c8c4SMiroslav Lichvar 85392f37fd2SEric Dumazet /* 85492f37fd2SEric Dumazet * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP) 85592f37fd2SEric Dumazet */ 85692f37fd2SEric Dumazet void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, 85792f37fd2SEric Dumazet struct sk_buff *skb) 85892f37fd2SEric Dumazet { 85920d49473SPatrick Ohly int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP); 860887feae3SDeepa Dinamani int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW); 8619718475eSDeepa Dinamani struct scm_timestamping_internal tss; 8629718475eSDeepa Dinamani 863b50a5c70SMiroslav Lichvar int empty = 1, false_tstamp = 0; 86420d49473SPatrick Ohly struct skb_shared_hwtstamps *shhwtstamps = 86520d49473SPatrick Ohly skb_hwtstamps(skb); 86697dc7cd9SGerhard Engleder int if_index; 867007747a9SMiroslav Lichvar ktime_t hwtstamp; 86892f37fd2SEric Dumazet 86920d49473SPatrick Ohly /* Race occurred between timestamp enabling and packet 87020d49473SPatrick Ohly receiving. Fill in the current time for now. */ 871b50a5c70SMiroslav Lichvar if (need_software_tstamp && skb->tstamp == 0) { 87220d49473SPatrick Ohly __net_timestamp(skb); 873b50a5c70SMiroslav Lichvar false_tstamp = 1; 874b50a5c70SMiroslav Lichvar } 87520d49473SPatrick Ohly 87620d49473SPatrick Ohly if (need_software_tstamp) { 87792f37fd2SEric Dumazet if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) { 878887feae3SDeepa Dinamani if (new_tstamp) { 879887feae3SDeepa Dinamani struct __kernel_sock_timeval tv; 880887feae3SDeepa Dinamani 881887feae3SDeepa Dinamani skb_get_new_timestamp(skb, &tv); 882887feae3SDeepa Dinamani put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW, 883887feae3SDeepa Dinamani sizeof(tv), &tv); 884887feae3SDeepa Dinamani } else { 88513c6ee2aSDeepa Dinamani struct __kernel_old_timeval tv; 886887feae3SDeepa Dinamani 88720d49473SPatrick Ohly skb_get_timestamp(skb, &tv); 8887f1bc6e9SDeepa Dinamani put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD, 88920d49473SPatrick Ohly sizeof(tv), &tv); 890887feae3SDeepa Dinamani } 891887feae3SDeepa Dinamani } else { 892887feae3SDeepa Dinamani if (new_tstamp) { 893887feae3SDeepa Dinamani struct __kernel_timespec ts; 894887feae3SDeepa Dinamani 895887feae3SDeepa Dinamani skb_get_new_timestampns(skb, &ts); 896887feae3SDeepa Dinamani put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW, 897887feae3SDeepa Dinamani sizeof(ts), &ts); 89892f37fd2SEric Dumazet } else { 899df1b4ba9SArnd Bergmann struct __kernel_old_timespec ts; 900887feae3SDeepa Dinamani 901f24b9be5SWillem de Bruijn skb_get_timestampns(skb, &ts); 9027f1bc6e9SDeepa Dinamani put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD, 903f24b9be5SWillem de Bruijn sizeof(ts), &ts); 90492f37fd2SEric Dumazet } 90592f37fd2SEric Dumazet } 906887feae3SDeepa Dinamani } 90792f37fd2SEric Dumazet 908f24b9be5SWillem de Bruijn memset(&tss, 0, sizeof(tss)); 909c199105dSWillem de Bruijn if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) && 9109718475eSDeepa Dinamani ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0)) 91120d49473SPatrick Ohly empty = 0; 9124d276eb6SWillem de Bruijn if (shhwtstamps && 913b9f40e21SWillem de Bruijn (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && 914d7c08826SYangbo Lu !skb_is_swtx_tstamp(skb, false_tstamp)) { 91597dc7cd9SGerhard Engleder if_index = 0; 91697dc7cd9SGerhard Engleder if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV) 91797dc7cd9SGerhard Engleder hwtstamp = get_timestamp(sk, skb, &if_index); 918007747a9SMiroslav Lichvar else 919007747a9SMiroslav Lichvar hwtstamp = shhwtstamps->hwtstamp; 920d7c08826SYangbo Lu 92197dc7cd9SGerhard Engleder if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) 92297dc7cd9SGerhard Engleder hwtstamp = ptp_convert_timestamp(&hwtstamp, 92397dc7cd9SGerhard Engleder sk->sk_bind_phc); 92497dc7cd9SGerhard Engleder 925007747a9SMiroslav Lichvar if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) { 92620d49473SPatrick Ohly empty = 0; 927d7c08826SYangbo Lu 928aad9c8c4SMiroslav Lichvar if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && 929aad9c8c4SMiroslav Lichvar !skb_is_err_queue(skb)) 93097dc7cd9SGerhard Engleder put_ts_pktinfo(msg, skb, if_index); 931aad9c8c4SMiroslav Lichvar } 932d7c08826SYangbo Lu } 9331c885808SFrancis Yan if (!empty) { 9349718475eSDeepa Dinamani if (sock_flag(sk, SOCK_TSTAMP_NEW)) 9359718475eSDeepa Dinamani put_cmsg_scm_timestamping64(msg, &tss); 9369718475eSDeepa Dinamani else 9379718475eSDeepa Dinamani put_cmsg_scm_timestamping(msg, &tss); 9381c885808SFrancis Yan 9398605330aSSoheil Hassas Yeganeh if (skb_is_err_queue(skb) && skb->len && 9404ef1b286SSoheil Hassas Yeganeh SKB_EXT_ERR(skb)->opt_stats) 9411c885808SFrancis Yan put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS, 9421c885808SFrancis Yan skb->len, skb->data); 9431c885808SFrancis Yan } 94420d49473SPatrick Ohly } 9457c81fd8bSArnaldo Carvalho de Melo EXPORT_SYMBOL_GPL(__sock_recv_timestamp); 9467c81fd8bSArnaldo Carvalho de Melo 9476e3e939fSJohannes Berg void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, 9486e3e939fSJohannes Berg struct sk_buff *skb) 9496e3e939fSJohannes Berg { 9506e3e939fSJohannes Berg int ack; 9516e3e939fSJohannes Berg 9526e3e939fSJohannes Berg if (!sock_flag(sk, SOCK_WIFI_STATUS)) 9536e3e939fSJohannes Berg return; 9546e3e939fSJohannes Berg if (!skb->wifi_acked_valid) 9556e3e939fSJohannes Berg return; 9566e3e939fSJohannes Berg 9576e3e939fSJohannes Berg ack = skb->wifi_acked; 9586e3e939fSJohannes Berg 9596e3e939fSJohannes Berg put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack); 9606e3e939fSJohannes Berg } 9616e3e939fSJohannes Berg EXPORT_SYMBOL_GPL(__sock_recv_wifi_status); 9626e3e939fSJohannes Berg 96311165f14Sstephen hemminger static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, 96411165f14Sstephen hemminger struct sk_buff *skb) 9653b885787SNeil Horman { 966744d5a3eSEyal Birger if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount) 9673b885787SNeil Horman put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL, 968744d5a3eSEyal Birger sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount); 9693b885787SNeil Horman } 9703b885787SNeil Horman 9716fd1d51cSErin MacNeil static void sock_recv_mark(struct msghdr *msg, struct sock *sk, 9726fd1d51cSErin MacNeil struct sk_buff *skb) 9736fd1d51cSErin MacNeil { 9746fd1d51cSErin MacNeil if (sock_flag(sk, SOCK_RCVMARK) && skb) 9756fd1d51cSErin MacNeil put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32), 9766fd1d51cSErin MacNeil &skb->mark); 9776fd1d51cSErin MacNeil } 9786fd1d51cSErin MacNeil 9796fd1d51cSErin MacNeil void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk, 9803b885787SNeil Horman struct sk_buff *skb) 9813b885787SNeil Horman { 9823b885787SNeil Horman sock_recv_timestamp(msg, sk, skb); 9833b885787SNeil Horman sock_recv_drops(msg, sk, skb); 9846fd1d51cSErin MacNeil sock_recv_mark(msg, sk, skb); 9853b885787SNeil Horman } 9866fd1d51cSErin MacNeil EXPORT_SYMBOL_GPL(__sock_recv_cmsgs); 9873b885787SNeil Horman 9888c3c447bSPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *, 9898c3c447bSPaolo Abeni size_t, int)); 990a648a592SPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet6_recvmsg(struct socket *, struct msghdr *, 991a648a592SPaolo Abeni size_t, int)); 9921b784140SYing Xue static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, 9931b784140SYing Xue int flags) 994a2e27255SArnaldo Carvalho de Melo { 995a648a592SPaolo Abeni return INDIRECT_CALL_INET(sock->ops->recvmsg, inet6_recvmsg, 996a648a592SPaolo Abeni inet_recvmsg, sock, msg, msg_data_left(msg), 997a648a592SPaolo Abeni flags); 9982da62906SAl Viro } 999a2e27255SArnaldo Carvalho de Melo 100085806af0SRandy Dunlap /** 100185806af0SRandy Dunlap * sock_recvmsg - receive a message from @sock 100285806af0SRandy Dunlap * @sock: socket 100385806af0SRandy Dunlap * @msg: message to receive 100485806af0SRandy Dunlap * @flags: message flags 100585806af0SRandy Dunlap * 100685806af0SRandy Dunlap * Receives @msg from @sock, passing through LSM. Returns the total number 100785806af0SRandy Dunlap * of bytes received, or an error. 100885806af0SRandy Dunlap */ 10092da62906SAl Viro int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags) 10102da62906SAl Viro { 10112da62906SAl Viro int err = security_socket_recvmsg(sock, msg, msg_data_left(msg), flags); 10122da62906SAl Viro 10132da62906SAl Viro return err ?: sock_recvmsg_nosec(sock, msg, flags); 10141da177e4SLinus Torvalds } 1015c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_recvmsg); 10161da177e4SLinus Torvalds 1017c1249c0aSMartin Lucina /** 1018c1249c0aSMartin Lucina * kernel_recvmsg - Receive a message from a socket (kernel space) 1019c1249c0aSMartin Lucina * @sock: The socket to receive the message from 1020c1249c0aSMartin Lucina * @msg: Received message 1021c1249c0aSMartin Lucina * @vec: Input s/g array for message data 1022c1249c0aSMartin Lucina * @num: Size of input s/g array 1023c1249c0aSMartin Lucina * @size: Number of bytes to read 1024c1249c0aSMartin Lucina * @flags: Message flags (MSG_DONTWAIT, etc...) 1025c1249c0aSMartin Lucina * 1026c1249c0aSMartin Lucina * On return the msg structure contains the scatter/gather array passed in the 1027c1249c0aSMartin Lucina * vec argument. The array is modified so that it consists of the unfilled 1028c1249c0aSMartin Lucina * portion of the original array. 1029c1249c0aSMartin Lucina * 1030c1249c0aSMartin Lucina * The returned value is the total number of bytes received, or an error. 1031c1249c0aSMartin Lucina */ 10328a3c245cSPedro Tammela 10331da177e4SLinus Torvalds int kernel_recvmsg(struct socket *sock, struct msghdr *msg, 103489bddce5SStephen Hemminger struct kvec *vec, size_t num, size_t size, int flags) 10351da177e4SLinus Torvalds { 10361f466e1fSChristoph Hellwig msg->msg_control_is_user = false; 1037*de4eda9dSAl Viro iov_iter_kvec(&msg->msg_iter, ITER_DEST, vec, num, size); 10381f466e1fSChristoph Hellwig return sock_recvmsg(sock, msg, flags); 10391da177e4SLinus Torvalds } 1040c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_recvmsg); 10411da177e4SLinus Torvalds 104220380731SArnaldo Carvalho de Melo static ssize_t sock_sendpage(struct file *file, struct page *page, 10431da177e4SLinus Torvalds int offset, size_t size, loff_t *ppos, int more) 10441da177e4SLinus Torvalds { 10451da177e4SLinus Torvalds struct socket *sock; 10461da177e4SLinus Torvalds int flags; 10471da177e4SLinus Torvalds 1048b69aee04SEric Dumazet sock = file->private_data; 10491da177e4SLinus Torvalds 105035f9c09fSEric Dumazet flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; 105135f9c09fSEric Dumazet /* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */ 105235f9c09fSEric Dumazet flags |= more; 10531da177e4SLinus Torvalds 1054e6949583SLinus Torvalds return kernel_sendpage(sock, page, offset, size, flags); 10551da177e4SLinus Torvalds } 10561da177e4SLinus Torvalds 10579c55e01cSJens Axboe static ssize_t sock_splice_read(struct file *file, loff_t *ppos, 10589c55e01cSJens Axboe struct pipe_inode_info *pipe, size_t len, 10599c55e01cSJens Axboe unsigned int flags) 10609c55e01cSJens Axboe { 10619c55e01cSJens Axboe struct socket *sock = file->private_data; 10629c55e01cSJens Axboe 1063997b37daSRémi Denis-Courmont if (unlikely(!sock->ops->splice_read)) 106495506588SSlavomir Kaslev return generic_file_splice_read(file, ppos, pipe, len, flags); 1065997b37daSRémi Denis-Courmont 10669c55e01cSJens Axboe return sock->ops->splice_read(sock, ppos, pipe, len, flags); 10679c55e01cSJens Axboe } 10689c55e01cSJens Axboe 10698ae5e030SAl Viro static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to) 1070ce1d4d3eSChristoph Hellwig { 10716d652330SAl Viro struct file *file = iocb->ki_filp; 10726d652330SAl Viro struct socket *sock = file->private_data; 10730345f931Stadeusz.struk@intel.com struct msghdr msg = {.msg_iter = *to, 10740345f931Stadeusz.struk@intel.com .msg_iocb = iocb}; 10758ae5e030SAl Viro ssize_t res; 1076ce1d4d3eSChristoph Hellwig 1077ebfcd895SJens Axboe if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT)) 10788ae5e030SAl Viro msg.msg_flags = MSG_DONTWAIT; 10798ae5e030SAl Viro 10808ae5e030SAl Viro if (iocb->ki_pos != 0) 1081ce1d4d3eSChristoph Hellwig return -ESPIPE; 1082027445c3SBadari Pulavarty 108366ee59afSChristoph Hellwig if (!iov_iter_count(to)) /* Match SYS5 behaviour */ 1084ce1d4d3eSChristoph Hellwig return 0; 1085ce1d4d3eSChristoph Hellwig 10862da62906SAl Viro res = sock_recvmsg(sock, &msg, msg.msg_flags); 10878ae5e030SAl Viro *to = msg.msg_iter; 10888ae5e030SAl Viro return res; 1089ce1d4d3eSChristoph Hellwig } 1090ce1d4d3eSChristoph Hellwig 10918ae5e030SAl Viro static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from) 10921da177e4SLinus Torvalds { 10936d652330SAl Viro struct file *file = iocb->ki_filp; 10946d652330SAl Viro struct socket *sock = file->private_data; 10950345f931Stadeusz.struk@intel.com struct msghdr msg = {.msg_iter = *from, 10960345f931Stadeusz.struk@intel.com .msg_iocb = iocb}; 10978ae5e030SAl Viro ssize_t res; 10981da177e4SLinus Torvalds 10998ae5e030SAl Viro if (iocb->ki_pos != 0) 1100ce1d4d3eSChristoph Hellwig return -ESPIPE; 1101027445c3SBadari Pulavarty 1102ebfcd895SJens Axboe if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT)) 11038ae5e030SAl Viro msg.msg_flags = MSG_DONTWAIT; 11048ae5e030SAl Viro 11056d652330SAl Viro if (sock->type == SOCK_SEQPACKET) 11066d652330SAl Viro msg.msg_flags |= MSG_EOR; 11076d652330SAl Viro 1108d8725c86SAl Viro res = sock_sendmsg(sock, &msg); 11098ae5e030SAl Viro *from = msg.msg_iter; 11108ae5e030SAl Viro return res; 11111da177e4SLinus Torvalds } 11121da177e4SLinus Torvalds 11131da177e4SLinus Torvalds /* 11141da177e4SLinus Torvalds * Atomic setting of ioctl hooks to avoid race 11151da177e4SLinus Torvalds * with module unload. 11161da177e4SLinus Torvalds */ 11171da177e4SLinus Torvalds 11184a3e2f71SArjan van de Ven static DEFINE_MUTEX(br_ioctl_mutex); 1119ad2f99aeSArnd Bergmann static int (*br_ioctl_hook)(struct net *net, struct net_bridge *br, 1120ad2f99aeSArnd Bergmann unsigned int cmd, struct ifreq *ifr, 1121ad2f99aeSArnd Bergmann void __user *uarg); 11221da177e4SLinus Torvalds 1123ad2f99aeSArnd Bergmann void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br, 1124ad2f99aeSArnd Bergmann unsigned int cmd, struct ifreq *ifr, 1125ad2f99aeSArnd Bergmann void __user *uarg)) 11261da177e4SLinus Torvalds { 11274a3e2f71SArjan van de Ven mutex_lock(&br_ioctl_mutex); 11281da177e4SLinus Torvalds br_ioctl_hook = hook; 11294a3e2f71SArjan van de Ven mutex_unlock(&br_ioctl_mutex); 11301da177e4SLinus Torvalds } 11311da177e4SLinus Torvalds EXPORT_SYMBOL(brioctl_set); 11321da177e4SLinus Torvalds 1133ad2f99aeSArnd Bergmann int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, 1134ad2f99aeSArnd Bergmann struct ifreq *ifr, void __user *uarg) 1135ad2f99aeSArnd Bergmann { 1136ad2f99aeSArnd Bergmann int err = -ENOPKG; 1137ad2f99aeSArnd Bergmann 1138ad2f99aeSArnd Bergmann if (!br_ioctl_hook) 1139ad2f99aeSArnd Bergmann request_module("bridge"); 1140ad2f99aeSArnd Bergmann 1141ad2f99aeSArnd Bergmann mutex_lock(&br_ioctl_mutex); 1142ad2f99aeSArnd Bergmann if (br_ioctl_hook) 1143ad2f99aeSArnd Bergmann err = br_ioctl_hook(net, br, cmd, ifr, uarg); 1144ad2f99aeSArnd Bergmann mutex_unlock(&br_ioctl_mutex); 1145ad2f99aeSArnd Bergmann 1146ad2f99aeSArnd Bergmann return err; 1147ad2f99aeSArnd Bergmann } 1148ad2f99aeSArnd Bergmann 11494a3e2f71SArjan van de Ven static DEFINE_MUTEX(vlan_ioctl_mutex); 1150881d966bSEric W. Biederman static int (*vlan_ioctl_hook) (struct net *, void __user *arg); 11511da177e4SLinus Torvalds 1152881d966bSEric W. Biederman void vlan_ioctl_set(int (*hook) (struct net *, void __user *)) 11531da177e4SLinus Torvalds { 11544a3e2f71SArjan van de Ven mutex_lock(&vlan_ioctl_mutex); 11551da177e4SLinus Torvalds vlan_ioctl_hook = hook; 11564a3e2f71SArjan van de Ven mutex_unlock(&vlan_ioctl_mutex); 11571da177e4SLinus Torvalds } 11581da177e4SLinus Torvalds EXPORT_SYMBOL(vlan_ioctl_set); 11591da177e4SLinus Torvalds 11606b96018bSArnd Bergmann static long sock_do_ioctl(struct net *net, struct socket *sock, 116163ff03abSJohannes Berg unsigned int cmd, unsigned long arg) 11626b96018bSArnd Bergmann { 1163876f0bf9SArnd Bergmann struct ifreq ifr; 1164876f0bf9SArnd Bergmann bool need_copyout; 11656b96018bSArnd Bergmann int err; 11666b96018bSArnd Bergmann void __user *argp = (void __user *)arg; 1167a554bf96SArnd Bergmann void __user *data; 11686b96018bSArnd Bergmann 11696b96018bSArnd Bergmann err = sock->ops->ioctl(sock, cmd, arg); 11706b96018bSArnd Bergmann 11716b96018bSArnd Bergmann /* 11726b96018bSArnd Bergmann * If this ioctl is unknown try to hand it down 11736b96018bSArnd Bergmann * to the NIC driver. 11746b96018bSArnd Bergmann */ 117536fd633eSAl Viro if (err != -ENOIOCTLCMD) 11766b96018bSArnd Bergmann return err; 11776b96018bSArnd Bergmann 117829ce8f97SJakub Kicinski if (!is_socket_ioctl_cmd(cmd)) 117929ce8f97SJakub Kicinski return -ENOTTY; 118029ce8f97SJakub Kicinski 1181a554bf96SArnd Bergmann if (get_user_ifreq(&ifr, &data, argp)) 118236fd633eSAl Viro return -EFAULT; 1183a554bf96SArnd Bergmann err = dev_ioctl(net, cmd, &ifr, data, &need_copyout); 118444c02a2cSAl Viro if (!err && need_copyout) 1185a554bf96SArnd Bergmann if (put_user_ifreq(&ifr, argp)) 118644c02a2cSAl Viro return -EFAULT; 1187876f0bf9SArnd Bergmann 11886b96018bSArnd Bergmann return err; 11896b96018bSArnd Bergmann } 11906b96018bSArnd Bergmann 11911da177e4SLinus Torvalds /* 11921da177e4SLinus Torvalds * With an ioctl, arg may well be a user mode pointer, but we don't know 11931da177e4SLinus Torvalds * what to do with it - that's up to the protocol still. 11941da177e4SLinus Torvalds */ 11951da177e4SLinus Torvalds 11961da177e4SLinus Torvalds static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) 11971da177e4SLinus Torvalds { 11981da177e4SLinus Torvalds struct socket *sock; 1199881d966bSEric W. Biederman struct sock *sk; 12001da177e4SLinus Torvalds void __user *argp = (void __user *)arg; 12011da177e4SLinus Torvalds int pid, err; 1202881d966bSEric W. Biederman struct net *net; 12031da177e4SLinus Torvalds 1204b69aee04SEric Dumazet sock = file->private_data; 1205881d966bSEric W. Biederman sk = sock->sk; 12063b1e0a65SYOSHIFUJI Hideaki net = sock_net(sk); 120744c02a2cSAl Viro if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) { 120844c02a2cSAl Viro struct ifreq ifr; 1209a554bf96SArnd Bergmann void __user *data; 121044c02a2cSAl Viro bool need_copyout; 1211a554bf96SArnd Bergmann if (get_user_ifreq(&ifr, &data, argp)) 121244c02a2cSAl Viro return -EFAULT; 1213a554bf96SArnd Bergmann err = dev_ioctl(net, cmd, &ifr, data, &need_copyout); 121444c02a2cSAl Viro if (!err && need_copyout) 1215a554bf96SArnd Bergmann if (put_user_ifreq(&ifr, argp)) 121644c02a2cSAl Viro return -EFAULT; 12171da177e4SLinus Torvalds } else 12183d23e349SJohannes Berg #ifdef CONFIG_WEXT_CORE 12191da177e4SLinus Torvalds if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { 1220b1b0c245SAl Viro err = wext_handle_ioctl(net, cmd, argp); 12211da177e4SLinus Torvalds } else 12223d23e349SJohannes Berg #endif 12231da177e4SLinus Torvalds switch (cmd) { 12241da177e4SLinus Torvalds case FIOSETOWN: 12251da177e4SLinus Torvalds case SIOCSPGRP: 12261da177e4SLinus Torvalds err = -EFAULT; 12271da177e4SLinus Torvalds if (get_user(pid, (int __user *)argp)) 12281da177e4SLinus Torvalds break; 1229393cc3f5SJiri Slaby err = f_setown(sock->file, pid, 1); 12301da177e4SLinus Torvalds break; 12311da177e4SLinus Torvalds case FIOGETOWN: 12321da177e4SLinus Torvalds case SIOCGPGRP: 1233609d7fa9SEric W. Biederman err = put_user(f_getown(sock->file), 123489bddce5SStephen Hemminger (int __user *)argp); 12351da177e4SLinus Torvalds break; 12361da177e4SLinus Torvalds case SIOCGIFBR: 12371da177e4SLinus Torvalds case SIOCSIFBR: 12381da177e4SLinus Torvalds case SIOCBRADDBR: 12391da177e4SLinus Torvalds case SIOCBRDELBR: 1240ad2f99aeSArnd Bergmann err = br_ioctl_call(net, NULL, cmd, NULL, argp); 12411da177e4SLinus Torvalds break; 12421da177e4SLinus Torvalds case SIOCGIFVLAN: 12431da177e4SLinus Torvalds case SIOCSIFVLAN: 12441da177e4SLinus Torvalds err = -ENOPKG; 12451da177e4SLinus Torvalds if (!vlan_ioctl_hook) 12461da177e4SLinus Torvalds request_module("8021q"); 12471da177e4SLinus Torvalds 12484a3e2f71SArjan van de Ven mutex_lock(&vlan_ioctl_mutex); 12491da177e4SLinus Torvalds if (vlan_ioctl_hook) 1250881d966bSEric W. Biederman err = vlan_ioctl_hook(net, argp); 12514a3e2f71SArjan van de Ven mutex_unlock(&vlan_ioctl_mutex); 12521da177e4SLinus Torvalds break; 1253c62cce2cSAndrey Vagin case SIOCGSKNS: 1254c62cce2cSAndrey Vagin err = -EPERM; 1255c62cce2cSAndrey Vagin if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 1256c62cce2cSAndrey Vagin break; 1257c62cce2cSAndrey Vagin 1258c62cce2cSAndrey Vagin err = open_related_ns(&net->ns, get_net_ns); 1259c62cce2cSAndrey Vagin break; 12600768e170SArnd Bergmann case SIOCGSTAMP_OLD: 12610768e170SArnd Bergmann case SIOCGSTAMPNS_OLD: 1262c7cbdbf2SArnd Bergmann if (!sock->ops->gettstamp) { 1263c7cbdbf2SArnd Bergmann err = -ENOIOCTLCMD; 1264c7cbdbf2SArnd Bergmann break; 1265c7cbdbf2SArnd Bergmann } 1266c7cbdbf2SArnd Bergmann err = sock->ops->gettstamp(sock, argp, 12670768e170SArnd Bergmann cmd == SIOCGSTAMP_OLD, 12680768e170SArnd Bergmann !IS_ENABLED(CONFIG_64BIT)); 126960747828SGustavo A. R. Silva break; 12700768e170SArnd Bergmann case SIOCGSTAMP_NEW: 12710768e170SArnd Bergmann case SIOCGSTAMPNS_NEW: 12720768e170SArnd Bergmann if (!sock->ops->gettstamp) { 12730768e170SArnd Bergmann err = -ENOIOCTLCMD; 12740768e170SArnd Bergmann break; 12750768e170SArnd Bergmann } 12760768e170SArnd Bergmann err = sock->ops->gettstamp(sock, argp, 12770768e170SArnd Bergmann cmd == SIOCGSTAMP_NEW, 12780768e170SArnd Bergmann false); 1279c7cbdbf2SArnd Bergmann break; 1280876f0bf9SArnd Bergmann 1281876f0bf9SArnd Bergmann case SIOCGIFCONF: 1282876f0bf9SArnd Bergmann err = dev_ifconf(net, argp); 1283876f0bf9SArnd Bergmann break; 1284876f0bf9SArnd Bergmann 12851da177e4SLinus Torvalds default: 128663ff03abSJohannes Berg err = sock_do_ioctl(net, sock, cmd, arg); 12871da177e4SLinus Torvalds break; 12881da177e4SLinus Torvalds } 12891da177e4SLinus Torvalds return err; 12901da177e4SLinus Torvalds } 12911da177e4SLinus Torvalds 12928a3c245cSPedro Tammela /** 12938a3c245cSPedro Tammela * sock_create_lite - creates a socket 12948a3c245cSPedro Tammela * @family: protocol family (AF_INET, ...) 12958a3c245cSPedro Tammela * @type: communication type (SOCK_STREAM, ...) 12968a3c245cSPedro Tammela * @protocol: protocol (0, ...) 12978a3c245cSPedro Tammela * @res: new socket 12988a3c245cSPedro Tammela * 12998a3c245cSPedro Tammela * Creates a new socket and assigns it to @res, passing through LSM. 13008a3c245cSPedro Tammela * The new socket initialization is not complete, see kernel_accept(). 13018a3c245cSPedro Tammela * Returns 0 or an error. On failure @res is set to %NULL. 13028a3c245cSPedro Tammela * This function internally uses GFP_KERNEL. 13038a3c245cSPedro Tammela */ 13048a3c245cSPedro Tammela 13051da177e4SLinus Torvalds int sock_create_lite(int family, int type, int protocol, struct socket **res) 13061da177e4SLinus Torvalds { 13071da177e4SLinus Torvalds int err; 13081da177e4SLinus Torvalds struct socket *sock = NULL; 13091da177e4SLinus Torvalds 13101da177e4SLinus Torvalds err = security_socket_create(family, type, protocol, 1); 13111da177e4SLinus Torvalds if (err) 13121da177e4SLinus Torvalds goto out; 13131da177e4SLinus Torvalds 13141da177e4SLinus Torvalds sock = sock_alloc(); 13151da177e4SLinus Torvalds if (!sock) { 13161da177e4SLinus Torvalds err = -ENOMEM; 13171da177e4SLinus Torvalds goto out; 13181da177e4SLinus Torvalds } 13191da177e4SLinus Torvalds 13201da177e4SLinus Torvalds sock->type = type; 13217420ed23SVenkat Yekkirala err = security_socket_post_create(sock, family, type, protocol, 1); 13227420ed23SVenkat Yekkirala if (err) 13237420ed23SVenkat Yekkirala goto out_release; 13247420ed23SVenkat Yekkirala 13251da177e4SLinus Torvalds out: 13261da177e4SLinus Torvalds *res = sock; 13271da177e4SLinus Torvalds return err; 13287420ed23SVenkat Yekkirala out_release: 13297420ed23SVenkat Yekkirala sock_release(sock); 13307420ed23SVenkat Yekkirala sock = NULL; 13317420ed23SVenkat Yekkirala goto out; 13321da177e4SLinus Torvalds } 1333c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_create_lite); 13341da177e4SLinus Torvalds 13351da177e4SLinus Torvalds /* No kernel lock held - perfect */ 1336ade994f4SAl Viro static __poll_t sock_poll(struct file *file, poll_table *wait) 13371da177e4SLinus Torvalds { 13383cafb376SChristoph Hellwig struct socket *sock = file->private_data; 1339a331de3bSChristoph Hellwig __poll_t events = poll_requested_events(wait), flag = 0; 13401da177e4SLinus Torvalds 1341e88958e6SChristoph Hellwig if (!sock->ops->poll) 1342e88958e6SChristoph Hellwig return 0; 1343f641f13bSChristoph Hellwig 1344a331de3bSChristoph Hellwig if (sk_can_busy_loop(sock->sk)) { 1345f641f13bSChristoph Hellwig /* poll once if requested by the syscall */ 1346a331de3bSChristoph Hellwig if (events & POLL_BUSY_LOOP) 1347f641f13bSChristoph Hellwig sk_busy_loop(sock->sk, 1); 1348a331de3bSChristoph Hellwig 1349a331de3bSChristoph Hellwig /* if this socket can poll_ll, tell the system call */ 1350a331de3bSChristoph Hellwig flag = POLL_BUSY_LOOP; 1351a331de3bSChristoph Hellwig } 1352a331de3bSChristoph Hellwig 1353a331de3bSChristoph Hellwig return sock->ops->poll(file, sock, wait) | flag; 13541da177e4SLinus Torvalds } 13551da177e4SLinus Torvalds 13561da177e4SLinus Torvalds static int sock_mmap(struct file *file, struct vm_area_struct *vma) 13571da177e4SLinus Torvalds { 1358b69aee04SEric Dumazet struct socket *sock = file->private_data; 13591da177e4SLinus Torvalds 13601da177e4SLinus Torvalds return sock->ops->mmap(file, sock, vma); 13611da177e4SLinus Torvalds } 13621da177e4SLinus Torvalds 136320380731SArnaldo Carvalho de Melo static int sock_close(struct inode *inode, struct file *filp) 13641da177e4SLinus Torvalds { 13656d8c50dcSCong Wang __sock_release(SOCKET_I(inode), inode); 13661da177e4SLinus Torvalds return 0; 13671da177e4SLinus Torvalds } 13681da177e4SLinus Torvalds 13691da177e4SLinus Torvalds /* 13701da177e4SLinus Torvalds * Update the socket async list 13711da177e4SLinus Torvalds * 13721da177e4SLinus Torvalds * Fasync_list locking strategy. 13731da177e4SLinus Torvalds * 13741da177e4SLinus Torvalds * 1. fasync_list is modified only under process context socket lock 13751da177e4SLinus Torvalds * i.e. under semaphore. 13761da177e4SLinus Torvalds * 2. fasync_list is used under read_lock(&sk->sk_callback_lock) 1377989a2979SEric Dumazet * or under socket lock 13781da177e4SLinus Torvalds */ 13791da177e4SLinus Torvalds 13801da177e4SLinus Torvalds static int sock_fasync(int fd, struct file *filp, int on) 13811da177e4SLinus Torvalds { 1382989a2979SEric Dumazet struct socket *sock = filp->private_data; 1383989a2979SEric Dumazet struct sock *sk = sock->sk; 1384333f7909SAl Viro struct socket_wq *wq = &sock->wq; 13851da177e4SLinus Torvalds 1386989a2979SEric Dumazet if (sk == NULL) 13871da177e4SLinus Torvalds return -EINVAL; 13881da177e4SLinus Torvalds 13891da177e4SLinus Torvalds lock_sock(sk); 1390eaefd110SEric Dumazet fasync_helper(fd, filp, on, &wq->fasync_list); 13911da177e4SLinus Torvalds 1392eaefd110SEric Dumazet if (!wq->fasync_list) 1393bcdce719SEric Dumazet sock_reset_flag(sk, SOCK_FASYNC); 1394989a2979SEric Dumazet else 1395989a2979SEric Dumazet sock_set_flag(sk, SOCK_FASYNC); 13961da177e4SLinus Torvalds 1397989a2979SEric Dumazet release_sock(sk); 13981da177e4SLinus Torvalds return 0; 13991da177e4SLinus Torvalds } 14001da177e4SLinus Torvalds 1401ceb5d58bSEric Dumazet /* This function may be called only under rcu_lock */ 14021da177e4SLinus Torvalds 1403ceb5d58bSEric Dumazet int sock_wake_async(struct socket_wq *wq, int how, int band) 14041da177e4SLinus Torvalds { 1405ceb5d58bSEric Dumazet if (!wq || !wq->fasync_list) 1406ceb5d58bSEric Dumazet return -1; 140743815482SEric Dumazet 140889bddce5SStephen Hemminger switch (how) { 14098d8ad9d7SPavel Emelyanov case SOCK_WAKE_WAITD: 1410ceb5d58bSEric Dumazet if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags)) 14111da177e4SLinus Torvalds break; 14121da177e4SLinus Torvalds goto call_kill; 14138d8ad9d7SPavel Emelyanov case SOCK_WAKE_SPACE: 1414ceb5d58bSEric Dumazet if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags)) 14151da177e4SLinus Torvalds break; 14167c7ab580SMiaohe Lin fallthrough; 14178d8ad9d7SPavel Emelyanov case SOCK_WAKE_IO: 14181da177e4SLinus Torvalds call_kill: 141943815482SEric Dumazet kill_fasync(&wq->fasync_list, SIGIO, band); 14201da177e4SLinus Torvalds break; 14218d8ad9d7SPavel Emelyanov case SOCK_WAKE_URG: 142243815482SEric Dumazet kill_fasync(&wq->fasync_list, SIGURG, band); 14231da177e4SLinus Torvalds } 1424ceb5d58bSEric Dumazet 14251da177e4SLinus Torvalds return 0; 14261da177e4SLinus Torvalds } 1427c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_wake_async); 14281da177e4SLinus Torvalds 14298a3c245cSPedro Tammela /** 14308a3c245cSPedro Tammela * __sock_create - creates a socket 14318a3c245cSPedro Tammela * @net: net namespace 14328a3c245cSPedro Tammela * @family: protocol family (AF_INET, ...) 14338a3c245cSPedro Tammela * @type: communication type (SOCK_STREAM, ...) 14348a3c245cSPedro Tammela * @protocol: protocol (0, ...) 14358a3c245cSPedro Tammela * @res: new socket 14368a3c245cSPedro Tammela * @kern: boolean for kernel space sockets 14378a3c245cSPedro Tammela * 14388a3c245cSPedro Tammela * Creates a new socket and assigns it to @res, passing through LSM. 14398a3c245cSPedro Tammela * Returns 0 or an error. On failure @res is set to %NULL. @kern must 14408a3c245cSPedro Tammela * be set to true if the socket resides in kernel space. 14418a3c245cSPedro Tammela * This function internally uses GFP_KERNEL. 14428a3c245cSPedro Tammela */ 14438a3c245cSPedro Tammela 1444721db93aSPavel Emelyanov int __sock_create(struct net *net, int family, int type, int protocol, 144589bddce5SStephen Hemminger struct socket **res, int kern) 14461da177e4SLinus Torvalds { 14471da177e4SLinus Torvalds int err; 14481da177e4SLinus Torvalds struct socket *sock; 144955737fdaSStephen Hemminger const struct net_proto_family *pf; 14501da177e4SLinus Torvalds 14511da177e4SLinus Torvalds /* 14521da177e4SLinus Torvalds * Check protocol is in range 14531da177e4SLinus Torvalds */ 14541da177e4SLinus Torvalds if (family < 0 || family >= NPROTO) 14551da177e4SLinus Torvalds return -EAFNOSUPPORT; 14561da177e4SLinus Torvalds if (type < 0 || type >= SOCK_MAX) 14571da177e4SLinus Torvalds return -EINVAL; 14581da177e4SLinus Torvalds 14591da177e4SLinus Torvalds /* Compatibility. 14601da177e4SLinus Torvalds 14611da177e4SLinus Torvalds This uglymoron is moved from INET layer to here to avoid 14621da177e4SLinus Torvalds deadlock in module load. 14631da177e4SLinus Torvalds */ 14641da177e4SLinus Torvalds if (family == PF_INET && type == SOCK_PACKET) { 1465f3c98690Sliping.zhang pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)\n", 146689bddce5SStephen Hemminger current->comm); 14671da177e4SLinus Torvalds family = PF_PACKET; 14681da177e4SLinus Torvalds } 14691da177e4SLinus Torvalds 14701da177e4SLinus Torvalds err = security_socket_create(family, type, protocol, kern); 14711da177e4SLinus Torvalds if (err) 14721da177e4SLinus Torvalds return err; 14731da177e4SLinus Torvalds 147455737fdaSStephen Hemminger /* 147555737fdaSStephen Hemminger * Allocate the socket and allow the family to set things up. if 147655737fdaSStephen Hemminger * the protocol is 0, the family is instructed to select an appropriate 147755737fdaSStephen Hemminger * default. 147855737fdaSStephen Hemminger */ 147955737fdaSStephen Hemminger sock = sock_alloc(); 148055737fdaSStephen Hemminger if (!sock) { 1481e87cc472SJoe Perches net_warn_ratelimited("socket: no more sockets\n"); 148255737fdaSStephen Hemminger return -ENFILE; /* Not exactly a match, but its the 148355737fdaSStephen Hemminger closest posix thing */ 148455737fdaSStephen Hemminger } 148555737fdaSStephen Hemminger 148655737fdaSStephen Hemminger sock->type = type; 148755737fdaSStephen Hemminger 148895a5afcaSJohannes Berg #ifdef CONFIG_MODULES 14891da177e4SLinus Torvalds /* Attempt to load a protocol module if the find failed. 14901da177e4SLinus Torvalds * 14911da177e4SLinus Torvalds * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user 14921da177e4SLinus Torvalds * requested real, full-featured networking support upon configuration. 14931da177e4SLinus Torvalds * Otherwise module support will break! 14941da177e4SLinus Torvalds */ 1495190683a9SEric Dumazet if (rcu_access_pointer(net_families[family]) == NULL) 14961da177e4SLinus Torvalds request_module("net-pf-%d", family); 14971da177e4SLinus Torvalds #endif 14981da177e4SLinus Torvalds 149955737fdaSStephen Hemminger rcu_read_lock(); 150055737fdaSStephen Hemminger pf = rcu_dereference(net_families[family]); 15011da177e4SLinus Torvalds err = -EAFNOSUPPORT; 150255737fdaSStephen Hemminger if (!pf) 150355737fdaSStephen Hemminger goto out_release; 15041da177e4SLinus Torvalds 15051da177e4SLinus Torvalds /* 15061da177e4SLinus Torvalds * We will call the ->create function, that possibly is in a loadable 15071da177e4SLinus Torvalds * module, so we have to bump that loadable module refcnt first. 15081da177e4SLinus Torvalds */ 150955737fdaSStephen Hemminger if (!try_module_get(pf->owner)) 15101da177e4SLinus Torvalds goto out_release; 15111da177e4SLinus Torvalds 151255737fdaSStephen Hemminger /* Now protected by module ref count */ 151355737fdaSStephen Hemminger rcu_read_unlock(); 151455737fdaSStephen Hemminger 15153f378b68SEric Paris err = pf->create(net, sock, protocol, kern); 151655737fdaSStephen Hemminger if (err < 0) 15171da177e4SLinus Torvalds goto out_module_put; 1518a79af59eSFrank Filz 15191da177e4SLinus Torvalds /* 15201da177e4SLinus Torvalds * Now to bump the refcnt of the [loadable] module that owns this 15211da177e4SLinus Torvalds * socket at sock_release time we decrement its refcnt. 15221da177e4SLinus Torvalds */ 152355737fdaSStephen Hemminger if (!try_module_get(sock->ops->owner)) 152455737fdaSStephen Hemminger goto out_module_busy; 152555737fdaSStephen Hemminger 15261da177e4SLinus Torvalds /* 15271da177e4SLinus Torvalds * Now that we're done with the ->create function, the [loadable] 15281da177e4SLinus Torvalds * module can have its refcnt decremented 15291da177e4SLinus Torvalds */ 153055737fdaSStephen Hemminger module_put(pf->owner); 15317420ed23SVenkat Yekkirala err = security_socket_post_create(sock, family, type, protocol, kern); 15327420ed23SVenkat Yekkirala if (err) 15333b185525SHerbert Xu goto out_sock_release; 153455737fdaSStephen Hemminger *res = sock; 15351da177e4SLinus Torvalds 153655737fdaSStephen Hemminger return 0; 153755737fdaSStephen Hemminger 153855737fdaSStephen Hemminger out_module_busy: 153955737fdaSStephen Hemminger err = -EAFNOSUPPORT; 15401da177e4SLinus Torvalds out_module_put: 154155737fdaSStephen Hemminger sock->ops = NULL; 154255737fdaSStephen Hemminger module_put(pf->owner); 154355737fdaSStephen Hemminger out_sock_release: 15441da177e4SLinus Torvalds sock_release(sock); 154555737fdaSStephen Hemminger return err; 154655737fdaSStephen Hemminger 154755737fdaSStephen Hemminger out_release: 154855737fdaSStephen Hemminger rcu_read_unlock(); 154955737fdaSStephen Hemminger goto out_sock_release; 15501da177e4SLinus Torvalds } 1551721db93aSPavel Emelyanov EXPORT_SYMBOL(__sock_create); 15521da177e4SLinus Torvalds 15538a3c245cSPedro Tammela /** 15548a3c245cSPedro Tammela * sock_create - creates a socket 15558a3c245cSPedro Tammela * @family: protocol family (AF_INET, ...) 15568a3c245cSPedro Tammela * @type: communication type (SOCK_STREAM, ...) 15578a3c245cSPedro Tammela * @protocol: protocol (0, ...) 15588a3c245cSPedro Tammela * @res: new socket 15598a3c245cSPedro Tammela * 15608a3c245cSPedro Tammela * A wrapper around __sock_create(). 15618a3c245cSPedro Tammela * Returns 0 or an error. This function internally uses GFP_KERNEL. 15628a3c245cSPedro Tammela */ 15638a3c245cSPedro Tammela 15641da177e4SLinus Torvalds int sock_create(int family, int type, int protocol, struct socket **res) 15651da177e4SLinus Torvalds { 15661b8d7ae4SEric W. Biederman return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0); 15671da177e4SLinus Torvalds } 1568c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_create); 15691da177e4SLinus Torvalds 15708a3c245cSPedro Tammela /** 15718a3c245cSPedro Tammela * sock_create_kern - creates a socket (kernel space) 15728a3c245cSPedro Tammela * @net: net namespace 15738a3c245cSPedro Tammela * @family: protocol family (AF_INET, ...) 15748a3c245cSPedro Tammela * @type: communication type (SOCK_STREAM, ...) 15758a3c245cSPedro Tammela * @protocol: protocol (0, ...) 15768a3c245cSPedro Tammela * @res: new socket 15778a3c245cSPedro Tammela * 15788a3c245cSPedro Tammela * A wrapper around __sock_create(). 15798a3c245cSPedro Tammela * Returns 0 or an error. This function internally uses GFP_KERNEL. 15808a3c245cSPedro Tammela */ 15818a3c245cSPedro Tammela 1582eeb1bd5cSEric W. Biederman int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res) 15831da177e4SLinus Torvalds { 1584eeb1bd5cSEric W. Biederman return __sock_create(net, family, type, protocol, res, 1); 15851da177e4SLinus Torvalds } 1586c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_create_kern); 15871da177e4SLinus Torvalds 1588da214a47SJens Axboe static struct socket *__sys_socket_create(int family, int type, int protocol) 15891da177e4SLinus Torvalds { 15901da177e4SLinus Torvalds struct socket *sock; 1591da214a47SJens Axboe int retval; 1592a677a039SUlrich Drepper 1593e38b36f3SUlrich Drepper /* Check the SOCK_* constants for consistency. */ 1594e38b36f3SUlrich Drepper BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC); 1595e38b36f3SUlrich Drepper BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK); 1596e38b36f3SUlrich Drepper BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK); 1597e38b36f3SUlrich Drepper BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK); 1598e38b36f3SUlrich Drepper 1599da214a47SJens Axboe if ((type & ~SOCK_TYPE_MASK) & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) 1600da214a47SJens Axboe return ERR_PTR(-EINVAL); 1601a677a039SUlrich Drepper type &= SOCK_TYPE_MASK; 16021da177e4SLinus Torvalds 16031da177e4SLinus Torvalds retval = sock_create(family, type, protocol, &sock); 16041da177e4SLinus Torvalds if (retval < 0) 1605da214a47SJens Axboe return ERR_PTR(retval); 1606da214a47SJens Axboe 1607da214a47SJens Axboe return sock; 1608da214a47SJens Axboe } 1609da214a47SJens Axboe 1610da214a47SJens Axboe struct file *__sys_socket_file(int family, int type, int protocol) 1611da214a47SJens Axboe { 1612da214a47SJens Axboe struct socket *sock; 1613da214a47SJens Axboe struct file *file; 1614da214a47SJens Axboe int flags; 1615da214a47SJens Axboe 1616da214a47SJens Axboe sock = __sys_socket_create(family, type, protocol); 1617da214a47SJens Axboe if (IS_ERR(sock)) 1618da214a47SJens Axboe return ERR_CAST(sock); 1619da214a47SJens Axboe 1620da214a47SJens Axboe flags = type & ~SOCK_TYPE_MASK; 1621da214a47SJens Axboe if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) 1622da214a47SJens Axboe flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; 1623da214a47SJens Axboe 1624da214a47SJens Axboe file = sock_alloc_file(sock, flags, NULL); 1625da214a47SJens Axboe if (IS_ERR(file)) 1626da214a47SJens Axboe sock_release(sock); 1627da214a47SJens Axboe 1628da214a47SJens Axboe return file; 1629da214a47SJens Axboe } 1630da214a47SJens Axboe 1631da214a47SJens Axboe int __sys_socket(int family, int type, int protocol) 1632da214a47SJens Axboe { 1633da214a47SJens Axboe struct socket *sock; 1634da214a47SJens Axboe int flags; 1635da214a47SJens Axboe 1636da214a47SJens Axboe sock = __sys_socket_create(family, type, protocol); 1637da214a47SJens Axboe if (IS_ERR(sock)) 1638da214a47SJens Axboe return PTR_ERR(sock); 1639da214a47SJens Axboe 1640da214a47SJens Axboe flags = type & ~SOCK_TYPE_MASK; 1641da214a47SJens Axboe if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) 1642da214a47SJens Axboe flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; 16431da177e4SLinus Torvalds 16448e1611e2SAl Viro return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK)); 16451da177e4SLinus Torvalds } 16461da177e4SLinus Torvalds 16479d6a15c3SDominik Brodowski SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) 16489d6a15c3SDominik Brodowski { 16499d6a15c3SDominik Brodowski return __sys_socket(family, type, protocol); 16509d6a15c3SDominik Brodowski } 16519d6a15c3SDominik Brodowski 16521da177e4SLinus Torvalds /* 16531da177e4SLinus Torvalds * Create a pair of connected sockets. 16541da177e4SLinus Torvalds */ 16551da177e4SLinus Torvalds 16566debc8d8SDominik Brodowski int __sys_socketpair(int family, int type, int protocol, int __user *usockvec) 16571da177e4SLinus Torvalds { 16581da177e4SLinus Torvalds struct socket *sock1, *sock2; 16591da177e4SLinus Torvalds int fd1, fd2, err; 1660db349509SAl Viro struct file *newfile1, *newfile2; 1661a677a039SUlrich Drepper int flags; 1662a677a039SUlrich Drepper 1663a677a039SUlrich Drepper flags = type & ~SOCK_TYPE_MASK; 166477d27200SUlrich Drepper if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) 1665a677a039SUlrich Drepper return -EINVAL; 1666a677a039SUlrich Drepper type &= SOCK_TYPE_MASK; 16671da177e4SLinus Torvalds 1668aaca0bdcSUlrich Drepper if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) 1669aaca0bdcSUlrich Drepper flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; 1670aaca0bdcSUlrich Drepper 16711da177e4SLinus Torvalds /* 1672016a266bSAl Viro * reserve descriptors and make sure we won't fail 1673016a266bSAl Viro * to return them to userland. 1674016a266bSAl Viro */ 1675016a266bSAl Viro fd1 = get_unused_fd_flags(flags); 1676016a266bSAl Viro if (unlikely(fd1 < 0)) 1677016a266bSAl Viro return fd1; 1678016a266bSAl Viro 1679016a266bSAl Viro fd2 = get_unused_fd_flags(flags); 1680016a266bSAl Viro if (unlikely(fd2 < 0)) { 1681016a266bSAl Viro put_unused_fd(fd1); 1682016a266bSAl Viro return fd2; 1683016a266bSAl Viro } 1684016a266bSAl Viro 1685016a266bSAl Viro err = put_user(fd1, &usockvec[0]); 1686016a266bSAl Viro if (err) 1687016a266bSAl Viro goto out; 1688016a266bSAl Viro 1689016a266bSAl Viro err = put_user(fd2, &usockvec[1]); 1690016a266bSAl Viro if (err) 1691016a266bSAl Viro goto out; 1692016a266bSAl Viro 1693016a266bSAl Viro /* 16941da177e4SLinus Torvalds * Obtain the first socket and check if the underlying protocol 16951da177e4SLinus Torvalds * supports the socketpair call. 16961da177e4SLinus Torvalds */ 16971da177e4SLinus Torvalds 16981da177e4SLinus Torvalds err = sock_create(family, type, protocol, &sock1); 1699016a266bSAl Viro if (unlikely(err < 0)) 17001da177e4SLinus Torvalds goto out; 17011da177e4SLinus Torvalds 17021da177e4SLinus Torvalds err = sock_create(family, type, protocol, &sock2); 1703016a266bSAl Viro if (unlikely(err < 0)) { 1704016a266bSAl Viro sock_release(sock1); 1705016a266bSAl Viro goto out; 1706bf3c23d1SDavid S. Miller } 1707d73aa286SYann Droneaud 1708d47cd945SDavid Herrmann err = security_socket_socketpair(sock1, sock2); 1709d47cd945SDavid Herrmann if (unlikely(err)) { 1710d47cd945SDavid Herrmann sock_release(sock2); 1711d47cd945SDavid Herrmann sock_release(sock1); 1712d47cd945SDavid Herrmann goto out; 1713d47cd945SDavid Herrmann } 1714d47cd945SDavid Herrmann 1715016a266bSAl Viro err = sock1->ops->socketpair(sock1, sock2); 1716016a266bSAl Viro if (unlikely(err < 0)) { 1717016a266bSAl Viro sock_release(sock2); 1718016a266bSAl Viro sock_release(sock1); 1719016a266bSAl Viro goto out; 172028407630SAl Viro } 172128407630SAl Viro 1722aab174f0SLinus Torvalds newfile1 = sock_alloc_file(sock1, flags, NULL); 1723b5ffe634SViresh Kumar if (IS_ERR(newfile1)) { 172428407630SAl Viro err = PTR_ERR(newfile1); 1725016a266bSAl Viro sock_release(sock2); 1726016a266bSAl Viro goto out; 172728407630SAl Viro } 172828407630SAl Viro 1729aab174f0SLinus Torvalds newfile2 = sock_alloc_file(sock2, flags, NULL); 173028407630SAl Viro if (IS_ERR(newfile2)) { 173128407630SAl Viro err = PTR_ERR(newfile2); 1732016a266bSAl Viro fput(newfile1); 1733016a266bSAl Viro goto out; 1734db349509SAl Viro } 1735db349509SAl Viro 1736157cf649SAl Viro audit_fd_pair(fd1, fd2); 1737d73aa286SYann Droneaud 1738db349509SAl Viro fd_install(fd1, newfile1); 1739db349509SAl Viro fd_install(fd2, newfile2); 17401da177e4SLinus Torvalds return 0; 17411da177e4SLinus Torvalds 17421da177e4SLinus Torvalds out: 1743016a266bSAl Viro put_unused_fd(fd2); 1744016a266bSAl Viro put_unused_fd(fd1); 17451da177e4SLinus Torvalds return err; 17461da177e4SLinus Torvalds } 17471da177e4SLinus Torvalds 17486debc8d8SDominik Brodowski SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, 17496debc8d8SDominik Brodowski int __user *, usockvec) 17506debc8d8SDominik Brodowski { 17516debc8d8SDominik Brodowski return __sys_socketpair(family, type, protocol, usockvec); 17526debc8d8SDominik Brodowski } 17536debc8d8SDominik Brodowski 17541da177e4SLinus Torvalds /* 17551da177e4SLinus Torvalds * Bind a name to a socket. Nothing much to do here since it's 17561da177e4SLinus Torvalds * the protocol's responsibility to handle the local address. 17571da177e4SLinus Torvalds * 17581da177e4SLinus Torvalds * We move the socket address to kernel space before we call 17591da177e4SLinus Torvalds * the protocol layer (having also checked the address is ok). 17601da177e4SLinus Torvalds */ 17611da177e4SLinus Torvalds 1762a87d35d8SDominik Brodowski int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen) 17631da177e4SLinus Torvalds { 17641da177e4SLinus Torvalds struct socket *sock; 1765230b1839SYOSHIFUJI Hideaki struct sockaddr_storage address; 17666cb153caSBenjamin LaHaise int err, fput_needed; 17671da177e4SLinus Torvalds 176889bddce5SStephen Hemminger sock = sockfd_lookup_light(fd, &err, &fput_needed); 176989bddce5SStephen Hemminger if (sock) { 177043db362dSMaciej Żenczykowski err = move_addr_to_kernel(umyaddr, addrlen, &address); 1771068b88ccSJakub Sitnicki if (!err) { 177289bddce5SStephen Hemminger err = security_socket_bind(sock, 1773230b1839SYOSHIFUJI Hideaki (struct sockaddr *)&address, 177489bddce5SStephen Hemminger addrlen); 17756cb153caSBenjamin LaHaise if (!err) 17766cb153caSBenjamin LaHaise err = sock->ops->bind(sock, 177789bddce5SStephen Hemminger (struct sockaddr *) 1778230b1839SYOSHIFUJI Hideaki &address, addrlen); 17791da177e4SLinus Torvalds } 17806cb153caSBenjamin LaHaise fput_light(sock->file, fput_needed); 17811da177e4SLinus Torvalds } 17821da177e4SLinus Torvalds return err; 17831da177e4SLinus Torvalds } 17841da177e4SLinus Torvalds 1785a87d35d8SDominik Brodowski SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) 1786a87d35d8SDominik Brodowski { 1787a87d35d8SDominik Brodowski return __sys_bind(fd, umyaddr, addrlen); 1788a87d35d8SDominik Brodowski } 1789a87d35d8SDominik Brodowski 17901da177e4SLinus Torvalds /* 17911da177e4SLinus Torvalds * Perform a listen. Basically, we allow the protocol to do anything 17921da177e4SLinus Torvalds * necessary for a listen, and if that works, we mark the socket as 17931da177e4SLinus Torvalds * ready for listening. 17941da177e4SLinus Torvalds */ 17951da177e4SLinus Torvalds 179625e290eeSDominik Brodowski int __sys_listen(int fd, int backlog) 17971da177e4SLinus Torvalds { 17981da177e4SLinus Torvalds struct socket *sock; 17996cb153caSBenjamin LaHaise int err, fput_needed; 1800b8e1f9b5SPavel Emelyanov int somaxconn; 18011da177e4SLinus Torvalds 180289bddce5SStephen Hemminger sock = sockfd_lookup_light(fd, &err, &fput_needed); 180389bddce5SStephen Hemminger if (sock) { 18043c9ba81dSKuniyuki Iwashima somaxconn = READ_ONCE(sock_net(sock->sk)->core.sysctl_somaxconn); 180595c96174SEric Dumazet if ((unsigned int)backlog > somaxconn) 1806b8e1f9b5SPavel Emelyanov backlog = somaxconn; 18071da177e4SLinus Torvalds 18081da177e4SLinus Torvalds err = security_socket_listen(sock, backlog); 18096cb153caSBenjamin LaHaise if (!err) 18101da177e4SLinus Torvalds err = sock->ops->listen(sock, backlog); 18116cb153caSBenjamin LaHaise 18126cb153caSBenjamin LaHaise fput_light(sock->file, fput_needed); 18131da177e4SLinus Torvalds } 18141da177e4SLinus Torvalds return err; 18151da177e4SLinus Torvalds } 18161da177e4SLinus Torvalds 181725e290eeSDominik Brodowski SYSCALL_DEFINE2(listen, int, fd, int, backlog) 181825e290eeSDominik Brodowski { 181925e290eeSDominik Brodowski return __sys_listen(fd, backlog); 182025e290eeSDominik Brodowski } 182125e290eeSDominik Brodowski 1822d32f89daSPavel Begunkov struct file *do_accept(struct file *file, unsigned file_flags, 1823de2ea4b6SJens Axboe struct sockaddr __user *upeer_sockaddr, 1824d32f89daSPavel Begunkov int __user *upeer_addrlen, int flags) 18251da177e4SLinus Torvalds { 18261da177e4SLinus Torvalds struct socket *sock, *newsock; 182739d8c1b6SDavid S. Miller struct file *newfile; 1828d32f89daSPavel Begunkov int err, len; 1829230b1839SYOSHIFUJI Hideaki struct sockaddr_storage address; 18301da177e4SLinus Torvalds 1831dba4a925SFlorent Revest sock = sock_from_file(file); 1832d32f89daSPavel Begunkov if (!sock) 1833d32f89daSPavel Begunkov return ERR_PTR(-ENOTSOCK); 18341da177e4SLinus Torvalds 1835c6d409cfSEric Dumazet newsock = sock_alloc(); 1836c6d409cfSEric Dumazet if (!newsock) 1837d32f89daSPavel Begunkov return ERR_PTR(-ENFILE); 18381da177e4SLinus Torvalds 18391da177e4SLinus Torvalds newsock->type = sock->type; 18401da177e4SLinus Torvalds newsock->ops = sock->ops; 18411da177e4SLinus Torvalds 18421da177e4SLinus Torvalds /* 18431da177e4SLinus Torvalds * We don't need try_module_get here, as the listening socket (sock) 18441da177e4SLinus Torvalds * has the protocol module (sock->ops->owner) held. 18451da177e4SLinus Torvalds */ 18461da177e4SLinus Torvalds __module_get(newsock->ops->owner); 18471da177e4SLinus Torvalds 1848aab174f0SLinus Torvalds newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name); 1849d32f89daSPavel Begunkov if (IS_ERR(newfile)) 1850d32f89daSPavel Begunkov return newfile; 185139d8c1b6SDavid S. Miller 1852a79af59eSFrank Filz err = security_socket_accept(sock, newsock); 1853a79af59eSFrank Filz if (err) 185439d8c1b6SDavid S. Miller goto out_fd; 1855a79af59eSFrank Filz 1856de2ea4b6SJens Axboe err = sock->ops->accept(sock, newsock, sock->file->f_flags | file_flags, 1857de2ea4b6SJens Axboe false); 18581da177e4SLinus Torvalds if (err < 0) 185939d8c1b6SDavid S. Miller goto out_fd; 18601da177e4SLinus Torvalds 18611da177e4SLinus Torvalds if (upeer_sockaddr) { 18629b2c45d4SDenys Vlasenko len = newsock->ops->getname(newsock, 18639b2c45d4SDenys Vlasenko (struct sockaddr *)&address, 2); 18649b2c45d4SDenys Vlasenko if (len < 0) { 18651da177e4SLinus Torvalds err = -ECONNABORTED; 186639d8c1b6SDavid S. Miller goto out_fd; 18671da177e4SLinus Torvalds } 186843db362dSMaciej Żenczykowski err = move_addr_to_user(&address, 1869230b1839SYOSHIFUJI Hideaki len, upeer_sockaddr, upeer_addrlen); 18701da177e4SLinus Torvalds if (err < 0) 187139d8c1b6SDavid S. Miller goto out_fd; 18721da177e4SLinus Torvalds } 18731da177e4SLinus Torvalds 18741da177e4SLinus Torvalds /* File flags are not inherited via accept() unlike another OSes. */ 1875d32f89daSPavel Begunkov return newfile; 187639d8c1b6SDavid S. Miller out_fd: 18779606a216SDavid S. Miller fput(newfile); 1878d32f89daSPavel Begunkov return ERR_PTR(err); 1879d32f89daSPavel Begunkov } 1880de2ea4b6SJens Axboe 1881c0424532SYajun Deng static int __sys_accept4_file(struct file *file, struct sockaddr __user *upeer_sockaddr, 1882c0424532SYajun Deng int __user *upeer_addrlen, int flags) 1883d32f89daSPavel Begunkov { 1884d32f89daSPavel Begunkov struct file *newfile; 1885d32f89daSPavel Begunkov int newfd; 1886d32f89daSPavel Begunkov 1887d32f89daSPavel Begunkov if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) 1888d32f89daSPavel Begunkov return -EINVAL; 1889d32f89daSPavel Begunkov 1890d32f89daSPavel Begunkov if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) 1891d32f89daSPavel Begunkov flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; 1892d32f89daSPavel Begunkov 1893c0424532SYajun Deng newfd = get_unused_fd_flags(flags); 1894d32f89daSPavel Begunkov if (unlikely(newfd < 0)) 1895d32f89daSPavel Begunkov return newfd; 1896d32f89daSPavel Begunkov 1897c0424532SYajun Deng newfile = do_accept(file, 0, upeer_sockaddr, upeer_addrlen, 1898d32f89daSPavel Begunkov flags); 1899d32f89daSPavel Begunkov if (IS_ERR(newfile)) { 1900d32f89daSPavel Begunkov put_unused_fd(newfd); 1901d32f89daSPavel Begunkov return PTR_ERR(newfile); 1902d32f89daSPavel Begunkov } 1903d32f89daSPavel Begunkov fd_install(newfd, newfile); 1904d32f89daSPavel Begunkov return newfd; 1905de2ea4b6SJens Axboe } 1906de2ea4b6SJens Axboe 1907de2ea4b6SJens Axboe /* 1908de2ea4b6SJens Axboe * For accept, we attempt to create a new socket, set up the link 1909de2ea4b6SJens Axboe * with the client, wake up the client, then return the new 1910de2ea4b6SJens Axboe * connected fd. We collect the address of the connector in kernel 1911de2ea4b6SJens Axboe * space and move it to user at the very end. This is unclean because 1912de2ea4b6SJens Axboe * we open the socket then return an error. 1913de2ea4b6SJens Axboe * 1914de2ea4b6SJens Axboe * 1003.1g adds the ability to recvmsg() to query connection pending 1915de2ea4b6SJens Axboe * status to recvmsg. We need to add that support in a way thats 1916de2ea4b6SJens Axboe * clean when we restructure accept also. 1917de2ea4b6SJens Axboe */ 1918de2ea4b6SJens Axboe 1919de2ea4b6SJens Axboe int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, 1920de2ea4b6SJens Axboe int __user *upeer_addrlen, int flags) 1921de2ea4b6SJens Axboe { 1922de2ea4b6SJens Axboe int ret = -EBADF; 1923de2ea4b6SJens Axboe struct fd f; 1924de2ea4b6SJens Axboe 1925de2ea4b6SJens Axboe f = fdget(fd); 1926de2ea4b6SJens Axboe if (f.file) { 1927c0424532SYajun Deng ret = __sys_accept4_file(f.file, upeer_sockaddr, 1928c0424532SYajun Deng upeer_addrlen, flags); 19296b07edebSMiaohe Lin fdput(f); 1930de2ea4b6SJens Axboe } 1931de2ea4b6SJens Axboe 1932de2ea4b6SJens Axboe return ret; 19331da177e4SLinus Torvalds } 19341da177e4SLinus Torvalds 19354541e805SDominik Brodowski SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, 19364541e805SDominik Brodowski int __user *, upeer_addrlen, int, flags) 19374541e805SDominik Brodowski { 19384541e805SDominik Brodowski return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, flags); 19394541e805SDominik Brodowski } 19404541e805SDominik Brodowski 194120f37034SHeiko Carstens SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr, 194220f37034SHeiko Carstens int __user *, upeer_addrlen) 1943aaca0bdcSUlrich Drepper { 19444541e805SDominik Brodowski return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0); 1945aaca0bdcSUlrich Drepper } 1946aaca0bdcSUlrich Drepper 19471da177e4SLinus Torvalds /* 19481da177e4SLinus Torvalds * Attempt to connect to a socket with the server address. The address 19491da177e4SLinus Torvalds * is in user space so we verify it is OK and move it to kernel space. 19501da177e4SLinus Torvalds * 19511da177e4SLinus Torvalds * For 1003.1g we need to add clean support for a bind to AF_UNSPEC to 19521da177e4SLinus Torvalds * break bindings 19531da177e4SLinus Torvalds * 19541da177e4SLinus Torvalds * NOTE: 1003.1g draft 6.3 is broken with respect to AX.25/NetROM and 19551da177e4SLinus Torvalds * other SEQPACKET protocols that take time to connect() as it doesn't 19561da177e4SLinus Torvalds * include the -EINPROGRESS status for such sockets. 19571da177e4SLinus Torvalds */ 19581da177e4SLinus Torvalds 1959f499a021SJens Axboe int __sys_connect_file(struct file *file, struct sockaddr_storage *address, 1960bd3ded31SJens Axboe int addrlen, int file_flags) 19611da177e4SLinus Torvalds { 19621da177e4SLinus Torvalds struct socket *sock; 1963bd3ded31SJens Axboe int err; 19641da177e4SLinus Torvalds 1965dba4a925SFlorent Revest sock = sock_from_file(file); 1966dba4a925SFlorent Revest if (!sock) { 1967dba4a925SFlorent Revest err = -ENOTSOCK; 19681da177e4SLinus Torvalds goto out; 1969dba4a925SFlorent Revest } 19701da177e4SLinus Torvalds 197189bddce5SStephen Hemminger err = 1972f499a021SJens Axboe security_socket_connect(sock, (struct sockaddr *)address, addrlen); 19731da177e4SLinus Torvalds if (err) 1974bd3ded31SJens Axboe goto out; 19751da177e4SLinus Torvalds 1976f499a021SJens Axboe err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen, 1977bd3ded31SJens Axboe sock->file->f_flags | file_flags); 19781da177e4SLinus Torvalds out: 19791da177e4SLinus Torvalds return err; 19801da177e4SLinus Torvalds } 19811da177e4SLinus Torvalds 1982bd3ded31SJens Axboe int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen) 1983bd3ded31SJens Axboe { 1984bd3ded31SJens Axboe int ret = -EBADF; 1985bd3ded31SJens Axboe struct fd f; 1986bd3ded31SJens Axboe 1987bd3ded31SJens Axboe f = fdget(fd); 1988bd3ded31SJens Axboe if (f.file) { 1989f499a021SJens Axboe struct sockaddr_storage address; 1990f499a021SJens Axboe 1991f499a021SJens Axboe ret = move_addr_to_kernel(uservaddr, addrlen, &address); 1992f499a021SJens Axboe if (!ret) 1993f499a021SJens Axboe ret = __sys_connect_file(f.file, &address, addrlen, 0); 19946b07edebSMiaohe Lin fdput(f); 1995bd3ded31SJens Axboe } 1996bd3ded31SJens Axboe 1997bd3ded31SJens Axboe return ret; 1998bd3ded31SJens Axboe } 1999bd3ded31SJens Axboe 20001387c2c2SDominik Brodowski SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, 20011387c2c2SDominik Brodowski int, addrlen) 20021387c2c2SDominik Brodowski { 20031387c2c2SDominik Brodowski return __sys_connect(fd, uservaddr, addrlen); 20041387c2c2SDominik Brodowski } 20051387c2c2SDominik Brodowski 20061da177e4SLinus Torvalds /* 20071da177e4SLinus Torvalds * Get the local address ('name') of a socket object. Move the obtained 20081da177e4SLinus Torvalds * name to user space. 20091da177e4SLinus Torvalds */ 20101da177e4SLinus Torvalds 20118882a107SDominik Brodowski int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, 20128882a107SDominik Brodowski int __user *usockaddr_len) 20131da177e4SLinus Torvalds { 20141da177e4SLinus Torvalds struct socket *sock; 2015230b1839SYOSHIFUJI Hideaki struct sockaddr_storage address; 20169b2c45d4SDenys Vlasenko int err, fput_needed; 20171da177e4SLinus Torvalds 20186cb153caSBenjamin LaHaise sock = sockfd_lookup_light(fd, &err, &fput_needed); 20191da177e4SLinus Torvalds if (!sock) 20201da177e4SLinus Torvalds goto out; 20211da177e4SLinus Torvalds 20221da177e4SLinus Torvalds err = security_socket_getsockname(sock); 20231da177e4SLinus Torvalds if (err) 20241da177e4SLinus Torvalds goto out_put; 20251da177e4SLinus Torvalds 20269b2c45d4SDenys Vlasenko err = sock->ops->getname(sock, (struct sockaddr *)&address, 0); 20279b2c45d4SDenys Vlasenko if (err < 0) 20281da177e4SLinus Torvalds goto out_put; 20299b2c45d4SDenys Vlasenko /* "err" is actually length in this case */ 20309b2c45d4SDenys Vlasenko err = move_addr_to_user(&address, err, usockaddr, usockaddr_len); 20311da177e4SLinus Torvalds 20321da177e4SLinus Torvalds out_put: 20336cb153caSBenjamin LaHaise fput_light(sock->file, fput_needed); 20341da177e4SLinus Torvalds out: 20351da177e4SLinus Torvalds return err; 20361da177e4SLinus Torvalds } 20371da177e4SLinus Torvalds 20388882a107SDominik Brodowski SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, 20398882a107SDominik Brodowski int __user *, usockaddr_len) 20408882a107SDominik Brodowski { 20418882a107SDominik Brodowski return __sys_getsockname(fd, usockaddr, usockaddr_len); 20428882a107SDominik Brodowski } 20438882a107SDominik Brodowski 20441da177e4SLinus Torvalds /* 20451da177e4SLinus Torvalds * Get the remote address ('name') of a socket object. Move the obtained 20461da177e4SLinus Torvalds * name to user space. 20471da177e4SLinus Torvalds */ 20481da177e4SLinus Torvalds 2049b21c8f83SDominik Brodowski int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, 2050b21c8f83SDominik Brodowski int __user *usockaddr_len) 20511da177e4SLinus Torvalds { 20521da177e4SLinus Torvalds struct socket *sock; 2053230b1839SYOSHIFUJI Hideaki struct sockaddr_storage address; 20549b2c45d4SDenys Vlasenko int err, fput_needed; 20551da177e4SLinus Torvalds 205689bddce5SStephen Hemminger sock = sockfd_lookup_light(fd, &err, &fput_needed); 205789bddce5SStephen Hemminger if (sock != NULL) { 20581da177e4SLinus Torvalds err = security_socket_getpeername(sock); 20591da177e4SLinus Torvalds if (err) { 20606cb153caSBenjamin LaHaise fput_light(sock->file, fput_needed); 20611da177e4SLinus Torvalds return err; 20621da177e4SLinus Torvalds } 20631da177e4SLinus Torvalds 20649b2c45d4SDenys Vlasenko err = sock->ops->getname(sock, (struct sockaddr *)&address, 1); 20659b2c45d4SDenys Vlasenko if (err >= 0) 20669b2c45d4SDenys Vlasenko /* "err" is actually length in this case */ 20679b2c45d4SDenys Vlasenko err = move_addr_to_user(&address, err, usockaddr, 206889bddce5SStephen Hemminger usockaddr_len); 20696cb153caSBenjamin LaHaise fput_light(sock->file, fput_needed); 20701da177e4SLinus Torvalds } 20711da177e4SLinus Torvalds return err; 20721da177e4SLinus Torvalds } 20731da177e4SLinus Torvalds 2074b21c8f83SDominik Brodowski SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, 2075b21c8f83SDominik Brodowski int __user *, usockaddr_len) 2076b21c8f83SDominik Brodowski { 2077b21c8f83SDominik Brodowski return __sys_getpeername(fd, usockaddr, usockaddr_len); 2078b21c8f83SDominik Brodowski } 2079b21c8f83SDominik Brodowski 20801da177e4SLinus Torvalds /* 20811da177e4SLinus Torvalds * Send a datagram to a given address. We move the address into kernel 20821da177e4SLinus Torvalds * space and check the user space data area is readable before invoking 20831da177e4SLinus Torvalds * the protocol. 20841da177e4SLinus Torvalds */ 2085211b634bSDominik Brodowski int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags, 2086211b634bSDominik Brodowski struct sockaddr __user *addr, int addr_len) 20871da177e4SLinus Torvalds { 20881da177e4SLinus Torvalds struct socket *sock; 2089230b1839SYOSHIFUJI Hideaki struct sockaddr_storage address; 20901da177e4SLinus Torvalds int err; 20911da177e4SLinus Torvalds struct msghdr msg; 20921da177e4SLinus Torvalds struct iovec iov; 20936cb153caSBenjamin LaHaise int fput_needed; 20941da177e4SLinus Torvalds 2095*de4eda9dSAl Viro err = import_single_range(ITER_SOURCE, buff, len, &iov, &msg.msg_iter); 2096602bd0e9SAl Viro if (unlikely(err)) 2097602bd0e9SAl Viro return err; 2098de0fa95cSPavel Emelyanov sock = sockfd_lookup_light(fd, &err, &fput_needed); 2099de0fa95cSPavel Emelyanov if (!sock) 21004387ff75SDavid S. Miller goto out; 21016cb153caSBenjamin LaHaise 21021da177e4SLinus Torvalds msg.msg_name = NULL; 21031da177e4SLinus Torvalds msg.msg_control = NULL; 21041da177e4SLinus Torvalds msg.msg_controllen = 0; 21051da177e4SLinus Torvalds msg.msg_namelen = 0; 21067c701d92SPavel Begunkov msg.msg_ubuf = NULL; 21076cb153caSBenjamin LaHaise if (addr) { 210843db362dSMaciej Żenczykowski err = move_addr_to_kernel(addr, addr_len, &address); 21091da177e4SLinus Torvalds if (err < 0) 21101da177e4SLinus Torvalds goto out_put; 2111230b1839SYOSHIFUJI Hideaki msg.msg_name = (struct sockaddr *)&address; 21121da177e4SLinus Torvalds msg.msg_namelen = addr_len; 21131da177e4SLinus Torvalds } 21141da177e4SLinus Torvalds if (sock->file->f_flags & O_NONBLOCK) 21151da177e4SLinus Torvalds flags |= MSG_DONTWAIT; 21161da177e4SLinus Torvalds msg.msg_flags = flags; 2117d8725c86SAl Viro err = sock_sendmsg(sock, &msg); 21181da177e4SLinus Torvalds 21191da177e4SLinus Torvalds out_put: 2120de0fa95cSPavel Emelyanov fput_light(sock->file, fput_needed); 21214387ff75SDavid S. Miller out: 21221da177e4SLinus Torvalds return err; 21231da177e4SLinus Torvalds } 21241da177e4SLinus Torvalds 2125211b634bSDominik Brodowski SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, 2126211b634bSDominik Brodowski unsigned int, flags, struct sockaddr __user *, addr, 2127211b634bSDominik Brodowski int, addr_len) 2128211b634bSDominik Brodowski { 2129211b634bSDominik Brodowski return __sys_sendto(fd, buff, len, flags, addr, addr_len); 2130211b634bSDominik Brodowski } 2131211b634bSDominik Brodowski 21321da177e4SLinus Torvalds /* 21331da177e4SLinus Torvalds * Send a datagram down a socket. 21341da177e4SLinus Torvalds */ 21351da177e4SLinus Torvalds 21363e0fa65fSHeiko Carstens SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len, 213795c96174SEric Dumazet unsigned int, flags) 21381da177e4SLinus Torvalds { 2139211b634bSDominik Brodowski return __sys_sendto(fd, buff, len, flags, NULL, 0); 21401da177e4SLinus Torvalds } 21411da177e4SLinus Torvalds 21421da177e4SLinus Torvalds /* 21431da177e4SLinus Torvalds * Receive a frame from the socket and optionally record the address of the 21441da177e4SLinus Torvalds * sender. We verify the buffers are writable and if needed move the 21451da177e4SLinus Torvalds * sender address from kernel to user space. 21461da177e4SLinus Torvalds */ 21477a09e1ebSDominik Brodowski int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags, 21487a09e1ebSDominik Brodowski struct sockaddr __user *addr, int __user *addr_len) 21491da177e4SLinus Torvalds { 21501228b34cSEric Dumazet struct sockaddr_storage address; 21511228b34cSEric Dumazet struct msghdr msg = { 21521228b34cSEric Dumazet /* Save some cycles and don't copy the address if not needed */ 21531228b34cSEric Dumazet .msg_name = addr ? (struct sockaddr *)&address : NULL, 21541228b34cSEric Dumazet }; 21551da177e4SLinus Torvalds struct socket *sock; 21561da177e4SLinus Torvalds struct iovec iov; 21571da177e4SLinus Torvalds int err, err2; 21586cb153caSBenjamin LaHaise int fput_needed; 21591da177e4SLinus Torvalds 2160*de4eda9dSAl Viro err = import_single_range(ITER_DEST, ubuf, size, &iov, &msg.msg_iter); 2161602bd0e9SAl Viro if (unlikely(err)) 2162602bd0e9SAl Viro return err; 2163de0fa95cSPavel Emelyanov sock = sockfd_lookup_light(fd, &err, &fput_needed); 21641da177e4SLinus Torvalds if (!sock) 2165de0fa95cSPavel Emelyanov goto out; 21661da177e4SLinus Torvalds 21671da177e4SLinus Torvalds if (sock->file->f_flags & O_NONBLOCK) 21681da177e4SLinus Torvalds flags |= MSG_DONTWAIT; 21692da62906SAl Viro err = sock_recvmsg(sock, &msg, flags); 21701da177e4SLinus Torvalds 217189bddce5SStephen Hemminger if (err >= 0 && addr != NULL) { 217243db362dSMaciej Żenczykowski err2 = move_addr_to_user(&address, 2173230b1839SYOSHIFUJI Hideaki msg.msg_namelen, addr, addr_len); 21741da177e4SLinus Torvalds if (err2 < 0) 21751da177e4SLinus Torvalds err = err2; 21761da177e4SLinus Torvalds } 2177de0fa95cSPavel Emelyanov 2178de0fa95cSPavel Emelyanov fput_light(sock->file, fput_needed); 21794387ff75SDavid S. Miller out: 21801da177e4SLinus Torvalds return err; 21811da177e4SLinus Torvalds } 21821da177e4SLinus Torvalds 21837a09e1ebSDominik Brodowski SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, 21847a09e1ebSDominik Brodowski unsigned int, flags, struct sockaddr __user *, addr, 21857a09e1ebSDominik Brodowski int __user *, addr_len) 21867a09e1ebSDominik Brodowski { 21877a09e1ebSDominik Brodowski return __sys_recvfrom(fd, ubuf, size, flags, addr, addr_len); 21887a09e1ebSDominik Brodowski } 21897a09e1ebSDominik Brodowski 21901da177e4SLinus Torvalds /* 21911da177e4SLinus Torvalds * Receive a datagram from a socket. 21921da177e4SLinus Torvalds */ 21931da177e4SLinus Torvalds 2194b7c0ddf5SJan Glauber SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size, 2195b7c0ddf5SJan Glauber unsigned int, flags) 21961da177e4SLinus Torvalds { 21977a09e1ebSDominik Brodowski return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL); 21981da177e4SLinus Torvalds } 21991da177e4SLinus Torvalds 220083f0c10bSFlorian Westphal static bool sock_use_custom_sol_socket(const struct socket *sock) 220183f0c10bSFlorian Westphal { 220283f0c10bSFlorian Westphal const struct sock *sk = sock->sk; 220383f0c10bSFlorian Westphal 220483f0c10bSFlorian Westphal /* Use sock->ops->setsockopt() for MPTCP */ 220583f0c10bSFlorian Westphal return IS_ENABLED(CONFIG_MPTCP) && 220683f0c10bSFlorian Westphal sk->sk_protocol == IPPROTO_MPTCP && 220783f0c10bSFlorian Westphal sk->sk_type == SOCK_STREAM && 220883f0c10bSFlorian Westphal (sk->sk_family == AF_INET || sk->sk_family == AF_INET6); 220983f0c10bSFlorian Westphal } 221083f0c10bSFlorian Westphal 22111da177e4SLinus Torvalds /* 22121da177e4SLinus Torvalds * Set a socket option. Because we don't know the option lengths we have 22131da177e4SLinus Torvalds * to pass the user mode parameter for the protocols to sort out. 22141da177e4SLinus Torvalds */ 2215a7b75c5aSChristoph Hellwig int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval, 221655db9c0eSChristoph Hellwig int optlen) 22171da177e4SLinus Torvalds { 2218519a8a6cSChristoph Hellwig sockptr_t optval = USER_SOCKPTR(user_optval); 22190d01da6aSStanislav Fomichev char *kernel_optval = NULL; 22206cb153caSBenjamin LaHaise int err, fput_needed; 22211da177e4SLinus Torvalds struct socket *sock; 22221da177e4SLinus Torvalds 22231da177e4SLinus Torvalds if (optlen < 0) 22241da177e4SLinus Torvalds return -EINVAL; 22251da177e4SLinus Torvalds 222689bddce5SStephen Hemminger sock = sockfd_lookup_light(fd, &err, &fput_needed); 22274a367299SChristoph Hellwig if (!sock) 22284a367299SChristoph Hellwig return err; 22294a367299SChristoph Hellwig 22301da177e4SLinus Torvalds err = security_socket_setsockopt(sock, level, optname); 22316cb153caSBenjamin LaHaise if (err) 22326cb153caSBenjamin LaHaise goto out_put; 22331da177e4SLinus Torvalds 223455db9c0eSChristoph Hellwig if (!in_compat_syscall()) 22354a367299SChristoph Hellwig err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname, 2236a7b75c5aSChristoph Hellwig user_optval, &optlen, 223755db9c0eSChristoph Hellwig &kernel_optval); 22384a367299SChristoph Hellwig if (err < 0) 22390d01da6aSStanislav Fomichev goto out_put; 22404a367299SChristoph Hellwig if (err > 0) { 22410d01da6aSStanislav Fomichev err = 0; 22420d01da6aSStanislav Fomichev goto out_put; 22430d01da6aSStanislav Fomichev } 22440d01da6aSStanislav Fomichev 2245a7b75c5aSChristoph Hellwig if (kernel_optval) 2246a7b75c5aSChristoph Hellwig optval = KERNEL_SOCKPTR(kernel_optval); 224783f0c10bSFlorian Westphal if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock)) 2248a7b75c5aSChristoph Hellwig err = sock_setsockopt(sock, level, optname, optval, optlen); 2249a44d9e72SChristoph Hellwig else if (unlikely(!sock->ops->setsockopt)) 2250a44d9e72SChristoph Hellwig err = -EOPNOTSUPP; 22511da177e4SLinus Torvalds else 22524a367299SChristoph Hellwig err = sock->ops->setsockopt(sock, level, optname, optval, 225389bddce5SStephen Hemminger optlen); 22540d01da6aSStanislav Fomichev kfree(kernel_optval); 22556cb153caSBenjamin LaHaise out_put: 22566cb153caSBenjamin LaHaise fput_light(sock->file, fput_needed); 22571da177e4SLinus Torvalds return err; 22581da177e4SLinus Torvalds } 22591da177e4SLinus Torvalds 2260cc36dca0SDominik Brodowski SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, 2261cc36dca0SDominik Brodowski char __user *, optval, int, optlen) 2262cc36dca0SDominik Brodowski { 2263cc36dca0SDominik Brodowski return __sys_setsockopt(fd, level, optname, optval, optlen); 2264cc36dca0SDominik Brodowski } 2265cc36dca0SDominik Brodowski 22669cacf81fSStanislav Fomichev INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level, 22679cacf81fSStanislav Fomichev int optname)); 22689cacf81fSStanislav Fomichev 22691da177e4SLinus Torvalds /* 22701da177e4SLinus Torvalds * Get a socket option. Because we don't know the option lengths we have 22711da177e4SLinus Torvalds * to pass a user mode parameter for the protocols to sort out. 22721da177e4SLinus Torvalds */ 227355db9c0eSChristoph Hellwig int __sys_getsockopt(int fd, int level, int optname, char __user *optval, 227455db9c0eSChristoph Hellwig int __user *optlen) 22751da177e4SLinus Torvalds { 22766cb153caSBenjamin LaHaise int err, fput_needed; 22771da177e4SLinus Torvalds struct socket *sock; 22780d01da6aSStanislav Fomichev int max_optlen; 22791da177e4SLinus Torvalds 228089bddce5SStephen Hemminger sock = sockfd_lookup_light(fd, &err, &fput_needed); 2281d8a9b38fSChristoph Hellwig if (!sock) 2282d8a9b38fSChristoph Hellwig return err; 2283d8a9b38fSChristoph Hellwig 22846cb153caSBenjamin LaHaise err = security_socket_getsockopt(sock, level, optname); 22856cb153caSBenjamin LaHaise if (err) 22866cb153caSBenjamin LaHaise goto out_put; 22871da177e4SLinus Torvalds 228855db9c0eSChristoph Hellwig if (!in_compat_syscall()) 22890d01da6aSStanislav Fomichev max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen); 22900d01da6aSStanislav Fomichev 22911da177e4SLinus Torvalds if (level == SOL_SOCKET) 2292d8a9b38fSChristoph Hellwig err = sock_getsockopt(sock, level, optname, optval, optlen); 2293a44d9e72SChristoph Hellwig else if (unlikely(!sock->ops->getsockopt)) 2294a44d9e72SChristoph Hellwig err = -EOPNOTSUPP; 22951da177e4SLinus Torvalds else 2296d8a9b38fSChristoph Hellwig err = sock->ops->getsockopt(sock, level, optname, optval, 229789bddce5SStephen Hemminger optlen); 22980d01da6aSStanislav Fomichev 229955db9c0eSChristoph Hellwig if (!in_compat_syscall()) 230055db9c0eSChristoph Hellwig err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname, 230155db9c0eSChristoph Hellwig optval, optlen, max_optlen, 230255db9c0eSChristoph Hellwig err); 23036cb153caSBenjamin LaHaise out_put: 23046cb153caSBenjamin LaHaise fput_light(sock->file, fput_needed); 23051da177e4SLinus Torvalds return err; 23061da177e4SLinus Torvalds } 23071da177e4SLinus Torvalds 230813a2d70eSDominik Brodowski SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname, 230913a2d70eSDominik Brodowski char __user *, optval, int __user *, optlen) 231013a2d70eSDominik Brodowski { 231113a2d70eSDominik Brodowski return __sys_getsockopt(fd, level, optname, optval, optlen); 231213a2d70eSDominik Brodowski } 231313a2d70eSDominik Brodowski 23141da177e4SLinus Torvalds /* 23151da177e4SLinus Torvalds * Shutdown a socket. 23161da177e4SLinus Torvalds */ 23171da177e4SLinus Torvalds 2318b713c195SJens Axboe int __sys_shutdown_sock(struct socket *sock, int how) 2319b713c195SJens Axboe { 2320b713c195SJens Axboe int err; 2321b713c195SJens Axboe 2322b713c195SJens Axboe err = security_socket_shutdown(sock, how); 2323b713c195SJens Axboe if (!err) 2324b713c195SJens Axboe err = sock->ops->shutdown(sock, how); 2325b713c195SJens Axboe 2326b713c195SJens Axboe return err; 2327b713c195SJens Axboe } 2328b713c195SJens Axboe 2329005a1aeaSDominik Brodowski int __sys_shutdown(int fd, int how) 23301da177e4SLinus Torvalds { 23316cb153caSBenjamin LaHaise int err, fput_needed; 23321da177e4SLinus Torvalds struct socket *sock; 23331da177e4SLinus Torvalds 233489bddce5SStephen Hemminger sock = sockfd_lookup_light(fd, &err, &fput_needed); 233589bddce5SStephen Hemminger if (sock != NULL) { 2336b713c195SJens Axboe err = __sys_shutdown_sock(sock, how); 23376cb153caSBenjamin LaHaise fput_light(sock->file, fput_needed); 23381da177e4SLinus Torvalds } 23391da177e4SLinus Torvalds return err; 23401da177e4SLinus Torvalds } 23411da177e4SLinus Torvalds 2342005a1aeaSDominik Brodowski SYSCALL_DEFINE2(shutdown, int, fd, int, how) 2343005a1aeaSDominik Brodowski { 2344005a1aeaSDominik Brodowski return __sys_shutdown(fd, how); 2345005a1aeaSDominik Brodowski } 2346005a1aeaSDominik Brodowski 23471da177e4SLinus Torvalds /* A couple of helpful macros for getting the address of the 32/64 bit 23481da177e4SLinus Torvalds * fields which are the same type (int / unsigned) on our platforms. 23491da177e4SLinus Torvalds */ 23501da177e4SLinus Torvalds #define COMPAT_MSG(msg, member) ((MSG_CMSG_COMPAT & flags) ? &msg##_compat->member : &msg->member) 23511da177e4SLinus Torvalds #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) 23521da177e4SLinus Torvalds #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) 23531da177e4SLinus Torvalds 2354c71d8ebeSTetsuo Handa struct used_address { 2355c71d8ebeSTetsuo Handa struct sockaddr_storage name; 2356c71d8ebeSTetsuo Handa unsigned int name_len; 2357c71d8ebeSTetsuo Handa }; 2358c71d8ebeSTetsuo Handa 23597fa875b8SDylan Yudaken int __copy_msghdr(struct msghdr *kmsg, 23607fa875b8SDylan Yudaken struct user_msghdr *msg, 23617fa875b8SDylan Yudaken struct sockaddr __user **save_addr) 23621661bf36SDan Carpenter { 236308adb7daSAl Viro ssize_t err; 236408adb7daSAl Viro 23651f466e1fSChristoph Hellwig kmsg->msg_control_is_user = true; 23661228b34cSEric Dumazet kmsg->msg_get_inq = 0; 23677fa875b8SDylan Yudaken kmsg->msg_control_user = msg->msg_control; 23687fa875b8SDylan Yudaken kmsg->msg_controllen = msg->msg_controllen; 23697fa875b8SDylan Yudaken kmsg->msg_flags = msg->msg_flags; 2370ffb07550SAl Viro 23717fa875b8SDylan Yudaken kmsg->msg_namelen = msg->msg_namelen; 23727fa875b8SDylan Yudaken if (!msg->msg_name) 23736a2a2b3aSAni Sinha kmsg->msg_namelen = 0; 23746a2a2b3aSAni Sinha 2375dbb490b9SMatthew Leach if (kmsg->msg_namelen < 0) 2376dbb490b9SMatthew Leach return -EINVAL; 2377dbb490b9SMatthew Leach 23781661bf36SDan Carpenter if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) 2379db31c55aSDan Carpenter kmsg->msg_namelen = sizeof(struct sockaddr_storage); 238008adb7daSAl Viro 238108adb7daSAl Viro if (save_addr) 23827fa875b8SDylan Yudaken *save_addr = msg->msg_name; 238308adb7daSAl Viro 23847fa875b8SDylan Yudaken if (msg->msg_name && kmsg->msg_namelen) { 238508adb7daSAl Viro if (!save_addr) { 23867fa875b8SDylan Yudaken err = move_addr_to_kernel(msg->msg_name, 2387864d9664SPaolo Abeni kmsg->msg_namelen, 238808adb7daSAl Viro kmsg->msg_name); 238908adb7daSAl Viro if (err < 0) 239008adb7daSAl Viro return err; 239108adb7daSAl Viro } 239208adb7daSAl Viro } else { 239308adb7daSAl Viro kmsg->msg_name = NULL; 239408adb7daSAl Viro kmsg->msg_namelen = 0; 239508adb7daSAl Viro } 239608adb7daSAl Viro 23977fa875b8SDylan Yudaken if (msg->msg_iovlen > UIO_MAXIOV) 239808adb7daSAl Viro return -EMSGSIZE; 239908adb7daSAl Viro 24000345f931Stadeusz.struk@intel.com kmsg->msg_iocb = NULL; 24017c701d92SPavel Begunkov kmsg->msg_ubuf = NULL; 24020a384abfSJens Axboe return 0; 24030a384abfSJens Axboe } 24040a384abfSJens Axboe 24050a384abfSJens Axboe static int copy_msghdr_from_user(struct msghdr *kmsg, 24060a384abfSJens Axboe struct user_msghdr __user *umsg, 24070a384abfSJens Axboe struct sockaddr __user **save_addr, 24080a384abfSJens Axboe struct iovec **iov) 24090a384abfSJens Axboe { 24100a384abfSJens Axboe struct user_msghdr msg; 24110a384abfSJens Axboe ssize_t err; 24120a384abfSJens Axboe 24137fa875b8SDylan Yudaken if (copy_from_user(&msg, umsg, sizeof(*umsg))) 24147fa875b8SDylan Yudaken return -EFAULT; 24157fa875b8SDylan Yudaken 24167fa875b8SDylan Yudaken err = __copy_msghdr(kmsg, &msg, save_addr); 24170a384abfSJens Axboe if (err) 24180a384abfSJens Axboe return err; 24190345f931Stadeusz.struk@intel.com 2420*de4eda9dSAl Viro err = import_iovec(save_addr ? ITER_DEST : ITER_SOURCE, 2421ffb07550SAl Viro msg.msg_iov, msg.msg_iovlen, 2422da184284SAl Viro UIO_FASTIOV, iov, &kmsg->msg_iter); 242387e5e6daSJens Axboe return err < 0 ? err : 0; 24241661bf36SDan Carpenter } 24251661bf36SDan Carpenter 24264257c8caSJens Axboe static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys, 24274257c8caSJens Axboe unsigned int flags, struct used_address *used_address, 242828a94d8fSTom Herbert unsigned int allowed_msghdr_flags) 24291da177e4SLinus Torvalds { 2430b9d717a7SAlex Williamson unsigned char ctl[sizeof(struct cmsghdr) + 20] 2431846cc123SAmit Kushwaha __aligned(sizeof(__kernel_size_t)); 2432b9d717a7SAlex Williamson /* 20 is size of ipv6_pktinfo */ 24331da177e4SLinus Torvalds unsigned char *ctl_buf = ctl; 2434d8725c86SAl Viro int ctl_len; 243508adb7daSAl Viro ssize_t err; 24361da177e4SLinus Torvalds 24371da177e4SLinus Torvalds err = -ENOBUFS; 24381da177e4SLinus Torvalds 2439228e548eSAnton Blanchard if (msg_sys->msg_controllen > INT_MAX) 24404257c8caSJens Axboe goto out; 244128a94d8fSTom Herbert flags |= (msg_sys->msg_flags & allowed_msghdr_flags); 2442228e548eSAnton Blanchard ctl_len = msg_sys->msg_controllen; 24431da177e4SLinus Torvalds if ((MSG_CMSG_COMPAT & flags) && ctl_len) { 244489bddce5SStephen Hemminger err = 2445228e548eSAnton Blanchard cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl, 244689bddce5SStephen Hemminger sizeof(ctl)); 24471da177e4SLinus Torvalds if (err) 24484257c8caSJens Axboe goto out; 2449228e548eSAnton Blanchard ctl_buf = msg_sys->msg_control; 2450228e548eSAnton Blanchard ctl_len = msg_sys->msg_controllen; 24511da177e4SLinus Torvalds } else if (ctl_len) { 2452ac4340fcSDavid S. Miller BUILD_BUG_ON(sizeof(struct cmsghdr) != 2453ac4340fcSDavid S. Miller CMSG_ALIGN(sizeof(struct cmsghdr))); 245489bddce5SStephen Hemminger if (ctl_len > sizeof(ctl)) { 24551da177e4SLinus Torvalds ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL); 24561da177e4SLinus Torvalds if (ctl_buf == NULL) 24574257c8caSJens Axboe goto out; 24581da177e4SLinus Torvalds } 24591da177e4SLinus Torvalds err = -EFAULT; 24601f466e1fSChristoph Hellwig if (copy_from_user(ctl_buf, msg_sys->msg_control_user, ctl_len)) 24611da177e4SLinus Torvalds goto out_freectl; 2462228e548eSAnton Blanchard msg_sys->msg_control = ctl_buf; 24631f466e1fSChristoph Hellwig msg_sys->msg_control_is_user = false; 24641da177e4SLinus Torvalds } 2465228e548eSAnton Blanchard msg_sys->msg_flags = flags; 24661da177e4SLinus Torvalds 24671da177e4SLinus Torvalds if (sock->file->f_flags & O_NONBLOCK) 2468228e548eSAnton Blanchard msg_sys->msg_flags |= MSG_DONTWAIT; 2469c71d8ebeSTetsuo Handa /* 2470c71d8ebeSTetsuo Handa * If this is sendmmsg() and current destination address is same as 2471c71d8ebeSTetsuo Handa * previously succeeded address, omit asking LSM's decision. 2472c71d8ebeSTetsuo Handa * used_address->name_len is initialized to UINT_MAX so that the first 2473c71d8ebeSTetsuo Handa * destination address never matches. 2474c71d8ebeSTetsuo Handa */ 2475bc909d9dSMathieu Desnoyers if (used_address && msg_sys->msg_name && 2476bc909d9dSMathieu Desnoyers used_address->name_len == msg_sys->msg_namelen && 2477bc909d9dSMathieu Desnoyers !memcmp(&used_address->name, msg_sys->msg_name, 2478c71d8ebeSTetsuo Handa used_address->name_len)) { 2479d8725c86SAl Viro err = sock_sendmsg_nosec(sock, msg_sys); 2480c71d8ebeSTetsuo Handa goto out_freectl; 2481c71d8ebeSTetsuo Handa } 2482d8725c86SAl Viro err = sock_sendmsg(sock, msg_sys); 2483c71d8ebeSTetsuo Handa /* 2484c71d8ebeSTetsuo Handa * If this is sendmmsg() and sending to current destination address was 2485c71d8ebeSTetsuo Handa * successful, remember it. 2486c71d8ebeSTetsuo Handa */ 2487c71d8ebeSTetsuo Handa if (used_address && err >= 0) { 2488c71d8ebeSTetsuo Handa used_address->name_len = msg_sys->msg_namelen; 2489bc909d9dSMathieu Desnoyers if (msg_sys->msg_name) 2490bc909d9dSMathieu Desnoyers memcpy(&used_address->name, msg_sys->msg_name, 2491c71d8ebeSTetsuo Handa used_address->name_len); 2492c71d8ebeSTetsuo Handa } 24931da177e4SLinus Torvalds 24941da177e4SLinus Torvalds out_freectl: 24951da177e4SLinus Torvalds if (ctl_buf != ctl) 24961da177e4SLinus Torvalds sock_kfree_s(sock->sk, ctl_buf, ctl_len); 24974257c8caSJens Axboe out: 24984257c8caSJens Axboe return err; 24994257c8caSJens Axboe } 25004257c8caSJens Axboe 250103b1230cSJens Axboe int sendmsg_copy_msghdr(struct msghdr *msg, 25024257c8caSJens Axboe struct user_msghdr __user *umsg, unsigned flags, 25034257c8caSJens Axboe struct iovec **iov) 25044257c8caSJens Axboe { 25054257c8caSJens Axboe int err; 25064257c8caSJens Axboe 25074257c8caSJens Axboe if (flags & MSG_CMSG_COMPAT) { 25084257c8caSJens Axboe struct compat_msghdr __user *msg_compat; 25094257c8caSJens Axboe 25104257c8caSJens Axboe msg_compat = (struct compat_msghdr __user *) umsg; 25114257c8caSJens Axboe err = get_compat_msghdr(msg, msg_compat, NULL, iov); 25124257c8caSJens Axboe } else { 25134257c8caSJens Axboe err = copy_msghdr_from_user(msg, umsg, NULL, iov); 25144257c8caSJens Axboe } 25154257c8caSJens Axboe if (err < 0) 25164257c8caSJens Axboe return err; 25174257c8caSJens Axboe 25184257c8caSJens Axboe return 0; 25194257c8caSJens Axboe } 25204257c8caSJens Axboe 25214257c8caSJens Axboe static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg, 25224257c8caSJens Axboe struct msghdr *msg_sys, unsigned int flags, 25234257c8caSJens Axboe struct used_address *used_address, 25244257c8caSJens Axboe unsigned int allowed_msghdr_flags) 25254257c8caSJens Axboe { 25264257c8caSJens Axboe struct sockaddr_storage address; 25274257c8caSJens Axboe struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; 25284257c8caSJens Axboe ssize_t err; 25294257c8caSJens Axboe 25304257c8caSJens Axboe msg_sys->msg_name = &address; 25314257c8caSJens Axboe 25324257c8caSJens Axboe err = sendmsg_copy_msghdr(msg_sys, msg, flags, &iov); 25334257c8caSJens Axboe if (err < 0) 25344257c8caSJens Axboe return err; 25354257c8caSJens Axboe 25364257c8caSJens Axboe err = ____sys_sendmsg(sock, msg_sys, flags, used_address, 25374257c8caSJens Axboe allowed_msghdr_flags); 2538a74e9106SEric Dumazet kfree(iov); 2539228e548eSAnton Blanchard return err; 2540228e548eSAnton Blanchard } 2541228e548eSAnton Blanchard 2542228e548eSAnton Blanchard /* 2543228e548eSAnton Blanchard * BSD sendmsg interface 2544228e548eSAnton Blanchard */ 254503b1230cSJens Axboe long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg, 25460fa03c62SJens Axboe unsigned int flags) 25470fa03c62SJens Axboe { 254803b1230cSJens Axboe return ____sys_sendmsg(sock, msg, flags, NULL, 0); 25490fa03c62SJens Axboe } 2550228e548eSAnton Blanchard 2551e1834a32SDominik Brodowski long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags, 2552e1834a32SDominik Brodowski bool forbid_cmsg_compat) 2553228e548eSAnton Blanchard { 2554228e548eSAnton Blanchard int fput_needed, err; 2555228e548eSAnton Blanchard struct msghdr msg_sys; 25561be374a0SAndy Lutomirski struct socket *sock; 2557228e548eSAnton Blanchard 2558e1834a32SDominik Brodowski if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT)) 2559e1834a32SDominik Brodowski return -EINVAL; 2560e1834a32SDominik Brodowski 25611be374a0SAndy Lutomirski sock = sockfd_lookup_light(fd, &err, &fput_needed); 2562228e548eSAnton Blanchard if (!sock) 2563228e548eSAnton Blanchard goto out; 2564228e548eSAnton Blanchard 256528a94d8fSTom Herbert err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0); 2566228e548eSAnton Blanchard 25676cb153caSBenjamin LaHaise fput_light(sock->file, fput_needed); 25681da177e4SLinus Torvalds out: 25691da177e4SLinus Torvalds return err; 25701da177e4SLinus Torvalds } 25711da177e4SLinus Torvalds 2572666547ffSAl Viro SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags) 2573a7526eb5SAndy Lutomirski { 2574e1834a32SDominik Brodowski return __sys_sendmsg(fd, msg, flags, true); 2575a7526eb5SAndy Lutomirski } 2576a7526eb5SAndy Lutomirski 2577228e548eSAnton Blanchard /* 2578228e548eSAnton Blanchard * Linux sendmmsg interface 2579228e548eSAnton Blanchard */ 2580228e548eSAnton Blanchard 2581228e548eSAnton Blanchard int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, 2582e1834a32SDominik Brodowski unsigned int flags, bool forbid_cmsg_compat) 2583228e548eSAnton Blanchard { 2584228e548eSAnton Blanchard int fput_needed, err, datagrams; 2585228e548eSAnton Blanchard struct socket *sock; 2586228e548eSAnton Blanchard struct mmsghdr __user *entry; 2587228e548eSAnton Blanchard struct compat_mmsghdr __user *compat_entry; 2588228e548eSAnton Blanchard struct msghdr msg_sys; 2589c71d8ebeSTetsuo Handa struct used_address used_address; 2590f092276dSTom Herbert unsigned int oflags = flags; 2591228e548eSAnton Blanchard 2592e1834a32SDominik Brodowski if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT)) 2593e1834a32SDominik Brodowski return -EINVAL; 2594e1834a32SDominik Brodowski 259598382f41SAnton Blanchard if (vlen > UIO_MAXIOV) 259698382f41SAnton Blanchard vlen = UIO_MAXIOV; 2597228e548eSAnton Blanchard 2598228e548eSAnton Blanchard datagrams = 0; 2599228e548eSAnton Blanchard 2600228e548eSAnton Blanchard sock = sockfd_lookup_light(fd, &err, &fput_needed); 2601228e548eSAnton Blanchard if (!sock) 2602228e548eSAnton Blanchard return err; 2603228e548eSAnton Blanchard 2604c71d8ebeSTetsuo Handa used_address.name_len = UINT_MAX; 2605228e548eSAnton Blanchard entry = mmsg; 2606228e548eSAnton Blanchard compat_entry = (struct compat_mmsghdr __user *)mmsg; 2607728ffb86SAnton Blanchard err = 0; 2608f092276dSTom Herbert flags |= MSG_BATCH; 2609228e548eSAnton Blanchard 2610228e548eSAnton Blanchard while (datagrams < vlen) { 2611f092276dSTom Herbert if (datagrams == vlen - 1) 2612f092276dSTom Herbert flags = oflags; 2613f092276dSTom Herbert 2614228e548eSAnton Blanchard if (MSG_CMSG_COMPAT & flags) { 2615666547ffSAl Viro err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry, 261628a94d8fSTom Herbert &msg_sys, flags, &used_address, MSG_EOR); 2617228e548eSAnton Blanchard if (err < 0) 2618228e548eSAnton Blanchard break; 2619228e548eSAnton Blanchard err = __put_user(err, &compat_entry->msg_len); 2620228e548eSAnton Blanchard ++compat_entry; 2621228e548eSAnton Blanchard } else { 2622a7526eb5SAndy Lutomirski err = ___sys_sendmsg(sock, 2623666547ffSAl Viro (struct user_msghdr __user *)entry, 262428a94d8fSTom Herbert &msg_sys, flags, &used_address, MSG_EOR); 2625228e548eSAnton Blanchard if (err < 0) 2626228e548eSAnton Blanchard break; 2627228e548eSAnton Blanchard err = put_user(err, &entry->msg_len); 2628228e548eSAnton Blanchard ++entry; 2629228e548eSAnton Blanchard } 2630228e548eSAnton Blanchard 2631228e548eSAnton Blanchard if (err) 2632228e548eSAnton Blanchard break; 2633228e548eSAnton Blanchard ++datagrams; 26343023898bSSoheil Hassas Yeganeh if (msg_data_left(&msg_sys)) 26353023898bSSoheil Hassas Yeganeh break; 2636a78cb84cSEric Dumazet cond_resched(); 2637228e548eSAnton Blanchard } 2638228e548eSAnton Blanchard 2639228e548eSAnton Blanchard fput_light(sock->file, fput_needed); 2640228e548eSAnton Blanchard 2641728ffb86SAnton Blanchard /* We only return an error if no datagrams were able to be sent */ 2642728ffb86SAnton Blanchard if (datagrams != 0) 2643228e548eSAnton Blanchard return datagrams; 2644228e548eSAnton Blanchard 2645228e548eSAnton Blanchard return err; 2646228e548eSAnton Blanchard } 2647228e548eSAnton Blanchard 2648228e548eSAnton Blanchard SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, 2649228e548eSAnton Blanchard unsigned int, vlen, unsigned int, flags) 2650228e548eSAnton Blanchard { 2651e1834a32SDominik Brodowski return __sys_sendmmsg(fd, mmsg, vlen, flags, true); 2652228e548eSAnton Blanchard } 2653228e548eSAnton Blanchard 265403b1230cSJens Axboe int recvmsg_copy_msghdr(struct msghdr *msg, 26554257c8caSJens Axboe struct user_msghdr __user *umsg, unsigned flags, 26564257c8caSJens Axboe struct sockaddr __user **uaddr, 26574257c8caSJens Axboe struct iovec **iov) 26584257c8caSJens Axboe { 26594257c8caSJens Axboe ssize_t err; 26604257c8caSJens Axboe 26614257c8caSJens Axboe if (MSG_CMSG_COMPAT & flags) { 26624257c8caSJens Axboe struct compat_msghdr __user *msg_compat; 26634257c8caSJens Axboe 26644257c8caSJens Axboe msg_compat = (struct compat_msghdr __user *) umsg; 26654257c8caSJens Axboe err = get_compat_msghdr(msg, msg_compat, uaddr, iov); 26664257c8caSJens Axboe } else { 26674257c8caSJens Axboe err = copy_msghdr_from_user(msg, umsg, uaddr, iov); 26684257c8caSJens Axboe } 26694257c8caSJens Axboe if (err < 0) 26704257c8caSJens Axboe return err; 26714257c8caSJens Axboe 26724257c8caSJens Axboe return 0; 26734257c8caSJens Axboe } 26744257c8caSJens Axboe 26754257c8caSJens Axboe static int ____sys_recvmsg(struct socket *sock, struct msghdr *msg_sys, 26764257c8caSJens Axboe struct user_msghdr __user *msg, 26774257c8caSJens Axboe struct sockaddr __user *uaddr, 26784257c8caSJens Axboe unsigned int flags, int nosec) 26791da177e4SLinus Torvalds { 268089bddce5SStephen Hemminger struct compat_msghdr __user *msg_compat = 268189bddce5SStephen Hemminger (struct compat_msghdr __user *) msg; 26824257c8caSJens Axboe int __user *uaddr_len = COMPAT_NAMELEN(msg); 26834257c8caSJens Axboe struct sockaddr_storage addr; 26841da177e4SLinus Torvalds unsigned long cmsg_ptr; 26852da62906SAl Viro int len; 268608adb7daSAl Viro ssize_t err; 26871da177e4SLinus Torvalds 268808adb7daSAl Viro msg_sys->msg_name = &addr; 2689a2e27255SArnaldo Carvalho de Melo cmsg_ptr = (unsigned long)msg_sys->msg_control; 2690a2e27255SArnaldo Carvalho de Melo msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT); 26911da177e4SLinus Torvalds 2692f3d33426SHannes Frederic Sowa /* We assume all kernel code knows the size of sockaddr_storage */ 2693f3d33426SHannes Frederic Sowa msg_sys->msg_namelen = 0; 2694f3d33426SHannes Frederic Sowa 26951da177e4SLinus Torvalds if (sock->file->f_flags & O_NONBLOCK) 26961da177e4SLinus Torvalds flags |= MSG_DONTWAIT; 26971af66221SEric Dumazet 26981af66221SEric Dumazet if (unlikely(nosec)) 26991af66221SEric Dumazet err = sock_recvmsg_nosec(sock, msg_sys, flags); 27001af66221SEric Dumazet else 27011af66221SEric Dumazet err = sock_recvmsg(sock, msg_sys, flags); 27021af66221SEric Dumazet 27031da177e4SLinus Torvalds if (err < 0) 27044257c8caSJens Axboe goto out; 27051da177e4SLinus Torvalds len = err; 27061da177e4SLinus Torvalds 27071da177e4SLinus Torvalds if (uaddr != NULL) { 270843db362dSMaciej Żenczykowski err = move_addr_to_user(&addr, 2709a2e27255SArnaldo Carvalho de Melo msg_sys->msg_namelen, uaddr, 271089bddce5SStephen Hemminger uaddr_len); 27111da177e4SLinus Torvalds if (err < 0) 27124257c8caSJens Axboe goto out; 27131da177e4SLinus Torvalds } 2714a2e27255SArnaldo Carvalho de Melo err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT), 271537f7f421SDavid S. Miller COMPAT_FLAGS(msg)); 27161da177e4SLinus Torvalds if (err) 27174257c8caSJens Axboe goto out; 27181da177e4SLinus Torvalds if (MSG_CMSG_COMPAT & flags) 2719a2e27255SArnaldo Carvalho de Melo err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr, 27201da177e4SLinus Torvalds &msg_compat->msg_controllen); 27211da177e4SLinus Torvalds else 2722a2e27255SArnaldo Carvalho de Melo err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr, 27231da177e4SLinus Torvalds &msg->msg_controllen); 27241da177e4SLinus Torvalds if (err) 27254257c8caSJens Axboe goto out; 27261da177e4SLinus Torvalds err = len; 27274257c8caSJens Axboe out: 27284257c8caSJens Axboe return err; 27294257c8caSJens Axboe } 27301da177e4SLinus Torvalds 27314257c8caSJens Axboe static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg, 27324257c8caSJens Axboe struct msghdr *msg_sys, unsigned int flags, int nosec) 27334257c8caSJens Axboe { 27344257c8caSJens Axboe struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; 27354257c8caSJens Axboe /* user mode address pointers */ 27364257c8caSJens Axboe struct sockaddr __user *uaddr; 27374257c8caSJens Axboe ssize_t err; 27384257c8caSJens Axboe 27394257c8caSJens Axboe err = recvmsg_copy_msghdr(msg_sys, msg, flags, &uaddr, &iov); 27404257c8caSJens Axboe if (err < 0) 27414257c8caSJens Axboe return err; 27424257c8caSJens Axboe 27434257c8caSJens Axboe err = ____sys_recvmsg(sock, msg_sys, msg, uaddr, flags, nosec); 2744a74e9106SEric Dumazet kfree(iov); 2745a2e27255SArnaldo Carvalho de Melo return err; 2746a2e27255SArnaldo Carvalho de Melo } 2747a2e27255SArnaldo Carvalho de Melo 2748a2e27255SArnaldo Carvalho de Melo /* 2749a2e27255SArnaldo Carvalho de Melo * BSD recvmsg interface 2750a2e27255SArnaldo Carvalho de Melo */ 2751a2e27255SArnaldo Carvalho de Melo 275203b1230cSJens Axboe long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg, 275303b1230cSJens Axboe struct user_msghdr __user *umsg, 275403b1230cSJens Axboe struct sockaddr __user *uaddr, unsigned int flags) 2755aa1fa28fSJens Axboe { 275603b1230cSJens Axboe return ____sys_recvmsg(sock, msg, umsg, uaddr, flags, 0); 2757aa1fa28fSJens Axboe } 2758aa1fa28fSJens Axboe 2759e1834a32SDominik Brodowski long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags, 2760e1834a32SDominik Brodowski bool forbid_cmsg_compat) 2761a2e27255SArnaldo Carvalho de Melo { 2762a2e27255SArnaldo Carvalho de Melo int fput_needed, err; 2763a2e27255SArnaldo Carvalho de Melo struct msghdr msg_sys; 27641be374a0SAndy Lutomirski struct socket *sock; 2765a2e27255SArnaldo Carvalho de Melo 2766e1834a32SDominik Brodowski if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT)) 2767e1834a32SDominik Brodowski return -EINVAL; 2768e1834a32SDominik Brodowski 27691be374a0SAndy Lutomirski sock = sockfd_lookup_light(fd, &err, &fput_needed); 2770a2e27255SArnaldo Carvalho de Melo if (!sock) 2771a2e27255SArnaldo Carvalho de Melo goto out; 2772a2e27255SArnaldo Carvalho de Melo 2773a7526eb5SAndy Lutomirski err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0); 2774a2e27255SArnaldo Carvalho de Melo 27756cb153caSBenjamin LaHaise fput_light(sock->file, fput_needed); 27761da177e4SLinus Torvalds out: 27771da177e4SLinus Torvalds return err; 27781da177e4SLinus Torvalds } 27791da177e4SLinus Torvalds 2780666547ffSAl Viro SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg, 2781a7526eb5SAndy Lutomirski unsigned int, flags) 2782a7526eb5SAndy Lutomirski { 2783e1834a32SDominik Brodowski return __sys_recvmsg(fd, msg, flags, true); 2784a7526eb5SAndy Lutomirski } 2785a7526eb5SAndy Lutomirski 2786a2e27255SArnaldo Carvalho de Melo /* 2787a2e27255SArnaldo Carvalho de Melo * Linux recvmmsg interface 2788a2e27255SArnaldo Carvalho de Melo */ 27891da177e4SLinus Torvalds 2790e11d4284SArnd Bergmann static int do_recvmmsg(int fd, struct mmsghdr __user *mmsg, 2791e11d4284SArnd Bergmann unsigned int vlen, unsigned int flags, 2792e11d4284SArnd Bergmann struct timespec64 *timeout) 2793a2e27255SArnaldo Carvalho de Melo { 2794a2e27255SArnaldo Carvalho de Melo int fput_needed, err, datagrams; 2795a2e27255SArnaldo Carvalho de Melo struct socket *sock; 2796a2e27255SArnaldo Carvalho de Melo struct mmsghdr __user *entry; 2797d7256d0eSJean-Mickael Guerin struct compat_mmsghdr __user *compat_entry; 2798a2e27255SArnaldo Carvalho de Melo struct msghdr msg_sys; 2799766b9f92SDeepa Dinamani struct timespec64 end_time; 2800766b9f92SDeepa Dinamani struct timespec64 timeout64; 2801a2e27255SArnaldo Carvalho de Melo 2802a2e27255SArnaldo Carvalho de Melo if (timeout && 2803a2e27255SArnaldo Carvalho de Melo poll_select_set_timeout(&end_time, timeout->tv_sec, 2804a2e27255SArnaldo Carvalho de Melo timeout->tv_nsec)) 2805a2e27255SArnaldo Carvalho de Melo return -EINVAL; 2806a2e27255SArnaldo Carvalho de Melo 2807a2e27255SArnaldo Carvalho de Melo datagrams = 0; 2808a2e27255SArnaldo Carvalho de Melo 2809a2e27255SArnaldo Carvalho de Melo sock = sockfd_lookup_light(fd, &err, &fput_needed); 2810a2e27255SArnaldo Carvalho de Melo if (!sock) 2811a2e27255SArnaldo Carvalho de Melo return err; 2812a2e27255SArnaldo Carvalho de Melo 28137797dc41SSoheil Hassas Yeganeh if (likely(!(flags & MSG_ERRQUEUE))) { 2814a2e27255SArnaldo Carvalho de Melo err = sock_error(sock->sk); 2815e623a9e9SMaxime Jayat if (err) { 2816e623a9e9SMaxime Jayat datagrams = err; 2817a2e27255SArnaldo Carvalho de Melo goto out_put; 2818e623a9e9SMaxime Jayat } 28197797dc41SSoheil Hassas Yeganeh } 2820a2e27255SArnaldo Carvalho de Melo 2821a2e27255SArnaldo Carvalho de Melo entry = mmsg; 2822d7256d0eSJean-Mickael Guerin compat_entry = (struct compat_mmsghdr __user *)mmsg; 2823a2e27255SArnaldo Carvalho de Melo 2824a2e27255SArnaldo Carvalho de Melo while (datagrams < vlen) { 2825a2e27255SArnaldo Carvalho de Melo /* 2826a2e27255SArnaldo Carvalho de Melo * No need to ask LSM for more than the first datagram. 2827a2e27255SArnaldo Carvalho de Melo */ 2828d7256d0eSJean-Mickael Guerin if (MSG_CMSG_COMPAT & flags) { 2829666547ffSAl Viro err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry, 2830b9eb8b87SAnton Blanchard &msg_sys, flags & ~MSG_WAITFORONE, 2831b9eb8b87SAnton Blanchard datagrams); 2832d7256d0eSJean-Mickael Guerin if (err < 0) 2833d7256d0eSJean-Mickael Guerin break; 2834d7256d0eSJean-Mickael Guerin err = __put_user(err, &compat_entry->msg_len); 2835d7256d0eSJean-Mickael Guerin ++compat_entry; 2836d7256d0eSJean-Mickael Guerin } else { 2837a7526eb5SAndy Lutomirski err = ___sys_recvmsg(sock, 2838666547ffSAl Viro (struct user_msghdr __user *)entry, 2839b9eb8b87SAnton Blanchard &msg_sys, flags & ~MSG_WAITFORONE, 2840b9eb8b87SAnton Blanchard datagrams); 2841a2e27255SArnaldo Carvalho de Melo if (err < 0) 2842a2e27255SArnaldo Carvalho de Melo break; 2843a2e27255SArnaldo Carvalho de Melo err = put_user(err, &entry->msg_len); 2844d7256d0eSJean-Mickael Guerin ++entry; 2845d7256d0eSJean-Mickael Guerin } 2846d7256d0eSJean-Mickael Guerin 2847a2e27255SArnaldo Carvalho de Melo if (err) 2848a2e27255SArnaldo Carvalho de Melo break; 2849a2e27255SArnaldo Carvalho de Melo ++datagrams; 2850a2e27255SArnaldo Carvalho de Melo 285171c5c159SBrandon L Black /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */ 285271c5c159SBrandon L Black if (flags & MSG_WAITFORONE) 285371c5c159SBrandon L Black flags |= MSG_DONTWAIT; 285471c5c159SBrandon L Black 2855a2e27255SArnaldo Carvalho de Melo if (timeout) { 2856766b9f92SDeepa Dinamani ktime_get_ts64(&timeout64); 2857c2e6c856SArnd Bergmann *timeout = timespec64_sub(end_time, timeout64); 2858a2e27255SArnaldo Carvalho de Melo if (timeout->tv_sec < 0) { 2859a2e27255SArnaldo Carvalho de Melo timeout->tv_sec = timeout->tv_nsec = 0; 2860a2e27255SArnaldo Carvalho de Melo break; 2861a2e27255SArnaldo Carvalho de Melo } 2862a2e27255SArnaldo Carvalho de Melo 2863a2e27255SArnaldo Carvalho de Melo /* Timeout, return less than vlen datagrams */ 2864a2e27255SArnaldo Carvalho de Melo if (timeout->tv_nsec == 0 && timeout->tv_sec == 0) 2865a2e27255SArnaldo Carvalho de Melo break; 2866a2e27255SArnaldo Carvalho de Melo } 2867a2e27255SArnaldo Carvalho de Melo 2868a2e27255SArnaldo Carvalho de Melo /* Out of band data, return right away */ 2869a2e27255SArnaldo Carvalho de Melo if (msg_sys.msg_flags & MSG_OOB) 2870a2e27255SArnaldo Carvalho de Melo break; 2871a78cb84cSEric Dumazet cond_resched(); 2872a2e27255SArnaldo Carvalho de Melo } 2873a2e27255SArnaldo Carvalho de Melo 2874a2e27255SArnaldo Carvalho de Melo if (err == 0) 287534b88a68SArnaldo Carvalho de Melo goto out_put; 2876a2e27255SArnaldo Carvalho de Melo 287734b88a68SArnaldo Carvalho de Melo if (datagrams == 0) { 287834b88a68SArnaldo Carvalho de Melo datagrams = err; 287934b88a68SArnaldo Carvalho de Melo goto out_put; 288034b88a68SArnaldo Carvalho de Melo } 288134b88a68SArnaldo Carvalho de Melo 2882a2e27255SArnaldo Carvalho de Melo /* 2883a2e27255SArnaldo Carvalho de Melo * We may return less entries than requested (vlen) if the 2884a2e27255SArnaldo Carvalho de Melo * sock is non block and there aren't enough datagrams... 2885a2e27255SArnaldo Carvalho de Melo */ 2886a2e27255SArnaldo Carvalho de Melo if (err != -EAGAIN) { 2887a2e27255SArnaldo Carvalho de Melo /* 2888a2e27255SArnaldo Carvalho de Melo * ... or if recvmsg returns an error after we 2889a2e27255SArnaldo Carvalho de Melo * received some datagrams, where we record the 2890a2e27255SArnaldo Carvalho de Melo * error to return on the next call or if the 2891a2e27255SArnaldo Carvalho de Melo * app asks about it using getsockopt(SO_ERROR). 2892a2e27255SArnaldo Carvalho de Melo */ 2893a2e27255SArnaldo Carvalho de Melo sock->sk->sk_err = -err; 2894a2e27255SArnaldo Carvalho de Melo } 289534b88a68SArnaldo Carvalho de Melo out_put: 289634b88a68SArnaldo Carvalho de Melo fput_light(sock->file, fput_needed); 2897a2e27255SArnaldo Carvalho de Melo 2898a2e27255SArnaldo Carvalho de Melo return datagrams; 2899a2e27255SArnaldo Carvalho de Melo } 2900a2e27255SArnaldo Carvalho de Melo 2901e11d4284SArnd Bergmann int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, 29021255e269SDominik Brodowski unsigned int vlen, unsigned int flags, 2903e11d4284SArnd Bergmann struct __kernel_timespec __user *timeout, 2904e11d4284SArnd Bergmann struct old_timespec32 __user *timeout32) 2905a2e27255SArnaldo Carvalho de Melo { 2906a2e27255SArnaldo Carvalho de Melo int datagrams; 2907c2e6c856SArnd Bergmann struct timespec64 timeout_sys; 2908a2e27255SArnaldo Carvalho de Melo 2909e11d4284SArnd Bergmann if (timeout && get_timespec64(&timeout_sys, timeout)) 2910a2e27255SArnaldo Carvalho de Melo return -EFAULT; 2911a2e27255SArnaldo Carvalho de Melo 2912e11d4284SArnd Bergmann if (timeout32 && get_old_timespec32(&timeout_sys, timeout32)) 2913e11d4284SArnd Bergmann return -EFAULT; 2914a2e27255SArnaldo Carvalho de Melo 2915e11d4284SArnd Bergmann if (!timeout && !timeout32) 2916e11d4284SArnd Bergmann return do_recvmmsg(fd, mmsg, vlen, flags, NULL); 2917e11d4284SArnd Bergmann 2918e11d4284SArnd Bergmann datagrams = do_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys); 2919e11d4284SArnd Bergmann 2920e11d4284SArnd Bergmann if (datagrams <= 0) 2921e11d4284SArnd Bergmann return datagrams; 2922e11d4284SArnd Bergmann 2923e11d4284SArnd Bergmann if (timeout && put_timespec64(&timeout_sys, timeout)) 2924e11d4284SArnd Bergmann datagrams = -EFAULT; 2925e11d4284SArnd Bergmann 2926e11d4284SArnd Bergmann if (timeout32 && put_old_timespec32(&timeout_sys, timeout32)) 2927a2e27255SArnaldo Carvalho de Melo datagrams = -EFAULT; 2928a2e27255SArnaldo Carvalho de Melo 2929a2e27255SArnaldo Carvalho de Melo return datagrams; 2930a2e27255SArnaldo Carvalho de Melo } 2931a2e27255SArnaldo Carvalho de Melo 29321255e269SDominik Brodowski SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, 29331255e269SDominik Brodowski unsigned int, vlen, unsigned int, flags, 2934c2e6c856SArnd Bergmann struct __kernel_timespec __user *, timeout) 29351255e269SDominik Brodowski { 2936e11d4284SArnd Bergmann if (flags & MSG_CMSG_COMPAT) 2937e11d4284SArnd Bergmann return -EINVAL; 2938e11d4284SArnd Bergmann 2939e11d4284SArnd Bergmann return __sys_recvmmsg(fd, mmsg, vlen, flags, timeout, NULL); 29401255e269SDominik Brodowski } 29411255e269SDominik Brodowski 2942e11d4284SArnd Bergmann #ifdef CONFIG_COMPAT_32BIT_TIME 2943e11d4284SArnd Bergmann SYSCALL_DEFINE5(recvmmsg_time32, int, fd, struct mmsghdr __user *, mmsg, 2944e11d4284SArnd Bergmann unsigned int, vlen, unsigned int, flags, 2945e11d4284SArnd Bergmann struct old_timespec32 __user *, timeout) 2946e11d4284SArnd Bergmann { 2947e11d4284SArnd Bergmann if (flags & MSG_CMSG_COMPAT) 2948e11d4284SArnd Bergmann return -EINVAL; 2949e11d4284SArnd Bergmann 2950e11d4284SArnd Bergmann return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL, timeout); 2951e11d4284SArnd Bergmann } 2952e11d4284SArnd Bergmann #endif 2953e11d4284SArnd Bergmann 2954a2e27255SArnaldo Carvalho de Melo #ifdef __ARCH_WANT_SYS_SOCKETCALL 29551da177e4SLinus Torvalds /* Argument list sizes for sys_socketcall */ 29561da177e4SLinus Torvalds #define AL(x) ((x) * sizeof(unsigned long)) 2957228e548eSAnton Blanchard static const unsigned char nargs[21] = { 295889bddce5SStephen Hemminger AL(0), AL(3), AL(3), AL(3), AL(2), AL(3), 29591da177e4SLinus Torvalds AL(3), AL(3), AL(4), AL(4), AL(4), AL(6), 2960aaca0bdcSUlrich Drepper AL(6), AL(2), AL(5), AL(5), AL(3), AL(3), 2961228e548eSAnton Blanchard AL(4), AL(5), AL(4) 296289bddce5SStephen Hemminger }; 296389bddce5SStephen Hemminger 29641da177e4SLinus Torvalds #undef AL 29651da177e4SLinus Torvalds 29661da177e4SLinus Torvalds /* 29671da177e4SLinus Torvalds * System call vectors. 29681da177e4SLinus Torvalds * 29691da177e4SLinus Torvalds * Argument checking cleaned up. Saved 20% in size. 29701da177e4SLinus Torvalds * This function doesn't need to set the kernel lock because 29711da177e4SLinus Torvalds * it is set by the callees. 29721da177e4SLinus Torvalds */ 29731da177e4SLinus Torvalds 29743e0fa65fSHeiko Carstens SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) 29751da177e4SLinus Torvalds { 29762950fa9dSChen Gang unsigned long a[AUDITSC_ARGS]; 29771da177e4SLinus Torvalds unsigned long a0, a1; 29781da177e4SLinus Torvalds int err; 297947379052SArjan van de Ven unsigned int len; 29801da177e4SLinus Torvalds 2981228e548eSAnton Blanchard if (call < 1 || call > SYS_SENDMMSG) 29821da177e4SLinus Torvalds return -EINVAL; 2983c8e8cd57SJeremy Cline call = array_index_nospec(call, SYS_SENDMMSG + 1); 29841da177e4SLinus Torvalds 298547379052SArjan van de Ven len = nargs[call]; 298647379052SArjan van de Ven if (len > sizeof(a)) 298747379052SArjan van de Ven return -EINVAL; 298847379052SArjan van de Ven 29891da177e4SLinus Torvalds /* copy_from_user should be SMP safe. */ 299047379052SArjan van de Ven if (copy_from_user(a, args, len)) 29911da177e4SLinus Torvalds return -EFAULT; 29921da177e4SLinus Torvalds 29932950fa9dSChen Gang err = audit_socketcall(nargs[call] / sizeof(unsigned long), a); 29942950fa9dSChen Gang if (err) 29952950fa9dSChen Gang return err; 29963ec3b2fbSDavid Woodhouse 29971da177e4SLinus Torvalds a0 = a[0]; 29981da177e4SLinus Torvalds a1 = a[1]; 29991da177e4SLinus Torvalds 300089bddce5SStephen Hemminger switch (call) { 30011da177e4SLinus Torvalds case SYS_SOCKET: 30029d6a15c3SDominik Brodowski err = __sys_socket(a0, a1, a[2]); 30031da177e4SLinus Torvalds break; 30041da177e4SLinus Torvalds case SYS_BIND: 3005a87d35d8SDominik Brodowski err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]); 30061da177e4SLinus Torvalds break; 30071da177e4SLinus Torvalds case SYS_CONNECT: 30081387c2c2SDominik Brodowski err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]); 30091da177e4SLinus Torvalds break; 30101da177e4SLinus Torvalds case SYS_LISTEN: 301125e290eeSDominik Brodowski err = __sys_listen(a0, a1); 30121da177e4SLinus Torvalds break; 30131da177e4SLinus Torvalds case SYS_ACCEPT: 30144541e805SDominik Brodowski err = __sys_accept4(a0, (struct sockaddr __user *)a1, 3015aaca0bdcSUlrich Drepper (int __user *)a[2], 0); 30161da177e4SLinus Torvalds break; 30171da177e4SLinus Torvalds case SYS_GETSOCKNAME: 301889bddce5SStephen Hemminger err = 30198882a107SDominik Brodowski __sys_getsockname(a0, (struct sockaddr __user *)a1, 302089bddce5SStephen Hemminger (int __user *)a[2]); 30211da177e4SLinus Torvalds break; 30221da177e4SLinus Torvalds case SYS_GETPEERNAME: 302389bddce5SStephen Hemminger err = 3024b21c8f83SDominik Brodowski __sys_getpeername(a0, (struct sockaddr __user *)a1, 302589bddce5SStephen Hemminger (int __user *)a[2]); 30261da177e4SLinus Torvalds break; 30271da177e4SLinus Torvalds case SYS_SOCKETPAIR: 30286debc8d8SDominik Brodowski err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]); 30291da177e4SLinus Torvalds break; 30301da177e4SLinus Torvalds case SYS_SEND: 3031f3bf896bSDominik Brodowski err = __sys_sendto(a0, (void __user *)a1, a[2], a[3], 3032f3bf896bSDominik Brodowski NULL, 0); 30331da177e4SLinus Torvalds break; 30341da177e4SLinus Torvalds case SYS_SENDTO: 3035211b634bSDominik Brodowski err = __sys_sendto(a0, (void __user *)a1, a[2], a[3], 30361da177e4SLinus Torvalds (struct sockaddr __user *)a[4], a[5]); 30371da177e4SLinus Torvalds break; 30381da177e4SLinus Torvalds case SYS_RECV: 3039d27e9afcSDominik Brodowski err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3], 3040d27e9afcSDominik Brodowski NULL, NULL); 30411da177e4SLinus Torvalds break; 30421da177e4SLinus Torvalds case SYS_RECVFROM: 30437a09e1ebSDominik Brodowski err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3], 304489bddce5SStephen Hemminger (struct sockaddr __user *)a[4], 304589bddce5SStephen Hemminger (int __user *)a[5]); 30461da177e4SLinus Torvalds break; 30471da177e4SLinus Torvalds case SYS_SHUTDOWN: 3048005a1aeaSDominik Brodowski err = __sys_shutdown(a0, a1); 30491da177e4SLinus Torvalds break; 30501da177e4SLinus Torvalds case SYS_SETSOCKOPT: 3051cc36dca0SDominik Brodowski err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3], 3052cc36dca0SDominik Brodowski a[4]); 30531da177e4SLinus Torvalds break; 30541da177e4SLinus Torvalds case SYS_GETSOCKOPT: 305589bddce5SStephen Hemminger err = 305613a2d70eSDominik Brodowski __sys_getsockopt(a0, a1, a[2], (char __user *)a[3], 305789bddce5SStephen Hemminger (int __user *)a[4]); 30581da177e4SLinus Torvalds break; 30591da177e4SLinus Torvalds case SYS_SENDMSG: 3060e1834a32SDominik Brodowski err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1, 3061e1834a32SDominik Brodowski a[2], true); 30621da177e4SLinus Torvalds break; 3063228e548eSAnton Blanchard case SYS_SENDMMSG: 3064e1834a32SDominik Brodowski err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], 3065e1834a32SDominik Brodowski a[3], true); 3066228e548eSAnton Blanchard break; 30671da177e4SLinus Torvalds case SYS_RECVMSG: 3068e1834a32SDominik Brodowski err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1, 3069e1834a32SDominik Brodowski a[2], true); 30701da177e4SLinus Torvalds break; 3071a2e27255SArnaldo Carvalho de Melo case SYS_RECVMMSG: 30723ca47e95SArnd Bergmann if (IS_ENABLED(CONFIG_64BIT)) 3073e11d4284SArnd Bergmann err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1, 3074e11d4284SArnd Bergmann a[2], a[3], 3075e11d4284SArnd Bergmann (struct __kernel_timespec __user *)a[4], 3076e11d4284SArnd Bergmann NULL); 3077e11d4284SArnd Bergmann else 3078e11d4284SArnd Bergmann err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1, 3079e11d4284SArnd Bergmann a[2], a[3], NULL, 3080e11d4284SArnd Bergmann (struct old_timespec32 __user *)a[4]); 3081a2e27255SArnaldo Carvalho de Melo break; 3082de11defeSUlrich Drepper case SYS_ACCEPT4: 30834541e805SDominik Brodowski err = __sys_accept4(a0, (struct sockaddr __user *)a1, 3084de11defeSUlrich Drepper (int __user *)a[2], a[3]); 3085aaca0bdcSUlrich Drepper break; 30861da177e4SLinus Torvalds default: 30871da177e4SLinus Torvalds err = -EINVAL; 30881da177e4SLinus Torvalds break; 30891da177e4SLinus Torvalds } 30901da177e4SLinus Torvalds return err; 30911da177e4SLinus Torvalds } 30921da177e4SLinus Torvalds 30931da177e4SLinus Torvalds #endif /* __ARCH_WANT_SYS_SOCKETCALL */ 30941da177e4SLinus Torvalds 309555737fdaSStephen Hemminger /** 309655737fdaSStephen Hemminger * sock_register - add a socket protocol handler 309755737fdaSStephen Hemminger * @ops: description of protocol 309855737fdaSStephen Hemminger * 30991da177e4SLinus Torvalds * This function is called by a protocol handler that wants to 31001da177e4SLinus Torvalds * advertise its address family, and have it linked into the 3101e793c0f7SMasanari Iida * socket interface. The value ops->family corresponds to the 310255737fdaSStephen Hemminger * socket system call protocol family. 31031da177e4SLinus Torvalds */ 3104f0fd27d4SStephen Hemminger int sock_register(const struct net_proto_family *ops) 31051da177e4SLinus Torvalds { 31061da177e4SLinus Torvalds int err; 31071da177e4SLinus Torvalds 31081da177e4SLinus Torvalds if (ops->family >= NPROTO) { 31093410f22eSYang Yingliang pr_crit("protocol %d >= NPROTO(%d)\n", ops->family, NPROTO); 31101da177e4SLinus Torvalds return -ENOBUFS; 31111da177e4SLinus Torvalds } 311255737fdaSStephen Hemminger 311355737fdaSStephen Hemminger spin_lock(&net_family_lock); 3114190683a9SEric Dumazet if (rcu_dereference_protected(net_families[ops->family], 3115190683a9SEric Dumazet lockdep_is_held(&net_family_lock))) 31161da177e4SLinus Torvalds err = -EEXIST; 311755737fdaSStephen Hemminger else { 3118cf778b00SEric Dumazet rcu_assign_pointer(net_families[ops->family], ops); 31191da177e4SLinus Torvalds err = 0; 31201da177e4SLinus Torvalds } 312155737fdaSStephen Hemminger spin_unlock(&net_family_lock); 312255737fdaSStephen Hemminger 3123fe0bdbdeSYejune Deng pr_info("NET: Registered %s protocol family\n", pf_family_names[ops->family]); 31241da177e4SLinus Torvalds return err; 31251da177e4SLinus Torvalds } 3126c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_register); 31271da177e4SLinus Torvalds 312855737fdaSStephen Hemminger /** 312955737fdaSStephen Hemminger * sock_unregister - remove a protocol handler 313055737fdaSStephen Hemminger * @family: protocol family to remove 313155737fdaSStephen Hemminger * 31321da177e4SLinus Torvalds * This function is called by a protocol handler that wants to 31331da177e4SLinus Torvalds * remove its address family, and have it unlinked from the 313455737fdaSStephen Hemminger * new socket creation. 313555737fdaSStephen Hemminger * 313655737fdaSStephen Hemminger * If protocol handler is a module, then it can use module reference 313755737fdaSStephen Hemminger * counts to protect against new references. If protocol handler is not 313855737fdaSStephen Hemminger * a module then it needs to provide its own protection in 313955737fdaSStephen Hemminger * the ops->create routine. 31401da177e4SLinus Torvalds */ 3141f0fd27d4SStephen Hemminger void sock_unregister(int family) 31421da177e4SLinus Torvalds { 3143f0fd27d4SStephen Hemminger BUG_ON(family < 0 || family >= NPROTO); 31441da177e4SLinus Torvalds 314555737fdaSStephen Hemminger spin_lock(&net_family_lock); 3146a9b3cd7fSStephen Hemminger RCU_INIT_POINTER(net_families[family], NULL); 314755737fdaSStephen Hemminger spin_unlock(&net_family_lock); 314855737fdaSStephen Hemminger 314955737fdaSStephen Hemminger synchronize_rcu(); 315055737fdaSStephen Hemminger 3151fe0bdbdeSYejune Deng pr_info("NET: Unregistered %s protocol family\n", pf_family_names[family]); 31521da177e4SLinus Torvalds } 3153c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_unregister); 31541da177e4SLinus Torvalds 3155bf2ae2e4SXin Long bool sock_is_registered(int family) 3156bf2ae2e4SXin Long { 315766b51b0aSJeremy Cline return family < NPROTO && rcu_access_pointer(net_families[family]); 3158bf2ae2e4SXin Long } 3159bf2ae2e4SXin Long 316077d76ea3SAndi Kleen static int __init sock_init(void) 31611da177e4SLinus Torvalds { 3162b3e19d92SNick Piggin int err; 31632ca794e5SEric W. Biederman /* 31642ca794e5SEric W. Biederman * Initialize the network sysctl infrastructure. 31652ca794e5SEric W. Biederman */ 31662ca794e5SEric W. Biederman err = net_sysctl_init(); 31672ca794e5SEric W. Biederman if (err) 31682ca794e5SEric W. Biederman goto out; 3169b3e19d92SNick Piggin 31701da177e4SLinus Torvalds /* 31711da177e4SLinus Torvalds * Initialize skbuff SLAB cache 31721da177e4SLinus Torvalds */ 31731da177e4SLinus Torvalds skb_init(); 31741da177e4SLinus Torvalds 31751da177e4SLinus Torvalds /* 31761da177e4SLinus Torvalds * Initialize the protocols module. 31771da177e4SLinus Torvalds */ 31781da177e4SLinus Torvalds 31791da177e4SLinus Torvalds init_inodecache(); 3180b3e19d92SNick Piggin 3181b3e19d92SNick Piggin err = register_filesystem(&sock_fs_type); 3182b3e19d92SNick Piggin if (err) 318347260ba9SMiaohe Lin goto out; 31841da177e4SLinus Torvalds sock_mnt = kern_mount(&sock_fs_type); 3185b3e19d92SNick Piggin if (IS_ERR(sock_mnt)) { 3186b3e19d92SNick Piggin err = PTR_ERR(sock_mnt); 3187b3e19d92SNick Piggin goto out_mount; 3188b3e19d92SNick Piggin } 318977d76ea3SAndi Kleen 319077d76ea3SAndi Kleen /* The real protocol initialization is performed in later initcalls. 31911da177e4SLinus Torvalds */ 31921da177e4SLinus Torvalds 31931da177e4SLinus Torvalds #ifdef CONFIG_NETFILTER 31946d11cfdbSPablo Neira Ayuso err = netfilter_init(); 31956d11cfdbSPablo Neira Ayuso if (err) 31966d11cfdbSPablo Neira Ayuso goto out; 31971da177e4SLinus Torvalds #endif 3198cbeb321aSDavid S. Miller 3199408eccceSDaniel Borkmann ptp_classifier_init(); 3200c1f19b51SRichard Cochran 3201b3e19d92SNick Piggin out: 3202b3e19d92SNick Piggin return err; 3203b3e19d92SNick Piggin 3204b3e19d92SNick Piggin out_mount: 3205b3e19d92SNick Piggin unregister_filesystem(&sock_fs_type); 3206b3e19d92SNick Piggin goto out; 32071da177e4SLinus Torvalds } 32081da177e4SLinus Torvalds 320977d76ea3SAndi Kleen core_initcall(sock_init); /* early initcall */ 321077d76ea3SAndi Kleen 32111da177e4SLinus Torvalds #ifdef CONFIG_PROC_FS 32121da177e4SLinus Torvalds void socket_seq_show(struct seq_file *seq) 32131da177e4SLinus Torvalds { 3214648845abSTonghao Zhang seq_printf(seq, "sockets: used %d\n", 3215648845abSTonghao Zhang sock_inuse_get(seq->private)); 32161da177e4SLinus Torvalds } 32171da177e4SLinus Torvalds #endif /* CONFIG_PROC_FS */ 32181da177e4SLinus Torvalds 321929c49648SArnd Bergmann /* Handle the fact that while struct ifreq has the same *layout* on 322029c49648SArnd Bergmann * 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data, 322129c49648SArnd Bergmann * which are handled elsewhere, it still has different *size* due to 322229c49648SArnd Bergmann * ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit, 322329c49648SArnd Bergmann * resulting in struct ifreq being 32 and 40 bytes respectively). 322429c49648SArnd Bergmann * As a result, if the struct happens to be at the end of a page and 322529c49648SArnd Bergmann * the next page isn't readable/writable, we get a fault. To prevent 322629c49648SArnd Bergmann * that, copy back and forth to the full size. 322729c49648SArnd Bergmann */ 322829c49648SArnd Bergmann int get_user_ifreq(struct ifreq *ifr, void __user **ifrdata, void __user *arg) 322929c49648SArnd Bergmann { 323029c49648SArnd Bergmann if (in_compat_syscall()) { 323129c49648SArnd Bergmann struct compat_ifreq *ifr32 = (struct compat_ifreq *)ifr; 323229c49648SArnd Bergmann 323329c49648SArnd Bergmann memset(ifr, 0, sizeof(*ifr)); 323429c49648SArnd Bergmann if (copy_from_user(ifr32, arg, sizeof(*ifr32))) 323529c49648SArnd Bergmann return -EFAULT; 323629c49648SArnd Bergmann 323729c49648SArnd Bergmann if (ifrdata) 323829c49648SArnd Bergmann *ifrdata = compat_ptr(ifr32->ifr_data); 323929c49648SArnd Bergmann 324029c49648SArnd Bergmann return 0; 324129c49648SArnd Bergmann } 324229c49648SArnd Bergmann 324329c49648SArnd Bergmann if (copy_from_user(ifr, arg, sizeof(*ifr))) 324429c49648SArnd Bergmann return -EFAULT; 324529c49648SArnd Bergmann 324629c49648SArnd Bergmann if (ifrdata) 324729c49648SArnd Bergmann *ifrdata = ifr->ifr_data; 324829c49648SArnd Bergmann 324929c49648SArnd Bergmann return 0; 325029c49648SArnd Bergmann } 325129c49648SArnd Bergmann EXPORT_SYMBOL(get_user_ifreq); 325229c49648SArnd Bergmann 325329c49648SArnd Bergmann int put_user_ifreq(struct ifreq *ifr, void __user *arg) 325429c49648SArnd Bergmann { 325529c49648SArnd Bergmann size_t size = sizeof(*ifr); 325629c49648SArnd Bergmann 325729c49648SArnd Bergmann if (in_compat_syscall()) 325829c49648SArnd Bergmann size = sizeof(struct compat_ifreq); 325929c49648SArnd Bergmann 326029c49648SArnd Bergmann if (copy_to_user(arg, ifr, size)) 326129c49648SArnd Bergmann return -EFAULT; 326229c49648SArnd Bergmann 326329c49648SArnd Bergmann return 0; 326429c49648SArnd Bergmann } 326529c49648SArnd Bergmann EXPORT_SYMBOL(put_user_ifreq); 326629c49648SArnd Bergmann 326789bbfc95SShaun Pereira #ifdef CONFIG_COMPAT 32687a50a240SArnd Bergmann static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32) 32697a50a240SArnd Bergmann { 32707a50a240SArnd Bergmann compat_uptr_t uptr32; 327144c02a2cSAl Viro struct ifreq ifr; 327244c02a2cSAl Viro void __user *saved; 327344c02a2cSAl Viro int err; 32747a50a240SArnd Bergmann 327529c49648SArnd Bergmann if (get_user_ifreq(&ifr, NULL, uifr32)) 32767a50a240SArnd Bergmann return -EFAULT; 32777a50a240SArnd Bergmann 32787a50a240SArnd Bergmann if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu)) 32797a50a240SArnd Bergmann return -EFAULT; 32807a50a240SArnd Bergmann 328144c02a2cSAl Viro saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc; 328244c02a2cSAl Viro ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32); 32837a50a240SArnd Bergmann 3284a554bf96SArnd Bergmann err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL, NULL); 328544c02a2cSAl Viro if (!err) { 328644c02a2cSAl Viro ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved; 328729c49648SArnd Bergmann if (put_user_ifreq(&ifr, uifr32)) 328844c02a2cSAl Viro err = -EFAULT; 32897a50a240SArnd Bergmann } 32907a229387SArnd Bergmann return err; 32917a229387SArnd Bergmann } 32927a229387SArnd Bergmann 3293590d4693SBen Hutchings /* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */ 3294590d4693SBen Hutchings static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd, 32956b96018bSArnd Bergmann struct compat_ifreq __user *u_ifreq32) 32967a229387SArnd Bergmann { 329744c02a2cSAl Viro struct ifreq ifreq; 3298a554bf96SArnd Bergmann void __user *data; 32997a229387SArnd Bergmann 3300d0efb162SPeter Collingbourne if (!is_socket_ioctl_cmd(cmd)) 3301d0efb162SPeter Collingbourne return -ENOTTY; 3302a554bf96SArnd Bergmann if (get_user_ifreq(&ifreq, &data, u_ifreq32)) 33037a229387SArnd Bergmann return -EFAULT; 3304a554bf96SArnd Bergmann ifreq.ifr_data = data; 33057a229387SArnd Bergmann 3306a554bf96SArnd Bergmann return dev_ioctl(net, cmd, &ifreq, data, NULL); 33077a229387SArnd Bergmann } 33087a229387SArnd Bergmann 33096b96018bSArnd Bergmann static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, 33106b96018bSArnd Bergmann unsigned int cmd, unsigned long arg) 33116b96018bSArnd Bergmann { 33126b96018bSArnd Bergmann void __user *argp = compat_ptr(arg); 33136b96018bSArnd Bergmann struct sock *sk = sock->sk; 33146b96018bSArnd Bergmann struct net *net = sock_net(sk); 33157a229387SArnd Bergmann 33166b96018bSArnd Bergmann if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) 331788fc023fSArnd Bergmann return sock_ioctl(file, cmd, (unsigned long)argp); 33187a229387SArnd Bergmann 33196b96018bSArnd Bergmann switch (cmd) { 33207a50a240SArnd Bergmann case SIOCWANDEV: 33217a50a240SArnd Bergmann return compat_siocwandev(net, argp); 33220768e170SArnd Bergmann case SIOCGSTAMP_OLD: 33230768e170SArnd Bergmann case SIOCGSTAMPNS_OLD: 3324c7cbdbf2SArnd Bergmann if (!sock->ops->gettstamp) 3325c7cbdbf2SArnd Bergmann return -ENOIOCTLCMD; 33260768e170SArnd Bergmann return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD, 3327c7cbdbf2SArnd Bergmann !COMPAT_USE_64BIT_TIME); 3328c7cbdbf2SArnd Bergmann 3329dd98d289SArnd Bergmann case SIOCETHTOOL: 3330590d4693SBen Hutchings case SIOCBONDSLAVEINFOQUERY: 3331590d4693SBen Hutchings case SIOCBONDINFOQUERY: 3332a2116ed2SArnd Bergmann case SIOCSHWTSTAMP: 3333fd468c74SBen Hutchings case SIOCGHWTSTAMP: 3334590d4693SBen Hutchings return compat_ifr_data_ioctl(net, cmd, argp); 33357a229387SArnd Bergmann 33366b96018bSArnd Bergmann case FIOSETOWN: 33376b96018bSArnd Bergmann case SIOCSPGRP: 33386b96018bSArnd Bergmann case FIOGETOWN: 33396b96018bSArnd Bergmann case SIOCGPGRP: 33406b96018bSArnd Bergmann case SIOCBRADDBR: 33416b96018bSArnd Bergmann case SIOCBRDELBR: 33426b96018bSArnd Bergmann case SIOCGIFVLAN: 33436b96018bSArnd Bergmann case SIOCSIFVLAN: 3344c62cce2cSAndrey Vagin case SIOCGSKNS: 33450768e170SArnd Bergmann case SIOCGSTAMP_NEW: 33460768e170SArnd Bergmann case SIOCGSTAMPNS_NEW: 3347876f0bf9SArnd Bergmann case SIOCGIFCONF: 3348fd3a4590SRemi Pommarel case SIOCSIFBR: 3349fd3a4590SRemi Pommarel case SIOCGIFBR: 33506b96018bSArnd Bergmann return sock_ioctl(file, cmd, arg); 33516b96018bSArnd Bergmann 33526b96018bSArnd Bergmann case SIOCGIFFLAGS: 33536b96018bSArnd Bergmann case SIOCSIFFLAGS: 3354709566d7SArnd Bergmann case SIOCGIFMAP: 3355709566d7SArnd Bergmann case SIOCSIFMAP: 33566b96018bSArnd Bergmann case SIOCGIFMETRIC: 33576b96018bSArnd Bergmann case SIOCSIFMETRIC: 33586b96018bSArnd Bergmann case SIOCGIFMTU: 33596b96018bSArnd Bergmann case SIOCSIFMTU: 33606b96018bSArnd Bergmann case SIOCGIFMEM: 33616b96018bSArnd Bergmann case SIOCSIFMEM: 33626b96018bSArnd Bergmann case SIOCGIFHWADDR: 33636b96018bSArnd Bergmann case SIOCSIFHWADDR: 33646b96018bSArnd Bergmann case SIOCADDMULTI: 33656b96018bSArnd Bergmann case SIOCDELMULTI: 33666b96018bSArnd Bergmann case SIOCGIFINDEX: 33676b96018bSArnd Bergmann case SIOCGIFADDR: 33686b96018bSArnd Bergmann case SIOCSIFADDR: 33696b96018bSArnd Bergmann case SIOCSIFHWBROADCAST: 33706b96018bSArnd Bergmann case SIOCDIFADDR: 33716b96018bSArnd Bergmann case SIOCGIFBRDADDR: 33726b96018bSArnd Bergmann case SIOCSIFBRDADDR: 33736b96018bSArnd Bergmann case SIOCGIFDSTADDR: 33746b96018bSArnd Bergmann case SIOCSIFDSTADDR: 33756b96018bSArnd Bergmann case SIOCGIFNETMASK: 33766b96018bSArnd Bergmann case SIOCSIFNETMASK: 33776b96018bSArnd Bergmann case SIOCSIFPFLAGS: 33786b96018bSArnd Bergmann case SIOCGIFPFLAGS: 33796b96018bSArnd Bergmann case SIOCGIFTXQLEN: 33806b96018bSArnd Bergmann case SIOCSIFTXQLEN: 33816b96018bSArnd Bergmann case SIOCBRADDIF: 33826b96018bSArnd Bergmann case SIOCBRDELIF: 3383c6c9fee3SJohannes Berg case SIOCGIFNAME: 33849177efd3SArnd Bergmann case SIOCSIFNAME: 33859177efd3SArnd Bergmann case SIOCGMIIPHY: 33869177efd3SArnd Bergmann case SIOCGMIIREG: 33879177efd3SArnd Bergmann case SIOCSMIIREG: 3388f92d4fc9SAl Viro case SIOCBONDENSLAVE: 3389f92d4fc9SAl Viro case SIOCBONDRELEASE: 3390f92d4fc9SAl Viro case SIOCBONDSETHWADDR: 3391f92d4fc9SAl Viro case SIOCBONDCHANGEACTIVE: 33926b96018bSArnd Bergmann case SIOCSARP: 33936b96018bSArnd Bergmann case SIOCGARP: 33946b96018bSArnd Bergmann case SIOCDARP: 3395c7dc504eSArnd Bergmann case SIOCOUTQ: 33969d7bf41fSArnd Bergmann case SIOCOUTQNSD: 33976b96018bSArnd Bergmann case SIOCATMARK: 339863ff03abSJohannes Berg return sock_do_ioctl(net, sock, cmd, arg); 33999177efd3SArnd Bergmann } 34009177efd3SArnd Bergmann 34016b96018bSArnd Bergmann return -ENOIOCTLCMD; 34026b96018bSArnd Bergmann } 34037a229387SArnd Bergmann 340495c96174SEric Dumazet static long compat_sock_ioctl(struct file *file, unsigned int cmd, 340589bbfc95SShaun Pereira unsigned long arg) 340689bbfc95SShaun Pereira { 340789bbfc95SShaun Pereira struct socket *sock = file->private_data; 340889bbfc95SShaun Pereira int ret = -ENOIOCTLCMD; 340987de87d5SDavid S. Miller struct sock *sk; 341087de87d5SDavid S. Miller struct net *net; 341187de87d5SDavid S. Miller 341287de87d5SDavid S. Miller sk = sock->sk; 341387de87d5SDavid S. Miller net = sock_net(sk); 341489bbfc95SShaun Pereira 341589bbfc95SShaun Pereira if (sock->ops->compat_ioctl) 341689bbfc95SShaun Pereira ret = sock->ops->compat_ioctl(sock, cmd, arg); 341789bbfc95SShaun Pereira 341887de87d5SDavid S. Miller if (ret == -ENOIOCTLCMD && 341987de87d5SDavid S. Miller (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)) 342087de87d5SDavid S. Miller ret = compat_wext_handle_ioctl(net, cmd, arg); 342187de87d5SDavid S. Miller 34226b96018bSArnd Bergmann if (ret == -ENOIOCTLCMD) 34236b96018bSArnd Bergmann ret = compat_sock_ioctl_trans(file, sock, cmd, arg); 34246b96018bSArnd Bergmann 342589bbfc95SShaun Pereira return ret; 342689bbfc95SShaun Pereira } 342789bbfc95SShaun Pereira #endif 342889bbfc95SShaun Pereira 34298a3c245cSPedro Tammela /** 34308a3c245cSPedro Tammela * kernel_bind - bind an address to a socket (kernel space) 34318a3c245cSPedro Tammela * @sock: socket 34328a3c245cSPedro Tammela * @addr: address 34338a3c245cSPedro Tammela * @addrlen: length of address 34348a3c245cSPedro Tammela * 34358a3c245cSPedro Tammela * Returns 0 or an error. 34368a3c245cSPedro Tammela */ 34378a3c245cSPedro Tammela 3438ac5a488eSSridhar Samudrala int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen) 3439ac5a488eSSridhar Samudrala { 3440ac5a488eSSridhar Samudrala return sock->ops->bind(sock, addr, addrlen); 3441ac5a488eSSridhar Samudrala } 3442c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_bind); 3443ac5a488eSSridhar Samudrala 34448a3c245cSPedro Tammela /** 34458a3c245cSPedro Tammela * kernel_listen - move socket to listening state (kernel space) 34468a3c245cSPedro Tammela * @sock: socket 34478a3c245cSPedro Tammela * @backlog: pending connections queue size 34488a3c245cSPedro Tammela * 34498a3c245cSPedro Tammela * Returns 0 or an error. 34508a3c245cSPedro Tammela */ 34518a3c245cSPedro Tammela 3452ac5a488eSSridhar Samudrala int kernel_listen(struct socket *sock, int backlog) 3453ac5a488eSSridhar Samudrala { 3454ac5a488eSSridhar Samudrala return sock->ops->listen(sock, backlog); 3455ac5a488eSSridhar Samudrala } 3456c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_listen); 3457ac5a488eSSridhar Samudrala 34588a3c245cSPedro Tammela /** 34598a3c245cSPedro Tammela * kernel_accept - accept a connection (kernel space) 34608a3c245cSPedro Tammela * @sock: listening socket 34618a3c245cSPedro Tammela * @newsock: new connected socket 34628a3c245cSPedro Tammela * @flags: flags 34638a3c245cSPedro Tammela * 34648a3c245cSPedro Tammela * @flags must be SOCK_CLOEXEC, SOCK_NONBLOCK or 0. 34658a3c245cSPedro Tammela * If it fails, @newsock is guaranteed to be %NULL. 34668a3c245cSPedro Tammela * Returns 0 or an error. 34678a3c245cSPedro Tammela */ 34688a3c245cSPedro Tammela 3469ac5a488eSSridhar Samudrala int kernel_accept(struct socket *sock, struct socket **newsock, int flags) 3470ac5a488eSSridhar Samudrala { 3471ac5a488eSSridhar Samudrala struct sock *sk = sock->sk; 3472ac5a488eSSridhar Samudrala int err; 3473ac5a488eSSridhar Samudrala 3474ac5a488eSSridhar Samudrala err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol, 3475ac5a488eSSridhar Samudrala newsock); 3476ac5a488eSSridhar Samudrala if (err < 0) 3477ac5a488eSSridhar Samudrala goto done; 3478ac5a488eSSridhar Samudrala 3479cdfbabfbSDavid Howells err = sock->ops->accept(sock, *newsock, flags, true); 3480ac5a488eSSridhar Samudrala if (err < 0) { 3481ac5a488eSSridhar Samudrala sock_release(*newsock); 3482fa8705b0STony Battersby *newsock = NULL; 3483ac5a488eSSridhar Samudrala goto done; 3484ac5a488eSSridhar Samudrala } 3485ac5a488eSSridhar Samudrala 3486ac5a488eSSridhar Samudrala (*newsock)->ops = sock->ops; 34871b08534eSWei Yongjun __module_get((*newsock)->ops->owner); 3488ac5a488eSSridhar Samudrala 3489ac5a488eSSridhar Samudrala done: 3490ac5a488eSSridhar Samudrala return err; 3491ac5a488eSSridhar Samudrala } 3492c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_accept); 3493ac5a488eSSridhar Samudrala 34948a3c245cSPedro Tammela /** 34958a3c245cSPedro Tammela * kernel_connect - connect a socket (kernel space) 34968a3c245cSPedro Tammela * @sock: socket 34978a3c245cSPedro Tammela * @addr: address 34988a3c245cSPedro Tammela * @addrlen: address length 34998a3c245cSPedro Tammela * @flags: flags (O_NONBLOCK, ...) 35008a3c245cSPedro Tammela * 3501f1dcffccSLu Wei * For datagram sockets, @addr is the address to which datagrams are sent 35028a3c245cSPedro Tammela * by default, and the only address from which datagrams are received. 35038a3c245cSPedro Tammela * For stream sockets, attempts to connect to @addr. 35048a3c245cSPedro Tammela * Returns 0 or an error code. 35058a3c245cSPedro Tammela */ 35068a3c245cSPedro Tammela 3507ac5a488eSSridhar Samudrala int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen, 3508ac5a488eSSridhar Samudrala int flags) 3509ac5a488eSSridhar Samudrala { 3510ac5a488eSSridhar Samudrala return sock->ops->connect(sock, addr, addrlen, flags); 3511ac5a488eSSridhar Samudrala } 3512c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_connect); 3513ac5a488eSSridhar Samudrala 35148a3c245cSPedro Tammela /** 35158a3c245cSPedro Tammela * kernel_getsockname - get the address which the socket is bound (kernel space) 35168a3c245cSPedro Tammela * @sock: socket 35178a3c245cSPedro Tammela * @addr: address holder 35188a3c245cSPedro Tammela * 35198a3c245cSPedro Tammela * Fills the @addr pointer with the address which the socket is bound. 35200fc95decSAlex Maydanik * Returns the length of the address in bytes or an error code. 35218a3c245cSPedro Tammela */ 35228a3c245cSPedro Tammela 35239b2c45d4SDenys Vlasenko int kernel_getsockname(struct socket *sock, struct sockaddr *addr) 3524ac5a488eSSridhar Samudrala { 35259b2c45d4SDenys Vlasenko return sock->ops->getname(sock, addr, 0); 3526ac5a488eSSridhar Samudrala } 3527c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_getsockname); 3528ac5a488eSSridhar Samudrala 35298a3c245cSPedro Tammela /** 3530645f0897SMiaohe Lin * kernel_getpeername - get the address which the socket is connected (kernel space) 35318a3c245cSPedro Tammela * @sock: socket 35328a3c245cSPedro Tammela * @addr: address holder 35338a3c245cSPedro Tammela * 35348a3c245cSPedro Tammela * Fills the @addr pointer with the address which the socket is connected. 35350fc95decSAlex Maydanik * Returns the length of the address in bytes or an error code. 35368a3c245cSPedro Tammela */ 35378a3c245cSPedro Tammela 35389b2c45d4SDenys Vlasenko int kernel_getpeername(struct socket *sock, struct sockaddr *addr) 3539ac5a488eSSridhar Samudrala { 35409b2c45d4SDenys Vlasenko return sock->ops->getname(sock, addr, 1); 3541ac5a488eSSridhar Samudrala } 3542c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_getpeername); 3543ac5a488eSSridhar Samudrala 35448a3c245cSPedro Tammela /** 35458a3c245cSPedro Tammela * kernel_sendpage - send a &page through a socket (kernel space) 35468a3c245cSPedro Tammela * @sock: socket 35478a3c245cSPedro Tammela * @page: page 35488a3c245cSPedro Tammela * @offset: page offset 35498a3c245cSPedro Tammela * @size: total size in bytes 35508a3c245cSPedro Tammela * @flags: flags (MSG_DONTWAIT, ...) 35518a3c245cSPedro Tammela * 35528a3c245cSPedro Tammela * Returns the total amount sent in bytes or an error. 35538a3c245cSPedro Tammela */ 35548a3c245cSPedro Tammela 3555ac5a488eSSridhar Samudrala int kernel_sendpage(struct socket *sock, struct page *page, int offset, 3556ac5a488eSSridhar Samudrala size_t size, int flags) 3557ac5a488eSSridhar Samudrala { 35587b62d31dSColy Li if (sock->ops->sendpage) { 35597b62d31dSColy Li /* Warn in case the improper page to zero-copy send */ 35607b62d31dSColy Li WARN_ONCE(!sendpage_ok(page), "improper page for zero-copy send"); 3561ac5a488eSSridhar Samudrala return sock->ops->sendpage(sock, page, offset, size, flags); 35627b62d31dSColy Li } 3563ac5a488eSSridhar Samudrala return sock_no_sendpage(sock, page, offset, size, flags); 3564ac5a488eSSridhar Samudrala } 3565c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_sendpage); 3566ac5a488eSSridhar Samudrala 35678a3c245cSPedro Tammela /** 35688a3c245cSPedro Tammela * kernel_sendpage_locked - send a &page through the locked sock (kernel space) 35698a3c245cSPedro Tammela * @sk: sock 35708a3c245cSPedro Tammela * @page: page 35718a3c245cSPedro Tammela * @offset: page offset 35728a3c245cSPedro Tammela * @size: total size in bytes 35738a3c245cSPedro Tammela * @flags: flags (MSG_DONTWAIT, ...) 35748a3c245cSPedro Tammela * 35758a3c245cSPedro Tammela * Returns the total amount sent in bytes or an error. 35768a3c245cSPedro Tammela * Caller must hold @sk. 35778a3c245cSPedro Tammela */ 35788a3c245cSPedro Tammela 3579306b13ebSTom Herbert int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset, 3580306b13ebSTom Herbert size_t size, int flags) 3581306b13ebSTom Herbert { 3582306b13ebSTom Herbert struct socket *sock = sk->sk_socket; 3583306b13ebSTom Herbert 3584306b13ebSTom Herbert if (sock->ops->sendpage_locked) 3585306b13ebSTom Herbert return sock->ops->sendpage_locked(sk, page, offset, size, 3586306b13ebSTom Herbert flags); 3587306b13ebSTom Herbert 3588306b13ebSTom Herbert return sock_no_sendpage_locked(sk, page, offset, size, flags); 3589306b13ebSTom Herbert } 3590306b13ebSTom Herbert EXPORT_SYMBOL(kernel_sendpage_locked); 3591306b13ebSTom Herbert 35928a3c245cSPedro Tammela /** 3593645f0897SMiaohe Lin * kernel_sock_shutdown - shut down part of a full-duplex connection (kernel space) 35948a3c245cSPedro Tammela * @sock: socket 35958a3c245cSPedro Tammela * @how: connection part 35968a3c245cSPedro Tammela * 35978a3c245cSPedro Tammela * Returns 0 or an error. 35988a3c245cSPedro Tammela */ 35998a3c245cSPedro Tammela 360091cf45f0STrond Myklebust int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how) 360191cf45f0STrond Myklebust { 360291cf45f0STrond Myklebust return sock->ops->shutdown(sock, how); 360391cf45f0STrond Myklebust } 360491cf45f0STrond Myklebust EXPORT_SYMBOL(kernel_sock_shutdown); 3605113c3075SR. Parameswaran 36068a3c245cSPedro Tammela /** 36078a3c245cSPedro Tammela * kernel_sock_ip_overhead - returns the IP overhead imposed by a socket 36088a3c245cSPedro Tammela * @sk: socket 36098a3c245cSPedro Tammela * 36108a3c245cSPedro Tammela * This routine returns the IP overhead imposed by a socket i.e. 3611113c3075SR. Parameswaran * the length of the underlying IP header, depending on whether 3612113c3075SR. Parameswaran * this is an IPv4 or IPv6 socket and the length from IP options turned 361357240d00SR. Parameswaran * on at the socket. Assumes that the caller has a lock on the socket. 3614113c3075SR. Parameswaran */ 36158a3c245cSPedro Tammela 3616113c3075SR. Parameswaran u32 kernel_sock_ip_overhead(struct sock *sk) 3617113c3075SR. Parameswaran { 3618113c3075SR. Parameswaran struct inet_sock *inet; 3619113c3075SR. Parameswaran struct ip_options_rcu *opt; 3620113c3075SR. Parameswaran u32 overhead = 0; 3621113c3075SR. Parameswaran #if IS_ENABLED(CONFIG_IPV6) 3622113c3075SR. Parameswaran struct ipv6_pinfo *np; 3623113c3075SR. Parameswaran struct ipv6_txoptions *optv6 = NULL; 3624113c3075SR. Parameswaran #endif /* IS_ENABLED(CONFIG_IPV6) */ 3625113c3075SR. Parameswaran 3626113c3075SR. Parameswaran if (!sk) 3627113c3075SR. Parameswaran return overhead; 3628113c3075SR. Parameswaran 3629113c3075SR. Parameswaran switch (sk->sk_family) { 3630113c3075SR. Parameswaran case AF_INET: 3631113c3075SR. Parameswaran inet = inet_sk(sk); 3632113c3075SR. Parameswaran overhead += sizeof(struct iphdr); 3633113c3075SR. Parameswaran opt = rcu_dereference_protected(inet->inet_opt, 3634614d79c0Sstephen hemminger sock_owned_by_user(sk)); 3635113c3075SR. Parameswaran if (opt) 3636113c3075SR. Parameswaran overhead += opt->opt.optlen; 3637113c3075SR. Parameswaran return overhead; 3638113c3075SR. Parameswaran #if IS_ENABLED(CONFIG_IPV6) 3639113c3075SR. Parameswaran case AF_INET6: 3640113c3075SR. Parameswaran np = inet6_sk(sk); 3641113c3075SR. Parameswaran overhead += sizeof(struct ipv6hdr); 3642113c3075SR. Parameswaran if (np) 3643113c3075SR. Parameswaran optv6 = rcu_dereference_protected(np->opt, 3644614d79c0Sstephen hemminger sock_owned_by_user(sk)); 3645113c3075SR. Parameswaran if (optv6) 3646113c3075SR. Parameswaran overhead += (optv6->opt_flen + optv6->opt_nflen); 3647113c3075SR. Parameswaran return overhead; 3648113c3075SR. Parameswaran #endif /* IS_ENABLED(CONFIG_IPV6) */ 3649113c3075SR. Parameswaran default: /* Returns 0 overhead if the socket is not ipv4 or ipv6 */ 3650113c3075SR. Parameswaran return overhead; 3651113c3075SR. Parameswaran } 3652113c3075SR. Parameswaran } 3653113c3075SR. Parameswaran EXPORT_SYMBOL(kernel_sock_ip_overhead); 3654