X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fsocket.c;h=02948b622bd2e938bfc6d02e44f2d13ae2b9f874;hb=c620953c32d301c2a7bc73f9f780301e110b7d7c;hp=e3c21d5ec2885aa4fea17eea23621580c07a6fb7;hpb=ca94f26d2b2ee8ad76be617b35f846444fedc07b;p=linux-2.6 diff --git a/net/socket.c b/net/socket.c index e3c21d5ec2..02948b622b 100644 --- a/net/socket.c +++ b/net/socket.c @@ -107,6 +107,10 @@ 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_COMPAT +static long compat_sock_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); +#endif static int sock_fasync(int fd, struct file *filp, int on); static ssize_t sock_readv(struct file *file, const struct iovec *vector, unsigned long count, loff_t *ppos); @@ -115,7 +119,6 @@ static ssize_t sock_writev(struct file *file, const struct iovec *vector, 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. @@ -128,13 +131,17 @@ static struct file_operations socket_file_ops = { .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, .readv = sock_readv, .writev = sock_writev, - .sendpage = sock_sendpage + .sendpage = sock_sendpage, + .splice_write = generic_splice_sendpage, }; /* @@ -260,6 +267,8 @@ int move_addr_to_user(void *kaddr, int klen, void __user *uaddr, int __user *ule return -EINVAL; if(len) { + if (audit_sockaddr(klen, kaddr)) + return -ENOMEM; if(copy_to_user(uaddr,kaddr,len)) return -EFAULT; } @@ -312,7 +321,8 @@ 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, + 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT| + SLAB_MEM_SPREAD), init_once, NULL); if (sock_inode_cachep == NULL) return -ENOMEM; @@ -482,6 +492,7 @@ 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); @@ -531,7 +542,7 @@ static int sock_no_open(struct inode *irrelevant, struct file *dontcare) return -ENXIO; } -struct file_operations bad_sock_fops = { +const struct file_operations bad_sock_fops = { .owner = THIS_MODULE, .open = sock_no_open, }; @@ -1406,7 +1417,8 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _ newfd = sock_alloc_fd(&newfile); if (unlikely(newfd < 0)) { err = newfd; - goto out_release; + sock_release(newsock); + goto out_put; } err = sock_attach_fd(newsock, newfile); @@ -1443,10 +1455,8 @@ out_put: out: return err; out_fd: - put_filp(newfile); + fput(newfile); put_unused_fd(newfd); -out_release: - sock_release(newsock); goto out_put; } @@ -2125,7 +2135,7 @@ void socket_seq_show(struct seq_file *seq) int cpu; int counter = 0; - for_each_cpu(cpu) + for_each_possible_cpu(cpu) counter += per_cpu(sockets_in_use, cpu); /* It can be negative, by the way. 8) */ @@ -2136,6 +2146,20 @@ void socket_seq_show(struct seq_file *seq) } #endif /* CONFIG_PROC_FS */ +#ifdef CONFIG_COMPAT +static long compat_sock_ioctl(struct file *file, unsigned cmd, + unsigned long arg) +{ + struct socket *sock = file->private_data; + int ret = -ENOIOCTLCMD; + + if (sock->ops->compat_ioctl) + ret = sock->ops->compat_ioctl(sock, cmd, arg); + + return ret; +} +#endif + /* ABI emulation layers need these two */ EXPORT_SYMBOL(move_addr_to_kernel); EXPORT_SYMBOL(move_addr_to_user);