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