VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / net / netlink / af_netlink.c
index 4c90113..69a81d0 100644 (file)
@@ -176,7 +176,7 @@ found:
        return sk;
 }
 
-extern struct proto_ops netlink_ops;
+static struct proto_ops netlink_ops;
 
 static int netlink_insert(struct sock *sk, u32 pid)
 {
@@ -365,6 +365,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
        struct sockaddr_nl *nladdr=(struct sockaddr_nl*)addr;
 
        if (addr->sa_family == AF_UNSPEC) {
+               sk->sk_state    = NETLINK_UNCONNECTED;
                nlk->dst_pid    = 0;
                nlk->dst_groups = 0;
                return 0;
@@ -380,11 +381,12 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
                err = netlink_autobind(sock);
 
        if (err == 0) {
+               sk->sk_state    = NETLINK_CONNECTED;
                nlk->dst_pid    = nladdr->nl_pid;
                nlk->dst_groups = nladdr->nl_groups;
        }
 
-       return 0;
+       return err;
 }
 
 static int netlink_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
@@ -427,7 +429,9 @@ struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
 
        /* Don't bother queuing skb if kernel socket has no input function */
        nlk = nlk_sk(sock);
-       if (nlk->pid == 0 && !nlk->data_ready) {
+       if ((nlk->pid == 0 && !nlk->data_ready) ||
+           (sock->sk_state == NETLINK_CONNECTED &&
+            nlk->dst_pid != nlk_sk(ssk)->pid)) {
                sock_put(sock);
                return ERR_PTR(-ECONNREFUSED);
        }
@@ -728,14 +732,14 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
           to corresponding kernel module.   --ANK (980802)
         */
 
-       err = security_netlink_send(skb);
-       if (err) {
+       err = -EFAULT;
+       if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
                kfree_skb(skb);
                goto out;
        }
 
-       err = -EFAULT;
-       if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
+       err = security_netlink_send(sk, skb);
+       if (err) {
                kfree_skb(skb);
                goto out;
        }