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, <[email protected]>
802c30a84SJesper Juhl * Ross Biro
91da177e4SLinus Torvalds * Fred N. van Kempen, <[email protected]>
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>
602dc334f1SDavid Howells #include <linux/splice.h>
611da177e4SLinus Torvalds #include <linux/net.h>
621da177e4SLinus Torvalds #include <linux/interrupt.h>
63aaca0bdcSUlrich Drepper #include <linux/thread_info.h>
6455737fdaSStephen Hemminger #include <linux/rcupdate.h>
651da177e4SLinus Torvalds #include <linux/netdevice.h>
661da177e4SLinus Torvalds #include <linux/proc_fs.h>
671da177e4SLinus Torvalds #include <linux/seq_file.h>
684a3e2f71SArjan van de Ven #include <linux/mutex.h>
691da177e4SLinus Torvalds #include <linux/if_bridge.h>
7020380731SArnaldo Carvalho de Melo #include <linux/if_vlan.h>
71408eccceSDaniel Borkmann #include <linux/ptp_classify.h>
721da177e4SLinus Torvalds #include <linux/init.h>
731da177e4SLinus Torvalds #include <linux/poll.h>
741da177e4SLinus Torvalds #include <linux/cache.h>
751da177e4SLinus Torvalds #include <linux/module.h>
761da177e4SLinus Torvalds #include <linux/highmem.h>
771da177e4SLinus Torvalds #include <linux/mount.h>
78fba9be49SDavid Howells #include <linux/pseudo_fs.h>
791da177e4SLinus Torvalds #include <linux/security.h>
801da177e4SLinus Torvalds #include <linux/syscalls.h>
811da177e4SLinus Torvalds #include <linux/compat.h>
821da177e4SLinus Torvalds #include <linux/kmod.h>
833ec3b2fbSDavid Woodhouse #include <linux/audit.h>
84d86b5e0eSAdrian Bunk #include <linux/wireless.h>
851b8d7ae4SEric W. Biederman #include <linux/nsproxy.h>
861fd7317dSNick Black #include <linux/magic.h>
875a0e3ad6STejun Heo #include <linux/slab.h>
88600e1779SMasatake YAMATO #include <linux/xattr.h>
89c8e8cd57SJeremy Cline #include <linux/nospec.h>
908c3c447bSPaolo Abeni #include <linux/indirect_call_wrapper.h>
918c9a6f54SPavel Begunkov #include <linux/io_uring/net.h>
921da177e4SLinus Torvalds
937c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
941da177e4SLinus Torvalds #include <asm/unistd.h>
951da177e4SLinus Torvalds
961da177e4SLinus Torvalds #include <net/compat.h>
9787de87d5SDavid S. Miller #include <net/wext.h>
98f8451725SHerbert Xu #include <net/cls_cgroup.h>
991da177e4SLinus Torvalds
1001da177e4SLinus Torvalds #include <net/sock.h>
1011da177e4SLinus Torvalds #include <linux/netfilter.h>
1021da177e4SLinus Torvalds
1036b96018bSArnd Bergmann #include <linux/if_tun.h>
1046b96018bSArnd Bergmann #include <linux/ipv6_route.h>
1056b96018bSArnd Bergmann #include <linux/route.h>
106c7dc504eSArnd Bergmann #include <linux/termios.h>
1076b96018bSArnd Bergmann #include <linux/sockios.h>
108076bb0c8SEliezer Tamir #include <net/busy_poll.h>
109f24b9be5SWillem de Bruijn #include <linux/errqueue.h>
110d7c08826SYangbo Lu #include <linux/ptp_clock_kernel.h>
1116e6eda44SYunhui Cui #include <trace/events/sock.h>
11206021292SEliezer Tamir
11321520e74SJakub Kicinski #include "core/dev.h"
11421520e74SJakub Kicinski
115e0d1095aSCong Wang #ifdef CONFIG_NET_RX_BUSY_POLL
11664b0dc51SEliezer Tamir unsigned int sysctl_net_busy_read __read_mostly;
11764b0dc51SEliezer Tamir unsigned int sysctl_net_busy_poll __read_mostly;
11806021292SEliezer Tamir #endif
1196b96018bSArnd Bergmann
1208ae5e030SAl Viro static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to);
1218ae5e030SAl Viro static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from);
1221da177e4SLinus Torvalds static int sock_mmap(struct file *file, struct vm_area_struct *vma);
1231da177e4SLinus Torvalds
1241da177e4SLinus Torvalds static int sock_close(struct inode *inode, struct file *file);
125a11e1d43SLinus Torvalds static __poll_t sock_poll(struct file *file,
126a11e1d43SLinus Torvalds struct poll_table_struct *wait);
12789bddce5SStephen Hemminger static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
12889bbfc95SShaun Pereira #ifdef CONFIG_COMPAT
12989bbfc95SShaun Pereira static long compat_sock_ioctl(struct file *file,
13089bbfc95SShaun Pereira unsigned int cmd, unsigned long arg);
13189bbfc95SShaun Pereira #endif
1321da177e4SLinus Torvalds static int sock_fasync(int fd, struct file *filp, int on);
1339c55e01cSJens Axboe static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
1349c55e01cSJens Axboe struct pipe_inode_info *pipe, size_t len,
1359c55e01cSJens Axboe unsigned int flags);
1362bfc6685SDavid Howells static void sock_splice_eof(struct file *file);
137542d3065SArnd Bergmann
138542d3065SArnd Bergmann #ifdef CONFIG_PROC_FS
sock_show_fdinfo(struct seq_file * m,struct file * f)139542d3065SArnd Bergmann static void sock_show_fdinfo(struct seq_file *m, struct file *f)
140542d3065SArnd Bergmann {
141542d3065SArnd Bergmann struct socket *sock = f->private_data;
1421ded5e5aSEric Dumazet const struct proto_ops *ops = READ_ONCE(sock->ops);
143542d3065SArnd Bergmann
1441ded5e5aSEric Dumazet if (ops->show_fdinfo)
1451ded5e5aSEric Dumazet ops->show_fdinfo(m, sock);
146542d3065SArnd Bergmann }
147542d3065SArnd Bergmann #else
148542d3065SArnd Bergmann #define sock_show_fdinfo NULL
149542d3065SArnd Bergmann #endif
1501da177e4SLinus Torvalds
1511da177e4SLinus Torvalds /*
1521da177e4SLinus Torvalds * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
1531da177e4SLinus Torvalds * in the operation structures but are done directly via the socketcall() multiplexor.
1541da177e4SLinus Torvalds */
1551da177e4SLinus Torvalds
156da7071d7SArjan van de Ven static const struct file_operations socket_file_ops = {
1571da177e4SLinus Torvalds .owner = THIS_MODULE,
1588ae5e030SAl Viro .read_iter = sock_read_iter,
1598ae5e030SAl Viro .write_iter = sock_write_iter,
1601da177e4SLinus Torvalds .poll = sock_poll,
1611da177e4SLinus Torvalds .unlocked_ioctl = sock_ioctl,
16289bbfc95SShaun Pereira #ifdef CONFIG_COMPAT
16389bbfc95SShaun Pereira .compat_ioctl = compat_sock_ioctl,
16489bbfc95SShaun Pereira #endif
1658e9fad0eSBreno Leitao .uring_cmd = io_uring_cmd_sock,
1661da177e4SLinus Torvalds .mmap = sock_mmap,
1671da177e4SLinus Torvalds .release = sock_close,
1681da177e4SLinus Torvalds .fasync = sock_fasync,
1692dc334f1SDavid Howells .splice_write = splice_to_socket,
1709c55e01cSJens Axboe .splice_read = sock_splice_read,
1712bfc6685SDavid Howells .splice_eof = sock_splice_eof,
172b4653342SKirill Tkhai .show_fdinfo = sock_show_fdinfo,
1731da177e4SLinus Torvalds };
1741da177e4SLinus Torvalds
175fe0bdbdeSYejune Deng static const char * const pf_family_names[] = {
176fe0bdbdeSYejune Deng [PF_UNSPEC] = "PF_UNSPEC",
177fe0bdbdeSYejune Deng [PF_UNIX] = "PF_UNIX/PF_LOCAL",
178fe0bdbdeSYejune Deng [PF_INET] = "PF_INET",
179fe0bdbdeSYejune Deng [PF_AX25] = "PF_AX25",
180fe0bdbdeSYejune Deng [PF_IPX] = "PF_IPX",
181fe0bdbdeSYejune Deng [PF_APPLETALK] = "PF_APPLETALK",
182fe0bdbdeSYejune Deng [PF_NETROM] = "PF_NETROM",
183fe0bdbdeSYejune Deng [PF_BRIDGE] = "PF_BRIDGE",
184fe0bdbdeSYejune Deng [PF_ATMPVC] = "PF_ATMPVC",
185fe0bdbdeSYejune Deng [PF_X25] = "PF_X25",
186fe0bdbdeSYejune Deng [PF_INET6] = "PF_INET6",
187fe0bdbdeSYejune Deng [PF_ROSE] = "PF_ROSE",
188fe0bdbdeSYejune Deng [PF_DECnet] = "PF_DECnet",
189fe0bdbdeSYejune Deng [PF_NETBEUI] = "PF_NETBEUI",
190fe0bdbdeSYejune Deng [PF_SECURITY] = "PF_SECURITY",
191fe0bdbdeSYejune Deng [PF_KEY] = "PF_KEY",
192fe0bdbdeSYejune Deng [PF_NETLINK] = "PF_NETLINK/PF_ROUTE",
193fe0bdbdeSYejune Deng [PF_PACKET] = "PF_PACKET",
194fe0bdbdeSYejune Deng [PF_ASH] = "PF_ASH",
195fe0bdbdeSYejune Deng [PF_ECONET] = "PF_ECONET",
196fe0bdbdeSYejune Deng [PF_ATMSVC] = "PF_ATMSVC",
197fe0bdbdeSYejune Deng [PF_RDS] = "PF_RDS",
198fe0bdbdeSYejune Deng [PF_SNA] = "PF_SNA",
199fe0bdbdeSYejune Deng [PF_IRDA] = "PF_IRDA",
200fe0bdbdeSYejune Deng [PF_PPPOX] = "PF_PPPOX",
201fe0bdbdeSYejune Deng [PF_WANPIPE] = "PF_WANPIPE",
202fe0bdbdeSYejune Deng [PF_LLC] = "PF_LLC",
203fe0bdbdeSYejune Deng [PF_IB] = "PF_IB",
204fe0bdbdeSYejune Deng [PF_MPLS] = "PF_MPLS",
205fe0bdbdeSYejune Deng [PF_CAN] = "PF_CAN",
206fe0bdbdeSYejune Deng [PF_TIPC] = "PF_TIPC",
207fe0bdbdeSYejune Deng [PF_BLUETOOTH] = "PF_BLUETOOTH",
208fe0bdbdeSYejune Deng [PF_IUCV] = "PF_IUCV",
209fe0bdbdeSYejune Deng [PF_RXRPC] = "PF_RXRPC",
210fe0bdbdeSYejune Deng [PF_ISDN] = "PF_ISDN",
211fe0bdbdeSYejune Deng [PF_PHONET] = "PF_PHONET",
212fe0bdbdeSYejune Deng [PF_IEEE802154] = "PF_IEEE802154",
213fe0bdbdeSYejune Deng [PF_CAIF] = "PF_CAIF",
214fe0bdbdeSYejune Deng [PF_ALG] = "PF_ALG",
215fe0bdbdeSYejune Deng [PF_NFC] = "PF_NFC",
216fe0bdbdeSYejune Deng [PF_VSOCK] = "PF_VSOCK",
217fe0bdbdeSYejune Deng [PF_KCM] = "PF_KCM",
218fe0bdbdeSYejune Deng [PF_QIPCRTR] = "PF_QIPCRTR",
219fe0bdbdeSYejune Deng [PF_SMC] = "PF_SMC",
220fe0bdbdeSYejune Deng [PF_XDP] = "PF_XDP",
221bc49d816SJeremy Kerr [PF_MCTP] = "PF_MCTP",
222fe0bdbdeSYejune Deng };
223fe0bdbdeSYejune Deng
2241da177e4SLinus Torvalds /*
2251da177e4SLinus Torvalds * The protocol list. Each protocol is registered in here.
2261da177e4SLinus Torvalds */
2271da177e4SLinus Torvalds
2281da177e4SLinus Torvalds static DEFINE_SPINLOCK(net_family_lock);
229190683a9SEric Dumazet static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
2301da177e4SLinus Torvalds
2311da177e4SLinus Torvalds /*
23289bddce5SStephen Hemminger * Support routines.
23389bddce5SStephen Hemminger * Move socket addresses back and forth across the kernel/user
2341da177e4SLinus Torvalds * divide and look after the messy bits.
2351da177e4SLinus Torvalds */
2361da177e4SLinus Torvalds
2371da177e4SLinus Torvalds /**
2381da177e4SLinus Torvalds * move_addr_to_kernel - copy a socket address into kernel space
2391da177e4SLinus Torvalds * @uaddr: Address in user space
2401da177e4SLinus Torvalds * @kaddr: Address in kernel space
2411da177e4SLinus Torvalds * @ulen: Length in user space
2421da177e4SLinus Torvalds *
2431da177e4SLinus Torvalds * The address is copied into kernel space. If the provided address is
2441da177e4SLinus Torvalds * too long an error code of -EINVAL is returned. If the copy gives
2451da177e4SLinus Torvalds * invalid addresses -EFAULT is returned. On a success 0 is returned.
2461da177e4SLinus Torvalds */
2471da177e4SLinus Torvalds
move_addr_to_kernel(void __user * uaddr,int ulen,struct sockaddr_storage * kaddr)24843db362dSMaciej Żenczykowski int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr)
2491da177e4SLinus Torvalds {
250230b1839SYOSHIFUJI Hideaki if (ulen < 0 || ulen > sizeof(struct sockaddr_storage))
2511da177e4SLinus Torvalds return -EINVAL;
2521da177e4SLinus Torvalds if (ulen == 0)
2531da177e4SLinus Torvalds return 0;
2541da177e4SLinus Torvalds if (copy_from_user(kaddr, uaddr, ulen))
2551da177e4SLinus Torvalds return -EFAULT;
2563ec3b2fbSDavid Woodhouse return audit_sockaddr(ulen, kaddr);
2571da177e4SLinus Torvalds }
2581da177e4SLinus Torvalds
2591da177e4SLinus Torvalds /**
2601da177e4SLinus Torvalds * move_addr_to_user - copy an address to user space
2611da177e4SLinus Torvalds * @kaddr: kernel space address
2621da177e4SLinus Torvalds * @klen: length of address in kernel
2631da177e4SLinus Torvalds * @uaddr: user space address
2641da177e4SLinus Torvalds * @ulen: pointer to user length field
2651da177e4SLinus Torvalds *
2661da177e4SLinus Torvalds * The value pointed to by ulen on entry is the buffer length available.
2671da177e4SLinus Torvalds * This is overwritten with the buffer space used. -EINVAL is returned
2681da177e4SLinus Torvalds * if an overlong buffer is specified or a negative buffer size. -EFAULT
2691da177e4SLinus Torvalds * is returned if either the buffer or the length field are not
2701da177e4SLinus Torvalds * accessible.
2711da177e4SLinus Torvalds * After copying the data up to the limit the user specifies, the true
2721da177e4SLinus Torvalds * length of the data is written over the length limit the user
2731da177e4SLinus Torvalds * specified. Zero is returned for a success.
2741da177e4SLinus Torvalds */
2751da177e4SLinus Torvalds
move_addr_to_user(struct sockaddr_storage * kaddr,int klen,void __user * uaddr,int __user * ulen)27643db362dSMaciej Żenczykowski static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
27711165f14Sstephen hemminger void __user *uaddr, int __user *ulen)
2781da177e4SLinus Torvalds {
2791da177e4SLinus Torvalds int err;
2801da177e4SLinus Torvalds int len;
2811da177e4SLinus Torvalds
28268c6beb3SHannes Frederic Sowa BUG_ON(klen > sizeof(struct sockaddr_storage));
28389bddce5SStephen Hemminger err = get_user(len, ulen);
28489bddce5SStephen Hemminger if (err)
2851da177e4SLinus Torvalds return err;
2861da177e4SLinus Torvalds if (len > klen)
2871da177e4SLinus Torvalds len = klen;
28868c6beb3SHannes Frederic Sowa if (len < 0)
2891da177e4SLinus Torvalds return -EINVAL;
29089bddce5SStephen Hemminger if (len) {
291d6fe3945SSteve Grubb if (audit_sockaddr(klen, kaddr))
292d6fe3945SSteve Grubb return -ENOMEM;
2931da177e4SLinus Torvalds if (copy_to_user(uaddr, kaddr, len))
2941da177e4SLinus Torvalds return -EFAULT;
2951da177e4SLinus Torvalds }
2961da177e4SLinus Torvalds /*
2971da177e4SLinus Torvalds * "fromlen shall refer to the value before truncation.."
2981da177e4SLinus Torvalds * 1003.1g
2991da177e4SLinus Torvalds */
3001da177e4SLinus Torvalds return __put_user(klen, ulen);
3011da177e4SLinus Torvalds }
3021da177e4SLinus Torvalds
30308009a76SAlexey Dobriyan static struct kmem_cache *sock_inode_cachep __ro_after_init;
3041da177e4SLinus Torvalds
sock_alloc_inode(struct super_block * sb)3051da177e4SLinus Torvalds static struct inode *sock_alloc_inode(struct super_block *sb)
3061da177e4SLinus Torvalds {
3071da177e4SLinus Torvalds struct socket_alloc *ei;
30889bddce5SStephen Hemminger
309fd60b288SMuchun Song ei = alloc_inode_sb(sb, sock_inode_cachep, GFP_KERNEL);
3101da177e4SLinus Torvalds if (!ei)
3111da177e4SLinus Torvalds return NULL;
312333f7909SAl Viro init_waitqueue_head(&ei->socket.wq.wait);
313333f7909SAl Viro ei->socket.wq.fasync_list = NULL;
314333f7909SAl Viro ei->socket.wq.flags = 0;
3151da177e4SLinus Torvalds
3161da177e4SLinus Torvalds ei->socket.state = SS_UNCONNECTED;
3171da177e4SLinus Torvalds ei->socket.flags = 0;
3181da177e4SLinus Torvalds ei->socket.ops = NULL;
3191da177e4SLinus Torvalds ei->socket.sk = NULL;
3201da177e4SLinus Torvalds ei->socket.file = NULL;
3211da177e4SLinus Torvalds
3221da177e4SLinus Torvalds return &ei->vfs_inode;
3231da177e4SLinus Torvalds }
3241da177e4SLinus Torvalds
sock_free_inode(struct inode * inode)3256d7855c5SAl Viro static void sock_free_inode(struct inode *inode)
3261da177e4SLinus Torvalds {
32743815482SEric Dumazet struct socket_alloc *ei;
32843815482SEric Dumazet
32943815482SEric Dumazet ei = container_of(inode, struct socket_alloc, vfs_inode);
33043815482SEric Dumazet kmem_cache_free(sock_inode_cachep, ei);
3311da177e4SLinus Torvalds }
3321da177e4SLinus Torvalds
init_once(void * foo)33351cc5068SAlexey Dobriyan static void init_once(void *foo)
3341da177e4SLinus Torvalds {
3351da177e4SLinus Torvalds struct socket_alloc *ei = (struct socket_alloc *)foo;
3361da177e4SLinus Torvalds
3371da177e4SLinus Torvalds inode_init_once(&ei->vfs_inode);
3381da177e4SLinus Torvalds }
3391da177e4SLinus Torvalds
init_inodecache(void)3401e911632Syuan linyu static void init_inodecache(void)
3411da177e4SLinus Torvalds {
3421da177e4SLinus Torvalds sock_inode_cachep = kmem_cache_create("sock_inode_cache",
3431da177e4SLinus Torvalds sizeof(struct socket_alloc),
34489bddce5SStephen Hemminger 0,
34589bddce5SStephen Hemminger (SLAB_HWCACHE_ALIGN |
34689bddce5SStephen Hemminger SLAB_RECLAIM_ACCOUNT |
347d4f01c5eSChengming Zhou SLAB_ACCOUNT),
34820c2df83SPaul Mundt init_once);
3491e911632Syuan linyu BUG_ON(sock_inode_cachep == NULL);
3501da177e4SLinus Torvalds }
3511da177e4SLinus Torvalds
352b87221deSAlexey Dobriyan static const struct super_operations sockfs_ops = {
3531da177e4SLinus Torvalds .alloc_inode = sock_alloc_inode,
3546d7855c5SAl Viro .free_inode = sock_free_inode,
3551da177e4SLinus Torvalds .statfs = simple_statfs,
3561da177e4SLinus Torvalds };
3571da177e4SLinus Torvalds
358c23fbb6bSEric Dumazet /*
359c23fbb6bSEric Dumazet * sockfs_dname() is called from d_path().
360c23fbb6bSEric Dumazet */
sockfs_dname(struct dentry * dentry,char * buffer,int buflen)361c23fbb6bSEric Dumazet static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
362c23fbb6bSEric Dumazet {
3630f60d288SAl Viro return dynamic_dname(buffer, buflen, "socket:[%lu]",
364c5ef6035SDavid Howells d_inode(dentry)->i_ino);
365c23fbb6bSEric Dumazet }
366c23fbb6bSEric Dumazet
3673ba13d17SAl Viro static const struct dentry_operations sockfs_dentry_operations = {
368c23fbb6bSEric Dumazet .d_dname = sockfs_dname,
3691da177e4SLinus Torvalds };
3701da177e4SLinus Torvalds
sockfs_xattr_get(const struct xattr_handler * handler,struct dentry * dentry,struct inode * inode,const char * suffix,void * value,size_t size)371bba0bd31SAndreas Gruenbacher static int sockfs_xattr_get(const struct xattr_handler *handler,
372bba0bd31SAndreas Gruenbacher struct dentry *dentry, struct inode *inode,
373bba0bd31SAndreas Gruenbacher const char *suffix, void *value, size_t size)
374bba0bd31SAndreas Gruenbacher {
375bba0bd31SAndreas Gruenbacher if (value) {
376bba0bd31SAndreas Gruenbacher if (dentry->d_name.len + 1 > size)
377bba0bd31SAndreas Gruenbacher return -ERANGE;
378bba0bd31SAndreas Gruenbacher memcpy(value, dentry->d_name.name, dentry->d_name.len + 1);
379bba0bd31SAndreas Gruenbacher }
380bba0bd31SAndreas Gruenbacher return dentry->d_name.len + 1;
381bba0bd31SAndreas Gruenbacher }
382bba0bd31SAndreas Gruenbacher
383bba0bd31SAndreas Gruenbacher #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
384bba0bd31SAndreas Gruenbacher #define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
385bba0bd31SAndreas Gruenbacher #define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
386bba0bd31SAndreas Gruenbacher
387bba0bd31SAndreas Gruenbacher static const struct xattr_handler sockfs_xattr_handler = {
388bba0bd31SAndreas Gruenbacher .name = XATTR_NAME_SOCKPROTONAME,
389bba0bd31SAndreas Gruenbacher .get = sockfs_xattr_get,
390bba0bd31SAndreas Gruenbacher };
391bba0bd31SAndreas Gruenbacher
sockfs_security_xattr_set(const struct xattr_handler * handler,struct mnt_idmap * idmap,struct dentry * dentry,struct inode * inode,const char * suffix,const void * value,size_t size,int flags)3924a590153SAndreas Gruenbacher static int sockfs_security_xattr_set(const struct xattr_handler *handler,
39339f60c1cSChristian Brauner struct mnt_idmap *idmap,
3944a590153SAndreas Gruenbacher struct dentry *dentry, struct inode *inode,
3954a590153SAndreas Gruenbacher const char *suffix, const void *value,
3964a590153SAndreas Gruenbacher size_t size, int flags)
3974a590153SAndreas Gruenbacher {
3984a590153SAndreas Gruenbacher /* Handled by LSM. */
3994a590153SAndreas Gruenbacher return -EAGAIN;
4004a590153SAndreas Gruenbacher }
4014a590153SAndreas Gruenbacher
4024a590153SAndreas Gruenbacher static const struct xattr_handler sockfs_security_xattr_handler = {
4034a590153SAndreas Gruenbacher .prefix = XATTR_SECURITY_PREFIX,
4044a590153SAndreas Gruenbacher .set = sockfs_security_xattr_set,
4054a590153SAndreas Gruenbacher };
4064a590153SAndreas Gruenbacher
407295d3c44SWedson Almeida Filho static const struct xattr_handler * const sockfs_xattr_handlers[] = {
408bba0bd31SAndreas Gruenbacher &sockfs_xattr_handler,
4094a590153SAndreas Gruenbacher &sockfs_security_xattr_handler,
410bba0bd31SAndreas Gruenbacher NULL
411bba0bd31SAndreas Gruenbacher };
412bba0bd31SAndreas Gruenbacher
sockfs_init_fs_context(struct fs_context * fc)413fba9be49SDavid Howells static int sockfs_init_fs_context(struct fs_context *fc)
414c74a1cbbSAl Viro {
415fba9be49SDavid Howells struct pseudo_fs_context *ctx = init_pseudo(fc, SOCKFS_MAGIC);
416fba9be49SDavid Howells if (!ctx)
417fba9be49SDavid Howells return -ENOMEM;
418fba9be49SDavid Howells ctx->ops = &sockfs_ops;
419fba9be49SDavid Howells ctx->dops = &sockfs_dentry_operations;
420fba9be49SDavid Howells ctx->xattr = sockfs_xattr_handlers;
421fba9be49SDavid Howells return 0;
422c74a1cbbSAl Viro }
423c74a1cbbSAl Viro
424c74a1cbbSAl Viro static struct vfsmount *sock_mnt __read_mostly;
425c74a1cbbSAl Viro
426c74a1cbbSAl Viro static struct file_system_type sock_fs_type = {
427c74a1cbbSAl Viro .name = "sockfs",
428fba9be49SDavid Howells .init_fs_context = sockfs_init_fs_context,
429c74a1cbbSAl Viro .kill_sb = kill_anon_super,
430c74a1cbbSAl Viro };
431c74a1cbbSAl Viro
4321da177e4SLinus Torvalds /*
4331da177e4SLinus Torvalds * Obtains the first available file descriptor and sets it up for use.
4341da177e4SLinus Torvalds *
43539d8c1b6SDavid S. Miller * These functions create file structures and maps them to fd space
43639d8c1b6SDavid S. Miller * of the current process. On success it returns file descriptor
4371da177e4SLinus Torvalds * and file struct implicitly stored in sock->file.
4381da177e4SLinus Torvalds * Note that another thread may close file descriptor before we return
4391da177e4SLinus Torvalds * from this function. We use the fact that now we do not refer
4401da177e4SLinus Torvalds * to socket after mapping. If one day we will need it, this
4411da177e4SLinus Torvalds * function will increment ref. count on file by 1.
4421da177e4SLinus Torvalds *
4431da177e4SLinus Torvalds * In any case returned fd MAY BE not valid!
4441da177e4SLinus Torvalds * This race condition is unavoidable
4451da177e4SLinus Torvalds * with shared fd spaces, we cannot solve it inside kernel,
4461da177e4SLinus Torvalds * but we take care of internal coherence yet.
4471da177e4SLinus Torvalds */
4481da177e4SLinus Torvalds
4498a3c245cSPedro Tammela /**
4508a3c245cSPedro Tammela * sock_alloc_file - Bind a &socket to a &file
4518a3c245cSPedro Tammela * @sock: socket
4528a3c245cSPedro Tammela * @flags: file status flags
4538a3c245cSPedro Tammela * @dname: protocol name
4548a3c245cSPedro Tammela *
4558a3c245cSPedro Tammela * Returns the &file bound with @sock, implicitly storing it
4568a3c245cSPedro Tammela * in sock->file. If dname is %NULL, sets to "".
457649c15c7SThadeu Lima de Souza Cascardo *
458649c15c7SThadeu Lima de Souza Cascardo * On failure @sock is released, and an ERR pointer is returned.
459649c15c7SThadeu Lima de Souza Cascardo *
4608a3c245cSPedro Tammela * This function uses GFP_KERNEL internally.
4618a3c245cSPedro Tammela */
4628a3c245cSPedro Tammela
sock_alloc_file(struct socket * sock,int flags,const char * dname)463aab174f0SLinus Torvalds struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)
4641da177e4SLinus Torvalds {
4657cbe66b6SAl Viro struct file *file;
4661da177e4SLinus Torvalds
467d93aa9d8SAl Viro if (!dname)
468d93aa9d8SAl Viro dname = sock->sk ? sock->sk->sk_prot_creator->name : "";
46939d8c1b6SDavid S. Miller
470d93aa9d8SAl Viro file = alloc_file_pseudo(SOCK_INODE(sock), sock_mnt, dname,
471d93aa9d8SAl Viro O_RDWR | (flags & O_NONBLOCK),
472cc3808f8SAl Viro &socket_file_ops);
473b5ffe634SViresh Kumar if (IS_ERR(file)) {
4748e1611e2SAl Viro sock_release(sock);
47539b65252SAnatol Pomozov return file;
476cc3808f8SAl Viro }
4771da177e4SLinus Torvalds
478fe34db06SJens Axboe file->f_mode |= FMODE_NOWAIT;
4791da177e4SLinus Torvalds sock->file = file;
48007dc3f07SBenjamin LaHaise file->private_data = sock;
481d8e464ecSLinus Torvalds stream_open(SOCK_INODE(sock), file);
4822a42754bSAmir Goldstein /*
4832a42754bSAmir Goldstein * Disable permission and pre-content events, but enable legacy
4842a42754bSAmir Goldstein * inotify events for legacy users.
4852a42754bSAmir Goldstein */
4862a42754bSAmir Goldstein file_set_fsnotify_mode(file, FMODE_NONOTIFY_PERM);
48728407630SAl Viro return file;
4881da177e4SLinus Torvalds }
48956b31d1cSAl Viro EXPORT_SYMBOL(sock_alloc_file);
4901da177e4SLinus Torvalds
sock_map_fd(struct socket * sock,int flags)49156b31d1cSAl Viro static int sock_map_fd(struct socket *sock, int flags)
49239d8c1b6SDavid S. Miller {
49339d8c1b6SDavid S. Miller struct file *newfile;
49428407630SAl Viro int fd = get_unused_fd_flags(flags);
495ce4bb04cSAl Viro if (unlikely(fd < 0)) {
496ce4bb04cSAl Viro sock_release(sock);
4971da177e4SLinus Torvalds return fd;
498ce4bb04cSAl Viro }
4991da177e4SLinus Torvalds
500aab174f0SLinus Torvalds newfile = sock_alloc_file(sock, flags, NULL);
5014546e44cSEnrico Weigelt if (!IS_ERR(newfile)) {
5021da177e4SLinus Torvalds fd_install(fd, newfile);
5031da177e4SLinus Torvalds return fd;
5041da177e4SLinus Torvalds }
50528407630SAl Viro
50628407630SAl Viro put_unused_fd(fd);
50728407630SAl Viro return PTR_ERR(newfile);
5081da177e4SLinus Torvalds }
5091da177e4SLinus Torvalds
5108a3c245cSPedro Tammela /**
5118a3c245cSPedro Tammela * sock_from_file - Return the &socket bounded to @file.
5128a3c245cSPedro Tammela * @file: file
5138a3c245cSPedro Tammela *
514dba4a925SFlorent Revest * On failure returns %NULL.
5158a3c245cSPedro Tammela */
5168a3c245cSPedro Tammela
sock_from_file(struct file * file)517dba4a925SFlorent Revest struct socket *sock_from_file(struct file *file)
5186cb153caSBenjamin LaHaise {
51953c0a58bSAl Viro if (likely(file->f_op == &socket_file_ops))
520da214a47SJens Axboe return file->private_data; /* set in sock_alloc_file */
5216cb153caSBenjamin LaHaise
5226cb153caSBenjamin LaHaise return NULL;
5236cb153caSBenjamin LaHaise }
524406a3c63SJohn Fastabend EXPORT_SYMBOL(sock_from_file);
5256cb153caSBenjamin LaHaise
5261da177e4SLinus Torvalds /**
5271da177e4SLinus Torvalds * sockfd_lookup - Go from a file number to its socket slot
5281da177e4SLinus Torvalds * @fd: file handle
5291da177e4SLinus Torvalds * @err: pointer to an error code return
5301da177e4SLinus Torvalds *
5311da177e4SLinus Torvalds * The file handle passed in is locked and the socket it is bound
532241c4667SRosen, Rami * to is returned. If an error occurs the err pointer is overwritten
5331da177e4SLinus Torvalds * with a negative errno code and NULL is returned. The function checks
5341da177e4SLinus Torvalds * for both invalid handles and passing a handle which is not a socket.
5351da177e4SLinus Torvalds *
5361da177e4SLinus Torvalds * On a success the socket object pointer is returned.
5371da177e4SLinus Torvalds */
5381da177e4SLinus Torvalds
sockfd_lookup(int fd,int * err)5391da177e4SLinus Torvalds struct socket *sockfd_lookup(int fd, int *err)
5401da177e4SLinus Torvalds {
5411da177e4SLinus Torvalds struct file *file;
5421da177e4SLinus Torvalds struct socket *sock;
5431da177e4SLinus Torvalds
54489bddce5SStephen Hemminger file = fget(fd);
54589bddce5SStephen Hemminger if (!file) {
5461da177e4SLinus Torvalds *err = -EBADF;
5471da177e4SLinus Torvalds return NULL;
5481da177e4SLinus Torvalds }
54989bddce5SStephen Hemminger
550dba4a925SFlorent Revest sock = sock_from_file(file);
551dba4a925SFlorent Revest if (!sock) {
552dba4a925SFlorent Revest *err = -ENOTSOCK;
5531da177e4SLinus Torvalds fput(file);
554dba4a925SFlorent Revest }
5556cb153caSBenjamin LaHaise return sock;
5561da177e4SLinus Torvalds }
557c6d409cfSEric Dumazet EXPORT_SYMBOL(sockfd_lookup);
5581da177e4SLinus Torvalds
sockfs_listxattr(struct dentry * dentry,char * buffer,size_t size)559600e1779SMasatake YAMATO static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
560600e1779SMasatake YAMATO size_t size)
561600e1779SMasatake YAMATO {
562600e1779SMasatake YAMATO ssize_t len;
563600e1779SMasatake YAMATO ssize_t used = 0;
564600e1779SMasatake YAMATO
565c5ef6035SDavid Howells len = security_inode_listsecurity(d_inode(dentry), buffer, size);
566600e1779SMasatake YAMATO if (len < 0)
567600e1779SMasatake YAMATO return len;
568600e1779SMasatake YAMATO used += len;
569600e1779SMasatake YAMATO if (buffer) {
570600e1779SMasatake YAMATO if (size < used)
571600e1779SMasatake YAMATO return -ERANGE;
572600e1779SMasatake YAMATO buffer += len;
573600e1779SMasatake YAMATO }
574600e1779SMasatake YAMATO
575600e1779SMasatake YAMATO len = (XATTR_NAME_SOCKPROTONAME_LEN + 1);
576600e1779SMasatake YAMATO used += len;
577600e1779SMasatake YAMATO if (buffer) {
578600e1779SMasatake YAMATO if (size < used)
579600e1779SMasatake YAMATO return -ERANGE;
580600e1779SMasatake YAMATO memcpy(buffer, XATTR_NAME_SOCKPROTONAME, len);
581600e1779SMasatake YAMATO buffer += len;
582600e1779SMasatake YAMATO }
583600e1779SMasatake YAMATO
584600e1779SMasatake YAMATO return used;
585600e1779SMasatake YAMATO }
586600e1779SMasatake YAMATO
sockfs_setattr(struct mnt_idmap * idmap,struct dentry * dentry,struct iattr * iattr)587c1632a0fSChristian Brauner static int sockfs_setattr(struct mnt_idmap *idmap,
588549c7297SChristian Brauner struct dentry *dentry, struct iattr *iattr)
58986741ec2SLorenzo Colitti {
590c1632a0fSChristian Brauner int err = simple_setattr(&nop_mnt_idmap, dentry, iattr);
59186741ec2SLorenzo Colitti
592e1a3a60aSEric Biggers if (!err && (iattr->ia_valid & ATTR_UID)) {
59386741ec2SLorenzo Colitti struct socket *sock = SOCKET_I(d_inode(dentry));
59486741ec2SLorenzo Colitti
5956d8c50dcSCong Wang if (sock->sk)
59686741ec2SLorenzo Colitti sock->sk->sk_uid = iattr->ia_uid;
5976d8c50dcSCong Wang else
5986d8c50dcSCong Wang err = -ENOENT;
59986741ec2SLorenzo Colitti }
60086741ec2SLorenzo Colitti
60186741ec2SLorenzo Colitti return err;
60286741ec2SLorenzo Colitti }
60386741ec2SLorenzo Colitti
604600e1779SMasatake YAMATO static const struct inode_operations sockfs_inode_ops = {
605600e1779SMasatake YAMATO .listxattr = sockfs_listxattr,
60686741ec2SLorenzo Colitti .setattr = sockfs_setattr,
607600e1779SMasatake YAMATO };
608600e1779SMasatake YAMATO
6091da177e4SLinus Torvalds /**
6101da177e4SLinus Torvalds * sock_alloc - allocate a socket
6111da177e4SLinus Torvalds *
6121da177e4SLinus Torvalds * Allocate a new inode and socket object. The two are bound together
6131da177e4SLinus Torvalds * and initialised. The socket is then returned. If we are out of inodes
6148a3c245cSPedro Tammela * NULL is returned. This functions uses GFP_KERNEL internally.
6151da177e4SLinus Torvalds */
6161da177e4SLinus Torvalds
sock_alloc(void)617f4a00aacSTom Herbert struct socket *sock_alloc(void)
6181da177e4SLinus Torvalds {
6191da177e4SLinus Torvalds struct inode *inode;
6201da177e4SLinus Torvalds struct socket *sock;
6211da177e4SLinus Torvalds
622a209dfc7SEric Dumazet inode = new_inode_pseudo(sock_mnt->mnt_sb);
6231da177e4SLinus Torvalds if (!inode)
6241da177e4SLinus Torvalds return NULL;
6251da177e4SLinus Torvalds
6261da177e4SLinus Torvalds sock = SOCKET_I(inode);
6271da177e4SLinus Torvalds
62885fe4025SChristoph Hellwig inode->i_ino = get_next_ino();
6291da177e4SLinus Torvalds inode->i_mode = S_IFSOCK | S_IRWXUGO;
6308192b0c4SDavid Howells inode->i_uid = current_fsuid();
6318192b0c4SDavid Howells inode->i_gid = current_fsgid();
632600e1779SMasatake YAMATO inode->i_op = &sockfs_inode_ops;
6331da177e4SLinus Torvalds
6341da177e4SLinus Torvalds return sock;
6351da177e4SLinus Torvalds }
636f4a00aacSTom Herbert EXPORT_SYMBOL(sock_alloc);
6371da177e4SLinus Torvalds
__sock_release(struct socket * sock,struct inode * inode)6386d8c50dcSCong Wang static void __sock_release(struct socket *sock, struct inode *inode)
6391da177e4SLinus Torvalds {
6401ded5e5aSEric Dumazet const struct proto_ops *ops = READ_ONCE(sock->ops);
6411ded5e5aSEric Dumazet
6421ded5e5aSEric Dumazet if (ops) {
6431ded5e5aSEric Dumazet struct module *owner = ops->owner;
6441da177e4SLinus Torvalds
6456d8c50dcSCong Wang if (inode)
6466d8c50dcSCong Wang inode_lock(inode);
6471ded5e5aSEric Dumazet ops->release(sock);
648ff7b11aaSEric Biggers sock->sk = NULL;
6496d8c50dcSCong Wang if (inode)
6506d8c50dcSCong Wang inode_unlock(inode);
6511da177e4SLinus Torvalds sock->ops = NULL;
6521da177e4SLinus Torvalds module_put(owner);
6531da177e4SLinus Torvalds }
6541da177e4SLinus Torvalds
655333f7909SAl Viro if (sock->wq.fasync_list)
6563410f22eSYang Yingliang pr_err("%s: fasync list not empty!\n", __func__);
6571da177e4SLinus Torvalds
6581da177e4SLinus Torvalds if (!sock->file) {
6591da177e4SLinus Torvalds iput(SOCK_INODE(sock));
6601da177e4SLinus Torvalds return;
6611da177e4SLinus Torvalds }
6621da177e4SLinus Torvalds sock->file = NULL;
6631da177e4SLinus Torvalds }
6646d8c50dcSCong Wang
6659a8ad9acSAndrew Lunn /**
6669a8ad9acSAndrew Lunn * sock_release - close a socket
6679a8ad9acSAndrew Lunn * @sock: socket to close
6689a8ad9acSAndrew Lunn *
6699a8ad9acSAndrew Lunn * The socket is released from the protocol stack if it has a release
6709a8ad9acSAndrew Lunn * callback, and the inode is then released if the socket is bound to
6719a8ad9acSAndrew Lunn * an inode not a file.
6729a8ad9acSAndrew Lunn */
sock_release(struct socket * sock)6736d8c50dcSCong Wang void sock_release(struct socket *sock)
6746d8c50dcSCong Wang {
6756d8c50dcSCong Wang __sock_release(sock, NULL);
6766d8c50dcSCong Wang }
677c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_release);
6781da177e4SLinus Torvalds
__sock_tx_timestamp(__u32 tsflags,__u8 * tx_flags)679822b5bc6SVadim Fedorenko void __sock_tx_timestamp(__u32 tsflags, __u8 *tx_flags)
68020d49473SPatrick Ohly {
681140c55d4SEric Dumazet u8 flags = *tx_flags;
682140c55d4SEric Dumazet
683e6116fc6SWillem de Bruijn if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE)
6842deaf7f4SJason Xing flags |= SKBTX_HW_TSTAMP_NOBPF;
685140c55d4SEric Dumazet
686c14ac945SSoheil Hassas Yeganeh if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE)
687140c55d4SEric Dumazet flags |= SKBTX_SW_TSTAMP;
688140c55d4SEric Dumazet
689c14ac945SSoheil Hassas Yeganeh if (tsflags & SOF_TIMESTAMPING_TX_SCHED)
690140c55d4SEric Dumazet flags |= SKBTX_SCHED_TSTAMP;
691140c55d4SEric Dumazet
692*983e0e4eSPauli Virtanen if (tsflags & SOF_TIMESTAMPING_TX_COMPLETION)
693*983e0e4eSPauli Virtanen flags |= SKBTX_COMPLETION_TSTAMP;
694*983e0e4eSPauli Virtanen
695140c55d4SEric Dumazet *tx_flags = flags;
69620d49473SPatrick Ohly }
69767cc0d40SWillem de Bruijn EXPORT_SYMBOL(__sock_tx_timestamp);
69820d49473SPatrick Ohly
6998c3c447bSPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet_sendmsg(struct socket *, struct msghdr *,
7008c3c447bSPaolo Abeni size_t));
701a648a592SPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet6_sendmsg(struct socket *, struct msghdr *,
702a648a592SPaolo Abeni size_t));
7036e6eda44SYunhui Cui
call_trace_sock_send_length(struct sock * sk,int ret,int flags)7046e6eda44SYunhui Cui static noinline void call_trace_sock_send_length(struct sock *sk, int ret,
7056e6eda44SYunhui Cui int flags)
7066e6eda44SYunhui Cui {
7076e6eda44SYunhui Cui trace_sock_send_length(sk, ret, 0);
7086e6eda44SYunhui Cui }
7096e6eda44SYunhui Cui
sock_sendmsg_nosec(struct socket * sock,struct msghdr * msg)710d8725c86SAl Viro static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
7111da177e4SLinus Torvalds {
7121ded5e5aSEric Dumazet int ret = INDIRECT_CALL_INET(READ_ONCE(sock->ops)->sendmsg, inet6_sendmsg,
713a648a592SPaolo Abeni inet_sendmsg, sock, msg,
714a648a592SPaolo Abeni msg_data_left(msg));
715d8725c86SAl Viro BUG_ON(ret == -EIOCBQUEUED);
7166e6eda44SYunhui Cui
7176e6eda44SYunhui Cui if (trace_sock_send_length_enabled())
7186e6eda44SYunhui Cui call_trace_sock_send_length(sock->sk, ret, 0);
719d8725c86SAl Viro return ret;
7201da177e4SLinus Torvalds }
7210cf00c6fSGu Zheng
__sock_sendmsg(struct socket * sock,struct msghdr * msg)72286a7e0b6SJordan Rife static int __sock_sendmsg(struct socket *sock, struct msghdr *msg)
72386a7e0b6SJordan Rife {
72486a7e0b6SJordan Rife int err = security_socket_sendmsg(sock, msg,
72586a7e0b6SJordan Rife msg_data_left(msg));
72686a7e0b6SJordan Rife
72786a7e0b6SJordan Rife return err ?: sock_sendmsg_nosec(sock, msg);
72886a7e0b6SJordan Rife }
72986a7e0b6SJordan Rife
73085806af0SRandy Dunlap /**
73185806af0SRandy Dunlap * sock_sendmsg - send a message through @sock
73285806af0SRandy Dunlap * @sock: socket
73385806af0SRandy Dunlap * @msg: message to send
73485806af0SRandy Dunlap *
73585806af0SRandy Dunlap * Sends @msg through @sock, passing through LSM.
73685806af0SRandy Dunlap * Returns the number of bytes sent, or an error code.
73785806af0SRandy Dunlap */
sock_sendmsg(struct socket * sock,struct msghdr * msg)738d8725c86SAl Viro int sock_sendmsg(struct socket *sock, struct msghdr *msg)
7390cf00c6fSGu Zheng {
74086a7e0b6SJordan Rife struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name;
74186a7e0b6SJordan Rife struct sockaddr_storage address;
74201b2885dSMarc Dionne int save_len = msg->msg_namelen;
74386a7e0b6SJordan Rife int ret;
7441b784140SYing Xue
74586a7e0b6SJordan Rife if (msg->msg_name) {
74686a7e0b6SJordan Rife memcpy(&address, msg->msg_name, msg->msg_namelen);
74786a7e0b6SJordan Rife msg->msg_name = &address;
74886a7e0b6SJordan Rife }
74986a7e0b6SJordan Rife
75086a7e0b6SJordan Rife ret = __sock_sendmsg(sock, msg);
75186a7e0b6SJordan Rife msg->msg_name = save_addr;
75201b2885dSMarc Dionne msg->msg_namelen = save_len;
75386a7e0b6SJordan Rife
75486a7e0b6SJordan Rife return ret;
7550cf00c6fSGu Zheng }
756c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_sendmsg);
7571da177e4SLinus Torvalds
7588a3c245cSPedro Tammela /**
7598a3c245cSPedro Tammela * kernel_sendmsg - send a message through @sock (kernel-space)
7608a3c245cSPedro Tammela * @sock: socket
7618a3c245cSPedro Tammela * @msg: message header
7628a3c245cSPedro Tammela * @vec: kernel vec
7638a3c245cSPedro Tammela * @num: vec 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 */
7698a3c245cSPedro Tammela
kernel_sendmsg(struct socket * sock,struct msghdr * msg,struct kvec * vec,size_t num,size_t size)7701da177e4SLinus Torvalds int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
7711da177e4SLinus Torvalds struct kvec *vec, size_t num, size_t size)
7721da177e4SLinus Torvalds {
773de4eda9dSAl Viro iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, num, size);
774d8725c86SAl Viro return sock_sendmsg(sock, msg);
7751da177e4SLinus Torvalds }
776c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_sendmsg);
7771da177e4SLinus Torvalds
skb_is_err_queue(const struct sk_buff * skb)7788605330aSSoheil Hassas Yeganeh static bool skb_is_err_queue(const struct sk_buff *skb)
7798605330aSSoheil Hassas Yeganeh {
7808605330aSSoheil Hassas Yeganeh /* pkt_type of skbs enqueued on the error queue are set to
7818605330aSSoheil Hassas Yeganeh * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
7828605330aSSoheil Hassas Yeganeh * in recvmsg, since skbs received on a local socket will never
7838605330aSSoheil Hassas Yeganeh * have a pkt_type of PACKET_OUTGOING.
7848605330aSSoheil Hassas Yeganeh */
7858605330aSSoheil Hassas Yeganeh return skb->pkt_type == PACKET_OUTGOING;
7868605330aSSoheil Hassas Yeganeh }
7878605330aSSoheil Hassas Yeganeh
788b50a5c70SMiroslav Lichvar /* On transmit, software and hardware timestamps are returned independently.
789b50a5c70SMiroslav Lichvar * As the two skb clones share the hardware timestamp, which may be updated
790b50a5c70SMiroslav Lichvar * before the software timestamp is received, a hardware TX timestamp may be
791b50a5c70SMiroslav Lichvar * returned only if there is no software TX timestamp. Ignore false software
792b50a5c70SMiroslav Lichvar * timestamps, which may be made in the __sock_recv_timestamp() call when the
7937f1bc6e9SDeepa Dinamani * option SO_TIMESTAMP_OLD(NS) is enabled on the socket, even when the skb has a
794b50a5c70SMiroslav Lichvar * hardware timestamp.
795b50a5c70SMiroslav Lichvar */
skb_is_swtx_tstamp(const struct sk_buff * skb,int false_tstamp)796b50a5c70SMiroslav Lichvar static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp)
797b50a5c70SMiroslav Lichvar {
798b50a5c70SMiroslav Lichvar return skb->tstamp && !false_tstamp && skb_is_err_queue(skb);
799b50a5c70SMiroslav Lichvar }
800b50a5c70SMiroslav Lichvar
get_timestamp(struct sock * sk,struct sk_buff * skb,int * if_index)80197dc7cd9SGerhard Engleder static ktime_t get_timestamp(struct sock *sk, struct sk_buff *skb, int *if_index)
80297dc7cd9SGerhard Engleder {
803e3390b30SEric Dumazet bool cycles = READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_BIND_PHC;
80497dc7cd9SGerhard Engleder struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
80597dc7cd9SGerhard Engleder struct net_device *orig_dev;
80697dc7cd9SGerhard Engleder ktime_t hwtstamp;
80797dc7cd9SGerhard Engleder
80897dc7cd9SGerhard Engleder rcu_read_lock();
80997dc7cd9SGerhard Engleder orig_dev = dev_get_by_napi_id(skb_napi_id(skb));
81097dc7cd9SGerhard Engleder if (orig_dev) {
81197dc7cd9SGerhard Engleder *if_index = orig_dev->ifindex;
81297dc7cd9SGerhard Engleder hwtstamp = netdev_get_tstamp(orig_dev, shhwtstamps, cycles);
81397dc7cd9SGerhard Engleder } else {
81497dc7cd9SGerhard Engleder hwtstamp = shhwtstamps->hwtstamp;
81597dc7cd9SGerhard Engleder }
81697dc7cd9SGerhard Engleder rcu_read_unlock();
81797dc7cd9SGerhard Engleder
81897dc7cd9SGerhard Engleder return hwtstamp;
81997dc7cd9SGerhard Engleder }
82097dc7cd9SGerhard Engleder
put_ts_pktinfo(struct msghdr * msg,struct sk_buff * skb,int if_index)82197dc7cd9SGerhard Engleder static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb,
82297dc7cd9SGerhard Engleder int if_index)
823aad9c8c4SMiroslav Lichvar {
824aad9c8c4SMiroslav Lichvar struct scm_ts_pktinfo ts_pktinfo;
825aad9c8c4SMiroslav Lichvar struct net_device *orig_dev;
826aad9c8c4SMiroslav Lichvar
827aad9c8c4SMiroslav Lichvar if (!skb_mac_header_was_set(skb))
828aad9c8c4SMiroslav Lichvar return;
829aad9c8c4SMiroslav Lichvar
830aad9c8c4SMiroslav Lichvar memset(&ts_pktinfo, 0, sizeof(ts_pktinfo));
831aad9c8c4SMiroslav Lichvar
83297dc7cd9SGerhard Engleder if (!if_index) {
833aad9c8c4SMiroslav Lichvar rcu_read_lock();
834aad9c8c4SMiroslav Lichvar orig_dev = dev_get_by_napi_id(skb_napi_id(skb));
835aad9c8c4SMiroslav Lichvar if (orig_dev)
83697dc7cd9SGerhard Engleder if_index = orig_dev->ifindex;
837aad9c8c4SMiroslav Lichvar rcu_read_unlock();
83897dc7cd9SGerhard Engleder }
83997dc7cd9SGerhard Engleder ts_pktinfo.if_index = if_index;
840aad9c8c4SMiroslav Lichvar
841aad9c8c4SMiroslav Lichvar ts_pktinfo.pkt_length = skb->len - skb_mac_offset(skb);
842aad9c8c4SMiroslav Lichvar put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO,
843aad9c8c4SMiroslav Lichvar sizeof(ts_pktinfo), &ts_pktinfo);
844aad9c8c4SMiroslav Lichvar }
845aad9c8c4SMiroslav Lichvar
84692f37fd2SEric Dumazet /*
84792f37fd2SEric Dumazet * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
84892f37fd2SEric Dumazet */
__sock_recv_timestamp(struct msghdr * msg,struct sock * sk,struct sk_buff * skb)84992f37fd2SEric Dumazet void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
85092f37fd2SEric Dumazet struct sk_buff *skb)
85192f37fd2SEric Dumazet {
85220d49473SPatrick Ohly int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
853887feae3SDeepa Dinamani int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
8549718475eSDeepa Dinamani struct scm_timestamping_internal tss;
855b50a5c70SMiroslav Lichvar int empty = 1, false_tstamp = 0;
85620d49473SPatrick Ohly struct skb_shared_hwtstamps *shhwtstamps =
85720d49473SPatrick Ohly skb_hwtstamps(skb);
85897dc7cd9SGerhard Engleder int if_index;
859007747a9SMiroslav Lichvar ktime_t hwtstamp;
860e3390b30SEric Dumazet u32 tsflags;
86192f37fd2SEric Dumazet
86220d49473SPatrick Ohly /* Race occurred between timestamp enabling and packet
86320d49473SPatrick Ohly receiving. Fill in the current time for now. */
864b50a5c70SMiroslav Lichvar if (need_software_tstamp && skb->tstamp == 0) {
86520d49473SPatrick Ohly __net_timestamp(skb);
866b50a5c70SMiroslav Lichvar false_tstamp = 1;
867b50a5c70SMiroslav Lichvar }
86820d49473SPatrick Ohly
86920d49473SPatrick Ohly if (need_software_tstamp) {
87092f37fd2SEric Dumazet if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
871887feae3SDeepa Dinamani if (new_tstamp) {
872887feae3SDeepa Dinamani struct __kernel_sock_timeval tv;
873887feae3SDeepa Dinamani
874887feae3SDeepa Dinamani skb_get_new_timestamp(skb, &tv);
875887feae3SDeepa Dinamani put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
876887feae3SDeepa Dinamani sizeof(tv), &tv);
877887feae3SDeepa Dinamani } else {
87813c6ee2aSDeepa Dinamani struct __kernel_old_timeval tv;
879887feae3SDeepa Dinamani
88020d49473SPatrick Ohly skb_get_timestamp(skb, &tv);
8817f1bc6e9SDeepa Dinamani put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
88220d49473SPatrick Ohly sizeof(tv), &tv);
883887feae3SDeepa Dinamani }
884887feae3SDeepa Dinamani } else {
885887feae3SDeepa Dinamani if (new_tstamp) {
886887feae3SDeepa Dinamani struct __kernel_timespec ts;
887887feae3SDeepa Dinamani
888887feae3SDeepa Dinamani skb_get_new_timestampns(skb, &ts);
889887feae3SDeepa Dinamani put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
890887feae3SDeepa Dinamani sizeof(ts), &ts);
89192f37fd2SEric Dumazet } else {
892df1b4ba9SArnd Bergmann struct __kernel_old_timespec ts;
893887feae3SDeepa Dinamani
894f24b9be5SWillem de Bruijn skb_get_timestampns(skb, &ts);
8957f1bc6e9SDeepa Dinamani put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
896f24b9be5SWillem de Bruijn sizeof(ts), &ts);
89792f37fd2SEric Dumazet }
89892f37fd2SEric Dumazet }
899887feae3SDeepa Dinamani }
90092f37fd2SEric Dumazet
901f24b9be5SWillem de Bruijn memset(&tss, 0, sizeof(tss));
902e3390b30SEric Dumazet tsflags = READ_ONCE(sk->sk_tsflags);
903be8e9eb3SJason Xing if ((tsflags & SOF_TIMESTAMPING_SOFTWARE &&
904be8e9eb3SJason Xing (tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
905be8e9eb3SJason Xing skb_is_err_queue(skb) ||
906be8e9eb3SJason Xing !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))) &&
9079718475eSDeepa Dinamani ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
90820d49473SPatrick Ohly empty = 0;
9094d276eb6SWillem de Bruijn if (shhwtstamps &&
910be8e9eb3SJason Xing (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE &&
911be8e9eb3SJason Xing (tsflags & SOF_TIMESTAMPING_RX_HARDWARE ||
912be8e9eb3SJason Xing skb_is_err_queue(skb) ||
913be8e9eb3SJason Xing !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))) &&
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
921e3390b30SEric Dumazet if (tsflags & SOF_TIMESTAMPING_BIND_PHC)
92297dc7cd9SGerhard Engleder hwtstamp = ptp_convert_timestamp(&hwtstamp,
923251cd405SEric Dumazet READ_ONCE(sk->sk_bind_phc));
92497dc7cd9SGerhard Engleder
925007747a9SMiroslav Lichvar if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) {
92620d49473SPatrick Ohly empty = 0;
927d7c08826SYangbo Lu
928e3390b30SEric Dumazet if ((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
947eb6fba75SJakub Kicinski #ifdef CONFIG_WIRELESS
__sock_recv_wifi_status(struct msghdr * msg,struct sock * sk,struct sk_buff * skb)9486e3e939fSJohannes Berg void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
9496e3e939fSJohannes Berg struct sk_buff *skb)
9506e3e939fSJohannes Berg {
9516e3e939fSJohannes Berg int ack;
9526e3e939fSJohannes Berg
9536e3e939fSJohannes Berg if (!sock_flag(sk, SOCK_WIFI_STATUS))
9546e3e939fSJohannes Berg return;
9556e3e939fSJohannes Berg if (!skb->wifi_acked_valid)
9566e3e939fSJohannes Berg return;
9576e3e939fSJohannes Berg
9586e3e939fSJohannes Berg ack = skb->wifi_acked;
9596e3e939fSJohannes Berg
9606e3e939fSJohannes Berg put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack);
9616e3e939fSJohannes Berg }
9626e3e939fSJohannes Berg EXPORT_SYMBOL_GPL(__sock_recv_wifi_status);
963eb6fba75SJakub Kicinski #endif
9646e3e939fSJohannes Berg
sock_recv_drops(struct msghdr * msg,struct sock * sk,struct sk_buff * skb)96511165f14Sstephen hemminger static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
96611165f14Sstephen hemminger struct sk_buff *skb)
9673b885787SNeil Horman {
968744d5a3eSEyal Birger if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount)
9693b885787SNeil Horman put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
970744d5a3eSEyal Birger sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
9713b885787SNeil Horman }
9723b885787SNeil Horman
sock_recv_mark(struct msghdr * msg,struct sock * sk,struct sk_buff * skb)9736fd1d51cSErin MacNeil static void sock_recv_mark(struct msghdr *msg, struct sock *sk,
9746fd1d51cSErin MacNeil struct sk_buff *skb)
9756fd1d51cSErin MacNeil {
9762558b803SEric Dumazet if (sock_flag(sk, SOCK_RCVMARK) && skb) {
9772558b803SEric Dumazet /* We must use a bounce buffer for CONFIG_HARDENED_USERCOPY=y */
9782558b803SEric Dumazet __u32 mark = skb->mark;
9792558b803SEric Dumazet
9802558b803SEric Dumazet put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32), &mark);
9812558b803SEric Dumazet }
9826fd1d51cSErin MacNeil }
9836fd1d51cSErin MacNeil
sock_recv_priority(struct msghdr * msg,struct sock * sk,struct sk_buff * skb)984e45469e5SAnna Emese Nyiri static void sock_recv_priority(struct msghdr *msg, struct sock *sk,
985e45469e5SAnna Emese Nyiri struct sk_buff *skb)
986e45469e5SAnna Emese Nyiri {
987e45469e5SAnna Emese Nyiri if (sock_flag(sk, SOCK_RCVPRIORITY) && skb) {
988e45469e5SAnna Emese Nyiri __u32 priority = skb->priority;
989e45469e5SAnna Emese Nyiri
990e45469e5SAnna Emese Nyiri put_cmsg(msg, SOL_SOCKET, SO_PRIORITY, sizeof(__u32), &priority);
991e45469e5SAnna Emese Nyiri }
992e45469e5SAnna Emese Nyiri }
993e45469e5SAnna Emese Nyiri
__sock_recv_cmsgs(struct msghdr * msg,struct sock * sk,struct sk_buff * skb)9946fd1d51cSErin MacNeil void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
9953b885787SNeil Horman struct sk_buff *skb)
9963b885787SNeil Horman {
9973b885787SNeil Horman sock_recv_timestamp(msg, sk, skb);
9983b885787SNeil Horman sock_recv_drops(msg, sk, skb);
9996fd1d51cSErin MacNeil sock_recv_mark(msg, sk, skb);
1000e45469e5SAnna Emese Nyiri sock_recv_priority(msg, sk, skb);
10013b885787SNeil Horman }
10026fd1d51cSErin MacNeil EXPORT_SYMBOL_GPL(__sock_recv_cmsgs);
10033b885787SNeil Horman
10048c3c447bSPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *,
10058c3c447bSPaolo Abeni size_t, int));
1006a648a592SPaolo Abeni INDIRECT_CALLABLE_DECLARE(int inet6_recvmsg(struct socket *, struct msghdr *,
1007a648a592SPaolo Abeni size_t, int));
10086e6eda44SYunhui Cui
call_trace_sock_recv_length(struct sock * sk,int ret,int flags)10096e6eda44SYunhui Cui static noinline void call_trace_sock_recv_length(struct sock *sk, int ret, int flags)
10106e6eda44SYunhui Cui {
10116e6eda44SYunhui Cui trace_sock_recv_length(sk, ret, flags);
10126e6eda44SYunhui Cui }
10136e6eda44SYunhui Cui
sock_recvmsg_nosec(struct socket * sock,struct msghdr * msg,int flags)10141b784140SYing Xue static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
10151b784140SYing Xue int flags)
1016a2e27255SArnaldo Carvalho de Melo {
10171ded5e5aSEric Dumazet int ret = INDIRECT_CALL_INET(READ_ONCE(sock->ops)->recvmsg,
10181ded5e5aSEric Dumazet inet6_recvmsg,
10196e6eda44SYunhui Cui inet_recvmsg, sock, msg,
10206e6eda44SYunhui Cui msg_data_left(msg), flags);
10216e6eda44SYunhui Cui if (trace_sock_recv_length_enabled())
10226e6eda44SYunhui Cui call_trace_sock_recv_length(sock->sk, ret, flags);
10236e6eda44SYunhui Cui return ret;
10242da62906SAl Viro }
1025a2e27255SArnaldo Carvalho de Melo
102685806af0SRandy Dunlap /**
102785806af0SRandy Dunlap * sock_recvmsg - receive a message from @sock
102885806af0SRandy Dunlap * @sock: socket
102985806af0SRandy Dunlap * @msg: message to receive
103085806af0SRandy Dunlap * @flags: message flags
103185806af0SRandy Dunlap *
103285806af0SRandy Dunlap * Receives @msg from @sock, passing through LSM. Returns the total number
103385806af0SRandy Dunlap * of bytes received, or an error.
103485806af0SRandy Dunlap */
sock_recvmsg(struct socket * sock,struct msghdr * msg,int flags)10352da62906SAl Viro int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags)
10362da62906SAl Viro {
10372da62906SAl Viro int err = security_socket_recvmsg(sock, msg, msg_data_left(msg), flags);
10382da62906SAl Viro
10392da62906SAl Viro return err ?: sock_recvmsg_nosec(sock, msg, flags);
10401da177e4SLinus Torvalds }
1041c6d409cfSEric Dumazet EXPORT_SYMBOL(sock_recvmsg);
10421da177e4SLinus Torvalds
1043c1249c0aSMartin Lucina /**
1044c1249c0aSMartin Lucina * kernel_recvmsg - Receive a message from a socket (kernel space)
1045c1249c0aSMartin Lucina * @sock: The socket to receive the message from
1046c1249c0aSMartin Lucina * @msg: Received message
1047c1249c0aSMartin Lucina * @vec: Input s/g array for message data
1048c1249c0aSMartin Lucina * @num: Size of input s/g array
1049c1249c0aSMartin Lucina * @size: Number of bytes to read
1050c1249c0aSMartin Lucina * @flags: Message flags (MSG_DONTWAIT, etc...)
1051c1249c0aSMartin Lucina *
1052c1249c0aSMartin Lucina * On return the msg structure contains the scatter/gather array passed in the
1053c1249c0aSMartin Lucina * vec argument. The array is modified so that it consists of the unfilled
1054c1249c0aSMartin Lucina * portion of the original array.
1055c1249c0aSMartin Lucina *
1056c1249c0aSMartin Lucina * The returned value is the total number of bytes received, or an error.
1057c1249c0aSMartin Lucina */
10588a3c245cSPedro Tammela
kernel_recvmsg(struct socket * sock,struct msghdr * msg,struct kvec * vec,size_t num,size_t size,int flags)10591da177e4SLinus Torvalds int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
106089bddce5SStephen Hemminger struct kvec *vec, size_t num, size_t size, int flags)
10611da177e4SLinus Torvalds {
10621f466e1fSChristoph Hellwig msg->msg_control_is_user = false;
1063de4eda9dSAl Viro iov_iter_kvec(&msg->msg_iter, ITER_DEST, vec, num, size);
10641f466e1fSChristoph Hellwig return sock_recvmsg(sock, msg, flags);
10651da177e4SLinus Torvalds }
1066c6d409cfSEric Dumazet EXPORT_SYMBOL(kernel_recvmsg);
10671da177e4SLinus Torvalds
sock_splice_read(struct file * file,loff_t * ppos,struct pipe_inode_info * pipe,size_t len,unsigned int flags)10689c55e01cSJens Axboe static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
10699c55e01cSJens Axboe struct pipe_inode_info *pipe, size_t len,
10709c55e01cSJens Axboe unsigned int flags)
10719c55e01cSJens Axboe {
10729c55e01cSJens Axboe struct socket *sock = file->private_data;
10731ded5e5aSEric Dumazet const struct proto_ops *ops;
10749c55e01cSJens Axboe
10751ded5e5aSEric Dumazet ops = READ_ONCE(sock->ops);
10761ded5e5aSEric Dumazet if (unlikely(!ops->splice_read))
107767178fd0SDavid Howells return copy_splice_read(file, ppos, pipe, len, flags);
1078997b37daSRémi Denis-Courmont
10791ded5e5aSEric Dumazet return ops->splice_read(sock, ppos, pipe, len, flags);
10809c55e01cSJens Axboe }
10819c55e01cSJens Axboe
sock_splice_eof(struct file * file)10822bfc6685SDavid Howells static void sock_splice_eof(struct file *file)
10832bfc6685SDavid Howells {
10842bfc6685SDavid Howells struct socket *sock = file->private_data;
10851ded5e5aSEric Dumazet const struct proto_ops *ops;
10862bfc6685SDavid Howells
10871ded5e5aSEric Dumazet ops = READ_ONCE(sock->ops);
10881ded5e5aSEric Dumazet if (ops->splice_eof)
10891ded5e5aSEric Dumazet ops->splice_eof(sock);
10902bfc6685SDavid Howells }
10912bfc6685SDavid Howells
sock_read_iter(struct kiocb * iocb,struct iov_iter * to)10928ae5e030SAl Viro static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
1093ce1d4d3eSChristoph Hellwig {
10946d652330SAl Viro struct file *file = iocb->ki_filp;
10956d652330SAl Viro struct socket *sock = file->private_data;
10960345f931S[email protected] struct msghdr msg = {.msg_iter = *to,
10970345f931S[email protected] .msg_iocb = iocb};
10988ae5e030SAl Viro ssize_t res;
1099ce1d4d3eSChristoph Hellwig
1100ebfcd895SJens Axboe if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT))
11018ae5e030SAl Viro msg.msg_flags = MSG_DONTWAIT;
11028ae5e030SAl Viro
11038ae5e030SAl Viro if (iocb->ki_pos != 0)
1104ce1d4d3eSChristoph Hellwig return -ESPIPE;
1105027445c3SBadari Pulavarty
110666ee59afSChristoph Hellwig if (!iov_iter_count(to)) /* Match SYS5 behaviour */
1107ce1d4d3eSChristoph Hellwig return 0;
1108ce1d4d3eSChristoph Hellwig
11092da62906SAl Viro res = sock_recvmsg(sock, &msg, msg.msg_flags);
11108ae5e030SAl Viro *to = msg.msg_iter;
11118ae5e030SAl Viro return res;
1112ce1d4d3eSChristoph Hellwig }
1113ce1d4d3eSChristoph Hellwig
sock_write_iter(struct kiocb * iocb,struct iov_iter * from)11148ae5e030SAl Viro static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
11151da177e4SLinus Torvalds {
11166d652330SAl Viro struct file *file = iocb->ki_filp;
11176d652330SAl Viro struct socket *sock = file->private_data;
11180345f931S[email protected] struct msghdr msg = {.msg_iter = *from,
11190345f931S[email protected] .msg_iocb = iocb};
11208ae5e030SAl Viro ssize_t res;
11211da177e4SLinus Torvalds
11228ae5e030SAl Viro if (iocb->ki_pos != 0)
1123ce1d4d3eSChristoph Hellwig return -ESPIPE;
1124027445c3SBadari Pulavarty
1125ebfcd895SJens Axboe if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT))
11268ae5e030SAl Viro msg.msg_flags = MSG_DONTWAIT;
11278ae5e030SAl Viro
11286d652330SAl Viro if (sock->type == SOCK_SEQPACKET)
11296d652330SAl Viro msg.msg_flags |= MSG_EOR;
11306d652330SAl Viro
113186a7e0b6SJordan Rife res = __sock_sendmsg(sock, &msg);
11328ae5e030SAl Viro *from = msg.msg_iter;
11338ae5e030SAl Viro return res;
11341da177e4SLinus Torvalds }
11351da177e4SLinus Torvalds
11361da177e4SLinus Torvalds /*
11371da177e4SLinus Torvalds * Atomic setting of ioctl hooks to avoid race
11381da177e4SLinus Torvalds * with module unload.
11391da177e4SLinus Torvalds */
11401da177e4SLinus Torvalds
11414a3e2f71SArjan van de Ven static DEFINE_MUTEX(br_ioctl_mutex);
1142ad2f99aeSArnd Bergmann static int (*br_ioctl_hook)(struct net *net, unsigned int cmd,
1143ad2f99aeSArnd Bergmann void __user *uarg);
1144ad2f99aeSArnd Bergmann
brioctl_set(int (* hook)(struct net * net,unsigned int cmd,void __user * uarg))11451da177e4SLinus Torvalds void brioctl_set(int (*hook)(struct net *net, unsigned int cmd,
1146ad2f99aeSArnd Bergmann void __user *uarg))
1147ad2f99aeSArnd Bergmann {
1148ad2f99aeSArnd Bergmann mutex_lock(&br_ioctl_mutex);
11491da177e4SLinus Torvalds br_ioctl_hook = hook;
11504a3e2f71SArjan van de Ven mutex_unlock(&br_ioctl_mutex);
11511da177e4SLinus Torvalds }
11524a3e2f71SArjan van de Ven EXPORT_SYMBOL(brioctl_set);
11531da177e4SLinus Torvalds
br_ioctl_call(struct net * net,unsigned int cmd,void __user * uarg)11541da177e4SLinus Torvalds int br_ioctl_call(struct net *net, unsigned int cmd, void __user *uarg)
11551da177e4SLinus Torvalds {
1156ad2f99aeSArnd Bergmann int err = -ENOPKG;
1157ad2f99aeSArnd Bergmann
1158ad2f99aeSArnd Bergmann if (!br_ioctl_hook)
1159ad2f99aeSArnd Bergmann request_module("bridge");
1160ad2f99aeSArnd Bergmann
1161ad2f99aeSArnd Bergmann mutex_lock(&br_ioctl_mutex);
1162ad2f99aeSArnd Bergmann if (br_ioctl_hook)
1163ad2f99aeSArnd Bergmann err = br_ioctl_hook(net, cmd, uarg);
1164ad2f99aeSArnd Bergmann mutex_unlock(&br_ioctl_mutex);
1165ad2f99aeSArnd Bergmann
1166ad2f99aeSArnd Bergmann return err;
1167ad2f99aeSArnd Bergmann }
1168ad2f99aeSArnd Bergmann
1169ad2f99aeSArnd Bergmann static DEFINE_MUTEX(vlan_ioctl_mutex);
1170ad2f99aeSArnd Bergmann static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
1171ad2f99aeSArnd Bergmann
vlan_ioctl_set(int (* hook)(struct net *,void __user *))11724a3e2f71SArjan van de Ven void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
1173881d966bSEric W. Biederman {
11741da177e4SLinus Torvalds mutex_lock(&vlan_ioctl_mutex);
1175881d966bSEric W. Biederman vlan_ioctl_hook = hook;
11761da177e4SLinus Torvalds mutex_unlock(&vlan_ioctl_mutex);
11774a3e2f71SArjan van de Ven }
11781da177e4SLinus Torvalds EXPORT_SYMBOL(vlan_ioctl_set);
11794a3e2f71SArjan van de Ven
sock_do_ioctl(struct net * net,struct socket * sock,unsigned int cmd,unsigned long arg)11801da177e4SLinus Torvalds static long sock_do_ioctl(struct net *net, struct socket *sock,
11811da177e4SLinus Torvalds unsigned int cmd, unsigned long arg)
11821da177e4SLinus Torvalds {
11836b96018bSArnd Bergmann const struct proto_ops *ops = READ_ONCE(sock->ops);
118463ff03abSJohannes Berg struct ifreq ifr;
11856b96018bSArnd Bergmann bool need_copyout;
11861ded5e5aSEric Dumazet int err;
1187876f0bf9SArnd Bergmann void __user *argp = (void __user *)arg;
1188876f0bf9SArnd Bergmann void __user *data;
11896b96018bSArnd Bergmann
11906b96018bSArnd Bergmann err = ops->ioctl(sock, cmd, arg);
1191a554bf96SArnd Bergmann
11926b96018bSArnd Bergmann /*
11931ded5e5aSEric Dumazet * If this ioctl is unknown try to hand it down
11946b96018bSArnd Bergmann * to the NIC driver.
11956b96018bSArnd Bergmann */
11966b96018bSArnd Bergmann if (err != -ENOIOCTLCMD)
11976b96018bSArnd Bergmann return err;
11986b96018bSArnd Bergmann
119936fd633eSAl Viro if (!is_socket_ioctl_cmd(cmd))
12006b96018bSArnd Bergmann return -ENOTTY;
12016b96018bSArnd Bergmann
120229ce8f97SJakub Kicinski if (get_user_ifreq(&ifr, &data, argp))
120329ce8f97SJakub Kicinski return -EFAULT;
120429ce8f97SJakub Kicinski err = dev_ioctl(net, cmd, &ifr, data, &need_copyout);
1205a554bf96SArnd Bergmann if (!err && need_copyout)
120636fd633eSAl Viro if (put_user_ifreq(&ifr, argp))
1207a554bf96SArnd Bergmann return -EFAULT;
120844c02a2cSAl Viro
1209a554bf96SArnd Bergmann return err;
121044c02a2cSAl Viro }
1211876f0bf9SArnd Bergmann
12126b96018bSArnd Bergmann /*
12136b96018bSArnd Bergmann * With an ioctl, arg may well be a user mode pointer, but we don't know
12146b96018bSArnd Bergmann * what to do with it - that's up to the protocol still.
12151da177e4SLinus Torvalds */
12161da177e4SLinus Torvalds
sock_ioctl(struct file * file,unsigned cmd,unsigned long arg)12171da177e4SLinus Torvalds static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
12181da177e4SLinus Torvalds {
12191da177e4SLinus Torvalds const struct proto_ops *ops;
12201da177e4SLinus Torvalds struct socket *sock;
12211da177e4SLinus Torvalds struct sock *sk;
12221ded5e5aSEric Dumazet void __user *argp = (void __user *)arg;
12231da177e4SLinus Torvalds int pid, err;
1224881d966bSEric W. Biederman struct net *net;
12251da177e4SLinus Torvalds
12261da177e4SLinus Torvalds sock = file->private_data;
1227881d966bSEric W. Biederman ops = READ_ONCE(sock->ops);
12281da177e4SLinus Torvalds sk = sock->sk;
1229b69aee04SEric Dumazet net = sock_net(sk);
12301ded5e5aSEric Dumazet if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) {
1231881d966bSEric W. Biederman struct ifreq ifr;
12323b1e0a65SYOSHIFUJI Hideaki void __user *data;
123344c02a2cSAl Viro bool need_copyout;
123444c02a2cSAl Viro if (get_user_ifreq(&ifr, &data, argp))
1235a554bf96SArnd Bergmann return -EFAULT;
123644c02a2cSAl Viro err = dev_ioctl(net, cmd, &ifr, data, &need_copyout);
1237a554bf96SArnd Bergmann if (!err && need_copyout)
123844c02a2cSAl Viro if (put_user_ifreq(&ifr, argp))
1239a554bf96SArnd Bergmann return -EFAULT;
124044c02a2cSAl Viro } else
1241a554bf96SArnd Bergmann #ifdef CONFIG_WEXT_CORE
124244c02a2cSAl Viro if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
12431da177e4SLinus Torvalds err = wext_handle_ioctl(net, cmd, argp);
12443d23e349SJohannes Berg } else
12451da177e4SLinus Torvalds #endif
1246b1b0c245SAl Viro switch (cmd) {
12471da177e4SLinus Torvalds case FIOSETOWN:
12483d23e349SJohannes Berg case SIOCSPGRP:
12491da177e4SLinus Torvalds err = -EFAULT;
12501da177e4SLinus Torvalds if (get_user(pid, (int __user *)argp))
12511da177e4SLinus Torvalds break;
12521da177e4SLinus Torvalds err = f_setown(sock->file, pid, 1);
12531da177e4SLinus Torvalds break;
12541da177e4SLinus Torvalds case FIOGETOWN:
1255393cc3f5SJiri Slaby case SIOCGPGRP:
12561da177e4SLinus Torvalds err = put_user(f_getown(sock->file),
12571da177e4SLinus Torvalds (int __user *)argp);
12581da177e4SLinus Torvalds break;
1259609d7fa9SEric W. Biederman case SIOCGIFBR:
126089bddce5SStephen Hemminger case SIOCSIFBR:
12611da177e4SLinus Torvalds case SIOCBRADDBR:
12621da177e4SLinus Torvalds case SIOCBRDELBR:
12631da177e4SLinus Torvalds case SIOCBRADDIF:
12641da177e4SLinus Torvalds case SIOCBRDELIF:
12651da177e4SLinus Torvalds err = br_ioctl_call(net, cmd, argp);
1266ad2f99aeSArnd Bergmann break;
12671da177e4SLinus Torvalds case SIOCGIFVLAN:
12681da177e4SLinus Torvalds case SIOCSIFVLAN:
12691da177e4SLinus Torvalds err = -ENOPKG;
12701da177e4SLinus Torvalds if (!vlan_ioctl_hook)
12711da177e4SLinus Torvalds request_module("8021q");
12721da177e4SLinus Torvalds
12731da177e4SLinus Torvalds mutex_lock(&vlan_ioctl_mutex);
12744a3e2f71SArjan van de Ven if (vlan_ioctl_hook)
12751da177e4SLinus Torvalds err = vlan_ioctl_hook(net, argp);
1276881d966bSEric W. Biederman mutex_unlock(&vlan_ioctl_mutex);
12774a3e2f71SArjan van de Ven break;
12781da177e4SLinus Torvalds case SIOCGSKNS:
1279c62cce2cSAndrey Vagin err = -EPERM;
1280c62cce2cSAndrey Vagin if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1281c62cce2cSAndrey Vagin break;
1282c62cce2cSAndrey Vagin
1283c62cce2cSAndrey Vagin err = open_related_ns(&net->ns, get_net_ns);
1284c62cce2cSAndrey Vagin break;
1285c62cce2cSAndrey Vagin case SIOCGSTAMP_OLD:
12860768e170SArnd Bergmann case SIOCGSTAMPNS_OLD:
12870768e170SArnd Bergmann if (!ops->gettstamp) {
12881ded5e5aSEric Dumazet err = -ENOIOCTLCMD;
1289c7cbdbf2SArnd Bergmann break;
1290c7cbdbf2SArnd Bergmann }
1291c7cbdbf2SArnd Bergmann err = ops->gettstamp(sock, argp,
12921ded5e5aSEric Dumazet cmd == SIOCGSTAMP_OLD,
12930768e170SArnd Bergmann !IS_ENABLED(CONFIG_64BIT));
12940768e170SArnd Bergmann break;
129560747828SGustavo A. R. Silva case SIOCGSTAMP_NEW:
12960768e170SArnd Bergmann case SIOCGSTAMPNS_NEW:
12970768e170SArnd Bergmann if (!ops->gettstamp) {
12981ded5e5aSEric Dumazet err = -ENOIOCTLCMD;
12990768e170SArnd Bergmann break;
13000768e170SArnd Bergmann }
13010768e170SArnd Bergmann err = ops->gettstamp(sock, argp,
13021ded5e5aSEric Dumazet cmd == SIOCGSTAMP_NEW,
13030768e170SArnd Bergmann false);
13040768e170SArnd Bergmann break;
1305c7cbdbf2SArnd Bergmann
1306876f0bf9SArnd Bergmann case SIOCGIFCONF:
1307876f0bf9SArnd Bergmann err = dev_ifconf(net, argp);
1308876f0bf9SArnd Bergmann break;
1309876f0bf9SArnd Bergmann
1310876f0bf9SArnd Bergmann default:
13111da177e4SLinus Torvalds err = sock_do_ioctl(net, sock, cmd, arg);
131263ff03abSJohannes Berg break;
13131da177e4SLinus Torvalds }
13141da177e4SLinus Torvalds return err;
13151da177e4SLinus Torvalds }
13161da177e4SLinus Torvalds
13171da177e4SLinus Torvalds /**
13188a3c245cSPedro Tammela * sock_create_lite - creates a socket
13198a3c245cSPedro Tammela * @family: protocol family (AF_INET, ...)
13208a3c245cSPedro Tammela * @type: communication type (SOCK_STREAM, ...)
13218a3c245cSPedro Tammela * @protocol: protocol (0, ...)
13228a3c245cSPedro Tammela * @res: new socket
13238a3c245cSPedro Tammela *
13248a3c245cSPedro Tammela * Creates a new socket and assigns it to @res, passing through LSM.
13258a3c245cSPedro Tammela * The new socket initialization is not complete, see kernel_accept().
13268a3c245cSPedro Tammela * Returns 0 or an error. On failure @res is set to %NULL.
13278a3c245cSPedro Tammela * This function internally uses GFP_KERNEL.
13288a3c245cSPedro Tammela */
13298a3c245cSPedro Tammela
sock_create_lite(int family,int type,int protocol,struct socket ** res)13308a3c245cSPedro Tammela int sock_create_lite(int family, int type, int protocol, struct socket **res)
13311da177e4SLinus Torvalds {
13321da177e4SLinus Torvalds int err;
13331da177e4SLinus Torvalds struct socket *sock = NULL;
13341da177e4SLinus Torvalds
13351da177e4SLinus Torvalds err = security_socket_create(family, type, protocol, 1);
13361da177e4SLinus Torvalds if (err)
13371da177e4SLinus Torvalds goto out;
13381da177e4SLinus Torvalds
13391da177e4SLinus Torvalds sock = sock_alloc();
13401da177e4SLinus Torvalds if (!sock) {
13411da177e4SLinus Torvalds err = -ENOMEM;
13421da177e4SLinus Torvalds goto out;
13431da177e4SLinus Torvalds }
13441da177e4SLinus Torvalds
13451da177e4SLinus Torvalds sock->type = type;
13461da177e4SLinus Torvalds err = security_socket_post_create(sock, family, type, protocol, 1);
13477420ed23SVenkat Yekkirala if (err)
13487420ed23SVenkat Yekkirala goto out_release;
13497420ed23SVenkat Yekkirala
13507420ed23SVenkat Yekkirala out:
13511da177e4SLinus Torvalds *res = sock;
13521da177e4SLinus Torvalds return err;
13531da177e4SLinus Torvalds out_release:
13547420ed23SVenkat Yekkirala sock_release(sock);
13557420ed23SVenkat Yekkirala sock = NULL;
13567420ed23SVenkat Yekkirala goto out;
13577420ed23SVenkat Yekkirala }
13581da177e4SLinus Torvalds EXPORT_SYMBOL(sock_create_lite);
1359c6d409cfSEric Dumazet
13601da177e4SLinus Torvalds /* No kernel lock held - perfect */
sock_poll(struct file * file,poll_table * wait)13611da177e4SLinus Torvalds static __poll_t sock_poll(struct file *file, poll_table *wait)
1362ade994f4SAl Viro {
13631da177e4SLinus Torvalds struct socket *sock = file->private_data;
13643cafb376SChristoph Hellwig const struct proto_ops *ops = READ_ONCE(sock->ops);
13651ded5e5aSEric Dumazet __poll_t events = poll_requested_events(wait), flag = 0;
1366a331de3bSChristoph Hellwig
13671da177e4SLinus Torvalds if (!ops->poll)
13681ded5e5aSEric Dumazet return 0;
1369e88958e6SChristoph Hellwig
1370f641f13bSChristoph Hellwig if (sk_can_busy_loop(sock->sk)) {
1371a331de3bSChristoph Hellwig /* poll once if requested by the syscall */
1372f641f13bSChristoph Hellwig if (events & POLL_BUSY_LOOP)
1373a331de3bSChristoph Hellwig sk_busy_loop(sock->sk, 1);
1374f641f13bSChristoph Hellwig
1375a331de3bSChristoph Hellwig /* if this socket can poll_ll, tell the system call */
1376a331de3bSChristoph Hellwig flag = POLL_BUSY_LOOP;
1377a331de3bSChristoph Hellwig }
1378a331de3bSChristoph Hellwig
1379a331de3bSChristoph Hellwig return ops->poll(file, sock, wait) | flag;
13801ded5e5aSEric Dumazet }
13811da177e4SLinus Torvalds
sock_mmap(struct file * file,struct vm_area_struct * vma)13821da177e4SLinus Torvalds static int sock_mmap(struct file *file, struct vm_area_struct *vma)
13831da177e4SLinus Torvalds {
13841da177e4SLinus Torvalds struct socket *sock = file->private_data;
1385b69aee04SEric Dumazet
13861da177e4SLinus Torvalds return READ_ONCE(sock->ops)->mmap(file, sock, vma);
13871ded5e5aSEric Dumazet }
13881da177e4SLinus Torvalds
sock_close(struct inode * inode,struct file * filp)13891da177e4SLinus Torvalds static int sock_close(struct inode *inode, struct file *filp)
139020380731SArnaldo Carvalho de Melo {
13911da177e4SLinus Torvalds __sock_release(SOCKET_I(inode), inode);
13926d8c50dcSCong Wang return 0;
13931da177e4SLinus Torvalds }
13941da177e4SLinus Torvalds
13951da177e4SLinus Torvalds /*
13961da177e4SLinus Torvalds * Update the socket async list
13971da177e4SLinus Torvalds *
13981da177e4SLinus Torvalds * Fasync_list locking strategy.
13991da177e4SLinus Torvalds *
14001da177e4SLinus Torvalds * 1. fasync_list is modified only under process context socket lock
14011da177e4SLinus Torvalds * i.e. under semaphore.
14021da177e4SLinus Torvalds * 2. fasync_list is used under read_lock(&sk->sk_callback_lock)
14031da177e4SLinus Torvalds * or under socket lock
1404989a2979SEric Dumazet */
14051da177e4SLinus Torvalds
sock_fasync(int fd,struct file * filp,int on)14061da177e4SLinus Torvalds static int sock_fasync(int fd, struct file *filp, int on)
14071da177e4SLinus Torvalds {
14081da177e4SLinus Torvalds struct socket *sock = filp->private_data;
1409989a2979SEric Dumazet struct sock *sk = sock->sk;
1410989a2979SEric Dumazet struct socket_wq *wq = &sock->wq;
1411333f7909SAl Viro
14121da177e4SLinus Torvalds if (sk == NULL)
1413989a2979SEric Dumazet return -EINVAL;
14141da177e4SLinus Torvalds
14151da177e4SLinus Torvalds lock_sock(sk);
14161da177e4SLinus Torvalds fasync_helper(fd, filp, on, &wq->fasync_list);
1417eaefd110SEric Dumazet
14181da177e4SLinus Torvalds if (!wq->fasync_list)
1419eaefd110SEric Dumazet sock_reset_flag(sk, SOCK_FASYNC);
1420bcdce719SEric Dumazet else
1421989a2979SEric Dumazet sock_set_flag(sk, SOCK_FASYNC);
1422989a2979SEric Dumazet
14231da177e4SLinus Torvalds release_sock(sk);
1424989a2979SEric Dumazet return 0;
14251da177e4SLinus Torvalds }
14261da177e4SLinus Torvalds
14271da177e4SLinus Torvalds /* This function may be called only under rcu_lock */
1428ceb5d58bSEric Dumazet
sock_wake_async(struct socket_wq * wq,int how,int band)14291da177e4SLinus Torvalds int sock_wake_async(struct socket_wq *wq, int how, int band)
1430ceb5d58bSEric Dumazet {
14311da177e4SLinus Torvalds if (!wq || !wq->fasync_list)
1432ceb5d58bSEric Dumazet return -1;
1433ceb5d58bSEric Dumazet
143443815482SEric Dumazet switch (how) {
143589bddce5SStephen Hemminger case SOCK_WAKE_WAITD:
14368d8ad9d7SPavel Emelyanov if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags))
1437ceb5d58bSEric Dumazet break;
14381da177e4SLinus Torvalds goto call_kill;
14391da177e4SLinus Torvalds case SOCK_WAKE_SPACE:
14408d8ad9d7SPavel Emelyanov if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags))
1441ceb5d58bSEric Dumazet break;
14421da177e4SLinus Torvalds fallthrough;
14437c7ab580SMiaohe Lin case SOCK_WAKE_IO:
14448d8ad9d7SPavel Emelyanov call_kill:
14451da177e4SLinus Torvalds kill_fasync(&wq->fasync_list, SIGIO, band);
144643815482SEric Dumazet break;
14471da177e4SLinus Torvalds case SOCK_WAKE_URG:
14488d8ad9d7SPavel Emelyanov kill_fasync(&wq->fasync_list, SIGURG, band);
144943815482SEric Dumazet }
14501da177e4SLinus Torvalds
1451ceb5d58bSEric Dumazet return 0;
14521da177e4SLinus Torvalds }
14531da177e4SLinus Torvalds EXPORT_SYMBOL(sock_wake_async);
1454c6d409cfSEric Dumazet
14551da177e4SLinus Torvalds /**
14568a3c245cSPedro Tammela * __sock_create - creates a socket
14578a3c245cSPedro Tammela * @net: net namespace
14588a3c245cSPedro Tammela * @family: protocol family (AF_INET, ...)
14598a3c245cSPedro Tammela * @type: communication type (SOCK_STREAM, ...)
14608a3c245cSPedro Tammela * @protocol: protocol (0, ...)
14618a3c245cSPedro Tammela * @res: new socket
14628a3c245cSPedro Tammela * @kern: boolean for kernel space sockets
14638a3c245cSPedro Tammela *
14648a3c245cSPedro Tammela * Creates a new socket and assigns it to @res, passing through LSM.
14658a3c245cSPedro Tammela * Returns 0 or an error. On failure @res is set to %NULL. @kern must
14668a3c245cSPedro Tammela * be set to true if the socket resides in kernel space.
14678a3c245cSPedro Tammela * This function internally uses GFP_KERNEL.
14688a3c245cSPedro Tammela */
14698a3c245cSPedro Tammela
__sock_create(struct net * net,int family,int type,int protocol,struct socket ** res,int kern)14708a3c245cSPedro Tammela int __sock_create(struct net *net, int family, int type, int protocol,
1471721db93aSPavel Emelyanov struct socket **res, int kern)
147289bddce5SStephen Hemminger {
14731da177e4SLinus Torvalds int err;
14741da177e4SLinus Torvalds struct socket *sock;
14751da177e4SLinus Torvalds const struct net_proto_family *pf;
147655737fdaSStephen Hemminger
14771da177e4SLinus Torvalds /*
14781da177e4SLinus Torvalds * Check protocol is in range
14791da177e4SLinus Torvalds */
14801da177e4SLinus Torvalds if (family < 0 || family >= NPROTO)
14811da177e4SLinus Torvalds return -EAFNOSUPPORT;
14821da177e4SLinus Torvalds if (type < 0 || type >= SOCK_MAX)
14831da177e4SLinus Torvalds return -EINVAL;
14841da177e4SLinus Torvalds
14851da177e4SLinus Torvalds /* Compatibility.
14861da177e4SLinus Torvalds
14871da177e4SLinus Torvalds This uglymoron is moved from INET layer to here to avoid
14881da177e4SLinus Torvalds deadlock in module load.
14891da177e4SLinus Torvalds */
14901da177e4SLinus Torvalds if (family == PF_INET && type == SOCK_PACKET) {
14911da177e4SLinus Torvalds pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)\n",
1492f3c98690Sliping.zhang current->comm);
149389bddce5SStephen Hemminger family = PF_PACKET;
14941da177e4SLinus Torvalds }
14951da177e4SLinus Torvalds
14961da177e4SLinus Torvalds err = security_socket_create(family, type, protocol, kern);
14971da177e4SLinus Torvalds if (err)
14981da177e4SLinus Torvalds return err;
14991da177e4SLinus Torvalds
15001da177e4SLinus Torvalds /*
150155737fdaSStephen Hemminger * Allocate the socket and allow the family to set things up. if
150255737fdaSStephen Hemminger * the protocol is 0, the family is instructed to select an appropriate
150355737fdaSStephen Hemminger * default.
150455737fdaSStephen Hemminger */
150555737fdaSStephen Hemminger sock = sock_alloc();
150655737fdaSStephen Hemminger if (!sock) {
150755737fdaSStephen Hemminger net_warn_ratelimited("socket: no more sockets\n");
1508e87cc472SJoe Perches return -ENFILE; /* Not exactly a match, but its the
150955737fdaSStephen Hemminger closest posix thing */
151055737fdaSStephen Hemminger }
151155737fdaSStephen Hemminger
151255737fdaSStephen Hemminger sock->type = type;
151355737fdaSStephen Hemminger
151455737fdaSStephen Hemminger #ifdef CONFIG_MODULES
151595a5afcaSJohannes Berg /* Attempt to load a protocol module if the find failed.
15161da177e4SLinus Torvalds *
15171da177e4SLinus Torvalds * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
15181da177e4SLinus Torvalds * requested real, full-featured networking support upon configuration.
15191da177e4SLinus Torvalds * Otherwise module support will break!
15201da177e4SLinus Torvalds */
15211da177e4SLinus Torvalds if (rcu_access_pointer(net_families[family]) == NULL)
1522190683a9SEric Dumazet request_module("net-pf-%d", family);
15231da177e4SLinus Torvalds #endif
15241da177e4SLinus Torvalds
15251da177e4SLinus Torvalds rcu_read_lock();
152655737fdaSStephen Hemminger pf = rcu_dereference(net_families[family]);
152755737fdaSStephen Hemminger err = -EAFNOSUPPORT;
15281da177e4SLinus Torvalds if (!pf)
152955737fdaSStephen Hemminger goto out_release;
153055737fdaSStephen Hemminger
15311da177e4SLinus Torvalds /*
15321da177e4SLinus Torvalds * We will call the ->create function, that possibly is in a loadable
15331da177e4SLinus Torvalds * module, so we have to bump that loadable module refcnt first.
15341da177e4SLinus Torvalds */
15351da177e4SLinus Torvalds if (!try_module_get(pf->owner))
153655737fdaSStephen Hemminger goto out_release;
15371da177e4SLinus Torvalds
15381da177e4SLinus Torvalds /* Now protected by module ref count */
153955737fdaSStephen Hemminger rcu_read_unlock();
154055737fdaSStephen Hemminger
154155737fdaSStephen Hemminger err = pf->create(net, sock, protocol, kern);
15423f378b68SEric Paris if (err < 0) {
154363108314SIgnat Korchagin /* ->create should release the allocated sock->sk object on error
154463108314SIgnat Korchagin * and make sure sock->sk is set to NULL to avoid use-after-free
154548156296SIgnat Korchagin */
154663108314SIgnat Korchagin DEBUG_NET_WARN_ONCE(sock->sk,
15474bbd360aSKuniyuki Iwashima "%ps must clear sock->sk on failure, family: %d, type: %d, protocol: %d\n",
15484bbd360aSKuniyuki Iwashima pf->create, family, type, protocol);
15494bbd360aSKuniyuki Iwashima goto out_module_put;
15501da177e4SLinus Torvalds }
155163108314SIgnat Korchagin
1552a79af59eSFrank Filz /*
15531da177e4SLinus Torvalds * Now to bump the refcnt of the [loadable] module that owns this
15541da177e4SLinus Torvalds * socket at sock_release time we decrement its refcnt.
15551da177e4SLinus Torvalds */
15561da177e4SLinus Torvalds if (!try_module_get(sock->ops->owner))
155755737fdaSStephen Hemminger goto out_module_busy;
155855737fdaSStephen Hemminger
155955737fdaSStephen Hemminger /*
15601da177e4SLinus Torvalds * Now that we're done with the ->create function, the [loadable]
15611da177e4SLinus Torvalds * module can have its refcnt decremented
15621da177e4SLinus Torvalds */
15631da177e4SLinus Torvalds module_put(pf->owner);
156455737fdaSStephen Hemminger err = security_socket_post_create(sock, family, type, protocol, kern);
15657420ed23SVenkat Yekkirala if (err)
15667420ed23SVenkat Yekkirala goto out_sock_release;
15673b185525SHerbert Xu *res = sock;
156855737fdaSStephen Hemminger
15691da177e4SLinus Torvalds return 0;
157055737fdaSStephen Hemminger
157155737fdaSStephen Hemminger out_module_busy:
157255737fdaSStephen Hemminger err = -EAFNOSUPPORT;
157355737fdaSStephen Hemminger out_module_put:
15741da177e4SLinus Torvalds sock->ops = NULL;
157555737fdaSStephen Hemminger module_put(pf->owner);
157655737fdaSStephen Hemminger out_sock_release:
157755737fdaSStephen Hemminger sock_release(sock);
15781da177e4SLinus Torvalds return err;
157955737fdaSStephen Hemminger
158055737fdaSStephen Hemminger out_release:
158155737fdaSStephen Hemminger rcu_read_unlock();
158255737fdaSStephen Hemminger goto out_sock_release;
158355737fdaSStephen Hemminger }
15841da177e4SLinus Torvalds EXPORT_SYMBOL(__sock_create);
1585721db93aSPavel Emelyanov
15861da177e4SLinus Torvalds /**
15878a3c245cSPedro Tammela * sock_create - creates a socket
15888a3c245cSPedro Tammela * @family: protocol family (AF_INET, ...)
15898a3c245cSPedro Tammela * @type: communication type (SOCK_STREAM, ...)
15908a3c245cSPedro Tammela * @protocol: protocol (0, ...)
15918a3c245cSPedro Tammela * @res: new socket
15928a3c245cSPedro Tammela *
15938a3c245cSPedro Tammela * A wrapper around __sock_create().
15948a3c245cSPedro Tammela * Returns 0 or an error. This function internally uses GFP_KERNEL.
15958a3c245cSPedro Tammela */
15968a3c245cSPedro Tammela
sock_create(int family,int type,int protocol,struct socket ** res)15978a3c245cSPedro Tammela int sock_create(int family, int type, int protocol, struct socket **res)
15981da177e4SLinus Torvalds {
15991da177e4SLinus Torvalds return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
16001b8d7ae4SEric W. Biederman }
16011da177e4SLinus Torvalds EXPORT_SYMBOL(sock_create);
1602c6d409cfSEric Dumazet
16031da177e4SLinus Torvalds /**
16048a3c245cSPedro Tammela * sock_create_kern - creates a socket (kernel space)
16058a3c245cSPedro Tammela * @net: net namespace
16068a3c245cSPedro Tammela * @family: protocol family (AF_INET, ...)
16078a3c245cSPedro Tammela * @type: communication type (SOCK_STREAM, ...)
16088a3c245cSPedro Tammela * @protocol: protocol (0, ...)
16098a3c245cSPedro Tammela * @res: new socket
16108a3c245cSPedro Tammela *
16118a3c245cSPedro Tammela * A wrapper around __sock_create().
16128a3c245cSPedro Tammela * Returns 0 or an error. This function internally uses GFP_KERNEL.
16138a3c245cSPedro Tammela */
16148a3c245cSPedro Tammela
sock_create_kern(struct net * net,int family,int type,int protocol,struct socket ** res)16158a3c245cSPedro Tammela int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
1616eeb1bd5cSEric W. Biederman {
16171da177e4SLinus Torvalds return __sock_create(net, family, type, protocol, res, 1);
1618eeb1bd5cSEric W. Biederman }
16191da177e4SLinus Torvalds EXPORT_SYMBOL(sock_create_kern);
1620c6d409cfSEric Dumazet
__sys_socket_create(int family,int type,int protocol)16211da177e4SLinus Torvalds static struct socket *__sys_socket_create(int family, int type, int protocol)
1622da214a47SJens Axboe {
16231da177e4SLinus Torvalds struct socket *sock;
16241da177e4SLinus Torvalds int retval;
1625da214a47SJens Axboe
1626a677a039SUlrich Drepper /* Check the SOCK_* constants for consistency. */
1627e38b36f3SUlrich Drepper BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC);
1628e38b36f3SUlrich Drepper BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK);
1629e38b36f3SUlrich Drepper BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK);
1630e38b36f3SUlrich Drepper BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK);
1631e38b36f3SUlrich Drepper
1632e38b36f3SUlrich Drepper if ((type & ~SOCK_TYPE_MASK) & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
1633da214a47SJens Axboe return ERR_PTR(-EINVAL);
1634da214a47SJens Axboe type &= SOCK_TYPE_MASK;
1635a677a039SUlrich Drepper
16361da177e4SLinus Torvalds retval = sock_create(family, type, protocol, &sock);
16371da177e4SLinus Torvalds if (retval < 0)
16381da177e4SLinus Torvalds return ERR_PTR(retval);
1639da214a47SJens Axboe
1640da214a47SJens Axboe return sock;
1641da214a47SJens Axboe }
1642da214a47SJens Axboe
__sys_socket_file(int family,int type,int protocol)1643da214a47SJens Axboe struct file *__sys_socket_file(int family, int type, int protocol)
1644da214a47SJens Axboe {
1645da214a47SJens Axboe struct socket *sock;
1646da214a47SJens Axboe int flags;
1647da214a47SJens Axboe
1648da214a47SJens Axboe sock = __sys_socket_create(family, type, protocol);
1649da214a47SJens Axboe if (IS_ERR(sock))
1650da214a47SJens Axboe return ERR_CAST(sock);
1651da214a47SJens Axboe
1652da214a47SJens Axboe flags = type & ~SOCK_TYPE_MASK;
1653da214a47SJens Axboe if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1654da214a47SJens Axboe flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1655da214a47SJens Axboe
1656da214a47SJens Axboe return sock_alloc_file(sock, flags, NULL);
1657649c15c7SThadeu Lima de Souza Cascardo }
1658da214a47SJens Axboe
1659da214a47SJens Axboe /* A hook for bpf progs to attach to and update socket protocol.
16600dd061a6SGeliang Tang *
16610dd061a6SGeliang Tang * A static noinline declaration here could cause the compiler to
16620dd061a6SGeliang Tang * optimize away the function. A global noinline declaration will
16630dd061a6SGeliang Tang * keep the definition, but may optimize away the callsite.
16640dd061a6SGeliang Tang * Therefore, __weak is needed to ensure that the call is still
16650dd061a6SGeliang Tang * emitted, by telling the compiler that we don't know what the
16660dd061a6SGeliang Tang * function might eventually be.
16670dd061a6SGeliang Tang */
16680dd061a6SGeliang Tang
16690dd061a6SGeliang Tang __bpf_hook_start();
167015fb6f2bSDave Marchevsky
update_socket_protocol(int family,int type,int protocol)16710dd061a6SGeliang Tang __weak noinline int update_socket_protocol(int family, int type, int protocol)
16720dd061a6SGeliang Tang {
16730dd061a6SGeliang Tang return protocol;
16740dd061a6SGeliang Tang }
16750dd061a6SGeliang Tang
16760dd061a6SGeliang Tang __bpf_hook_end();
167715fb6f2bSDave Marchevsky
__sys_socket(int family,int type,int protocol)16780dd061a6SGeliang Tang int __sys_socket(int family, int type, int protocol)
1679da214a47SJens Axboe {
1680da214a47SJens Axboe struct socket *sock;
1681da214a47SJens Axboe int flags;
1682da214a47SJens Axboe
1683da214a47SJens Axboe sock = __sys_socket_create(family, type,
16840dd061a6SGeliang Tang update_socket_protocol(family, type, protocol));
16850dd061a6SGeliang Tang if (IS_ERR(sock))
1686da214a47SJens Axboe return PTR_ERR(sock);
1687da214a47SJens Axboe
1688da214a47SJens Axboe flags = type & ~SOCK_TYPE_MASK;
1689da214a47SJens Axboe if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1690da214a47SJens Axboe flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1691da214a47SJens Axboe
16921da177e4SLinus Torvalds return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
16938e1611e2SAl Viro }
16941da177e4SLinus Torvalds
SYSCALL_DEFINE3(socket,int,family,int,type,int,protocol)16951da177e4SLinus Torvalds SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
16969d6a15c3SDominik Brodowski {
16979d6a15c3SDominik Brodowski return __sys_socket(family, type, protocol);
16989d6a15c3SDominik Brodowski }
16999d6a15c3SDominik Brodowski
17009d6a15c3SDominik Brodowski /*
17011da177e4SLinus Torvalds * Create a pair of connected sockets.
17021da177e4SLinus Torvalds */
17031da177e4SLinus Torvalds
__sys_socketpair(int family,int type,int protocol,int __user * usockvec)17041da177e4SLinus Torvalds int __sys_socketpair(int family, int type, int protocol, int __user *usockvec)
17056debc8d8SDominik Brodowski {
17061da177e4SLinus Torvalds struct socket *sock1, *sock2;
17071da177e4SLinus Torvalds int fd1, fd2, err;
17081da177e4SLinus Torvalds struct file *newfile1, *newfile2;
1709db349509SAl Viro int flags;
1710a677a039SUlrich Drepper
1711a677a039SUlrich Drepper flags = type & ~SOCK_TYPE_MASK;
1712a677a039SUlrich Drepper if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
171377d27200SUlrich Drepper return -EINVAL;
1714a677a039SUlrich Drepper type &= SOCK_TYPE_MASK;
1715a677a039SUlrich Drepper
17161da177e4SLinus Torvalds if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1717aaca0bdcSUlrich Drepper flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1718aaca0bdcSUlrich Drepper
1719aaca0bdcSUlrich Drepper /*
17201da177e4SLinus Torvalds * reserve descriptors and make sure we won't fail
1721016a266bSAl Viro * to return them to userland.
1722016a266bSAl Viro */
1723016a266bSAl Viro fd1 = get_unused_fd_flags(flags);
1724016a266bSAl Viro if (unlikely(fd1 < 0))
1725016a266bSAl Viro return fd1;
1726016a266bSAl Viro
1727016a266bSAl Viro fd2 = get_unused_fd_flags(flags);
1728016a266bSAl Viro if (unlikely(fd2 < 0)) {
1729016a266bSAl Viro put_unused_fd(fd1);
1730016a266bSAl Viro return fd2;
1731016a266bSAl Viro }
1732016a266bSAl Viro
1733016a266bSAl Viro err = put_user(fd1, &usockvec[0]);
1734016a266bSAl Viro if (err)
1735016a266bSAl Viro goto out;
1736016a266bSAl Viro
1737016a266bSAl Viro err = put_user(fd2, &usockvec[1]);
1738016a266bSAl Viro if (err)
1739016a266bSAl Viro goto out;
1740016a266bSAl Viro
1741016a266bSAl Viro /*
1742016a266bSAl Viro * Obtain the first socket and check if the underlying protocol
17431da177e4SLinus Torvalds * supports the socketpair call.
17441da177e4SLinus Torvalds */
17451da177e4SLinus Torvalds
17461da177e4SLinus Torvalds err = sock_create(family, type, protocol, &sock1);
17471da177e4SLinus Torvalds if (unlikely(err < 0))
1748016a266bSAl Viro goto out;
17491da177e4SLinus Torvalds
17501da177e4SLinus Torvalds err = sock_create(family, type, protocol, &sock2);
17511da177e4SLinus Torvalds if (unlikely(err < 0)) {
1752016a266bSAl Viro sock_release(sock1);
1753016a266bSAl Viro goto out;
1754016a266bSAl Viro }
1755bf3c23d1SDavid S. Miller
1756d73aa286SYann Droneaud err = security_socket_socketpair(sock1, sock2);
1757d47cd945SDavid Herrmann if (unlikely(err)) {
1758d47cd945SDavid Herrmann sock_release(sock2);
1759d47cd945SDavid Herrmann sock_release(sock1);
1760d47cd945SDavid Herrmann goto out;
1761d47cd945SDavid Herrmann }
1762d47cd945SDavid Herrmann
1763d47cd945SDavid Herrmann err = READ_ONCE(sock1->ops)->socketpair(sock1, sock2);
17641ded5e5aSEric Dumazet if (unlikely(err < 0)) {
1765016a266bSAl Viro sock_release(sock2);
1766016a266bSAl Viro sock_release(sock1);
1767016a266bSAl Viro goto out;
1768016a266bSAl Viro }
176928407630SAl Viro
177028407630SAl Viro newfile1 = sock_alloc_file(sock1, flags, NULL);
1771aab174f0SLinus Torvalds if (IS_ERR(newfile1)) {
1772b5ffe634SViresh Kumar err = PTR_ERR(newfile1);
177328407630SAl Viro sock_release(sock2);
1774016a266bSAl Viro goto out;
1775016a266bSAl Viro }
177628407630SAl Viro
177728407630SAl Viro newfile2 = sock_alloc_file(sock2, flags, NULL);
1778aab174f0SLinus Torvalds if (IS_ERR(newfile2)) {
177928407630SAl Viro err = PTR_ERR(newfile2);
178028407630SAl Viro fput(newfile1);
1781016a266bSAl Viro goto out;
1782016a266bSAl Viro }
1783db349509SAl Viro
1784db349509SAl Viro audit_fd_pair(fd1, fd2);
1785157cf649SAl Viro
1786d73aa286SYann Droneaud fd_install(fd1, newfile1);
1787db349509SAl Viro fd_install(fd2, newfile2);
1788db349509SAl Viro return 0;
17891da177e4SLinus Torvalds
17901da177e4SLinus Torvalds out:
17911da177e4SLinus Torvalds put_unused_fd(fd2);
1792016a266bSAl Viro put_unused_fd(fd1);
1793016a266bSAl Viro return err;
17941da177e4SLinus Torvalds }
17951da177e4SLinus Torvalds
SYSCALL_DEFINE4(socketpair,int,family,int,type,int,protocol,int __user *,usockvec)17961da177e4SLinus Torvalds SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
17976debc8d8SDominik Brodowski int __user *, usockvec)
17986debc8d8SDominik Brodowski {
17996debc8d8SDominik Brodowski return __sys_socketpair(family, type, protocol, usockvec);
18006debc8d8SDominik Brodowski }
18016debc8d8SDominik Brodowski
__sys_bind_socket(struct socket * sock,struct sockaddr_storage * address,int addrlen)18026debc8d8SDominik Brodowski int __sys_bind_socket(struct socket *sock, struct sockaddr_storage *address,
1803dc2e7797SGabriel Krisman Bertazi int addrlen)
1804dc2e7797SGabriel Krisman Bertazi {
1805dc2e7797SGabriel Krisman Bertazi int err;
1806dc2e7797SGabriel Krisman Bertazi
1807dc2e7797SGabriel Krisman Bertazi err = security_socket_bind(sock, (struct sockaddr *)address,
1808dc2e7797SGabriel Krisman Bertazi addrlen);
1809dc2e7797SGabriel Krisman Bertazi if (!err)
1810dc2e7797SGabriel Krisman Bertazi err = READ_ONCE(sock->ops)->bind(sock,
1811dc2e7797SGabriel Krisman Bertazi (struct sockaddr *)address,
1812dc2e7797SGabriel Krisman Bertazi addrlen);
1813dc2e7797SGabriel Krisman Bertazi return err;
1814dc2e7797SGabriel Krisman Bertazi }
1815dc2e7797SGabriel Krisman Bertazi
1816dc2e7797SGabriel Krisman Bertazi /*
18171da177e4SLinus Torvalds * Bind a name to a socket. Nothing much to do here since it's
18181da177e4SLinus Torvalds * the protocol's responsibility to handle the local address.
18191da177e4SLinus Torvalds *
18201da177e4SLinus Torvalds * We move the socket address to kernel space before we call
18211da177e4SLinus Torvalds * the protocol layer (having also checked the address is ok).
18221da177e4SLinus Torvalds */
18231da177e4SLinus Torvalds
__sys_bind(int fd,struct sockaddr __user * umyaddr,int addrlen)18241da177e4SLinus Torvalds int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
1825a87d35d8SDominik Brodowski {
18261da177e4SLinus Torvalds struct socket *sock;
18271da177e4SLinus Torvalds struct sockaddr_storage address;
1828230b1839SYOSHIFUJI Hideaki CLASS(fd, f)(fd);
182953c0a58bSAl Viro int err;
183053c0a58bSAl Viro
18311da177e4SLinus Torvalds if (fd_empty(f))
183253c0a58bSAl Viro return -EBADF;
183353c0a58bSAl Viro sock = sock_from_file(fd_file(f));
183453c0a58bSAl Viro if (unlikely(!sock))
183553c0a58bSAl Viro return -ENOTSOCK;
183653c0a58bSAl Viro
183753c0a58bSAl Viro err = move_addr_to_kernel(umyaddr, addrlen, &address);
183843db362dSMaciej Żenczykowski if (unlikely(err))
183953c0a58bSAl Viro return err;
18401da177e4SLinus Torvalds
184153c0a58bSAl Viro return __sys_bind_socket(sock, &address, addrlen);
184253c0a58bSAl Viro }
18431da177e4SLinus Torvalds
SYSCALL_DEFINE3(bind,int,fd,struct sockaddr __user *,umyaddr,int,addrlen)18441da177e4SLinus Torvalds SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
1845a87d35d8SDominik Brodowski {
1846a87d35d8SDominik Brodowski return __sys_bind(fd, umyaddr, addrlen);
1847a87d35d8SDominik Brodowski }
1848a87d35d8SDominik Brodowski
1849a87d35d8SDominik Brodowski /*
18501da177e4SLinus Torvalds * Perform a listen. Basically, we allow the protocol to do anything
18511da177e4SLinus Torvalds * necessary for a listen, and if that works, we mark the socket as
18521da177e4SLinus Torvalds * ready for listening.
18531da177e4SLinus Torvalds */
__sys_listen_socket(struct socket * sock,int backlog)18541da177e4SLinus Torvalds int __sys_listen_socket(struct socket *sock, int backlog)
1855bb6aaf73SGabriel Krisman Bertazi {
18561da177e4SLinus Torvalds int somaxconn, err;
1857bb6aaf73SGabriel Krisman Bertazi
18581da177e4SLinus Torvalds somaxconn = READ_ONCE(sock_net(sock->sk)->core.sysctl_somaxconn);
18593c9ba81dSKuniyuki Iwashima if ((unsigned int)backlog > somaxconn)
186095c96174SEric Dumazet backlog = somaxconn;
1861b8e1f9b5SPavel Emelyanov
18621da177e4SLinus Torvalds err = security_socket_listen(sock, backlog);
18631da177e4SLinus Torvalds if (!err)
18646cb153caSBenjamin LaHaise err = READ_ONCE(sock->ops)->listen(sock, backlog);
18651ded5e5aSEric Dumazet return err;
1866bb6aaf73SGabriel Krisman Bertazi }
1867bb6aaf73SGabriel Krisman Bertazi
__sys_listen(int fd,int backlog)18686cb153caSBenjamin LaHaise int __sys_listen(int fd, int backlog)
1869bb6aaf73SGabriel Krisman Bertazi {
1870bb6aaf73SGabriel Krisman Bertazi CLASS(fd, f)(fd);
187153c0a58bSAl Viro struct socket *sock;
1872bb6aaf73SGabriel Krisman Bertazi
1873bb6aaf73SGabriel Krisman Bertazi if (fd_empty(f))
187453c0a58bSAl Viro return -EBADF;
187553c0a58bSAl Viro sock = sock_from_file(fd_file(f));
187653c0a58bSAl Viro if (unlikely(!sock))
187753c0a58bSAl Viro return -ENOTSOCK;
187853c0a58bSAl Viro
187953c0a58bSAl Viro return __sys_listen_socket(sock, backlog);
188053c0a58bSAl Viro }
18811da177e4SLinus Torvalds
SYSCALL_DEFINE2(listen,int,fd,int,backlog)18821da177e4SLinus Torvalds SYSCALL_DEFINE2(listen, int, fd, int, backlog)
188325e290eeSDominik Brodowski {
188425e290eeSDominik Brodowski return __sys_listen(fd, backlog);
188525e290eeSDominik Brodowski }
188625e290eeSDominik Brodowski
do_accept(struct file * file,struct proto_accept_arg * arg,struct sockaddr __user * upeer_sockaddr,int __user * upeer_addrlen,int flags)188725e290eeSDominik Brodowski struct file *do_accept(struct file *file, struct proto_accept_arg *arg,
18880645fbe7SJens Axboe struct sockaddr __user *upeer_sockaddr,
1889de2ea4b6SJens Axboe int __user *upeer_addrlen, int flags)
1890d32f89daSPavel Begunkov {
18911da177e4SLinus Torvalds struct socket *sock, *newsock;
18921da177e4SLinus Torvalds struct file *newfile;
189339d8c1b6SDavid S. Miller int err, len;
1894d32f89daSPavel Begunkov struct sockaddr_storage address;
1895230b1839SYOSHIFUJI Hideaki const struct proto_ops *ops;
18961ded5e5aSEric Dumazet
18971da177e4SLinus Torvalds sock = sock_from_file(file);
1898dba4a925SFlorent Revest if (!sock)
1899d32f89daSPavel Begunkov return ERR_PTR(-ENOTSOCK);
1900d32f89daSPavel Begunkov
19011da177e4SLinus Torvalds newsock = sock_alloc();
1902c6d409cfSEric Dumazet if (!newsock)
1903c6d409cfSEric Dumazet return ERR_PTR(-ENFILE);
1904d32f89daSPavel Begunkov ops = READ_ONCE(sock->ops);
19051ded5e5aSEric Dumazet
19061da177e4SLinus Torvalds newsock->type = sock->type;
19071da177e4SLinus Torvalds newsock->ops = ops;
19081ded5e5aSEric Dumazet
19091da177e4SLinus Torvalds /*
19101da177e4SLinus Torvalds * We don't need try_module_get here, as the listening socket (sock)
19111da177e4SLinus Torvalds * has the protocol module (sock->ops->owner) held.
19121da177e4SLinus Torvalds */
19131da177e4SLinus Torvalds __module_get(ops->owner);
19141ded5e5aSEric Dumazet
19151da177e4SLinus Torvalds newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
1916aab174f0SLinus Torvalds if (IS_ERR(newfile))
1917d32f89daSPavel Begunkov return newfile;
1918d32f89daSPavel Begunkov
191939d8c1b6SDavid S. Miller err = security_socket_accept(sock, newsock);
1920a79af59eSFrank Filz if (err)
1921a79af59eSFrank Filz goto out_fd;
192239d8c1b6SDavid S. Miller
1923a79af59eSFrank Filz arg->flags |= sock->file->f_flags;
19240645fbe7SJens Axboe err = ops->accept(sock, newsock, arg);
19250645fbe7SJens Axboe if (err < 0)
19261da177e4SLinus Torvalds goto out_fd;
192739d8c1b6SDavid S. Miller
19281da177e4SLinus Torvalds if (upeer_sockaddr) {
19291da177e4SLinus Torvalds len = ops->getname(newsock, (struct sockaddr *)&address, 2);
19301ded5e5aSEric Dumazet if (len < 0) {
19319b2c45d4SDenys Vlasenko err = -ECONNABORTED;
19321da177e4SLinus Torvalds goto out_fd;
193339d8c1b6SDavid S. Miller }
19341da177e4SLinus Torvalds err = move_addr_to_user(&address,
193543db362dSMaciej Żenczykowski len, upeer_sockaddr, upeer_addrlen);
1936230b1839SYOSHIFUJI Hideaki if (err < 0)
19371da177e4SLinus Torvalds goto out_fd;
193839d8c1b6SDavid S. Miller }
19391da177e4SLinus Torvalds
19401da177e4SLinus Torvalds /* File flags are not inherited via accept() unlike another OSes. */
19411da177e4SLinus Torvalds return newfile;
1942d32f89daSPavel Begunkov out_fd:
194339d8c1b6SDavid S. Miller fput(newfile);
19449606a216SDavid S. Miller return ERR_PTR(err);
1945d32f89daSPavel Begunkov }
1946d32f89daSPavel Begunkov
__sys_accept4_file(struct file * file,struct sockaddr __user * upeer_sockaddr,int __user * upeer_addrlen,int flags)1947de2ea4b6SJens Axboe static int __sys_accept4_file(struct file *file, struct sockaddr __user *upeer_sockaddr,
1948c0424532SYajun Deng int __user *upeer_addrlen, int flags)
1949c0424532SYajun Deng {
1950d32f89daSPavel Begunkov struct proto_accept_arg arg = { };
19510645fbe7SJens Axboe struct file *newfile;
1952d32f89daSPavel Begunkov int newfd;
1953d32f89daSPavel Begunkov
1954d32f89daSPavel Begunkov if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
1955d32f89daSPavel Begunkov return -EINVAL;
1956d32f89daSPavel Begunkov
1957d32f89daSPavel Begunkov if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1958d32f89daSPavel Begunkov flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1959d32f89daSPavel Begunkov
1960d32f89daSPavel Begunkov newfd = get_unused_fd_flags(flags);
1961c0424532SYajun Deng if (unlikely(newfd < 0))
1962d32f89daSPavel Begunkov return newfd;
1963d32f89daSPavel Begunkov
1964d32f89daSPavel Begunkov newfile = do_accept(file, &arg, upeer_sockaddr, upeer_addrlen,
19650645fbe7SJens Axboe flags);
1966d32f89daSPavel Begunkov if (IS_ERR(newfile)) {
1967d32f89daSPavel Begunkov put_unused_fd(newfd);
1968d32f89daSPavel Begunkov return PTR_ERR(newfile);
1969d32f89daSPavel Begunkov }
1970d32f89daSPavel Begunkov fd_install(newfd, newfile);
1971d32f89daSPavel Begunkov return newfd;
1972d32f89daSPavel Begunkov }
1973de2ea4b6SJens Axboe
1974de2ea4b6SJens Axboe /*
1975de2ea4b6SJens Axboe * For accept, we attempt to create a new socket, set up the link
1976de2ea4b6SJens Axboe * with the client, wake up the client, then return the new
1977de2ea4b6SJens Axboe * connected fd. We collect the address of the connector in kernel
1978de2ea4b6SJens Axboe * space and move it to user at the very end. This is unclean because
1979de2ea4b6SJens Axboe * we open the socket then return an error.
1980de2ea4b6SJens Axboe *
1981de2ea4b6SJens Axboe * 1003.1g adds the ability to recvmsg() to query connection pending
1982de2ea4b6SJens Axboe * status to recvmsg. We need to add that support in a way thats
1983de2ea4b6SJens Axboe * clean when we restructure accept also.
1984de2ea4b6SJens Axboe */
1985de2ea4b6SJens Axboe
__sys_accept4(int fd,struct sockaddr __user * upeer_sockaddr,int __user * upeer_addrlen,int flags)1986de2ea4b6SJens Axboe int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
1987de2ea4b6SJens Axboe int __user *upeer_addrlen, int flags)
1988de2ea4b6SJens Axboe {
1989de2ea4b6SJens Axboe CLASS(fd, f)(fd);
199053c0a58bSAl Viro
1991de2ea4b6SJens Axboe if (fd_empty(f))
199253c0a58bSAl Viro return -EBADF;
199353c0a58bSAl Viro return __sys_accept4_file(fd_file(f), upeer_sockaddr,
199453c0a58bSAl Viro upeer_addrlen, flags);
1995c0424532SYajun Deng }
19961da177e4SLinus Torvalds
SYSCALL_DEFINE4(accept4,int,fd,struct sockaddr __user *,upeer_sockaddr,int __user *,upeer_addrlen,int,flags)19971da177e4SLinus Torvalds SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
19984541e805SDominik Brodowski int __user *, upeer_addrlen, int, flags)
19994541e805SDominik Brodowski {
20004541e805SDominik Brodowski return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, flags);
20014541e805SDominik Brodowski }
20024541e805SDominik Brodowski
SYSCALL_DEFINE3(accept,int,fd,struct sockaddr __user *,upeer_sockaddr,int __user *,upeer_addrlen)20034541e805SDominik Brodowski SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
200420f37034SHeiko Carstens int __user *, upeer_addrlen)
200520f37034SHeiko Carstens {
2006aaca0bdcSUlrich Drepper return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
20074541e805SDominik Brodowski }
2008aaca0bdcSUlrich Drepper
2009aaca0bdcSUlrich Drepper /*
20101da177e4SLinus Torvalds * Attempt to connect to a socket with the server address. The address
20111da177e4SLinus Torvalds * is in user space so we verify it is OK and move it to kernel space.
20121da177e4SLinus Torvalds *
20131da177e4SLinus Torvalds * For 1003.1g we need to add clean support for a bind to AF_UNSPEC to
20141da177e4SLinus Torvalds * break bindings
20151da177e4SLinus Torvalds *
20161da177e4SLinus Torvalds * NOTE: 1003.1g draft 6.3 is broken with respect to AX.25/NetROM and
20171da177e4SLinus Torvalds * other SEQPACKET protocols that take time to connect() as it doesn't
20181da177e4SLinus Torvalds * include the -EINPROGRESS status for such sockets.
20191da177e4SLinus Torvalds */
20201da177e4SLinus Torvalds
__sys_connect_file(struct file * file,struct sockaddr_storage * address,int addrlen,int file_flags)20211da177e4SLinus Torvalds int __sys_connect_file(struct file *file, struct sockaddr_storage *address,
2022f499a021SJens Axboe int addrlen, int file_flags)
2023bd3ded31SJens Axboe {
20241da177e4SLinus Torvalds struct socket *sock;
20251da177e4SLinus Torvalds int err;
2026bd3ded31SJens Axboe
20271da177e4SLinus Torvalds sock = sock_from_file(file);
2028dba4a925SFlorent Revest if (!sock) {
2029dba4a925SFlorent Revest err = -ENOTSOCK;
2030dba4a925SFlorent Revest goto out;
20311da177e4SLinus Torvalds }
2032dba4a925SFlorent Revest
20331da177e4SLinus Torvalds err =
203489bddce5SStephen Hemminger security_socket_connect(sock, (struct sockaddr *)address, addrlen);
2035f499a021SJens Axboe if (err)
20361da177e4SLinus Torvalds goto out;
2037bd3ded31SJens Axboe
20381da177e4SLinus Torvalds err = READ_ONCE(sock->ops)->connect(sock, (struct sockaddr *)address,
20391ded5e5aSEric Dumazet addrlen, sock->file->f_flags | file_flags);
20401ded5e5aSEric Dumazet out:
20411da177e4SLinus Torvalds return err;
20421da177e4SLinus Torvalds }
20431da177e4SLinus Torvalds
__sys_connect(int fd,struct sockaddr __user * uservaddr,int addrlen)20441da177e4SLinus Torvalds int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
2045bd3ded31SJens Axboe {
2046bd3ded31SJens Axboe struct sockaddr_storage address;
2047f499a021SJens Axboe CLASS(fd, f)(fd);
204853c0a58bSAl Viro int ret;
204953c0a58bSAl Viro
205053c0a58bSAl Viro if (fd_empty(f))
205153c0a58bSAl Viro return -EBADF;
205253c0a58bSAl Viro
2053f499a021SJens Axboe ret = move_addr_to_kernel(uservaddr, addrlen, &address);
2054f499a021SJens Axboe if (ret)
205553c0a58bSAl Viro return ret;
2056bd3ded31SJens Axboe
205753c0a58bSAl Viro return __sys_connect_file(fd_file(f), &address, addrlen, 0);
205853c0a58bSAl Viro }
2059bd3ded31SJens Axboe
SYSCALL_DEFINE3(connect,int,fd,struct sockaddr __user *,uservaddr,int,addrlen)2060bd3ded31SJens Axboe SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
20611387c2c2SDominik Brodowski int, addrlen)
20621387c2c2SDominik Brodowski {
20631387c2c2SDominik Brodowski return __sys_connect(fd, uservaddr, addrlen);
20641387c2c2SDominik Brodowski }
20651387c2c2SDominik Brodowski
20661387c2c2SDominik Brodowski /*
20671da177e4SLinus Torvalds * Get the local address ('name') of a socket object. Move the obtained
20681da177e4SLinus Torvalds * name to user space.
20691da177e4SLinus Torvalds */
20701da177e4SLinus Torvalds
__sys_getsockname(int fd,struct sockaddr __user * usockaddr,int __user * usockaddr_len)20711da177e4SLinus Torvalds int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
20728882a107SDominik Brodowski int __user *usockaddr_len)
20738882a107SDominik Brodowski {
20741da177e4SLinus Torvalds struct socket *sock;
20751da177e4SLinus Torvalds struct sockaddr_storage address;
2076230b1839SYOSHIFUJI Hideaki CLASS(fd, f)(fd);
207753c0a58bSAl Viro int err;
207853c0a58bSAl Viro
20791da177e4SLinus Torvalds if (fd_empty(f))
208053c0a58bSAl Viro return -EBADF;
208153c0a58bSAl Viro sock = sock_from_file(fd_file(f));
208253c0a58bSAl Viro if (unlikely(!sock))
208353c0a58bSAl Viro return -ENOTSOCK;
208453c0a58bSAl Viro
20851da177e4SLinus Torvalds err = security_socket_getsockname(sock);
20861da177e4SLinus Torvalds if (err)
20871da177e4SLinus Torvalds return err;
208853c0a58bSAl Viro
20891da177e4SLinus Torvalds err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 0);
20901ded5e5aSEric Dumazet if (err < 0)
20919b2c45d4SDenys Vlasenko return err;
20921da177e4SLinus Torvalds
209353c0a58bSAl Viro /* "err" is actually length in this case */
209453c0a58bSAl Viro return move_addr_to_user(&address, err, usockaddr, usockaddr_len);
209553c0a58bSAl Viro }
20961da177e4SLinus Torvalds
SYSCALL_DEFINE3(getsockname,int,fd,struct sockaddr __user *,usockaddr,int __user *,usockaddr_len)20971da177e4SLinus Torvalds SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
20988882a107SDominik Brodowski int __user *, usockaddr_len)
20998882a107SDominik Brodowski {
21008882a107SDominik Brodowski return __sys_getsockname(fd, usockaddr, usockaddr_len);
21018882a107SDominik Brodowski }
21028882a107SDominik Brodowski
21038882a107SDominik Brodowski /*
21041da177e4SLinus Torvalds * Get the remote address ('name') of a socket object. Move the obtained
21051da177e4SLinus Torvalds * name to user space.
21061da177e4SLinus Torvalds */
21071da177e4SLinus Torvalds
__sys_getpeername(int fd,struct sockaddr __user * usockaddr,int __user * usockaddr_len)21081da177e4SLinus Torvalds int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
2109b21c8f83SDominik Brodowski int __user *usockaddr_len)
2110b21c8f83SDominik Brodowski {
21111da177e4SLinus Torvalds struct socket *sock;
21121da177e4SLinus Torvalds struct sockaddr_storage address;
2113230b1839SYOSHIFUJI Hideaki CLASS(fd, f)(fd);
211453c0a58bSAl Viro int err;
211553c0a58bSAl Viro
21161da177e4SLinus Torvalds if (fd_empty(f))
211753c0a58bSAl Viro return -EBADF;
211853c0a58bSAl Viro sock = sock_from_file(fd_file(f));
211953c0a58bSAl Viro if (unlikely(!sock))
212053c0a58bSAl Viro return -ENOTSOCK;
212153c0a58bSAl Viro
21221ded5e5aSEric Dumazet err = security_socket_getpeername(sock);
21231da177e4SLinus Torvalds if (err)
212453c0a58bSAl Viro return err;
21251da177e4SLinus Torvalds
21261da177e4SLinus Torvalds err = READ_ONCE(sock->ops)->getname(sock, (struct sockaddr *)&address, 1);
212753c0a58bSAl Viro if (err < 0)
212853c0a58bSAl Viro return err;
21291da177e4SLinus Torvalds
213053c0a58bSAl Viro /* "err" is actually length in this case */
213153c0a58bSAl Viro return move_addr_to_user(&address, err, usockaddr, usockaddr_len);
213253c0a58bSAl Viro }
21331da177e4SLinus Torvalds
SYSCALL_DEFINE3(getpeername,int,fd,struct sockaddr __user *,usockaddr,int __user *,usockaddr_len)21341da177e4SLinus Torvalds SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
2135b21c8f83SDominik Brodowski int __user *, usockaddr_len)
2136b21c8f83SDominik Brodowski {
2137b21c8f83SDominik Brodowski return __sys_getpeername(fd, usockaddr, usockaddr_len);
2138b21c8f83SDominik Brodowski }
2139b21c8f83SDominik Brodowski
2140b21c8f83SDominik Brodowski /*
21411da177e4SLinus Torvalds * Send a datagram to a given address. We move the address into kernel
21421da177e4SLinus Torvalds * space and check the user space data area is readable before invoking
21431da177e4SLinus Torvalds * the protocol.
21441da177e4SLinus Torvalds */
__sys_sendto(int fd,void __user * buff,size_t len,unsigned int flags,struct sockaddr __user * addr,int addr_len)21451da177e4SLinus Torvalds int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags,
2146211b634bSDominik Brodowski struct sockaddr __user *addr, int addr_len)
2147211b634bSDominik Brodowski {
21481da177e4SLinus Torvalds struct socket *sock;
21491da177e4SLinus Torvalds struct sockaddr_storage address;
2150230b1839SYOSHIFUJI Hideaki int err;
21511da177e4SLinus Torvalds struct msghdr msg;
21521da177e4SLinus Torvalds
21531da177e4SLinus Torvalds err = import_ubuf(ITER_SOURCE, buff, len, &msg.msg_iter);
21549fd7874cSJens Axboe if (unlikely(err))
2155602bd0e9SAl Viro return err;
2156602bd0e9SAl Viro
215753c0a58bSAl Viro CLASS(fd, f)(fd);
215853c0a58bSAl Viro if (fd_empty(f))
215953c0a58bSAl Viro return -EBADF;
216053c0a58bSAl Viro sock = sock_from_file(fd_file(f));
216153c0a58bSAl Viro if (unlikely(!sock))
216253c0a58bSAl Viro return -ENOTSOCK;
216353c0a58bSAl Viro
21646cb153caSBenjamin LaHaise msg.msg_name = NULL;
21651da177e4SLinus Torvalds msg.msg_control = NULL;
21661da177e4SLinus Torvalds msg.msg_controllen = 0;
21671da177e4SLinus Torvalds msg.msg_namelen = 0;
21681da177e4SLinus Torvalds msg.msg_ubuf = NULL;
21697c701d92SPavel Begunkov if (addr) {
21706cb153caSBenjamin LaHaise err = move_addr_to_kernel(addr, addr_len, &address);
217143db362dSMaciej Żenczykowski if (err < 0)
21721da177e4SLinus Torvalds return err;
217353c0a58bSAl Viro msg.msg_name = (struct sockaddr *)&address;
2174230b1839SYOSHIFUJI Hideaki msg.msg_namelen = addr_len;
21751da177e4SLinus Torvalds }
21761da177e4SLinus Torvalds flags &= ~MSG_INTERNAL_SENDMSG_FLAGS;
2177b841b901SDavid Howells if (sock->file->f_flags & O_NONBLOCK)
21781da177e4SLinus Torvalds flags |= MSG_DONTWAIT;
21791da177e4SLinus Torvalds msg.msg_flags = flags;
21801da177e4SLinus Torvalds return __sock_sendmsg(sock, &msg);
218153c0a58bSAl Viro }
21821da177e4SLinus Torvalds
SYSCALL_DEFINE6(sendto,int,fd,void __user *,buff,size_t,len,unsigned int,flags,struct sockaddr __user *,addr,int,addr_len)21831da177e4SLinus Torvalds SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
2184211b634bSDominik Brodowski unsigned int, flags, struct sockaddr __user *, addr,
2185211b634bSDominik Brodowski int, addr_len)
2186211b634bSDominik Brodowski {
2187211b634bSDominik Brodowski return __sys_sendto(fd, buff, len, flags, addr, addr_len);
2188211b634bSDominik Brodowski }
2189211b634bSDominik Brodowski
2190211b634bSDominik Brodowski /*
21911da177e4SLinus Torvalds * Send a datagram down a socket.
21921da177e4SLinus Torvalds */
21931da177e4SLinus Torvalds
SYSCALL_DEFINE4(send,int,fd,void __user *,buff,size_t,len,unsigned int,flags)21941da177e4SLinus Torvalds SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
21953e0fa65fSHeiko Carstens unsigned int, flags)
219695c96174SEric Dumazet {
21971da177e4SLinus Torvalds return __sys_sendto(fd, buff, len, flags, NULL, 0);
2198211b634bSDominik Brodowski }
21991da177e4SLinus Torvalds
22001da177e4SLinus Torvalds /*
22011da177e4SLinus Torvalds * Receive a frame from the socket and optionally record the address of the
22021da177e4SLinus Torvalds * sender. We verify the buffers are writable and if needed move the
22031da177e4SLinus Torvalds * sender address from kernel to user space.
22041da177e4SLinus Torvalds */
__sys_recvfrom(int fd,void __user * ubuf,size_t size,unsigned int flags,struct sockaddr __user * addr,int __user * addr_len)22051da177e4SLinus Torvalds int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags,
22067a09e1ebSDominik Brodowski struct sockaddr __user *addr, int __user *addr_len)
22077a09e1ebSDominik Brodowski {
22081da177e4SLinus Torvalds struct sockaddr_storage address;
22091228b34cSEric Dumazet struct msghdr msg = {
22101228b34cSEric Dumazet /* Save some cycles and don't copy the address if not needed */
22111228b34cSEric Dumazet .msg_name = addr ? (struct sockaddr *)&address : NULL,
22121228b34cSEric Dumazet };
22131228b34cSEric Dumazet struct socket *sock;
22141da177e4SLinus Torvalds int err, err2;
22151da177e4SLinus Torvalds
22161da177e4SLinus Torvalds err = import_ubuf(ITER_DEST, ubuf, size, &msg.msg_iter);
22179fd7874cSJens Axboe if (unlikely(err))
2218602bd0e9SAl Viro return err;
2219602bd0e9SAl Viro
222053c0a58bSAl Viro CLASS(fd, f)(fd);
222153c0a58bSAl Viro
222253c0a58bSAl Viro if (fd_empty(f))
222353c0a58bSAl Viro return -EBADF;
222453c0a58bSAl Viro sock = sock_from_file(fd_file(f));
222553c0a58bSAl Viro if (unlikely(!sock))
222653c0a58bSAl Viro return -ENOTSOCK;
222753c0a58bSAl Viro
22281da177e4SLinus Torvalds if (sock->file->f_flags & O_NONBLOCK)
22291da177e4SLinus Torvalds flags |= MSG_DONTWAIT;
22301da177e4SLinus Torvalds err = sock_recvmsg(sock, &msg, flags);
22312da62906SAl Viro
22321da177e4SLinus Torvalds if (err >= 0 && addr != NULL) {
223389bddce5SStephen Hemminger err2 = move_addr_to_user(&address,
223443db362dSMaciej Żenczykowski msg.msg_namelen, addr, addr_len);
2235230b1839SYOSHIFUJI Hideaki if (err2 < 0)
22361da177e4SLinus Torvalds err = err2;
22371da177e4SLinus Torvalds }
22381da177e4SLinus Torvalds return err;
22391da177e4SLinus Torvalds }
22401da177e4SLinus Torvalds
SYSCALL_DEFINE6(recvfrom,int,fd,void __user *,ubuf,size_t,size,unsigned int,flags,struct sockaddr __user *,addr,int __user *,addr_len)22411da177e4SLinus Torvalds SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
22427a09e1ebSDominik Brodowski unsigned int, flags, struct sockaddr __user *, addr,
22437a09e1ebSDominik Brodowski int __user *, addr_len)
22447a09e1ebSDominik Brodowski {
22457a09e1ebSDominik Brodowski return __sys_recvfrom(fd, ubuf, size, flags, addr, addr_len);
22467a09e1ebSDominik Brodowski }
22477a09e1ebSDominik Brodowski
22487a09e1ebSDominik Brodowski /*
22491da177e4SLinus Torvalds * Receive a datagram from a socket.
22501da177e4SLinus Torvalds */
22511da177e4SLinus Torvalds
SYSCALL_DEFINE4(recv,int,fd,void __user *,ubuf,size_t,size,unsigned int,flags)22521da177e4SLinus Torvalds SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
2253b7c0ddf5SJan Glauber unsigned int, flags)
2254b7c0ddf5SJan Glauber {
22551da177e4SLinus Torvalds return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
22567a09e1ebSDominik Brodowski }
22571da177e4SLinus Torvalds
sock_use_custom_sol_socket(const struct socket * sock)22581da177e4SLinus Torvalds static bool sock_use_custom_sol_socket(const struct socket *sock)
225983f0c10bSFlorian Westphal {
226083f0c10bSFlorian Westphal return test_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags);
2261a5ef058dSPaolo Abeni }
226283f0c10bSFlorian Westphal
do_sock_setsockopt(struct socket * sock,bool compat,int level,int optname,sockptr_t optval,int optlen)226383f0c10bSFlorian Westphal int do_sock_setsockopt(struct socket *sock, bool compat, int level,
22641406245cSBreno Leitao int optname, sockptr_t optval, int optlen)
22651406245cSBreno Leitao {
22661da177e4SLinus Torvalds const struct proto_ops *ops;
22671ded5e5aSEric Dumazet char *kernel_optval = NULL;
22680d01da6aSStanislav Fomichev int err;
22691406245cSBreno Leitao
22701da177e4SLinus Torvalds if (optlen < 0)
22711da177e4SLinus Torvalds return -EINVAL;
22721da177e4SLinus Torvalds
22731da177e4SLinus Torvalds err = security_socket_setsockopt(sock, level, optname);
22741da177e4SLinus Torvalds if (err)
22756cb153caSBenjamin LaHaise goto out_put;
22766cb153caSBenjamin LaHaise
22771da177e4SLinus Torvalds if (!compat)
22781406245cSBreno Leitao err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname,
22794a367299SChristoph Hellwig optval, &optlen,
22803f31e0d1SBreno Leitao &kernel_optval);
228155db9c0eSChristoph Hellwig if (err < 0)
22824a367299SChristoph Hellwig goto out_put;
22830d01da6aSStanislav Fomichev if (err > 0) {
22844a367299SChristoph Hellwig err = 0;
22850d01da6aSStanislav Fomichev goto out_put;
22860d01da6aSStanislav Fomichev }
22870d01da6aSStanislav Fomichev
22880d01da6aSStanislav Fomichev if (kernel_optval)
2289a7b75c5aSChristoph Hellwig optval = KERNEL_SOCKPTR(kernel_optval);
2290a7b75c5aSChristoph Hellwig ops = READ_ONCE(sock->ops);
22911ded5e5aSEric Dumazet if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock))
229283f0c10bSFlorian Westphal err = sock_setsockopt(sock, level, optname, optval, optlen);
2293a7b75c5aSChristoph Hellwig else if (unlikely(!ops->setsockopt))
22941ded5e5aSEric Dumazet err = -EOPNOTSUPP;
2295a44d9e72SChristoph Hellwig else
22961da177e4SLinus Torvalds err = ops->setsockopt(sock, level, optname, optval,
22971ded5e5aSEric Dumazet optlen);
229889bddce5SStephen Hemminger kfree(kernel_optval);
22990d01da6aSStanislav Fomichev out_put:
23006cb153caSBenjamin LaHaise return err;
23011406245cSBreno Leitao }
23021406245cSBreno Leitao EXPORT_SYMBOL(do_sock_setsockopt);
23031406245cSBreno Leitao
23041406245cSBreno Leitao /* Set a socket option. Because we don't know the option lengths we have
23051406245cSBreno Leitao * to pass the user mode parameter for the protocols to sort out.
23061406245cSBreno Leitao */
__sys_setsockopt(int fd,int level,int optname,char __user * user_optval,int optlen)23071406245cSBreno Leitao int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval,
23081406245cSBreno Leitao int optlen)
23091406245cSBreno Leitao {
23101406245cSBreno Leitao sockptr_t optval = USER_SOCKPTR(user_optval);
23111406245cSBreno Leitao bool compat = in_compat_syscall();
23121406245cSBreno Leitao struct socket *sock;
23131406245cSBreno Leitao CLASS(fd, f)(fd);
231453c0a58bSAl Viro
23151406245cSBreno Leitao if (fd_empty(f))
231653c0a58bSAl Viro return -EBADF;
231753c0a58bSAl Viro sock = sock_from_file(fd_file(f));
231853c0a58bSAl Viro if (unlikely(!sock))
231953c0a58bSAl Viro return -ENOTSOCK;
232053c0a58bSAl Viro
23211406245cSBreno Leitao return do_sock_setsockopt(sock, compat, level, optname, optval, optlen);
232253c0a58bSAl Viro }
23231da177e4SLinus Torvalds
SYSCALL_DEFINE5(setsockopt,int,fd,int,level,int,optname,char __user *,optval,int,optlen)23241da177e4SLinus Torvalds SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
2325cc36dca0SDominik Brodowski char __user *, optval, int, optlen)
2326cc36dca0SDominik Brodowski {
2327cc36dca0SDominik Brodowski return __sys_setsockopt(fd, level, optname, optval, optlen);
2328cc36dca0SDominik Brodowski }
2329cc36dca0SDominik Brodowski
2330cc36dca0SDominik Brodowski INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level,
23319cacf81fSStanislav Fomichev int optname));
23329cacf81fSStanislav Fomichev
do_sock_getsockopt(struct socket * sock,bool compat,int level,int optname,sockptr_t optval,sockptr_t optlen)23339cacf81fSStanislav Fomichev int do_sock_getsockopt(struct socket *sock, bool compat, int level,
23340b05b0cdSBreno Leitao int optname, sockptr_t optval, sockptr_t optlen)
23350b05b0cdSBreno Leitao {
23360b05b0cdSBreno Leitao int max_optlen __maybe_unused = 0;
233733f339a1STze-nan Wu const struct proto_ops *ops;
23380b05b0cdSBreno Leitao int err;
23390b05b0cdSBreno Leitao
23400b05b0cdSBreno Leitao err = security_socket_getsockopt(sock, level, optname);
23410b05b0cdSBreno Leitao if (err)
23420b05b0cdSBreno Leitao return err;
23430b05b0cdSBreno Leitao
23440b05b0cdSBreno Leitao if (!compat)
23450b05b0cdSBreno Leitao copy_from_sockptr(&max_optlen, optlen, sizeof(int));
234633f339a1STze-nan Wu
23470b05b0cdSBreno Leitao ops = READ_ONCE(sock->ops);
23480b05b0cdSBreno Leitao if (level == SOL_SOCKET) {
23490b05b0cdSBreno Leitao err = sk_getsockopt(sock->sk, level, optname, optval, optlen);
23500b05b0cdSBreno Leitao } else if (unlikely(!ops->getsockopt)) {
23510b05b0cdSBreno Leitao err = -EOPNOTSUPP;
23520b05b0cdSBreno Leitao } else {
23530b05b0cdSBreno Leitao if (WARN_ONCE(optval.is_kernel || optlen.is_kernel,
23540b05b0cdSBreno Leitao "Invalid argument type"))
23550b05b0cdSBreno Leitao return -EOPNOTSUPP;
23560b05b0cdSBreno Leitao
23570b05b0cdSBreno Leitao err = ops->getsockopt(sock, level, optname, optval.user,
23580b05b0cdSBreno Leitao optlen.user);
23590b05b0cdSBreno Leitao }
23600b05b0cdSBreno Leitao
23610b05b0cdSBreno Leitao if (!compat)
23620b05b0cdSBreno Leitao err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname,
23630b05b0cdSBreno Leitao optval, optlen, max_optlen,
23640b05b0cdSBreno Leitao err);
23650b05b0cdSBreno Leitao
23660b05b0cdSBreno Leitao return err;
23670b05b0cdSBreno Leitao }
23680b05b0cdSBreno Leitao EXPORT_SYMBOL(do_sock_getsockopt);
23690b05b0cdSBreno Leitao
23700b05b0cdSBreno Leitao /*
23711da177e4SLinus Torvalds * Get a socket option. Because we don't know the option lengths we have
23721da177e4SLinus Torvalds * to pass a user mode parameter for the protocols to sort out.
23731da177e4SLinus Torvalds */
__sys_getsockopt(int fd,int level,int optname,char __user * optval,int __user * optlen)23741da177e4SLinus Torvalds int __sys_getsockopt(int fd, int level, int optname, char __user *optval,
237555db9c0eSChristoph Hellwig int __user *optlen)
237655db9c0eSChristoph Hellwig {
23771da177e4SLinus Torvalds struct socket *sock;
23781da177e4SLinus Torvalds CLASS(fd, f)(fd);
237953c0a58bSAl Viro
23801da177e4SLinus Torvalds if (fd_empty(f))
238153c0a58bSAl Viro return -EBADF;
238253c0a58bSAl Viro sock = sock_from_file(fd_file(f));
238353c0a58bSAl Viro if (unlikely(!sock))
238453c0a58bSAl Viro return -ENOTSOCK;
238553c0a58bSAl Viro
2386d8a9b38fSChristoph Hellwig return do_sock_getsockopt(sock, in_compat_syscall(), level, optname,
238753c0a58bSAl Viro USER_SOCKPTR(optval), USER_SOCKPTR(optlen));
23880b05b0cdSBreno Leitao }
23891da177e4SLinus Torvalds
SYSCALL_DEFINE5(getsockopt,int,fd,int,level,int,optname,char __user *,optval,int __user *,optlen)23901da177e4SLinus Torvalds SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
239113a2d70eSDominik Brodowski char __user *, optval, int __user *, optlen)
239213a2d70eSDominik Brodowski {
239313a2d70eSDominik Brodowski return __sys_getsockopt(fd, level, optname, optval, optlen);
239413a2d70eSDominik Brodowski }
239513a2d70eSDominik Brodowski
239613a2d70eSDominik Brodowski /*
23971da177e4SLinus Torvalds * Shutdown a socket.
23981da177e4SLinus Torvalds */
23991da177e4SLinus Torvalds
__sys_shutdown_sock(struct socket * sock,int how)24001da177e4SLinus Torvalds int __sys_shutdown_sock(struct socket *sock, int how)
2401b713c195SJens Axboe {
2402b713c195SJens Axboe int err;
2403b713c195SJens Axboe
2404b713c195SJens Axboe err = security_socket_shutdown(sock, how);
2405b713c195SJens Axboe if (!err)
2406b713c195SJens Axboe err = READ_ONCE(sock->ops)->shutdown(sock, how);
24071ded5e5aSEric Dumazet
2408b713c195SJens Axboe return err;
2409b713c195SJens Axboe }
2410b713c195SJens Axboe
__sys_shutdown(int fd,int how)2411b713c195SJens Axboe int __sys_shutdown(int fd, int how)
2412005a1aeaSDominik Brodowski {
24131da177e4SLinus Torvalds struct socket *sock;
24141da177e4SLinus Torvalds CLASS(fd, f)(fd);
241553c0a58bSAl Viro
24161da177e4SLinus Torvalds if (fd_empty(f))
241753c0a58bSAl Viro return -EBADF;
241853c0a58bSAl Viro sock = sock_from_file(fd_file(f));
241953c0a58bSAl Viro if (unlikely(!sock))
242053c0a58bSAl Viro return -ENOTSOCK;
242153c0a58bSAl Viro
242253c0a58bSAl Viro return __sys_shutdown_sock(sock, how);
242353c0a58bSAl Viro }
24241da177e4SLinus Torvalds
SYSCALL_DEFINE2(shutdown,int,fd,int,how)24251da177e4SLinus Torvalds SYSCALL_DEFINE2(shutdown, int, fd, int, how)
2426005a1aeaSDominik Brodowski {
2427005a1aeaSDominik Brodowski return __sys_shutdown(fd, how);
2428005a1aeaSDominik Brodowski }
2429005a1aeaSDominik Brodowski
2430005a1aeaSDominik Brodowski /* A couple of helpful macros for getting the address of the 32/64 bit
24311da177e4SLinus Torvalds * fields which are the same type (int / unsigned) on our platforms.
24321da177e4SLinus Torvalds */
24331da177e4SLinus Torvalds #define COMPAT_MSG(msg, member) ((MSG_CMSG_COMPAT & flags) ? &msg##_compat->member : &msg->member)
24341da177e4SLinus Torvalds #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen)
24351da177e4SLinus Torvalds #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags)
24361da177e4SLinus Torvalds
24371da177e4SLinus Torvalds struct used_address {
2438c71d8ebeSTetsuo Handa struct sockaddr_storage name;
2439c71d8ebeSTetsuo Handa unsigned int name_len;
2440c71d8ebeSTetsuo Handa };
2441c71d8ebeSTetsuo Handa
__copy_msghdr(struct msghdr * kmsg,struct user_msghdr * msg,struct sockaddr __user ** save_addr)2442c71d8ebeSTetsuo Handa int __copy_msghdr(struct msghdr *kmsg,
24437fa875b8SDylan Yudaken struct user_msghdr *msg,
24447fa875b8SDylan Yudaken struct sockaddr __user **save_addr)
24457fa875b8SDylan Yudaken {
24461661bf36SDan Carpenter ssize_t err;
244708adb7daSAl Viro
244808adb7daSAl Viro kmsg->msg_control_is_user = true;
24491f466e1fSChristoph Hellwig kmsg->msg_get_inq = 0;
24501228b34cSEric Dumazet kmsg->msg_control_user = msg->msg_control;
24517fa875b8SDylan Yudaken kmsg->msg_controllen = msg->msg_controllen;
24527fa875b8SDylan Yudaken kmsg->msg_flags = msg->msg_flags;
24537fa875b8SDylan Yudaken
2454ffb07550SAl Viro kmsg->msg_namelen = msg->msg_namelen;
24557fa875b8SDylan Yudaken if (!msg->msg_name)
24567fa875b8SDylan Yudaken kmsg->msg_namelen = 0;
24576a2a2b3aSAni Sinha
24586a2a2b3aSAni Sinha if (kmsg->msg_namelen < 0)
2459dbb490b9SMatthew Leach return -EINVAL;
2460dbb490b9SMatthew Leach
2461dbb490b9SMatthew Leach if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
24621661bf36SDan Carpenter kmsg->msg_namelen = sizeof(struct sockaddr_storage);
2463db31c55aSDan Carpenter
246408adb7daSAl Viro if (save_addr)
246508adb7daSAl Viro *save_addr = msg->msg_name;
24667fa875b8SDylan Yudaken
246708adb7daSAl Viro if (msg->msg_name && kmsg->msg_namelen) {
24687fa875b8SDylan Yudaken if (!save_addr) {
246908adb7daSAl Viro err = move_addr_to_kernel(msg->msg_name,
24707fa875b8SDylan Yudaken kmsg->msg_namelen,
2471864d9664SPaolo Abeni kmsg->msg_name);
247208adb7daSAl Viro if (err < 0)
247308adb7daSAl Viro return err;
247408adb7daSAl Viro }
247508adb7daSAl Viro } else {
247608adb7daSAl Viro kmsg->msg_name = NULL;
247708adb7daSAl Viro kmsg->msg_namelen = 0;
247808adb7daSAl Viro }
247908adb7daSAl Viro
248008adb7daSAl Viro if (msg->msg_iovlen > UIO_MAXIOV)
24817fa875b8SDylan Yudaken return -EMSGSIZE;
248208adb7daSAl Viro
248308adb7daSAl Viro kmsg->msg_iocb = NULL;
24840345f931S[email protected] kmsg->msg_ubuf = NULL;
24857c701d92SPavel Begunkov return 0;
24860a384abfSJens Axboe }
24870a384abfSJens Axboe
copy_msghdr_from_user(struct msghdr * kmsg,struct user_msghdr __user * umsg,struct sockaddr __user ** save_addr,struct iovec ** iov)24880a384abfSJens Axboe static int copy_msghdr_from_user(struct msghdr *kmsg,
24890a384abfSJens Axboe struct user_msghdr __user *umsg,
24900a384abfSJens Axboe struct sockaddr __user **save_addr,
24910a384abfSJens Axboe struct iovec **iov)
24920a384abfSJens Axboe {
24930a384abfSJens Axboe struct user_msghdr msg;
24940a384abfSJens Axboe ssize_t err;
24950a384abfSJens Axboe
24960a384abfSJens Axboe if (copy_from_user(&msg, umsg, sizeof(*umsg)))
24977fa875b8SDylan Yudaken return -EFAULT;
24987fa875b8SDylan Yudaken
24997fa875b8SDylan Yudaken err = __copy_msghdr(kmsg, &msg, save_addr);
25007fa875b8SDylan Yudaken if (err)
25010a384abfSJens Axboe return err;
25020a384abfSJens Axboe
25030345f931S[email protected] err = import_iovec(save_addr ? ITER_DEST : ITER_SOURCE,
2504de4eda9dSAl Viro msg.msg_iov, msg.msg_iovlen,
2505ffb07550SAl Viro UIO_FASTIOV, iov, &kmsg->msg_iter);
2506da184284SAl Viro return err < 0 ? err : 0;
250787e5e6daSJens Axboe }
25081661bf36SDan Carpenter
____sys_sendmsg(struct socket * sock,struct msghdr * msg_sys,unsigned int flags,struct used_address * used_address,unsigned int allowed_msghdr_flags)25091661bf36SDan Carpenter static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys,
25104257c8caSJens Axboe unsigned int flags, struct used_address *used_address,
25114257c8caSJens Axboe unsigned int allowed_msghdr_flags)
251228a94d8fSTom Herbert {
25131da177e4SLinus Torvalds unsigned char ctl[sizeof(struct cmsghdr) + 20]
2514b9d717a7SAlex Williamson __aligned(sizeof(__kernel_size_t));
2515846cc123SAmit Kushwaha /* 20 is size of ipv6_pktinfo */
2516b9d717a7SAlex Williamson unsigned char *ctl_buf = ctl;
25171da177e4SLinus Torvalds int ctl_len;
2518d8725c86SAl Viro ssize_t err;
251908adb7daSAl Viro
25201da177e4SLinus Torvalds err = -ENOBUFS;
25211da177e4SLinus Torvalds
25221da177e4SLinus Torvalds if (msg_sys->msg_controllen > INT_MAX)
2523228e548eSAnton Blanchard goto out;
25244257c8caSJens Axboe flags |= (msg_sys->msg_flags & allowed_msghdr_flags);
252528a94d8fSTom Herbert ctl_len = msg_sys->msg_controllen;
2526228e548eSAnton Blanchard if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
25271da177e4SLinus Torvalds err =
252889bddce5SStephen Hemminger cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
2529228e548eSAnton Blanchard sizeof(ctl));
253089bddce5SStephen Hemminger if (err)
25311da177e4SLinus Torvalds goto out;
25324257c8caSJens Axboe ctl_buf = msg_sys->msg_control;
2533228e548eSAnton Blanchard ctl_len = msg_sys->msg_controllen;
2534228e548eSAnton Blanchard } else if (ctl_len) {
25351da177e4SLinus Torvalds BUILD_BUG_ON(sizeof(struct cmsghdr) !=
2536ac4340fcSDavid S. Miller CMSG_ALIGN(sizeof(struct cmsghdr)));
2537ac4340fcSDavid S. Miller if (ctl_len > sizeof(ctl)) {
253889bddce5SStephen Hemminger ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
25391da177e4SLinus Torvalds if (ctl_buf == NULL)
25401da177e4SLinus Torvalds goto out;
25414257c8caSJens Axboe }
25421da177e4SLinus Torvalds err = -EFAULT;
25431da177e4SLinus Torvalds if (copy_from_user(ctl_buf, msg_sys->msg_control_user, ctl_len))
25441f466e1fSChristoph Hellwig goto out_freectl;
25451da177e4SLinus Torvalds msg_sys->msg_control = ctl_buf;
2546228e548eSAnton Blanchard msg_sys->msg_control_is_user = false;
25471f466e1fSChristoph Hellwig }
25481da177e4SLinus Torvalds flags &= ~MSG_INTERNAL_SENDMSG_FLAGS;
2549b841b901SDavid Howells msg_sys->msg_flags = flags;
2550228e548eSAnton Blanchard
25511da177e4SLinus Torvalds if (sock->file->f_flags & O_NONBLOCK)
25521da177e4SLinus Torvalds msg_sys->msg_flags |= MSG_DONTWAIT;
2553228e548eSAnton Blanchard /*
2554c71d8ebeSTetsuo Handa * If this is sendmmsg() and current destination address is same as
2555c71d8ebeSTetsuo Handa * previously succeeded address, omit asking LSM's decision.
2556c71d8ebeSTetsuo Handa * used_address->name_len is initialized to UINT_MAX so that the first
2557c71d8ebeSTetsuo Handa * destination address never matches.
2558c71d8ebeSTetsuo Handa */
2559c71d8ebeSTetsuo Handa if (used_address && msg_sys->msg_name &&
2560bc909d9dSMathieu Desnoyers used_address->name_len == msg_sys->msg_namelen &&
2561bc909d9dSMathieu Desnoyers !memcmp(&used_address->name, msg_sys->msg_name,
2562bc909d9dSMathieu Desnoyers used_address->name_len)) {
2563c71d8ebeSTetsuo Handa err = sock_sendmsg_nosec(sock, msg_sys);
2564d8725c86SAl Viro goto out_freectl;
2565c71d8ebeSTetsuo Handa }
2566c71d8ebeSTetsuo Handa err = __sock_sendmsg(sock, msg_sys);
256786a7e0b6SJordan Rife /*
2568c71d8ebeSTetsuo Handa * If this is sendmmsg() and sending to current destination address was
2569c71d8ebeSTetsuo Handa * successful, remember it.
2570c71d8ebeSTetsuo Handa */
2571c71d8ebeSTetsuo Handa if (used_address && err >= 0) {
2572c71d8ebeSTetsuo Handa used_address->name_len = msg_sys->msg_namelen;
2573c71d8ebeSTetsuo Handa if (msg_sys->msg_name)
2574bc909d9dSMathieu Desnoyers memcpy(&used_address->name, msg_sys->msg_name,
2575bc909d9dSMathieu Desnoyers used_address->name_len);
2576c71d8ebeSTetsuo Handa }
2577c71d8ebeSTetsuo Handa
25781da177e4SLinus Torvalds out_freectl:
25791da177e4SLinus Torvalds if (ctl_buf != ctl)
25801da177e4SLinus Torvalds sock_kfree_s(sock->sk, ctl_buf, ctl_len);
25811da177e4SLinus Torvalds out:
25824257c8caSJens Axboe return err;
25834257c8caSJens Axboe }
25844257c8caSJens Axboe
sendmsg_copy_msghdr(struct msghdr * msg,struct user_msghdr __user * umsg,unsigned flags,struct iovec ** iov)25854257c8caSJens Axboe static int sendmsg_copy_msghdr(struct msghdr *msg,
2586e54e09c0SJens Axboe struct user_msghdr __user *umsg, unsigned flags,
25874257c8caSJens Axboe struct iovec **iov)
25884257c8caSJens Axboe {
25894257c8caSJens Axboe int err;
25904257c8caSJens Axboe
25914257c8caSJens Axboe if (flags & MSG_CMSG_COMPAT) {
25924257c8caSJens Axboe struct compat_msghdr __user *msg_compat;
25934257c8caSJens Axboe
25944257c8caSJens Axboe msg_compat = (struct compat_msghdr __user *) umsg;
25954257c8caSJens Axboe err = get_compat_msghdr(msg, msg_compat, NULL, iov);
25964257c8caSJens Axboe } else {
25974257c8caSJens Axboe err = copy_msghdr_from_user(msg, umsg, NULL, iov);
25984257c8caSJens Axboe }
25994257c8caSJens Axboe if (err < 0)
26004257c8caSJens Axboe return err;
26014257c8caSJens Axboe
26024257c8caSJens Axboe return 0;
26034257c8caSJens Axboe }
26044257c8caSJens Axboe
___sys_sendmsg(struct socket * sock,struct user_msghdr __user * msg,struct msghdr * msg_sys,unsigned int flags,struct used_address * used_address,unsigned int allowed_msghdr_flags)26054257c8caSJens Axboe static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
26064257c8caSJens Axboe struct msghdr *msg_sys, unsigned int flags,
26074257c8caSJens Axboe struct used_address *used_address,
26084257c8caSJens Axboe unsigned int allowed_msghdr_flags)
26094257c8caSJens Axboe {
26104257c8caSJens Axboe struct sockaddr_storage address;
26114257c8caSJens Axboe struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
26124257c8caSJens Axboe ssize_t err;
26134257c8caSJens Axboe
26144257c8caSJens Axboe msg_sys->msg_name = &address;
26154257c8caSJens Axboe
26164257c8caSJens Axboe err = sendmsg_copy_msghdr(msg_sys, msg, flags, &iov);
26174257c8caSJens Axboe if (err < 0)
26184257c8caSJens Axboe return err;
26194257c8caSJens Axboe
26204257c8caSJens Axboe err = ____sys_sendmsg(sock, msg_sys, flags, used_address,
26214257c8caSJens Axboe allowed_msghdr_flags);
26224257c8caSJens Axboe kfree(iov);
2623a74e9106SEric Dumazet return err;
2624228e548eSAnton Blanchard }
2625228e548eSAnton Blanchard
2626228e548eSAnton Blanchard /*
2627228e548eSAnton Blanchard * BSD sendmsg interface
2628228e548eSAnton Blanchard */
__sys_sendmsg_sock(struct socket * sock,struct msghdr * msg,unsigned int flags)2629228e548eSAnton Blanchard long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg,
263003b1230cSJens Axboe unsigned int flags)
26310fa03c62SJens Axboe {
26320fa03c62SJens Axboe return ____sys_sendmsg(sock, msg, flags, NULL, 0);
263303b1230cSJens Axboe }
26340fa03c62SJens Axboe
__sys_sendmsg(int fd,struct user_msghdr __user * msg,unsigned int flags,bool forbid_cmsg_compat)2635228e548eSAnton Blanchard long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
2636e1834a32SDominik Brodowski bool forbid_cmsg_compat)
2637e1834a32SDominik Brodowski {
2638228e548eSAnton Blanchard struct msghdr msg_sys;
2639228e548eSAnton Blanchard struct socket *sock;
26401be374a0SAndy Lutomirski
2641228e548eSAnton Blanchard if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
2642e1834a32SDominik Brodowski return -EINVAL;
2643e1834a32SDominik Brodowski
2644e1834a32SDominik Brodowski CLASS(fd, f)(fd);
264553c0a58bSAl Viro
2646228e548eSAnton Blanchard if (fd_empty(f))
264753c0a58bSAl Viro return -EBADF;
264853c0a58bSAl Viro sock = sock_from_file(fd_file(f));
264953c0a58bSAl Viro if (unlikely(!sock))
265053c0a58bSAl Viro return -ENOTSOCK;
265153c0a58bSAl Viro
2652228e548eSAnton Blanchard return ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0);
265353c0a58bSAl Viro }
26541da177e4SLinus Torvalds
SYSCALL_DEFINE3(sendmsg,int,fd,struct user_msghdr __user *,msg,unsigned int,flags)26551da177e4SLinus Torvalds SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
2656666547ffSAl Viro {
2657a7526eb5SAndy Lutomirski return __sys_sendmsg(fd, msg, flags, true);
2658e1834a32SDominik Brodowski }
2659a7526eb5SAndy Lutomirski
2660a7526eb5SAndy Lutomirski /*
2661228e548eSAnton Blanchard * Linux sendmmsg interface
2662228e548eSAnton Blanchard */
2663228e548eSAnton Blanchard
__sys_sendmmsg(int fd,struct mmsghdr __user * mmsg,unsigned int vlen,unsigned int flags,bool forbid_cmsg_compat)2664228e548eSAnton Blanchard int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2665228e548eSAnton Blanchard unsigned int flags, bool forbid_cmsg_compat)
2666e1834a32SDominik Brodowski {
2667228e548eSAnton Blanchard int err, datagrams;
266853c0a58bSAl Viro struct socket *sock;
2669228e548eSAnton Blanchard struct mmsghdr __user *entry;
2670228e548eSAnton Blanchard struct compat_mmsghdr __user *compat_entry;
2671228e548eSAnton Blanchard struct msghdr msg_sys;
2672228e548eSAnton Blanchard struct used_address used_address;
2673c71d8ebeSTetsuo Handa unsigned int oflags = flags;
2674f092276dSTom Herbert
2675228e548eSAnton Blanchard if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
2676e1834a32SDominik Brodowski return -EINVAL;
2677e1834a32SDominik Brodowski
2678e1834a32SDominik Brodowski if (vlen > UIO_MAXIOV)
267998382f41SAnton Blanchard vlen = UIO_MAXIOV;
268098382f41SAnton Blanchard
2681228e548eSAnton Blanchard datagrams = 0;
2682228e548eSAnton Blanchard
2683228e548eSAnton Blanchard CLASS(fd, f)(fd);
268453c0a58bSAl Viro
268553c0a58bSAl Viro if (fd_empty(f))
268653c0a58bSAl Viro return -EBADF;
268753c0a58bSAl Viro sock = sock_from_file(fd_file(f));
268853c0a58bSAl Viro if (unlikely(!sock))
268953c0a58bSAl Viro return -ENOTSOCK;
269053c0a58bSAl Viro
2691228e548eSAnton Blanchard used_address.name_len = UINT_MAX;
2692c71d8ebeSTetsuo Handa entry = mmsg;
2693228e548eSAnton Blanchard compat_entry = (struct compat_mmsghdr __user *)mmsg;
2694228e548eSAnton Blanchard err = 0;
2695728ffb86SAnton Blanchard flags |= MSG_BATCH;
2696f092276dSTom Herbert
2697228e548eSAnton Blanchard while (datagrams < vlen) {
2698228e548eSAnton Blanchard if (datagrams == vlen - 1)
2699f092276dSTom Herbert flags = oflags;
2700f092276dSTom Herbert
2701f092276dSTom Herbert if (MSG_CMSG_COMPAT & flags) {
2702228e548eSAnton Blanchard err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry,
2703666547ffSAl Viro &msg_sys, flags, &used_address, MSG_EOR);
270428a94d8fSTom Herbert if (err < 0)
2705228e548eSAnton Blanchard break;
2706228e548eSAnton Blanchard err = __put_user(err, &compat_entry->msg_len);
2707228e548eSAnton Blanchard ++compat_entry;
2708228e548eSAnton Blanchard } else {
2709228e548eSAnton Blanchard err = ___sys_sendmsg(sock,
2710a7526eb5SAndy Lutomirski (struct user_msghdr __user *)entry,
2711666547ffSAl Viro &msg_sys, flags, &used_address, MSG_EOR);
271228a94d8fSTom Herbert if (err < 0)
2713228e548eSAnton Blanchard break;
2714228e548eSAnton Blanchard err = put_user(err, &entry->msg_len);
2715228e548eSAnton Blanchard ++entry;
2716228e548eSAnton Blanchard }
2717228e548eSAnton Blanchard
2718228e548eSAnton Blanchard if (err)
2719228e548eSAnton Blanchard break;
2720228e548eSAnton Blanchard ++datagrams;
2721228e548eSAnton Blanchard if (msg_data_left(&msg_sys))
27223023898bSSoheil Hassas Yeganeh break;
27233023898bSSoheil Hassas Yeganeh cond_resched();
2724a78cb84cSEric Dumazet }
2725228e548eSAnton Blanchard
2726228e548eSAnton Blanchard /* We only return an error if no datagrams were able to be sent */
2727728ffb86SAnton Blanchard if (datagrams != 0)
2728728ffb86SAnton Blanchard return datagrams;
2729228e548eSAnton Blanchard
2730228e548eSAnton Blanchard return err;
2731228e548eSAnton Blanchard }
2732228e548eSAnton Blanchard
SYSCALL_DEFINE4(sendmmsg,int,fd,struct mmsghdr __user *,mmsg,unsigned int,vlen,unsigned int,flags)2733228e548eSAnton Blanchard SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
2734228e548eSAnton Blanchard unsigned int, vlen, unsigned int, flags)
2735228e548eSAnton Blanchard {
2736228e548eSAnton Blanchard return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
2737e1834a32SDominik Brodowski }
2738228e548eSAnton Blanchard
recvmsg_copy_msghdr(struct msghdr * msg,struct user_msghdr __user * umsg,unsigned flags,struct sockaddr __user ** uaddr,struct iovec ** iov)2739228e548eSAnton Blanchard static int recvmsg_copy_msghdr(struct msghdr *msg,
2740e54e09c0SJens Axboe struct user_msghdr __user *umsg, unsigned flags,
27414257c8caSJens Axboe struct sockaddr __user **uaddr,
27424257c8caSJens Axboe struct iovec **iov)
27434257c8caSJens Axboe {
27444257c8caSJens Axboe ssize_t err;
27454257c8caSJens Axboe
27464257c8caSJens Axboe if (MSG_CMSG_COMPAT & flags) {
27474257c8caSJens Axboe struct compat_msghdr __user *msg_compat;
27484257c8caSJens Axboe
27494257c8caSJens Axboe msg_compat = (struct compat_msghdr __user *) umsg;
27504257c8caSJens Axboe err = get_compat_msghdr(msg, msg_compat, uaddr, iov);
27514257c8caSJens Axboe } else {
27524257c8caSJens Axboe err = copy_msghdr_from_user(msg, umsg, uaddr, iov);
27534257c8caSJens Axboe }
27544257c8caSJens Axboe if (err < 0)
27554257c8caSJens Axboe return err;
27564257c8caSJens Axboe
27574257c8caSJens Axboe return 0;
27584257c8caSJens Axboe }
27594257c8caSJens Axboe
____sys_recvmsg(struct socket * sock,struct msghdr * msg_sys,struct user_msghdr __user * msg,struct sockaddr __user * uaddr,unsigned int flags,int nosec)27604257c8caSJens Axboe static int ____sys_recvmsg(struct socket *sock, struct msghdr *msg_sys,
27614257c8caSJens Axboe struct user_msghdr __user *msg,
27624257c8caSJens Axboe struct sockaddr __user *uaddr,
27634257c8caSJens Axboe unsigned int flags, int nosec)
27644257c8caSJens Axboe {
27651da177e4SLinus Torvalds struct compat_msghdr __user *msg_compat =
276689bddce5SStephen Hemminger (struct compat_msghdr __user *) msg;
276789bddce5SStephen Hemminger int __user *uaddr_len = COMPAT_NAMELEN(msg);
27684257c8caSJens Axboe struct sockaddr_storage addr;
27694257c8caSJens Axboe unsigned long cmsg_ptr;
27701da177e4SLinus Torvalds int len;
27712da62906SAl Viro ssize_t err;
277208adb7daSAl Viro
27731da177e4SLinus Torvalds msg_sys->msg_name = &addr;
277408adb7daSAl Viro cmsg_ptr = (unsigned long)msg_sys->msg_control;
2775a2e27255SArnaldo Carvalho de Melo msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
2776a2e27255SArnaldo Carvalho de Melo
27771da177e4SLinus Torvalds /* We assume all kernel code knows the size of sockaddr_storage */
2778f3d33426SHannes Frederic Sowa msg_sys->msg_namelen = 0;
2779f3d33426SHannes Frederic Sowa
2780f3d33426SHannes Frederic Sowa if (sock->file->f_flags & O_NONBLOCK)
27811da177e4SLinus Torvalds flags |= MSG_DONTWAIT;
27821da177e4SLinus Torvalds
27831af66221SEric Dumazet if (unlikely(nosec))
27841af66221SEric Dumazet err = sock_recvmsg_nosec(sock, msg_sys, flags);
27851af66221SEric Dumazet else
27861af66221SEric Dumazet err = sock_recvmsg(sock, msg_sys, flags);
27871af66221SEric Dumazet
27881af66221SEric Dumazet if (err < 0)
27891da177e4SLinus Torvalds goto out;
27904257c8caSJens Axboe len = err;
27911da177e4SLinus Torvalds
27921da177e4SLinus Torvalds if (uaddr != NULL) {
27931da177e4SLinus Torvalds err = move_addr_to_user(&addr,
279443db362dSMaciej Żenczykowski msg_sys->msg_namelen, uaddr,
2795a2e27255SArnaldo Carvalho de Melo uaddr_len);
279689bddce5SStephen Hemminger if (err < 0)
27971da177e4SLinus Torvalds goto out;
27984257c8caSJens Axboe }
27991da177e4SLinus Torvalds err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
2800a2e27255SArnaldo Carvalho de Melo COMPAT_FLAGS(msg));
280137f7f421SDavid S. Miller if (err)
28021da177e4SLinus Torvalds goto out;
28034257c8caSJens Axboe if (MSG_CMSG_COMPAT & flags)
28041da177e4SLinus Torvalds err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
2805a2e27255SArnaldo Carvalho de Melo &msg_compat->msg_controllen);
28061da177e4SLinus Torvalds else
28071da177e4SLinus Torvalds err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
2808a2e27255SArnaldo Carvalho de Melo &msg->msg_controllen);
28091da177e4SLinus Torvalds if (err)
28101da177e4SLinus Torvalds goto out;
28114257c8caSJens Axboe err = len;
28121da177e4SLinus Torvalds out:
28134257c8caSJens Axboe return err;
28144257c8caSJens Axboe }
28154257c8caSJens Axboe
___sys_recvmsg(struct socket * sock,struct user_msghdr __user * msg,struct msghdr * msg_sys,unsigned int flags,int nosec)28161da177e4SLinus Torvalds static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
28174257c8caSJens Axboe struct msghdr *msg_sys, unsigned int flags, int nosec)
28184257c8caSJens Axboe {
28194257c8caSJens Axboe struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
28204257c8caSJens Axboe /* user mode address pointers */
28214257c8caSJens Axboe struct sockaddr __user *uaddr;
28224257c8caSJens Axboe ssize_t err;
28234257c8caSJens Axboe
28244257c8caSJens Axboe err = recvmsg_copy_msghdr(msg_sys, msg, flags, &uaddr, &iov);
28254257c8caSJens Axboe if (err < 0)
28264257c8caSJens Axboe return err;
28274257c8caSJens Axboe
28284257c8caSJens Axboe err = ____sys_recvmsg(sock, msg_sys, msg, uaddr, flags, nosec);
28294257c8caSJens Axboe kfree(iov);
2830a74e9106SEric Dumazet return err;
2831a2e27255SArnaldo Carvalho de Melo }
2832a2e27255SArnaldo Carvalho de Melo
2833a2e27255SArnaldo Carvalho de Melo /*
2834a2e27255SArnaldo Carvalho de Melo * BSD recvmsg interface
2835a2e27255SArnaldo Carvalho de Melo */
2836a2e27255SArnaldo Carvalho de Melo
__sys_recvmsg_sock(struct socket * sock,struct msghdr * msg,struct user_msghdr __user * umsg,struct sockaddr __user * uaddr,unsigned int flags)2837a2e27255SArnaldo Carvalho de Melo long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
283803b1230cSJens Axboe struct user_msghdr __user *umsg,
283903b1230cSJens Axboe struct sockaddr __user *uaddr, unsigned int flags)
284003b1230cSJens Axboe {
2841aa1fa28fSJens Axboe return ____sys_recvmsg(sock, msg, umsg, uaddr, flags, 0);
284203b1230cSJens Axboe }
2843aa1fa28fSJens Axboe
__sys_recvmsg(int fd,struct user_msghdr __user * msg,unsigned int flags,bool forbid_cmsg_compat)2844aa1fa28fSJens Axboe long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
2845e1834a32SDominik Brodowski bool forbid_cmsg_compat)
2846e1834a32SDominik Brodowski {
2847a2e27255SArnaldo Carvalho de Melo struct msghdr msg_sys;
2848a2e27255SArnaldo Carvalho de Melo struct socket *sock;
28491be374a0SAndy Lutomirski
2850a2e27255SArnaldo Carvalho de Melo if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
2851e1834a32SDominik Brodowski return -EINVAL;
2852e1834a32SDominik Brodowski
2853e1834a32SDominik Brodowski CLASS(fd, f)(fd);
285453c0a58bSAl Viro
2855a2e27255SArnaldo Carvalho de Melo if (fd_empty(f))
285653c0a58bSAl Viro return -EBADF;
285753c0a58bSAl Viro sock = sock_from_file(fd_file(f));
285853c0a58bSAl Viro if (unlikely(!sock))
285953c0a58bSAl Viro return -ENOTSOCK;
286053c0a58bSAl Viro
2861a2e27255SArnaldo Carvalho de Melo return ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
286253c0a58bSAl Viro }
28631da177e4SLinus Torvalds
SYSCALL_DEFINE3(recvmsg,int,fd,struct user_msghdr __user *,msg,unsigned int,flags)28641da177e4SLinus Torvalds SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
2865666547ffSAl Viro unsigned int, flags)
2866a7526eb5SAndy Lutomirski {
2867a7526eb5SAndy Lutomirski return __sys_recvmsg(fd, msg, flags, true);
2868e1834a32SDominik Brodowski }
2869a7526eb5SAndy Lutomirski
2870a7526eb5SAndy Lutomirski /*
2871a2e27255SArnaldo Carvalho de Melo * Linux recvmmsg interface
2872a2e27255SArnaldo Carvalho de Melo */
2873a2e27255SArnaldo Carvalho de Melo
do_recvmmsg(int fd,struct mmsghdr __user * mmsg,unsigned int vlen,unsigned int flags,struct timespec64 * timeout)28741da177e4SLinus Torvalds static int do_recvmmsg(int fd, struct mmsghdr __user *mmsg,
2875e11d4284SArnd Bergmann unsigned int vlen, unsigned int flags,
2876e11d4284SArnd Bergmann struct timespec64 *timeout)
2877e11d4284SArnd Bergmann {
2878a2e27255SArnaldo Carvalho de Melo int err = 0, datagrams;
287953c0a58bSAl Viro struct socket *sock;
2880a2e27255SArnaldo Carvalho de Melo struct mmsghdr __user *entry;
2881a2e27255SArnaldo Carvalho de Melo struct compat_mmsghdr __user *compat_entry;
2882d7256d0eSJean-Mickael Guerin struct msghdr msg_sys;
2883a2e27255SArnaldo Carvalho de Melo struct timespec64 end_time;
2884766b9f92SDeepa Dinamani struct timespec64 timeout64;
2885766b9f92SDeepa Dinamani
2886a2e27255SArnaldo Carvalho de Melo if (timeout &&
2887a2e27255SArnaldo Carvalho de Melo poll_select_set_timeout(&end_time, timeout->tv_sec,
2888a2e27255SArnaldo Carvalho de Melo timeout->tv_nsec))
2889a2e27255SArnaldo Carvalho de Melo return -EINVAL;
2890a2e27255SArnaldo Carvalho de Melo
2891a2e27255SArnaldo Carvalho de Melo datagrams = 0;
2892a2e27255SArnaldo Carvalho de Melo
2893a2e27255SArnaldo Carvalho de Melo CLASS(fd, f)(fd);
289453c0a58bSAl Viro
289553c0a58bSAl Viro if (fd_empty(f))
289653c0a58bSAl Viro return -EBADF;
289753c0a58bSAl Viro sock = sock_from_file(fd_file(f));
289853c0a58bSAl Viro if (unlikely(!sock))
289953c0a58bSAl Viro return -ENOTSOCK;
290053c0a58bSAl Viro
2901a2e27255SArnaldo Carvalho de Melo if (likely(!(flags & MSG_ERRQUEUE))) {
29027797dc41SSoheil Hassas Yeganeh err = sock_error(sock->sk);
2903a2e27255SArnaldo Carvalho de Melo if (err)
290453c0a58bSAl Viro return err;
290553c0a58bSAl Viro }
29067797dc41SSoheil Hassas Yeganeh
2907a2e27255SArnaldo Carvalho de Melo entry = mmsg;
2908a2e27255SArnaldo Carvalho de Melo compat_entry = (struct compat_mmsghdr __user *)mmsg;
2909d7256d0eSJean-Mickael Guerin
2910a2e27255SArnaldo Carvalho de Melo while (datagrams < vlen) {
2911a2e27255SArnaldo Carvalho de Melo /*
2912a2e27255SArnaldo Carvalho de Melo * No need to ask LSM for more than the first datagram.
2913a2e27255SArnaldo Carvalho de Melo */
2914a2e27255SArnaldo Carvalho de Melo if (MSG_CMSG_COMPAT & flags) {
2915d7256d0eSJean-Mickael Guerin err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry,
2916666547ffSAl Viro &msg_sys, flags & ~MSG_WAITFORONE,
2917b9eb8b87SAnton Blanchard datagrams);
2918b9eb8b87SAnton Blanchard if (err < 0)
2919d7256d0eSJean-Mickael Guerin break;
2920d7256d0eSJean-Mickael Guerin err = __put_user(err, &compat_entry->msg_len);
2921d7256d0eSJean-Mickael Guerin ++compat_entry;
2922d7256d0eSJean-Mickael Guerin } else {
2923d7256d0eSJean-Mickael Guerin err = ___sys_recvmsg(sock,
2924a7526eb5SAndy Lutomirski (struct user_msghdr __user *)entry,
2925666547ffSAl Viro &msg_sys, flags & ~MSG_WAITFORONE,
2926b9eb8b87SAnton Blanchard datagrams);
2927b9eb8b87SAnton Blanchard if (err < 0)
2928a2e27255SArnaldo Carvalho de Melo break;
2929a2e27255SArnaldo Carvalho de Melo err = put_user(err, &entry->msg_len);
2930a2e27255SArnaldo Carvalho de Melo ++entry;
2931d7256d0eSJean-Mickael Guerin }
2932d7256d0eSJean-Mickael Guerin
2933d7256d0eSJean-Mickael Guerin if (err)
2934a2e27255SArnaldo Carvalho de Melo break;
2935a2e27255SArnaldo Carvalho de Melo ++datagrams;
2936a2e27255SArnaldo Carvalho de Melo
2937a2e27255SArnaldo Carvalho de Melo /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
293871c5c159SBrandon L Black if (flags & MSG_WAITFORONE)
293971c5c159SBrandon L Black flags |= MSG_DONTWAIT;
294071c5c159SBrandon L Black
294171c5c159SBrandon L Black if (timeout) {
2942a2e27255SArnaldo Carvalho de Melo ktime_get_ts64(&timeout64);
2943766b9f92SDeepa Dinamani *timeout = timespec64_sub(end_time, timeout64);
2944c2e6c856SArnd Bergmann if (timeout->tv_sec < 0) {
2945a2e27255SArnaldo Carvalho de Melo timeout->tv_sec = timeout->tv_nsec = 0;
2946a2e27255SArnaldo Carvalho de Melo break;
2947a2e27255SArnaldo Carvalho de Melo }
2948a2e27255SArnaldo Carvalho de Melo
2949a2e27255SArnaldo Carvalho de Melo /* Timeout, return less than vlen datagrams */
2950a2e27255SArnaldo Carvalho de Melo if (timeout->tv_nsec == 0 && timeout->tv_sec == 0)
2951a2e27255SArnaldo Carvalho de Melo break;
2952a2e27255SArnaldo Carvalho de Melo }
2953a2e27255SArnaldo Carvalho de Melo
2954a2e27255SArnaldo Carvalho de Melo /* Out of band data, return right away */
2955a2e27255SArnaldo Carvalho de Melo if (msg_sys.msg_flags & MSG_OOB)
2956a2e27255SArnaldo Carvalho de Melo break;
2957a2e27255SArnaldo Carvalho de Melo cond_resched();
2958a78cb84cSEric Dumazet }
2959a2e27255SArnaldo Carvalho de Melo
2960a2e27255SArnaldo Carvalho de Melo if (err == 0)
2961a2e27255SArnaldo Carvalho de Melo return datagrams;
296253c0a58bSAl Viro
2963a2e27255SArnaldo Carvalho de Melo if (datagrams == 0)
296453c0a58bSAl Viro return err;
296553c0a58bSAl Viro
296634b88a68SArnaldo Carvalho de Melo /*
2967a2e27255SArnaldo Carvalho de Melo * We may return less entries than requested (vlen) if the
2968a2e27255SArnaldo Carvalho de Melo * sock is non block and there aren't enough datagrams...
2969a2e27255SArnaldo Carvalho de Melo */
2970a2e27255SArnaldo Carvalho de Melo if (err != -EAGAIN) {
2971a2e27255SArnaldo Carvalho de Melo /*
2972a2e27255SArnaldo Carvalho de Melo * ... or if recvmsg returns an error after we
2973a2e27255SArnaldo Carvalho de Melo * received some datagrams, where we record the
2974a2e27255SArnaldo Carvalho de Melo * error to return on the next call or if the
2975a2e27255SArnaldo Carvalho de Melo * app asks about it using getsockopt(SO_ERROR).
2976a2e27255SArnaldo Carvalho de Melo */
2977a2e27255SArnaldo Carvalho de Melo WRITE_ONCE(sock->sk->sk_err, -err);
2978e05a5f51SEric Dumazet }
2979a2e27255SArnaldo Carvalho de Melo return datagrams;
2980a2e27255SArnaldo Carvalho de Melo }
2981a2e27255SArnaldo Carvalho de Melo
__sys_recvmmsg(int fd,struct mmsghdr __user * mmsg,unsigned int vlen,unsigned int flags,struct __kernel_timespec __user * timeout,struct old_timespec32 __user * timeout32)2982a2e27255SArnaldo Carvalho de Melo int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
2983e11d4284SArnd Bergmann unsigned int vlen, unsigned int flags,
29841255e269SDominik Brodowski struct __kernel_timespec __user *timeout,
2985e11d4284SArnd Bergmann struct old_timespec32 __user *timeout32)
2986e11d4284SArnd Bergmann {
2987a2e27255SArnaldo Carvalho de Melo int datagrams;
2988a2e27255SArnaldo Carvalho de Melo struct timespec64 timeout_sys;
2989c2e6c856SArnd Bergmann
2990a2e27255SArnaldo Carvalho de Melo if (timeout && get_timespec64(&timeout_sys, timeout))
2991e11d4284SArnd Bergmann return -EFAULT;
2992a2e27255SArnaldo Carvalho de Melo
2993a2e27255SArnaldo Carvalho de Melo if (timeout32 && get_old_timespec32(&timeout_sys, timeout32))
2994e11d4284SArnd Bergmann return -EFAULT;
2995e11d4284SArnd Bergmann
2996a2e27255SArnaldo Carvalho de Melo if (!timeout && !timeout32)
2997e11d4284SArnd Bergmann return do_recvmmsg(fd, mmsg, vlen, flags, NULL);
2998e11d4284SArnd Bergmann
2999e11d4284SArnd Bergmann datagrams = do_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys);
3000e11d4284SArnd Bergmann
3001e11d4284SArnd Bergmann if (datagrams <= 0)
3002e11d4284SArnd Bergmann return datagrams;
3003e11d4284SArnd Bergmann
3004e11d4284SArnd Bergmann if (timeout && put_timespec64(&timeout_sys, timeout))
3005e11d4284SArnd Bergmann datagrams = -EFAULT;
3006e11d4284SArnd Bergmann
3007e11d4284SArnd Bergmann if (timeout32 && put_old_timespec32(&timeout_sys, timeout32))
3008e11d4284SArnd Bergmann datagrams = -EFAULT;
3009a2e27255SArnaldo Carvalho de Melo
3010a2e27255SArnaldo Carvalho de Melo return datagrams;
3011a2e27255SArnaldo Carvalho de Melo }
3012a2e27255SArnaldo Carvalho de Melo
SYSCALL_DEFINE5(recvmmsg,int,fd,struct mmsghdr __user *,mmsg,unsigned int,vlen,unsigned int,flags,struct __kernel_timespec __user *,timeout)3013a2e27255SArnaldo Carvalho de Melo SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
30141255e269SDominik Brodowski unsigned int, vlen, unsigned int, flags,
30151255e269SDominik Brodowski struct __kernel_timespec __user *, timeout)
3016c2e6c856SArnd Bergmann {
30171255e269SDominik Brodowski if (flags & MSG_CMSG_COMPAT)
3018e11d4284SArnd Bergmann return -EINVAL;
3019e11d4284SArnd Bergmann
3020e11d4284SArnd Bergmann return __sys_recvmmsg(fd, mmsg, vlen, flags, timeout, NULL);
3021e11d4284SArnd Bergmann }
30221255e269SDominik Brodowski
30231255e269SDominik Brodowski #ifdef CONFIG_COMPAT_32BIT_TIME
SYSCALL_DEFINE5(recvmmsg_time32,int,fd,struct mmsghdr __user *,mmsg,unsigned int,vlen,unsigned int,flags,struct old_timespec32 __user *,timeout)3024e11d4284SArnd Bergmann SYSCALL_DEFINE5(recvmmsg_time32, int, fd, struct mmsghdr __user *, mmsg,
3025e11d4284SArnd Bergmann unsigned int, vlen, unsigned int, flags,
3026e11d4284SArnd Bergmann struct old_timespec32 __user *, timeout)
3027e11d4284SArnd Bergmann {
3028e11d4284SArnd Bergmann if (flags & MSG_CMSG_COMPAT)
3029e11d4284SArnd Bergmann return -EINVAL;
3030e11d4284SArnd Bergmann
3031e11d4284SArnd Bergmann return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL, timeout);
3032e11d4284SArnd Bergmann }
3033e11d4284SArnd Bergmann #endif
3034e11d4284SArnd Bergmann
3035e11d4284SArnd Bergmann #ifdef __ARCH_WANT_SYS_SOCKETCALL
3036a2e27255SArnaldo Carvalho de Melo /* Argument list sizes for sys_socketcall */
30371da177e4SLinus Torvalds #define AL(x) ((x) * sizeof(unsigned long))
30381da177e4SLinus Torvalds static const unsigned char nargs[21] = {
3039228e548eSAnton Blanchard AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
304089bddce5SStephen Hemminger AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
30411da177e4SLinus Torvalds AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
3042aaca0bdcSUlrich Drepper AL(4), AL(5), AL(4)
3043228e548eSAnton Blanchard };
304489bddce5SStephen Hemminger
304589bddce5SStephen Hemminger #undef AL
30461da177e4SLinus Torvalds
30471da177e4SLinus Torvalds /*
30481da177e4SLinus Torvalds * System call vectors.
30491da177e4SLinus Torvalds *
30501da177e4SLinus Torvalds * Argument checking cleaned up. Saved 20% in size.
30511da177e4SLinus Torvalds * This function doesn't need to set the kernel lock because
30521da177e4SLinus Torvalds * it is set by the callees.
30531da177e4SLinus Torvalds */
30541da177e4SLinus Torvalds
SYSCALL_DEFINE2(socketcall,int,call,unsigned long __user *,args)30551da177e4SLinus Torvalds SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
30563e0fa65fSHeiko Carstens {
30571da177e4SLinus Torvalds unsigned long a[AUDITSC_ARGS];
30582950fa9dSChen Gang unsigned long a0, a1;
30591da177e4SLinus Torvalds int err;
30601da177e4SLinus Torvalds unsigned int len;
306147379052SArjan van de Ven
30621da177e4SLinus Torvalds if (call < 1 || call > SYS_SENDMMSG)
3063228e548eSAnton Blanchard return -EINVAL;
30641da177e4SLinus Torvalds call = array_index_nospec(call, SYS_SENDMMSG + 1);
3065c8e8cd57SJeremy Cline
30661da177e4SLinus Torvalds len = nargs[call];
306747379052SArjan van de Ven if (len > sizeof(a))
306847379052SArjan van de Ven return -EINVAL;
306947379052SArjan van de Ven
307047379052SArjan van de Ven /* copy_from_user should be SMP safe. */
30711da177e4SLinus Torvalds if (copy_from_user(a, args, len))
307247379052SArjan van de Ven return -EFAULT;
30731da177e4SLinus Torvalds
30741da177e4SLinus Torvalds err = audit_socketcall(nargs[call] / sizeof(unsigned long), a);
30752950fa9dSChen Gang if (err)
30762950fa9dSChen Gang return err;
30772950fa9dSChen Gang
30783ec3b2fbSDavid Woodhouse a0 = a[0];
30791da177e4SLinus Torvalds a1 = a[1];
30801da177e4SLinus Torvalds
30811da177e4SLinus Torvalds switch (call) {
308289bddce5SStephen Hemminger case SYS_SOCKET:
30831da177e4SLinus Torvalds err = __sys_socket(a0, a1, a[2]);
30849d6a15c3SDominik Brodowski break;
30851da177e4SLinus Torvalds case SYS_BIND:
30861da177e4SLinus Torvalds err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
3087a87d35d8SDominik Brodowski break;
30881da177e4SLinus Torvalds case SYS_CONNECT:
30891da177e4SLinus Torvalds err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
30901387c2c2SDominik Brodowski break;
30911da177e4SLinus Torvalds case SYS_LISTEN:
30921da177e4SLinus Torvalds err = __sys_listen(a0, a1);
309325e290eeSDominik Brodowski break;
30941da177e4SLinus Torvalds case SYS_ACCEPT:
30951da177e4SLinus Torvalds err = __sys_accept4(a0, (struct sockaddr __user *)a1,
30964541e805SDominik Brodowski (int __user *)a[2], 0);
3097aaca0bdcSUlrich Drepper break;
30981da177e4SLinus Torvalds case SYS_GETSOCKNAME:
30991da177e4SLinus Torvalds err =
310089bddce5SStephen Hemminger __sys_getsockname(a0, (struct sockaddr __user *)a1,
31018882a107SDominik Brodowski (int __user *)a[2]);
310289bddce5SStephen Hemminger break;
31031da177e4SLinus Torvalds case SYS_GETPEERNAME:
31041da177e4SLinus Torvalds err =
310589bddce5SStephen Hemminger __sys_getpeername(a0, (struct sockaddr __user *)a1,
3106b21c8f83SDominik Brodowski (int __user *)a[2]);
310789bddce5SStephen Hemminger break;
31081da177e4SLinus Torvalds case SYS_SOCKETPAIR:
31091da177e4SLinus Torvalds err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
31106debc8d8SDominik Brodowski break;
31111da177e4SLinus Torvalds case SYS_SEND:
31121da177e4SLinus Torvalds err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
3113f3bf896bSDominik Brodowski NULL, 0);
3114f3bf896bSDominik Brodowski break;
31151da177e4SLinus Torvalds case SYS_SENDTO:
31161da177e4SLinus Torvalds err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
3117211b634bSDominik Brodowski (struct sockaddr __user *)a[4], a[5]);
31181da177e4SLinus Torvalds break;
31191da177e4SLinus Torvalds case SYS_RECV:
31201da177e4SLinus Torvalds err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
3121d27e9afcSDominik Brodowski NULL, NULL);
3122d27e9afcSDominik Brodowski break;
31231da177e4SLinus Torvalds case SYS_RECVFROM:
31241da177e4SLinus Torvalds err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
31257a09e1ebSDominik Brodowski (struct sockaddr __user *)a[4],
312689bddce5SStephen Hemminger (int __user *)a[5]);
312789bddce5SStephen Hemminger break;
31281da177e4SLinus Torvalds case SYS_SHUTDOWN:
31291da177e4SLinus Torvalds err = __sys_shutdown(a0, a1);
3130005a1aeaSDominik Brodowski break;
31311da177e4SLinus Torvalds case SYS_SETSOCKOPT:
31321da177e4SLinus Torvalds err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3],
3133cc36dca0SDominik Brodowski a[4]);
3134cc36dca0SDominik Brodowski break;
31351da177e4SLinus Torvalds case SYS_GETSOCKOPT:
31361da177e4SLinus Torvalds err =
313789bddce5SStephen Hemminger __sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
313813a2d70eSDominik Brodowski (int __user *)a[4]);
313989bddce5SStephen Hemminger break;
31401da177e4SLinus Torvalds case SYS_SENDMSG:
31411da177e4SLinus Torvalds err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1,
3142e1834a32SDominik Brodowski a[2], true);
3143e1834a32SDominik Brodowski break;
31441da177e4SLinus Torvalds case SYS_SENDMMSG:
3145228e548eSAnton Blanchard err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2],
3146e1834a32SDominik Brodowski a[3], true);
3147e1834a32SDominik Brodowski break;
3148228e548eSAnton Blanchard case SYS_RECVMSG:
31491da177e4SLinus Torvalds err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1,
3150e1834a32SDominik Brodowski a[2], true);
3151e1834a32SDominik Brodowski break;
31521da177e4SLinus Torvalds case SYS_RECVMMSG:
3153a2e27255SArnaldo Carvalho de Melo if (IS_ENABLED(CONFIG_64BIT))
31543ca47e95SArnd Bergmann err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1,
3155e11d4284SArnd Bergmann a[2], a[3],
3156e11d4284SArnd Bergmann (struct __kernel_timespec __user *)a[4],
3157e11d4284SArnd Bergmann NULL);
3158e11d4284SArnd Bergmann else
3159e11d4284SArnd Bergmann err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1,
3160e11d4284SArnd Bergmann a[2], a[3], NULL,
3161e11d4284SArnd Bergmann (struct old_timespec32 __user *)a[4]);
3162e11d4284SArnd Bergmann break;
3163a2e27255SArnaldo Carvalho de Melo case SYS_ACCEPT4:
3164de11defeSUlrich Drepper err = __sys_accept4(a0, (struct sockaddr __user *)a1,
31654541e805SDominik Brodowski (int __user *)a[2], a[3]);
3166de11defeSUlrich Drepper break;
3167aaca0bdcSUlrich Drepper default:
31681da177e4SLinus Torvalds err = -EINVAL;
31691da177e4SLinus Torvalds break;
31701da177e4SLinus Torvalds }
31711da177e4SLinus Torvalds return err;
31721da177e4SLinus Torvalds }
31731da177e4SLinus Torvalds
31741da177e4SLinus Torvalds #endif /* __ARCH_WANT_SYS_SOCKETCALL */
31751da177e4SLinus Torvalds
31761da177e4SLinus Torvalds /**
317755737fdaSStephen Hemminger * sock_register - add a socket protocol handler
317855737fdaSStephen Hemminger * @ops: description of protocol
317955737fdaSStephen Hemminger *
318055737fdaSStephen Hemminger * This function is called by a protocol handler that wants to
31811da177e4SLinus Torvalds * advertise its address family, and have it linked into the
31821da177e4SLinus Torvalds * socket interface. The value ops->family corresponds to the
3183e793c0f7SMasanari Iida * socket system call protocol family.
318455737fdaSStephen Hemminger */
sock_register(const struct net_proto_family * ops)31851da177e4SLinus Torvalds int sock_register(const struct net_proto_family *ops)
3186f0fd27d4SStephen Hemminger {
31871da177e4SLinus Torvalds int err;
31881da177e4SLinus Torvalds
31891da177e4SLinus Torvalds if (ops->family >= NPROTO) {
31901da177e4SLinus Torvalds pr_crit("protocol %d >= NPROTO(%d)\n", ops->family, NPROTO);
31913410f22eSYang Yingliang return -ENOBUFS;
31921da177e4SLinus Torvalds }
31931da177e4SLinus Torvalds
319455737fdaSStephen Hemminger spin_lock(&net_family_lock);
319555737fdaSStephen Hemminger if (rcu_dereference_protected(net_families[ops->family],
3196190683a9SEric Dumazet lockdep_is_held(&net_family_lock)))
3197190683a9SEric Dumazet err = -EEXIST;
31981da177e4SLinus Torvalds else {
319955737fdaSStephen Hemminger rcu_assign_pointer(net_families[ops->family], ops);
3200cf778b00SEric Dumazet err = 0;
32011da177e4SLinus Torvalds }
32021da177e4SLinus Torvalds spin_unlock(&net_family_lock);
320355737fdaSStephen Hemminger
320455737fdaSStephen Hemminger pr_info("NET: Registered %s protocol family\n", pf_family_names[ops->family]);
3205fe0bdbdeSYejune Deng return err;
32061da177e4SLinus Torvalds }
32071da177e4SLinus Torvalds EXPORT_SYMBOL(sock_register);
3208c6d409cfSEric Dumazet
32091da177e4SLinus Torvalds /**
321055737fdaSStephen Hemminger * sock_unregister - remove a protocol handler
321155737fdaSStephen Hemminger * @family: protocol family to remove
321255737fdaSStephen Hemminger *
321355737fdaSStephen Hemminger * This function is called by a protocol handler that wants to
32141da177e4SLinus Torvalds * remove its address family, and have it unlinked from the
32151da177e4SLinus Torvalds * new socket creation.
321655737fdaSStephen Hemminger *
321755737fdaSStephen Hemminger * If protocol handler is a module, then it can use module reference
321855737fdaSStephen Hemminger * counts to protect against new references. If protocol handler is not
321955737fdaSStephen Hemminger * a module then it needs to provide its own protection in
322055737fdaSStephen Hemminger * the ops->create routine.
322155737fdaSStephen Hemminger */
sock_unregister(int family)32221da177e4SLinus Torvalds void sock_unregister(int family)
3223f0fd27d4SStephen Hemminger {
32241da177e4SLinus Torvalds BUG_ON(family < 0 || family >= NPROTO);
3225f0fd27d4SStephen Hemminger
32261da177e4SLinus Torvalds spin_lock(&net_family_lock);
322755737fdaSStephen Hemminger RCU_INIT_POINTER(net_families[family], NULL);
3228a9b3cd7fSStephen Hemminger spin_unlock(&net_family_lock);
322955737fdaSStephen Hemminger
323055737fdaSStephen Hemminger synchronize_rcu();
323155737fdaSStephen Hemminger
323255737fdaSStephen Hemminger pr_info("NET: Unregistered %s protocol family\n", pf_family_names[family]);
3233fe0bdbdeSYejune Deng }
32341da177e4SLinus Torvalds EXPORT_SYMBOL(sock_unregister);
3235c6d409cfSEric Dumazet
sock_is_registered(int family)32361da177e4SLinus Torvalds bool sock_is_registered(int family)
3237bf2ae2e4SXin Long {
3238bf2ae2e4SXin Long return family < NPROTO && rcu_access_pointer(net_families[family]);
323966b51b0aSJeremy Cline }
3240bf2ae2e4SXin Long
sock_init(void)3241bf2ae2e4SXin Long static int __init sock_init(void)
324277d76ea3SAndi Kleen {
32431da177e4SLinus Torvalds int err;
3244b3e19d92SNick Piggin /*
32452ca794e5SEric W. Biederman * Initialize the network sysctl infrastructure.
32462ca794e5SEric W. Biederman */
32472ca794e5SEric W. Biederman err = net_sysctl_init();
32482ca794e5SEric W. Biederman if (err)
32492ca794e5SEric W. Biederman goto out;
32502ca794e5SEric W. Biederman
3251b3e19d92SNick Piggin /*
32521da177e4SLinus Torvalds * Initialize skbuff SLAB cache
32531da177e4SLinus Torvalds */
32541da177e4SLinus Torvalds skb_init();
32551da177e4SLinus Torvalds
32561da177e4SLinus Torvalds /*
32571da177e4SLinus Torvalds * Initialize the protocols module.
32581da177e4SLinus Torvalds */
32591da177e4SLinus Torvalds
32601da177e4SLinus Torvalds init_inodecache();
32611da177e4SLinus Torvalds
3262b3e19d92SNick Piggin err = register_filesystem(&sock_fs_type);
3263b3e19d92SNick Piggin if (err)
3264b3e19d92SNick Piggin goto out;
326547260ba9SMiaohe Lin sock_mnt = kern_mount(&sock_fs_type);
32661da177e4SLinus Torvalds if (IS_ERR(sock_mnt)) {
3267b3e19d92SNick Piggin err = PTR_ERR(sock_mnt);
3268b3e19d92SNick Piggin goto out_mount;
3269b3e19d92SNick Piggin }
3270b3e19d92SNick Piggin
327177d76ea3SAndi Kleen /* The real protocol initialization is performed in later initcalls.
327277d76ea3SAndi Kleen */
32731da177e4SLinus Torvalds
32741da177e4SLinus Torvalds #ifdef CONFIG_NETFILTER
32751da177e4SLinus Torvalds err = netfilter_init();
32766d11cfdbSPablo Neira Ayuso if (err)
32776d11cfdbSPablo Neira Ayuso goto out;
32786d11cfdbSPablo Neira Ayuso #endif
32791da177e4SLinus Torvalds
3280cbeb321aSDavid S. Miller ptp_classifier_init();
3281408eccceSDaniel Borkmann
3282c1f19b51SRichard Cochran out:
3283b3e19d92SNick Piggin return err;
3284b3e19d92SNick Piggin
3285b3e19d92SNick Piggin out_mount:
3286b3e19d92SNick Piggin unregister_filesystem(&sock_fs_type);
3287b3e19d92SNick Piggin goto out;
3288b3e19d92SNick Piggin }
32891da177e4SLinus Torvalds
32901da177e4SLinus Torvalds core_initcall(sock_init); /* early initcall */
329177d76ea3SAndi Kleen
329277d76ea3SAndi Kleen #ifdef CONFIG_PROC_FS
socket_seq_show(struct seq_file * seq)32931da177e4SLinus Torvalds void socket_seq_show(struct seq_file *seq)
32941da177e4SLinus Torvalds {
32951da177e4SLinus Torvalds seq_printf(seq, "sockets: used %d\n",
3296648845abSTonghao Zhang sock_inuse_get(seq->private));
3297648845abSTonghao Zhang }
32981da177e4SLinus Torvalds #endif /* CONFIG_PROC_FS */
32991da177e4SLinus Torvalds
33001da177e4SLinus Torvalds /* Handle the fact that while struct ifreq has the same *layout* on
330129c49648SArnd Bergmann * 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data,
330229c49648SArnd Bergmann * which are handled elsewhere, it still has different *size* due to
330329c49648SArnd Bergmann * ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit,
330429c49648SArnd Bergmann * resulting in struct ifreq being 32 and 40 bytes respectively).
330529c49648SArnd Bergmann * As a result, if the struct happens to be at the end of a page and
330629c49648SArnd Bergmann * the next page isn't readable/writable, we get a fault. To prevent
330729c49648SArnd Bergmann * that, copy back and forth to the full size.
330829c49648SArnd Bergmann */
get_user_ifreq(struct ifreq * ifr,void __user ** ifrdata,void __user * arg)330929c49648SArnd Bergmann int get_user_ifreq(struct ifreq *ifr, void __user **ifrdata, void __user *arg)
331029c49648SArnd Bergmann {
331129c49648SArnd Bergmann if (in_compat_syscall()) {
331229c49648SArnd Bergmann struct compat_ifreq *ifr32 = (struct compat_ifreq *)ifr;
331329c49648SArnd Bergmann
331429c49648SArnd Bergmann memset(ifr, 0, sizeof(*ifr));
331529c49648SArnd Bergmann if (copy_from_user(ifr32, arg, sizeof(*ifr32)))
331629c49648SArnd Bergmann return -EFAULT;
331729c49648SArnd Bergmann
331829c49648SArnd Bergmann if (ifrdata)
331929c49648SArnd Bergmann *ifrdata = compat_ptr(ifr32->ifr_data);
332029c49648SArnd Bergmann
332129c49648SArnd Bergmann return 0;
332229c49648SArnd Bergmann }
332329c49648SArnd Bergmann
332429c49648SArnd Bergmann if (copy_from_user(ifr, arg, sizeof(*ifr)))
332529c49648SArnd Bergmann return -EFAULT;
332629c49648SArnd Bergmann
332729c49648SArnd Bergmann if (ifrdata)
332829c49648SArnd Bergmann *ifrdata = ifr->ifr_data;
332929c49648SArnd Bergmann
333029c49648SArnd Bergmann return 0;
333129c49648SArnd Bergmann }
333229c49648SArnd Bergmann EXPORT_SYMBOL(get_user_ifreq);
333329c49648SArnd Bergmann
put_user_ifreq(struct ifreq * ifr,void __user * arg)333429c49648SArnd Bergmann int put_user_ifreq(struct ifreq *ifr, void __user *arg)
333529c49648SArnd Bergmann {
333629c49648SArnd Bergmann size_t size = sizeof(*ifr);
333729c49648SArnd Bergmann
333829c49648SArnd Bergmann if (in_compat_syscall())
333929c49648SArnd Bergmann size = sizeof(struct compat_ifreq);
334029c49648SArnd Bergmann
334129c49648SArnd Bergmann if (copy_to_user(arg, ifr, size))
334229c49648SArnd Bergmann return -EFAULT;
334329c49648SArnd Bergmann
334429c49648SArnd Bergmann return 0;
334529c49648SArnd Bergmann }
334629c49648SArnd Bergmann EXPORT_SYMBOL(put_user_ifreq);
334729c49648SArnd Bergmann
334829c49648SArnd Bergmann #ifdef CONFIG_COMPAT
compat_siocwandev(struct net * net,struct compat_ifreq __user * uifr32)334989bbfc95SShaun Pereira static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
33507a50a240SArnd Bergmann {
33517a50a240SArnd Bergmann compat_uptr_t uptr32;
33527a50a240SArnd Bergmann struct ifreq ifr;
335344c02a2cSAl Viro void __user *saved;
335444c02a2cSAl Viro int err;
335544c02a2cSAl Viro
33567a50a240SArnd Bergmann if (get_user_ifreq(&ifr, NULL, uifr32))
335729c49648SArnd Bergmann return -EFAULT;
33587a50a240SArnd Bergmann
33597a50a240SArnd Bergmann if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
33607a50a240SArnd Bergmann return -EFAULT;
33617a50a240SArnd Bergmann
33627a50a240SArnd Bergmann saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
336344c02a2cSAl Viro ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
336444c02a2cSAl Viro
33657a50a240SArnd Bergmann err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL, NULL);
3366a554bf96SArnd Bergmann if (!err) {
336744c02a2cSAl Viro ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved;
336844c02a2cSAl Viro if (put_user_ifreq(&ifr, uifr32))
336929c49648SArnd Bergmann err = -EFAULT;
337044c02a2cSAl Viro }
33717a50a240SArnd Bergmann return err;
33727a229387SArnd Bergmann }
33737a229387SArnd Bergmann
33747a229387SArnd Bergmann /* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
compat_ifr_data_ioctl(struct net * net,unsigned int cmd,struct compat_ifreq __user * u_ifreq32)3375590d4693SBen Hutchings static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
3376590d4693SBen Hutchings struct compat_ifreq __user *u_ifreq32)
33776b96018bSArnd Bergmann {
33787a229387SArnd Bergmann struct ifreq ifreq;
337944c02a2cSAl Viro void __user *data;
3380a554bf96SArnd Bergmann
33817a229387SArnd Bergmann if (!is_socket_ioctl_cmd(cmd))
3382d0efb162SPeter Collingbourne return -ENOTTY;
3383d0efb162SPeter Collingbourne if (get_user_ifreq(&ifreq, &data, u_ifreq32))
3384a554bf96SArnd Bergmann return -EFAULT;
33857a229387SArnd Bergmann ifreq.ifr_data = data;
3386a554bf96SArnd Bergmann
33877a229387SArnd Bergmann return dev_ioctl(net, cmd, &ifreq, data, NULL);
3388a554bf96SArnd Bergmann }
33897a229387SArnd Bergmann
compat_sock_ioctl_trans(struct file * file,struct socket * sock,unsigned int cmd,unsigned long arg)33907a229387SArnd Bergmann static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
33916b96018bSArnd Bergmann unsigned int cmd, unsigned long arg)
33926b96018bSArnd Bergmann {
33936b96018bSArnd Bergmann void __user *argp = compat_ptr(arg);
33946b96018bSArnd Bergmann struct sock *sk = sock->sk;
33956b96018bSArnd Bergmann struct net *net = sock_net(sk);
33966b96018bSArnd Bergmann const struct proto_ops *ops;
33971ded5e5aSEric Dumazet
33987a229387SArnd Bergmann if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
33996b96018bSArnd Bergmann return sock_ioctl(file, cmd, (unsigned long)argp);
340088fc023fSArnd Bergmann
34017a229387SArnd Bergmann switch (cmd) {
34026b96018bSArnd Bergmann case SIOCWANDEV:
34037a50a240SArnd Bergmann return compat_siocwandev(net, argp);
34047a50a240SArnd Bergmann case SIOCGSTAMP_OLD:
34050768e170SArnd Bergmann case SIOCGSTAMPNS_OLD:
34060768e170SArnd Bergmann ops = READ_ONCE(sock->ops);
34071ded5e5aSEric Dumazet if (!ops->gettstamp)
34081ded5e5aSEric Dumazet return -ENOIOCTLCMD;
3409c7cbdbf2SArnd Bergmann return ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD,
34101ded5e5aSEric Dumazet !COMPAT_USE_64BIT_TIME);
3411c7cbdbf2SArnd Bergmann
3412c7cbdbf2SArnd Bergmann case SIOCETHTOOL:
3413dd98d289SArnd Bergmann case SIOCBONDSLAVEINFOQUERY:
3414590d4693SBen Hutchings case SIOCBONDINFOQUERY:
3415590d4693SBen Hutchings case SIOCSHWTSTAMP:
3416a2116ed2SArnd Bergmann case SIOCGHWTSTAMP:
3417fd468c74SBen Hutchings return compat_ifr_data_ioctl(net, cmd, argp);
3418590d4693SBen Hutchings
34197a229387SArnd Bergmann case FIOSETOWN:
34206b96018bSArnd Bergmann case SIOCSPGRP:
34216b96018bSArnd Bergmann case FIOGETOWN:
34226b96018bSArnd Bergmann case SIOCGPGRP:
34236b96018bSArnd Bergmann case SIOCBRADDBR:
34246b96018bSArnd Bergmann case SIOCBRDELBR:
34256b96018bSArnd Bergmann case SIOCBRADDIF:
34266b96018bSArnd Bergmann case SIOCBRDELIF:
34276b96018bSArnd Bergmann case SIOCGIFVLAN:
3428c62cce2cSAndrey Vagin case SIOCSIFVLAN:
34290768e170SArnd Bergmann case SIOCGSKNS:
34300768e170SArnd Bergmann case SIOCGSTAMP_NEW:
3431876f0bf9SArnd Bergmann case SIOCGSTAMPNS_NEW:
3432fd3a4590SRemi Pommarel case SIOCGIFCONF:
3433fd3a4590SRemi Pommarel case SIOCSIFBR:
34346b96018bSArnd Bergmann case SIOCGIFBR:
34356b96018bSArnd Bergmann return sock_ioctl(file, cmd, arg);
34366b96018bSArnd Bergmann
34376b96018bSArnd Bergmann case SIOCGIFFLAGS:
3438709566d7SArnd Bergmann case SIOCSIFFLAGS:
3439709566d7SArnd Bergmann case SIOCGIFMAP:
34406b96018bSArnd Bergmann case SIOCSIFMAP:
34416b96018bSArnd Bergmann case SIOCGIFMETRIC:
34426b96018bSArnd Bergmann case SIOCSIFMETRIC:
34436b96018bSArnd Bergmann case SIOCGIFMTU:
34446b96018bSArnd Bergmann case SIOCSIFMTU:
34456b96018bSArnd Bergmann case SIOCGIFMEM:
34466b96018bSArnd Bergmann case SIOCSIFMEM:
34476b96018bSArnd Bergmann case SIOCGIFHWADDR:
34486b96018bSArnd Bergmann case SIOCSIFHWADDR:
34496b96018bSArnd Bergmann case SIOCADDMULTI:
34506b96018bSArnd Bergmann case SIOCDELMULTI:
34516b96018bSArnd Bergmann case SIOCGIFINDEX:
34526b96018bSArnd Bergmann case SIOCGIFADDR:
34536b96018bSArnd Bergmann case SIOCSIFADDR:
34546b96018bSArnd Bergmann case SIOCSIFHWBROADCAST:
34556b96018bSArnd Bergmann case SIOCDIFADDR:
34566b96018bSArnd Bergmann case SIOCGIFBRDADDR:
34576b96018bSArnd Bergmann case SIOCSIFBRDADDR:
34586b96018bSArnd Bergmann case SIOCGIFDSTADDR:
34596b96018bSArnd Bergmann case SIOCSIFDSTADDR:
34606b96018bSArnd Bergmann case SIOCGIFNETMASK:
34616b96018bSArnd Bergmann case SIOCSIFNETMASK:
34626b96018bSArnd Bergmann case SIOCSIFPFLAGS:
34636b96018bSArnd Bergmann case SIOCGIFPFLAGS:
34646b96018bSArnd Bergmann case SIOCGIFTXQLEN:
34656b96018bSArnd Bergmann case SIOCSIFTXQLEN:
34666b96018bSArnd Bergmann case SIOCGIFNAME:
3467c6c9fee3SJohannes Berg case SIOCSIFNAME:
34689177efd3SArnd Bergmann case SIOCGMIIPHY:
34699177efd3SArnd Bergmann case SIOCGMIIREG:
34709177efd3SArnd Bergmann case SIOCSMIIREG:
34719177efd3SArnd Bergmann case SIOCBONDENSLAVE:
3472f92d4fc9SAl Viro case SIOCBONDRELEASE:
3473f92d4fc9SAl Viro case SIOCBONDSETHWADDR:
3474f92d4fc9SAl Viro case SIOCBONDCHANGEACTIVE:
3475f92d4fc9SAl Viro case SIOCSARP:
34766b96018bSArnd Bergmann case SIOCGARP:
34776b96018bSArnd Bergmann case SIOCDARP:
34786b96018bSArnd Bergmann case SIOCOUTQ:
3479c7dc504eSArnd Bergmann case SIOCOUTQNSD:
34809d7bf41fSArnd Bergmann case SIOCATMARK:
34816b96018bSArnd Bergmann return sock_do_ioctl(net, sock, cmd, arg);
348263ff03abSJohannes Berg }
34839177efd3SArnd Bergmann
34849177efd3SArnd Bergmann return -ENOIOCTLCMD;
34856b96018bSArnd Bergmann }
34866b96018bSArnd Bergmann
compat_sock_ioctl(struct file * file,unsigned int cmd,unsigned long arg)34877a229387SArnd Bergmann static long compat_sock_ioctl(struct file *file, unsigned int cmd,
348895c96174SEric Dumazet unsigned long arg)
348989bbfc95SShaun Pereira {
349089bbfc95SShaun Pereira struct socket *sock = file->private_data;
349189bbfc95SShaun Pereira const struct proto_ops *ops = READ_ONCE(sock->ops);
34921ded5e5aSEric Dumazet int ret = -ENOIOCTLCMD;
349389bbfc95SShaun Pereira struct sock *sk;
349487de87d5SDavid S. Miller struct net *net;
349587de87d5SDavid S. Miller
349687de87d5SDavid S. Miller sk = sock->sk;
349787de87d5SDavid S. Miller net = sock_net(sk);
349887de87d5SDavid S. Miller
349989bbfc95SShaun Pereira if (ops->compat_ioctl)
35001ded5e5aSEric Dumazet ret = ops->compat_ioctl(sock, cmd, arg);
35011ded5e5aSEric Dumazet
350289bbfc95SShaun Pereira if (ret == -ENOIOCTLCMD &&
350387de87d5SDavid S. Miller (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
350487de87d5SDavid S. Miller ret = compat_wext_handle_ioctl(net, cmd, arg);
350587de87d5SDavid S. Miller
350687de87d5SDavid S. Miller if (ret == -ENOIOCTLCMD)
35076b96018bSArnd Bergmann ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
35086b96018bSArnd Bergmann
35096b96018bSArnd Bergmann return ret;
351089bbfc95SShaun Pereira }
351189bbfc95SShaun Pereira #endif
351289bbfc95SShaun Pereira
351389bbfc95SShaun Pereira /**
35148a3c245cSPedro Tammela * kernel_bind - bind an address to a socket (kernel space)
35158a3c245cSPedro Tammela * @sock: socket
35168a3c245cSPedro Tammela * @addr: address
35178a3c245cSPedro Tammela * @addrlen: length of address
35188a3c245cSPedro Tammela *
35198a3c245cSPedro Tammela * Returns 0 or an error.
35208a3c245cSPedro Tammela */
35218a3c245cSPedro Tammela
kernel_bind(struct socket * sock,struct sockaddr * addr,int addrlen)35228a3c245cSPedro Tammela int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
3523ac5a488eSSridhar Samudrala {
3524ac5a488eSSridhar Samudrala struct sockaddr_storage address;
3525c889a99aSJordan Rife
3526c889a99aSJordan Rife memcpy(&address, addr, addrlen);
3527c889a99aSJordan Rife
3528c889a99aSJordan Rife return READ_ONCE(sock->ops)->bind(sock, (struct sockaddr *)&address,
3529c889a99aSJordan Rife addrlen);
3530c889a99aSJordan Rife }
3531ac5a488eSSridhar Samudrala EXPORT_SYMBOL(kernel_bind);
3532c6d409cfSEric Dumazet
3533ac5a488eSSridhar Samudrala /**
35348a3c245cSPedro Tammela * kernel_listen - move socket to listening state (kernel space)
35358a3c245cSPedro Tammela * @sock: socket
35368a3c245cSPedro Tammela * @backlog: pending connections queue size
35378a3c245cSPedro Tammela *
35388a3c245cSPedro Tammela * Returns 0 or an error.
35398a3c245cSPedro Tammela */
35408a3c245cSPedro Tammela
kernel_listen(struct socket * sock,int backlog)35418a3c245cSPedro Tammela int kernel_listen(struct socket *sock, int backlog)
3542ac5a488eSSridhar Samudrala {
3543ac5a488eSSridhar Samudrala return READ_ONCE(sock->ops)->listen(sock, backlog);
35441ded5e5aSEric Dumazet }
3545ac5a488eSSridhar Samudrala EXPORT_SYMBOL(kernel_listen);
3546c6d409cfSEric Dumazet
3547ac5a488eSSridhar Samudrala /**
35488a3c245cSPedro Tammela * kernel_accept - accept a connection (kernel space)
35498a3c245cSPedro Tammela * @sock: listening socket
35508a3c245cSPedro Tammela * @newsock: new connected socket
35518a3c245cSPedro Tammela * @flags: flags
35528a3c245cSPedro Tammela *
35538a3c245cSPedro Tammela * @flags must be SOCK_CLOEXEC, SOCK_NONBLOCK or 0.
35548a3c245cSPedro Tammela * If it fails, @newsock is guaranteed to be %NULL.
35558a3c245cSPedro Tammela * Returns 0 or an error.
35568a3c245cSPedro Tammela */
35578a3c245cSPedro Tammela
kernel_accept(struct socket * sock,struct socket ** newsock,int flags)35588a3c245cSPedro Tammela int kernel_accept(struct socket *sock, struct socket **newsock, int flags)
3559ac5a488eSSridhar Samudrala {
3560ac5a488eSSridhar Samudrala struct sock *sk = sock->sk;
3561ac5a488eSSridhar Samudrala const struct proto_ops *ops = READ_ONCE(sock->ops);
35621ded5e5aSEric Dumazet struct proto_accept_arg arg = {
356392ef0fd5SJens Axboe .flags = flags,
356492ef0fd5SJens Axboe .kern = true,
356592ef0fd5SJens Axboe };
356692ef0fd5SJens Axboe int err;
3567ac5a488eSSridhar Samudrala
3568ac5a488eSSridhar Samudrala err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol,
3569ac5a488eSSridhar Samudrala newsock);
3570ac5a488eSSridhar Samudrala if (err < 0)
3571ac5a488eSSridhar Samudrala goto done;
3572ac5a488eSSridhar Samudrala
3573ac5a488eSSridhar Samudrala err = ops->accept(sock, *newsock, &arg);
357492ef0fd5SJens Axboe if (err < 0) {
3575ac5a488eSSridhar Samudrala sock_release(*newsock);
3576ac5a488eSSridhar Samudrala *newsock = NULL;
3577fa8705b0STony Battersby goto done;
3578ac5a488eSSridhar Samudrala }
3579ac5a488eSSridhar Samudrala
3580ac5a488eSSridhar Samudrala (*newsock)->ops = ops;
35811ded5e5aSEric Dumazet __module_get(ops->owner);
35821ded5e5aSEric Dumazet
3583ac5a488eSSridhar Samudrala done:
3584ac5a488eSSridhar Samudrala return err;
3585ac5a488eSSridhar Samudrala }
3586ac5a488eSSridhar Samudrala EXPORT_SYMBOL(kernel_accept);
3587c6d409cfSEric Dumazet
3588ac5a488eSSridhar Samudrala /**
35898a3c245cSPedro Tammela * kernel_connect - connect a socket (kernel space)
35908a3c245cSPedro Tammela * @sock: socket
35918a3c245cSPedro Tammela * @addr: address
35928a3c245cSPedro Tammela * @addrlen: address length
35938a3c245cSPedro Tammela * @flags: flags (O_NONBLOCK, ...)
35948a3c245cSPedro Tammela *
35958a3c245cSPedro Tammela * For datagram sockets, @addr is the address to which datagrams are sent
3596f1dcffccSLu Wei * by default, and the only address from which datagrams are received.
35978a3c245cSPedro Tammela * For stream sockets, attempts to connect to @addr.
35988a3c245cSPedro Tammela * Returns 0 or an error code.
35998a3c245cSPedro Tammela */
36008a3c245cSPedro Tammela
kernel_connect(struct socket * sock,struct sockaddr * addr,int addrlen,int flags)36018a3c245cSPedro Tammela int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
3602ac5a488eSSridhar Samudrala int flags)
3603ac5a488eSSridhar Samudrala {
3604ac5a488eSSridhar Samudrala struct sockaddr_storage address;
36050bdf3993SJordan Rife
36060bdf3993SJordan Rife memcpy(&address, addr, addrlen);
36070bdf3993SJordan Rife
36080bdf3993SJordan Rife return READ_ONCE(sock->ops)->connect(sock, (struct sockaddr *)&address,
36090bdf3993SJordan Rife addrlen, flags);
36100bdf3993SJordan Rife }
3611ac5a488eSSridhar Samudrala EXPORT_SYMBOL(kernel_connect);
3612c6d409cfSEric Dumazet
3613ac5a488eSSridhar Samudrala /**
36148a3c245cSPedro Tammela * kernel_getsockname - get the address which the socket is bound (kernel space)
36158a3c245cSPedro Tammela * @sock: socket
36168a3c245cSPedro Tammela * @addr: address holder
36178a3c245cSPedro Tammela *
36188a3c245cSPedro Tammela * Fills the @addr pointer with the address which the socket is bound.
36198a3c245cSPedro Tammela * Returns the length of the address in bytes or an error code.
36200fc95decSAlex Maydanik */
36218a3c245cSPedro Tammela
kernel_getsockname(struct socket * sock,struct sockaddr * addr)36228a3c245cSPedro Tammela int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
36239b2c45d4SDenys Vlasenko {
3624ac5a488eSSridhar Samudrala return READ_ONCE(sock->ops)->getname(sock, addr, 0);
36251ded5e5aSEric Dumazet }
3626ac5a488eSSridhar Samudrala EXPORT_SYMBOL(kernel_getsockname);
3627c6d409cfSEric Dumazet
3628ac5a488eSSridhar Samudrala /**
36298a3c245cSPedro Tammela * kernel_getpeername - get the address which the socket is connected (kernel space)
3630645f0897SMiaohe Lin * @sock: socket
36318a3c245cSPedro Tammela * @addr: address holder
36328a3c245cSPedro Tammela *
36338a3c245cSPedro Tammela * Fills the @addr pointer with the address which the socket is connected.
36348a3c245cSPedro Tammela * Returns the length of the address in bytes or an error code.
36350fc95decSAlex Maydanik */
36368a3c245cSPedro Tammela
kernel_getpeername(struct socket * sock,struct sockaddr * addr)36378a3c245cSPedro Tammela int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
36389b2c45d4SDenys Vlasenko {
3639ac5a488eSSridhar Samudrala return READ_ONCE(sock->ops)->getname(sock, addr, 1);
36401ded5e5aSEric Dumazet }
3641ac5a488eSSridhar Samudrala EXPORT_SYMBOL(kernel_getpeername);
3642c6d409cfSEric Dumazet
3643ac5a488eSSridhar Samudrala /**
36448a3c245cSPedro Tammela * kernel_sock_shutdown - shut down part of a full-duplex connection (kernel space)
3645645f0897SMiaohe Lin * @sock: socket
36468a3c245cSPedro Tammela * @how: connection part
36478a3c245cSPedro Tammela *
36488a3c245cSPedro Tammela * Returns 0 or an error.
36498a3c245cSPedro Tammela */
36508a3c245cSPedro Tammela
kernel_sock_shutdown(struct socket * sock,enum sock_shutdown_cmd how)36518a3c245cSPedro Tammela int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)
365291cf45f0STrond Myklebust {
365391cf45f0STrond Myklebust return READ_ONCE(sock->ops)->shutdown(sock, how);
36541ded5e5aSEric Dumazet }
365591cf45f0STrond Myklebust EXPORT_SYMBOL(kernel_sock_shutdown);
365691cf45f0STrond Myklebust
3657113c3075SR. Parameswaran /**
36588a3c245cSPedro Tammela * kernel_sock_ip_overhead - returns the IP overhead imposed by a socket
36598a3c245cSPedro Tammela * @sk: socket
36608a3c245cSPedro Tammela *
36618a3c245cSPedro Tammela * This routine returns the IP overhead imposed by a socket i.e.
36628a3c245cSPedro Tammela * the length of the underlying IP header, depending on whether
3663113c3075SR. Parameswaran * this is an IPv4 or IPv6 socket and the length from IP options turned
3664113c3075SR. Parameswaran * on at the socket. Assumes that the caller has a lock on the socket.
366557240d00SR. Parameswaran */
3666113c3075SR. Parameswaran
kernel_sock_ip_overhead(struct sock * sk)36678a3c245cSPedro Tammela u32 kernel_sock_ip_overhead(struct sock *sk)
3668113c3075SR. Parameswaran {
3669113c3075SR. Parameswaran struct inet_sock *inet;
3670113c3075SR. Parameswaran struct ip_options_rcu *opt;
3671113c3075SR. Parameswaran u32 overhead = 0;
3672113c3075SR. Parameswaran #if IS_ENABLED(CONFIG_IPV6)
3673113c3075SR. Parameswaran struct ipv6_pinfo *np;
3674113c3075SR. Parameswaran struct ipv6_txoptions *optv6 = NULL;
3675113c3075SR. Parameswaran #endif /* IS_ENABLED(CONFIG_IPV6) */
3676113c3075SR. Parameswaran
3677113c3075SR. Parameswaran if (!sk)
3678113c3075SR. Parameswaran return overhead;
3679113c3075SR. Parameswaran
3680113c3075SR. Parameswaran switch (sk->sk_family) {
3681113c3075SR. Parameswaran case AF_INET:
3682113c3075SR. Parameswaran inet = inet_sk(sk);
3683113c3075SR. Parameswaran overhead += sizeof(struct iphdr);
3684113c3075SR. Parameswaran opt = rcu_dereference_protected(inet->inet_opt,
3685113c3075SR. Parameswaran sock_owned_by_user(sk));
3686614d79c0Sstephen hemminger if (opt)
3687113c3075SR. Parameswaran overhead += opt->opt.optlen;
3688113c3075SR. Parameswaran return overhead;
3689113c3075SR. Parameswaran #if IS_ENABLED(CONFIG_IPV6)
3690113c3075SR. Parameswaran case AF_INET6:
3691113c3075SR. Parameswaran np = inet6_sk(sk);
3692113c3075SR. Parameswaran overhead += sizeof(struct ipv6hdr);
3693113c3075SR. Parameswaran if (np)
3694113c3075SR. Parameswaran optv6 = rcu_dereference_protected(np->opt,
3695113c3075SR. Parameswaran sock_owned_by_user(sk));
3696614d79c0Sstephen hemminger if (optv6)
3697113c3075SR. Parameswaran overhead += (optv6->opt_flen + optv6->opt_nflen);
3698113c3075SR. Parameswaran return overhead;
3699113c3075SR. Parameswaran #endif /* IS_ENABLED(CONFIG_IPV6) */
3700113c3075SR. Parameswaran default: /* Returns 0 overhead if the socket is not ipv4 or ipv6 */
3701113c3075SR. Parameswaran return overhead;
3702113c3075SR. Parameswaran }
3703113c3075SR. Parameswaran }
3704113c3075SR. Parameswaran EXPORT_SYMBOL(kernel_sock_ip_overhead);
3705113c3075SR. Parameswaran