aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netlink.h7
-rw-r--r--net/netlink/af_netlink.c7
2 files changed, 10 insertions, 4 deletions
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index f64b01787ddc..034cda789a15 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -16,9 +16,10 @@ static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb)
16} 16}
17 17
18enum netlink_skb_flags { 18enum netlink_skb_flags {
19 NETLINK_SKB_MMAPED = 0x1, /* Packet data is mmaped */ 19 NETLINK_SKB_MMAPED = 0x1, /* Packet data is mmaped */
20 NETLINK_SKB_TX = 0x2, /* Packet was sent by userspace */ 20 NETLINK_SKB_TX = 0x2, /* Packet was sent by userspace */
21 NETLINK_SKB_DELIVERED = 0x4, /* Packet was delivered */ 21 NETLINK_SKB_DELIVERED = 0x4, /* Packet was delivered */
22 NETLINK_SKB_DST = 0x8, /* Dst set in sendto or sendmsg */
22}; 23};
23 24
24struct netlink_skb_parms { 25struct netlink_skb_parms {
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 81dca96d2be6..f22757a29cd0 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1373,7 +1373,9 @@ retry:
1373bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, 1373bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
1374 struct user_namespace *user_ns, int cap) 1374 struct user_namespace *user_ns, int cap)
1375{ 1375{
1376 return sk_ns_capable(nsp->sk, user_ns, cap); 1376 return ((nsp->flags & NETLINK_SKB_DST) ||
1377 file_ns_capable(nsp->sk->sk_socket->file, user_ns, cap)) &&
1378 ns_capable(user_ns, cap);
1377} 1379}
1378EXPORT_SYMBOL(__netlink_ns_capable); 1380EXPORT_SYMBOL(__netlink_ns_capable);
1379 1381
@@ -2293,6 +2295,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
2293 struct sk_buff *skb; 2295 struct sk_buff *skb;
2294 int err; 2296 int err;
2295 struct scm_cookie scm; 2297 struct scm_cookie scm;
2298 u32 netlink_skb_flags = 0;
2296 2299
2297 if (msg->msg_flags&MSG_OOB) 2300 if (msg->msg_flags&MSG_OOB)
2298 return -EOPNOTSUPP; 2301 return -EOPNOTSUPP;
@@ -2314,6 +2317,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
2314 if ((dst_group || dst_portid) && 2317 if ((dst_group || dst_portid) &&
2315 !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) 2318 !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
2316 goto out; 2319 goto out;
2320 netlink_skb_flags |= NETLINK_SKB_DST;
2317 } else { 2321 } else {
2318 dst_portid = nlk->dst_portid; 2322 dst_portid = nlk->dst_portid;
2319 dst_group = nlk->dst_group; 2323 dst_group = nlk->dst_group;
@@ -2343,6 +2347,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
2343 NETLINK_CB(skb).portid = nlk->portid; 2347 NETLINK_CB(skb).portid = nlk->portid;
2344 NETLINK_CB(skb).dst_group = dst_group; 2348 NETLINK_CB(skb).dst_group = dst_group;
2345 NETLINK_CB(skb).creds = siocb->scm->creds; 2349 NETLINK_CB(skb).creds = siocb->scm->creds;
2350 NETLINK_CB(skb).flags = netlink_skb_flags;
2346 2351
2347 err = -EFAULT; 2352 err = -EFAULT;
2348 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { 2353 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {