[NET]: Make socket creation namespace safe.
[deliverable/linux.git] / net / iucv / af_iucv.c
index 2f1373855a8bc92901bc601b52e10d4e6463fbcf..53668585e947720cbfced1ebb02c82c61ec62e13 100644 (file)
@@ -213,12 +213,13 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
 {
        struct sock *sk;
 
-       sk = sk_alloc(PF_IUCV, prio, &iucv_proto, 1);
+       sk = sk_alloc(&init_net, PF_IUCV, prio, &iucv_proto, 1);
        if (!sk)
                return NULL;
 
        sock_init_data(sock, sk);
        INIT_LIST_HEAD(&iucv_sk(sk)->accept_q);
+       spin_lock_init(&iucv_sk(sk)->accept_q_lock);
        skb_queue_head_init(&iucv_sk(sk)->send_skb_q);
        skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q);
        iucv_sk(sk)->send_tag = 0;
@@ -239,7 +240,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
 }
 
 /* Create an IUCV socket */
-static int iucv_sock_create(struct socket *sock, int protocol)
+static int iucv_sock_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
@@ -274,15 +275,25 @@ void iucv_sock_unlink(struct iucv_sock_list *l, struct sock *sk)
 
 void iucv_accept_enqueue(struct sock *parent, struct sock *sk)
 {
+       unsigned long flags;
+       struct iucv_sock *par = iucv_sk(parent);
+
        sock_hold(sk);
-       list_add_tail(&iucv_sk(sk)->accept_q, &iucv_sk(parent)->accept_q);
+       spin_lock_irqsave(&par->accept_q_lock, flags);
+       list_add_tail(&iucv_sk(sk)->accept_q, &par->accept_q);
+       spin_unlock_irqrestore(&par->accept_q_lock, flags);
        iucv_sk(sk)->parent = parent;
        parent->sk_ack_backlog++;
 }
 
 void iucv_accept_unlink(struct sock *sk)
 {
+       unsigned long flags;
+       struct iucv_sock *par = iucv_sk(iucv_sk(sk)->parent);
+
+       spin_lock_irqsave(&par->accept_q_lock, flags);
        list_del_init(&iucv_sk(sk)->accept_q);
+       spin_unlock_irqrestore(&par->accept_q_lock, flags);
        iucv_sk(sk)->parent->sk_ack_backlog--;
        iucv_sk(sk)->parent = NULL;
        sock_put(sk);
@@ -298,8 +309,8 @@ struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock)
                lock_sock(sk);
 
                if (sk->sk_state == IUCV_CLOSED) {
-                       release_sock(sk);
                        iucv_accept_unlink(sk);
+                       release_sock(sk);
                        continue;
                }
 
@@ -879,6 +890,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
        /* Find out if this path belongs to af_iucv. */
        read_lock(&iucv_sk_list.lock);
        iucv = NULL;
+       sk = NULL;
        sk_for_each(sk, node, &iucv_sk_list.head)
                if (sk->sk_state == IUCV_LISTEN &&
                    !memcmp(&iucv_sk(sk)->src_name, src_name, 8)) {
@@ -961,7 +973,7 @@ static void iucv_callback_connack(struct iucv_path *path, u8 ipuser[16])
 }
 
 static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len,
-                            struct sk_buff_head fragmented_skb_q)
+                            struct sk_buff_head *fragmented_skb_q)
 {
        int dataleft, size, copied = 0;
        struct sk_buff *nskb;
@@ -981,8 +993,8 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len,
                copied += size;
                dataleft -= size;
 
-               nskb->h.raw = nskb->data;
-               nskb->nh.raw = nskb->data;
+               skb_reset_transport_header(nskb);
+               skb_reset_network_header(nskb);
                nskb->len = size;
 
                skb_queue_tail(fragmented_skb_q, nskb);
This page took 0.052235 seconds and 5 git commands to generate.