3584 lines · 87.0 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* * NET		An implementation of the SOCKET network access protocol. * * Version:	@(#)socket.c	1.1.93	18/02/95 * * Authors:	Orest Zborowski, <obz@Kodak.COM> *		Ross Biro *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * * Fixes: *		Anonymous	:	NOTSOCK/BADF cleanup. Error fix in *					shutdown() *		Alan Cox	:	verify_area() fixes *		Alan Cox	:	Removed DDI *		Jonathan Kamens	:	SOCK_DGRAM reconnect bug *		Alan Cox	:	Moved a load of checks to the very *					top level. *		Alan Cox	:	Move address structures to/from user *					mode above the protocol layers. *		Rob Janssen	:	Allow 0 length sends. *		Alan Cox	:	Asynchronous I/O support (cribbed from the *					tty drivers). *		Niibe Yutaka	:	Asynchronous I/O for writes (4.4BSD style) *		Jeff Uphoff	:	Made max number of sockets command-line *					configurable. *		Matti Aarnio	:	Made the number of sockets dynamic, *					to be allocated when needed, and mr. *					Uphoff's max is used as max to be *					allowed to allocate. *		Linus		:	Argh. removed all the socket allocation *					altogether: it's in the inode now. *		Alan Cox	:	Made sock_alloc()/sock_release() public *					for NetROM and future kernel nfsd type *					stuff. *		Alan Cox	:	sendmsg/recvmsg basics. *		Tom Dyas	:	Export net symbols. *		Marcin Dalecki	:	Fixed problems with CONFIG_NET="n". *		Alan Cox	:	Added thread locking to sys_* calls *					for sockets. May have errors at the *					moment. *		Kevin Buhr	:	Fixed the dumb errors in the above. *		Andi Kleen	:	Some small cleanups, optimizations, *					and fixed a copy_from_user() bug. *		Tigran Aivazian	:	sys_send(args) calls sys_sendto(args, NULL, 0) *		Tigran Aivazian	:	Made listen(2) backlog sanity checks *					protocol-independent * *	This module is effectively the top level interface to the BSD socket *	paradigm. * *	Based upon Swansea University Computer Society NET3.039 */ #include <linux/bpf-cgroup.h>#include <linux/ethtool.h>#include <linux/mm.h>#include <linux/socket.h>#include <linux/file.h>#include <linux/net.h>#include <linux/interrupt.h>#include <linux/thread_info.h>#include <linux/rcupdate.h>#include <linux/netdevice.h>#include <linux/proc_fs.h>#include <linux/seq_file.h>#include <linux/mutex.h>#include <linux/if_bridge.h>#include <linux/if_vlan.h>#include <linux/ptp_classify.h>#include <linux/init.h>#include <linux/poll.h>#include <linux/cache.h>#include <linux/module.h>#include <linux/highmem.h>#include <linux/mount.h>#include <linux/pseudo_fs.h>#include <linux/security.h>#include <linux/syscalls.h>#include <linux/compat.h>#include <linux/kmod.h>#include <linux/audit.h>#include <linux/wireless.h>#include <linux/nsproxy.h>#include <linux/magic.h>#include <linux/slab.h>#include <linux/xattr.h>#include <linux/nospec.h>#include <linux/indirect_call_wrapper.h> #include <linux/uaccess.h>#include <asm/unistd.h> #include <net/compat.h>#include <net/wext.h>#include <net/cls_cgroup.h> #include <net/sock.h>#include <linux/netfilter.h> #include <linux/if_tun.h>#include <linux/ipv6_route.h>#include <linux/route.h>#include <linux/termios.h>#include <linux/sockios.h>#include <net/busy_poll.h>#include <linux/errqueue.h>#include <linux/ptp_clock_kernel.h> #ifdef CONFIG_NET_RX_BUSY_POLLunsigned int sysctl_net_busy_read __read_mostly;unsigned int sysctl_net_busy_poll __read_mostly;#endif static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to);static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from);static int sock_mmap(struct file *file, struct vm_area_struct *vma); static int sock_close(struct inode *inode, struct file *file);static __poll_t sock_poll(struct file *file,			      struct poll_table_struct *wait);static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);#ifdef CONFIG_COMPATstatic long compat_sock_ioctl(struct file *file,			      unsigned int cmd, unsigned long arg);#endifstatic int sock_fasync(int fd, struct file *filp, int on);static ssize_t sock_sendpage(struct file *file, struct page *page,			     int offset, size_t size, loff_t *ppos, int more);static ssize_t sock_splice_read(struct file *file, loff_t *ppos,				struct pipe_inode_info *pipe, size_t len,				unsigned int flags); #ifdef CONFIG_PROC_FSstatic void sock_show_fdinfo(struct seq_file *m, struct file *f){	struct socket *sock = f->private_data; 	if (sock->ops->show_fdinfo)		sock->ops->show_fdinfo(m, sock);}#else#define sock_show_fdinfo NULL#endif /* *	Socket files have a set of 'special' operations as well as the generic file ones. These don't appear *	in the operation structures but are done directly via the socketcall() multiplexor. */ static const struct file_operations socket_file_ops = {	.owner =	THIS_MODULE,	.llseek =	no_llseek,	.read_iter =	sock_read_iter,	.write_iter =	sock_write_iter,	.poll =		sock_poll,	.unlocked_ioctl = sock_ioctl,#ifdef CONFIG_COMPAT	.compat_ioctl = compat_sock_ioctl,#endif	.mmap =		sock_mmap,	.release =	sock_close,	.fasync =	sock_fasync,	.sendpage =	sock_sendpage,	.splice_write = generic_splice_sendpage,	.splice_read =	sock_splice_read,	.show_fdinfo =	sock_show_fdinfo,}; static const char * const pf_family_names[] = {	[PF_UNSPEC]	= "PF_UNSPEC",	[PF_UNIX]	= "PF_UNIX/PF_LOCAL",	[PF_INET]	= "PF_INET",	[PF_AX25]	= "PF_AX25",	[PF_IPX]	= "PF_IPX",	[PF_APPLETALK]	= "PF_APPLETALK",	[PF_NETROM]	= "PF_NETROM",	[PF_BRIDGE]	= "PF_BRIDGE",	[PF_ATMPVC]	= "PF_ATMPVC",	[PF_X25]	= "PF_X25",	[PF_INET6]	= "PF_INET6",	[PF_ROSE]	= "PF_ROSE",	[PF_DECnet]	= "PF_DECnet",	[PF_NETBEUI]	= "PF_NETBEUI",	[PF_SECURITY]	= "PF_SECURITY",	[PF_KEY]	= "PF_KEY",	[PF_NETLINK]	= "PF_NETLINK/PF_ROUTE",	[PF_PACKET]	= "PF_PACKET",	[PF_ASH]	= "PF_ASH",	[PF_ECONET]	= "PF_ECONET",	[PF_ATMSVC]	= "PF_ATMSVC",	[PF_RDS]	= "PF_RDS",	[PF_SNA]	= "PF_SNA",	[PF_IRDA]	= "PF_IRDA",	[PF_PPPOX]	= "PF_PPPOX",	[PF_WANPIPE]	= "PF_WANPIPE",	[PF_LLC]	= "PF_LLC",	[PF_IB]		= "PF_IB",	[PF_MPLS]	= "PF_MPLS",	[PF_CAN]	= "PF_CAN",	[PF_TIPC]	= "PF_TIPC",	[PF_BLUETOOTH]	= "PF_BLUETOOTH",	[PF_IUCV]	= "PF_IUCV",	[PF_RXRPC]	= "PF_RXRPC",	[PF_ISDN]	= "PF_ISDN",	[PF_PHONET]	= "PF_PHONET",	[PF_IEEE802154]	= "PF_IEEE802154",	[PF_CAIF]	= "PF_CAIF",	[PF_ALG]	= "PF_ALG",	[PF_NFC]	= "PF_NFC",	[PF_VSOCK]	= "PF_VSOCK",	[PF_KCM]	= "PF_KCM",	[PF_QIPCRTR]	= "PF_QIPCRTR",	[PF_SMC]	= "PF_SMC",	[PF_XDP]	= "PF_XDP",	[PF_MCTP]	= "PF_MCTP",}; /* *	The protocol list. Each protocol is registered in here. */ static DEFINE_SPINLOCK(net_family_lock);static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly; /* * Support routines. * Move socket addresses back and forth across the kernel/user * divide and look after the messy bits. */ /** *	move_addr_to_kernel	-	copy a socket address into kernel space *	@uaddr: Address in user space *	@kaddr: Address in kernel space *	@ulen: Length in user space * *	The address is copied into kernel space. If the provided address is *	too long an error code of -EINVAL is returned. If the copy gives *	invalid addresses -EFAULT is returned. On a success 0 is returned. */ int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr){	if (ulen < 0 || ulen > sizeof(struct sockaddr_storage))		return -EINVAL;	if (ulen == 0)		return 0;	if (copy_from_user(kaddr, uaddr, ulen))		return -EFAULT;	return audit_sockaddr(ulen, kaddr);} /** *	move_addr_to_user	-	copy an address to user space *	@kaddr: kernel space address *	@klen: length of address in kernel *	@uaddr: user space address *	@ulen: pointer to user length field * *	The value pointed to by ulen on entry is the buffer length available. *	This is overwritten with the buffer space used. -EINVAL is returned *	if an overlong buffer is specified or a negative buffer size. -EFAULT *	is returned if either the buffer or the length field are not *	accessible. *	After copying the data up to the limit the user specifies, the true *	length of the data is written over the length limit the user *	specified. Zero is returned for a success. */ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,			     void __user *uaddr, int __user *ulen){	int err;	int len; 	BUG_ON(klen > sizeof(struct sockaddr_storage));	err = get_user(len, ulen);	if (err)		return err;	if (len > klen)		len = klen;	if (len < 0)		return -EINVAL;	if (len) {		if (audit_sockaddr(klen, kaddr))			return -ENOMEM;		if (copy_to_user(uaddr, kaddr, len))			return -EFAULT;	}	/*	 *      "fromlen shall refer to the value before truncation.."	 *                      1003.1g	 */	return __put_user(klen, ulen);} static struct kmem_cache *sock_inode_cachep __ro_after_init; static struct inode *sock_alloc_inode(struct super_block *sb){	struct socket_alloc *ei; 	ei = alloc_inode_sb(sb, sock_inode_cachep, GFP_KERNEL);	if (!ei)		return NULL;	init_waitqueue_head(&ei->socket.wq.wait);	ei->socket.wq.fasync_list = NULL;	ei->socket.wq.flags = 0; 	ei->socket.state = SS_UNCONNECTED;	ei->socket.flags = 0;	ei->socket.ops = NULL;	ei->socket.sk = NULL;	ei->socket.file = NULL; 	return &ei->vfs_inode;} static void sock_free_inode(struct inode *inode){	struct socket_alloc *ei; 	ei = container_of(inode, struct socket_alloc, vfs_inode);	kmem_cache_free(sock_inode_cachep, ei);} static void init_once(void *foo){	struct socket_alloc *ei = (struct socket_alloc *)foo; 	inode_init_once(&ei->vfs_inode);} static void init_inodecache(void){	sock_inode_cachep = kmem_cache_create("sock_inode_cache",					      sizeof(struct socket_alloc),					      0,					      (SLAB_HWCACHE_ALIGN |					       SLAB_RECLAIM_ACCOUNT |					       SLAB_MEM_SPREAD | SLAB_ACCOUNT),					      init_once);	BUG_ON(sock_inode_cachep == NULL);} static const struct super_operations sockfs_ops = {	.alloc_inode	= sock_alloc_inode,	.free_inode	= sock_free_inode,	.statfs		= simple_statfs,}; /* * sockfs_dname() is called from d_path(). */static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen){	return dynamic_dname(dentry, buffer, buflen, "socket:[%lu]",				d_inode(dentry)->i_ino);} static const struct dentry_operations sockfs_dentry_operations = {	.d_dname  = sockfs_dname,}; static int sockfs_xattr_get(const struct xattr_handler *handler,			    struct dentry *dentry, struct inode *inode,			    const char *suffix, void *value, size_t size){	if (value) {		if (dentry->d_name.len + 1 > size)			return -ERANGE;		memcpy(value, dentry->d_name.name, dentry->d_name.len + 1);	}	return dentry->d_name.len + 1;} #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"#define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)#define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1) static const struct xattr_handler sockfs_xattr_handler = {	.name = XATTR_NAME_SOCKPROTONAME,	.get = sockfs_xattr_get,}; static int sockfs_security_xattr_set(const struct xattr_handler *handler,				     struct user_namespace *mnt_userns,				     struct dentry *dentry, struct inode *inode,				     const char *suffix, const void *value,				     size_t size, int flags){	/* Handled by LSM. */	return -EAGAIN;} static const struct xattr_handler sockfs_security_xattr_handler = {	.prefix = XATTR_SECURITY_PREFIX,	.set = sockfs_security_xattr_set,}; static const struct xattr_handler *sockfs_xattr_handlers[] = {	&sockfs_xattr_handler,	&sockfs_security_xattr_handler,	NULL}; static int sockfs_init_fs_context(struct fs_context *fc){	struct pseudo_fs_context *ctx = init_pseudo(fc, SOCKFS_MAGIC);	if (!ctx)		return -ENOMEM;	ctx->ops = &sockfs_ops;	ctx->dops = &sockfs_dentry_operations;	ctx->xattr = sockfs_xattr_handlers;	return 0;} static struct vfsmount *sock_mnt __read_mostly; static struct file_system_type sock_fs_type = {	.name =		"sockfs",	.init_fs_context = sockfs_init_fs_context,	.kill_sb =	kill_anon_super,}; /* *	Obtains the first available file descriptor and sets it up for use. * *	These functions create file structures and maps them to fd space *	of the current process. On success it returns file descriptor *	and file struct implicitly stored in sock->file. *	Note that another thread may close file descriptor before we return *	from this function. We use the fact that now we do not refer *	to socket after mapping. If one day we will need it, this *	function will increment ref. count on file by 1. * *	In any case returned fd MAY BE not valid! *	This race condition is unavoidable *	with shared fd spaces, we cannot solve it inside kernel, *	but we take care of internal coherence yet. */ /** *	sock_alloc_file - Bind a &socket to a &file *	@sock: socket *	@flags: file status flags *	@dname: protocol name * *	Returns the &file bound with @sock, implicitly storing it *	in sock->file. If dname is %NULL, sets to "". *	On failure the return is a ERR pointer (see linux/err.h). *	This function uses GFP_KERNEL internally. */ struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname){	struct file *file; 	if (!dname)		dname = sock->sk ? sock->sk->sk_prot_creator->name : ""; 	file = alloc_file_pseudo(SOCK_INODE(sock), sock_mnt, dname,				O_RDWR | (flags & O_NONBLOCK),				&socket_file_ops);	if (IS_ERR(file)) {		sock_release(sock);		return file;	} 	sock->file = file;	file->private_data = sock;	stream_open(SOCK_INODE(sock), file);	return file;}EXPORT_SYMBOL(sock_alloc_file); static int sock_map_fd(struct socket *sock, int flags){	struct file *newfile;	int fd = get_unused_fd_flags(flags);	if (unlikely(fd < 0)) {		sock_release(sock);		return fd;	} 	newfile = sock_alloc_file(sock, flags, NULL);	if (!IS_ERR(newfile)) {		fd_install(fd, newfile);		return fd;	} 	put_unused_fd(fd);	return PTR_ERR(newfile);} /** *	sock_from_file - Return the &socket bounded to @file. *	@file: file *

Lines 1–500 of 3584.