2309 lines · 53.7 KB · C
RawDownload
/* * 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 program is free software; you can redistribute it and/or *		modify it under the terms of the GNU General Public License *		as published by the Free Software Foundation; either version *		2 of the License, or (at your option) any later version. * * *	This module is effectively the top level interface to the BSD socket *	paradigm. * *	Based upon Swansea University Computer Society NET3.039 */ #include <linux/mm.h>#include <linux/socket.h>#include <linux/file.h>#include <linux/net.h>#include <linux/interrupt.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/wanrouter.h>#include <linux/if_bridge.h>#include <linux/if_frad.h>#include <linux/if_vlan.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/security.h>#include <linux/syscalls.h>#include <linux/compat.h>#include <linux/kmod.h>#include <linux/audit.h>#include <linux/wireless.h> #include <asm/uaccess.h>#include <asm/unistd.h> #include <net/compat.h> #include <net/sock.h>#include <linux/netfilter.h> static int sock_no_open(struct inode *irrelevant, struct file *dontcare);static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,			 unsigned long nr_segs, loff_t pos);static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,			  unsigned long nr_segs, loff_t pos);static int sock_mmap(struct file *file, struct vm_area_struct *vma); static int sock_close(struct inode *inode, struct file *file);static unsigned int 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); /* *	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,	.aio_read =	sock_aio_read,	.aio_write =	sock_aio_write,	.poll =		sock_poll,	.unlocked_ioctl = sock_ioctl,#ifdef CONFIG_COMPAT	.compat_ioctl = compat_sock_ioctl,#endif	.mmap =		sock_mmap,	.open =		sock_no_open,	/* special open code to disallow open via /proc */	.release =	sock_close,	.fasync =	sock_fasync,	.sendpage =	sock_sendpage,	.splice_write = generic_splice_sendpage,}; /* *	The protocol list. Each protocol is registered in here. */ static DEFINE_SPINLOCK(net_family_lock);static const struct net_proto_family *net_families[NPROTO] __read_mostly; /* *	Statistics counters of the socket lists */ static DEFINE_PER_CPU(int, sockets_in_use) = 0; /* * Support routines. * Move socket addresses back and forth across the kernel/user * divide and look after the messy bits. */ #define MAX_SOCK_ADDR	128		/* 108 for Unix domain -					   16 for IP, 16 for IPX,					   24 for IPv6,					   about 80 for AX.25					   must be at least one bigger than					   the AF_UNIX size (see net/unix/af_unix.c					   :unix_mkname()).					 */ /** *	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, void *kaddr){	if (ulen < 0 || ulen > MAX_SOCK_ADDR)		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. */ int move_addr_to_user(void *kaddr, int klen, void __user *uaddr,		      int __user *ulen){	int err;	int len; 	err = get_user(len, ulen);	if (err)		return err;	if (len > klen)		len = klen;	if (len < 0 || len > MAX_SOCK_ADDR)		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);} #define SOCKFS_MAGIC 0x534F434B static struct kmem_cache *sock_inode_cachep __read_mostly; static struct inode *sock_alloc_inode(struct super_block *sb){	struct socket_alloc *ei; 	ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);	if (!ei)		return NULL;	init_waitqueue_head(&ei->socket.wait); 	ei->socket.fasync_list = NULL;	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_destroy_inode(struct inode *inode){	kmem_cache_free(sock_inode_cachep,			container_of(inode, struct socket_alloc, vfs_inode));} static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags){	struct socket_alloc *ei = (struct socket_alloc *)foo; 	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR))	    == SLAB_CTOR_CONSTRUCTOR)		inode_init_once(&ei->vfs_inode);} static int 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),					      init_once,					      NULL);	if (sock_inode_cachep == NULL)		return -ENOMEM;	return 0;} static struct super_operations sockfs_ops = {	.alloc_inode =	sock_alloc_inode,	.destroy_inode =sock_destroy_inode,	.statfs =	simple_statfs,}; static int sockfs_get_sb(struct file_system_type *fs_type,			 int flags, const char *dev_name, void *data,			 struct vfsmount *mnt){	return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC,			     mnt);} static struct vfsmount *sock_mnt __read_mostly; static struct file_system_type sock_fs_type = {	.name =		"sockfs",	.get_sb =	sockfs_get_sb,	.kill_sb =	kill_anon_super,}; static int sockfs_delete_dentry(struct dentry *dentry){	/*	 * At creation time, we pretended this dentry was hashed	 * (by clearing DCACHE_UNHASHED bit in d_flags)	 * At delete time, we restore the truth : not hashed.	 * (so that dput() can proceed correctly)	 */	dentry->d_flags |= DCACHE_UNHASHED;	return 0;}static struct dentry_operations sockfs_dentry_operations = {	.d_delete = sockfs_delete_dentry,}; /* *	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. */ static int sock_alloc_fd(struct file **filep){	int fd; 	fd = get_unused_fd();	if (likely(fd >= 0)) {		struct file *file = get_empty_filp(); 		*filep = file;		if (unlikely(!file)) {			put_unused_fd(fd);			return -ENFILE;		}	} else		*filep = NULL;	return fd;} static int sock_attach_fd(struct socket *sock, struct file *file){	struct qstr this;	char name[32]; 	this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);	this.name = name;	this.hash = 0; 	file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);	if (unlikely(!file->f_path.dentry))		return -ENOMEM; 	file->f_path.dentry->d_op = &sockfs_dentry_operations;	/*	 * We dont want to push this dentry into global dentry hash table.	 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED	 * This permits a working /proc/$pid/fd/XXX on sockets	 */	file->f_path.dentry->d_flags &= ~DCACHE_UNHASHED;	d_instantiate(file->f_path.dentry, SOCK_INODE(sock));	file->f_path.mnt = mntget(sock_mnt);	file->f_mapping = file->f_path.dentry->d_inode->i_mapping; 	sock->file = file;	file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;	file->f_mode = FMODE_READ | FMODE_WRITE;	file->f_flags = O_RDWR;	file->f_pos = 0;	file->private_data = sock; 	return 0;} int sock_map_fd(struct socket *sock){	struct file *newfile;	int fd = sock_alloc_fd(&newfile); 	if (likely(fd >= 0)) {		int err = sock_attach_fd(sock, newfile); 		if (unlikely(err < 0)) {			put_filp(newfile);			put_unused_fd(fd);			return err;		}		fd_install(fd, newfile);	}	return fd;} static struct socket *sock_from_file(struct file *file, int *err){	if (file->f_op == &socket_file_ops)		return file->private_data;	/* set in sock_map_fd */ 	*err = -ENOTSOCK;	return NULL;} /** *	sockfd_lookup	- 	Go from a file number to its socket slot *	@fd: file handle *	@err: pointer to an error code return * *	The file handle passed in is locked and the socket it is bound *	too is returned. If an error occurs the err pointer is overwritten *	with a negative errno code and NULL is returned. The function checks *	for both invalid handles and passing a handle which is not a socket. * *	On a success the socket object pointer is returned. */ struct socket *sockfd_lookup(int fd, int *err){	struct file *file;	struct socket *sock; 	file = fget(fd);	if (!file) {		*err = -EBADF;		return NULL;	} 	sock = sock_from_file(file, err);	if (!sock)		fput(file);	return sock;} static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed){	struct file *file;	struct socket *sock; 	*err = -EBADF;	file = fget_light(fd, fput_needed);	if (file) {		sock = sock_from_file(file, err);		if (sock)			return sock;		fput_light(file, *fput_needed);	}	return NULL;} /** *	sock_alloc	-	allocate a socket * *	Allocate a new inode and socket object. The two are bound together *	and initialised. The socket is then returned. If we are out of inodes *	NULL is returned. */ static struct socket *sock_alloc(void){	struct inode *inode;	struct socket *sock; 	inode = new_inode(sock_mnt->mnt_sb);	if (!inode)		return NULL; 	sock = SOCKET_I(inode); 	inode->i_mode = S_IFSOCK | S_IRWXUGO;	inode->i_uid = current->fsuid;	inode->i_gid = current->fsgid; 	get_cpu_var(sockets_in_use)++;	put_cpu_var(sockets_in_use);	return sock;} /* *	In theory you can't get an open on this inode, but /proc provides *	a back door. Remember to keep it shut otherwise you'll let the *	creepy crawlies in. */ static int sock_no_open(struct inode *irrelevant, struct file *dontcare){	return -ENXIO;}

Lines 1–500 of 2309.