]> err.no Git - linux-2.6/blobdiff - net/core/sock.c
fix reentrancy bug in arcmsr_get_iop_{r,w}qbuffer()
[linux-2.6] / net / core / sock.c
index 190de61cd648db8400ec852e40a652a6897a9e7d..bba9949681ff7e132f84629602814dc7d9aa17d4 100644 (file)
 #include <linux/netdevice.h>
 #include <net/protocol.h>
 #include <linux/skbuff.h>
+#include <net/net_namespace.h>
 #include <net/request_sock.h>
 #include <net/sock.h>
 #include <net/xfrm.h>
@@ -231,7 +232,7 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
                        warned++;
                        printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) "
                               "tries to set negative timeout\n",
-                               current->comm, current->pid);
+                               current->comm, task_pid_nr(current));
                return 0;
        }
        *timeo_p = MAX_SCHEDULE_TIMEOUT;
@@ -366,6 +367,7 @@ static int sock_bindtodevice(struct sock *sk, char __user *optval, int optlen)
 {
        int ret = -ENOPROTOOPT;
 #ifdef CONFIG_NETDEVICES
+       struct net *net = sk->sk_net;
        char devname[IFNAMSIZ];
        int index;
 
@@ -394,7 +396,7 @@ static int sock_bindtodevice(struct sock *sk, char __user *optval, int optlen)
        if (devname[0] == '\0') {
                index = 0;
        } else {
-               struct net_device *dev = dev_get_by_name(devname);
+               struct net_device *dev = dev_get_by_name(net, devname);
 
                ret = -ENODEV;
                if (!dev)
@@ -426,7 +428,6 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                    char __user *optval, int optlen)
 {
        struct sock *sk=sock->sk;
-       struct sk_filter *filter;
        int val;
        int valbool;
        struct linger ling;
@@ -650,16 +651,7 @@ set_rcvbuf:
                break;
 
        case SO_DETACH_FILTER:
-               rcu_read_lock_bh();
-               filter = rcu_dereference(sk->sk_filter);
-               if (filter) {
-                       rcu_assign_pointer(sk->sk_filter, NULL);
-                       sk_filter_release(sk, filter);
-                       rcu_read_unlock_bh();
-                       break;
-               }
-               rcu_read_unlock_bh();
-               ret = -ENONET;
+               ret = sk_detach_filter(sk);
                break;
 
        case SO_PASSSEC:
@@ -867,12 +859,13 @@ static inline void sock_lock_init(struct sock *sk)
 
 /**
  *     sk_alloc - All socket objects are allocated here
+ *     @net: the applicable net namespace
  *     @family: protocol family
  *     @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
  *     @prot: struct proto associated with this new sock instance
  *     @zero_it: if we should zero the newly allocated sock
  */
-struct sock *sk_alloc(int family, gfp_t priority,
+struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
                      struct proto *prot, int zero_it)
 {
        struct sock *sk = NULL;
@@ -893,6 +886,7 @@ struct sock *sk_alloc(int family, gfp_t priority,
                         */
                        sk->sk_prot = sk->sk_prot_creator = prot;
                        sock_lock_init(sk);
+                       sk->sk_net = get_net(net);
                }
 
                if (security_sk_alloc(sk, family, priority))
@@ -921,7 +915,7 @@ void sk_free(struct sock *sk)
 
        filter = rcu_dereference(sk->sk_filter);
        if (filter) {
-               sk_filter_release(sk, filter);
+               sk_filter_uncharge(sk, filter);
                rcu_assign_pointer(sk->sk_filter, NULL);
        }
 
@@ -932,6 +926,7 @@ void sk_free(struct sock *sk)
                       __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
 
        security_sk_free(sk);
+       put_net(sk->sk_net);
        if (sk->sk_prot_creator->slab != NULL)
                kmem_cache_free(sk->sk_prot_creator->slab, sk);
        else
@@ -941,7 +936,7 @@ void sk_free(struct sock *sk)
 
 struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
 {
-       struct sock *newsk = sk_alloc(sk->sk_family, priority, sk->sk_prot, 0);
+       struct sock *newsk = sk_alloc(sk->sk_net, sk->sk_family, priority, sk->sk_prot, 0);
 
        if (newsk != NULL) {
                struct sk_filter *filter;
@@ -1585,9 +1580,9 @@ void fastcall lock_sock_nested(struct sock *sk, int subclass)
 {
        might_sleep();
        spin_lock_bh(&sk->sk_lock.slock);
-       if (sk->sk_lock.owner)
+       if (sk->sk_lock.owned)
                __lock_sock(sk);
-       sk->sk_lock.owner = (void *)1;
+       sk->sk_lock.owned = 1;
        spin_unlock(&sk->sk_lock.slock);
        /*
         * The sk_lock has mutex_lock() semantics here:
@@ -1608,7 +1603,7 @@ void fastcall release_sock(struct sock *sk)
        spin_lock_bh(&sk->sk_lock.slock);
        if (sk->sk_backlog.tail)
                __release_sock(sk);
-       sk->sk_lock.owner = NULL;
+       sk->sk_lock.owned = 0;
        if (waitqueue_active(&sk->sk_lock.wq))
                wake_up(&sk->sk_lock.wq);
        spin_unlock_bh(&sk->sk_lock.slock);
@@ -1654,7 +1649,6 @@ void sock_enable_timestamp(struct sock *sk)
                net_enable_timestamp();
        }
 }
-EXPORT_SYMBOL(sock_enable_timestamp);
 
 /*
  *     Get a socket option on an socket.
@@ -1973,7 +1967,7 @@ static const struct file_operations proto_seq_fops = {
 static int __init proto_init(void)
 {
        /* register /proc/net/protocols */
-       return proc_net_fops_create("protocols", S_IRUGO, &proto_seq_fops) == NULL ? -ENOBUFS : 0;
+       return proc_net_fops_create(&init_net, "protocols", S_IRUGO, &proto_seq_fops) == NULL ? -ENOBUFS : 0;
 }
 
 subsys_initcall(proto_init);