Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux-2.6-block.git] / net / netlink / af_netlink.c
index e0ccd84d4d6781ab761349e0ac913f6ddc3e8994..15c731f03fa664a64f7bf3cdde36cf1a8e4150b6 100644 (file)
@@ -1377,7 +1377,9 @@ retry:
 bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
                        struct user_namespace *user_ns, int cap)
 {
-       return sk_ns_capable(nsp->sk, user_ns, cap);
+       return ((nsp->flags & NETLINK_SKB_DST) ||
+               file_ns_capable(nsp->sk->sk_socket->file, user_ns, cap)) &&
+               ns_capable(user_ns, cap);
 }
 EXPORT_SYMBOL(__netlink_ns_capable);
 
@@ -2323,6 +2325,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct sk_buff *skb;
        int err;
        struct scm_cookie scm;
+       u32 netlink_skb_flags = 0;
 
        if (msg->msg_flags&MSG_OOB)
                return -EOPNOTSUPP;
@@ -2344,6 +2347,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
                if ((dst_group || dst_portid) &&
                    !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
                        goto out;
+               netlink_skb_flags |= NETLINK_SKB_DST;
        } else {
                dst_portid = nlk->dst_portid;
                dst_group = nlk->dst_group;
@@ -2373,6 +2377,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
        NETLINK_CB(skb).portid  = nlk->portid;
        NETLINK_CB(skb).dst_group = dst_group;
        NETLINK_CB(skb).creds   = siocb->scm->creds;
+       NETLINK_CB(skb).flags   = netlink_skb_flags;
 
        err = -EFAULT;
        if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {