nfsd: simplify fh_verify access checks
[safe/jmp/linux-2.6] / net / socket.c
index 47a3dc0..7565536 100644 (file)
@@ -86,6 +86,7 @@
 #include <linux/audit.h>
 #include <linux/wireless.h>
 #include <linux/nsproxy.h>
+#include <linux/magic.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -235,8 +236,6 @@ int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr,
        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)
@@ -285,7 +284,7 @@ static int init_inodecache(void)
        return 0;
 }
 
-static struct super_operations sockfs_ops = {
+static const struct super_operations sockfs_ops = {
        .alloc_inode =  sock_alloc_inode,
        .destroy_inode =sock_destroy_inode,
        .statfs =       simple_statfs,
@@ -328,7 +327,7 @@ static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
                                dentry->d_inode->i_ino);
 }
 
-static struct dentry_operations sockfs_dentry_operations = {
+static const struct dentry_operations sockfs_dentry_operations = {
        .d_delete = sockfs_delete_dentry,
        .d_dname  = sockfs_dname,
 };
@@ -489,12 +488,12 @@ static struct socket *sock_alloc(void)
 
        sock = SOCKET_I(inode);
 
+       kmemcheck_annotate_bitfield(sock, type);
        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);
+       percpu_add(sockets_in_use, 1);
        return sock;
 }
 
@@ -536,8 +535,7 @@ void sock_release(struct socket *sock)
        if (sock->fasync_list)
                printk(KERN_ERR "sock_release: fasync list not empty!\n");
 
-       get_cpu_var(sockets_in_use)--;
-       put_cpu_var(sockets_in_use);
+       percpu_sub(sockets_in_use, 1);
        if (!sock->file) {
                iput(SOCK_INODE(sock));
                return;
@@ -738,7 +736,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
        if (more)
                flags |= MSG_MORE;
 
-       return sock->ops->sendpage(sock, page, offset, size, flags);
+       return kernel_sendpage(sock, page, offset, size, flags);
 }
 
 static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
@@ -1074,6 +1072,13 @@ static int sock_fasync(int fd, struct file *filp, int on)
 
        lock_sock(sk);
 
+       spin_lock(&filp->f_lock);
+       if (on)
+               filp->f_flags |= FASYNC;
+       else
+               filp->f_flags &= ~FASYNC;
+       spin_unlock(&filp->f_lock);
+
        prev = &(sock->fasync_list);
 
        for (fa = *prev; fa != NULL; prev = &fa->fa_next, fa = *prev)
@@ -1529,8 +1534,6 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
        fd_install(newfd, newfile);
        err = newfd;
 
-       security_socket_post_accept(sock, newsock);
-
 out_put:
        fput_light(sock->file, fput_needed);
 out:
@@ -2095,12 +2098,17 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
        unsigned long a[6];
        unsigned long a0, a1;
        int err;
+       unsigned int len;
 
        if (call < 1 || call > SYS_ACCEPT4)
                return -EINVAL;
 
+       len = nargs[call];
+       if (len > sizeof(a))
+               return -EINVAL;
+
        /* copy_from_user should be SMP safe. */
-       if (copy_from_user(a, args, nargs[call]))
+       if (copy_from_user(a, args, len))
                return -EFAULT;
 
        audit_socketcall(nargs[call] / sizeof(unsigned long), a);
@@ -2383,7 +2391,7 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
 }
 
 int kernel_setsockopt(struct socket *sock, int level, int optname,
-                       char *optval, int optlen)
+                       char *optval, unsigned int optlen)
 {
        mm_segment_t oldfs = get_fs();
        int err;