aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2014-05-30 14:04:00 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-02 19:34:09 -0400
commit2d7a85f4b06e9c27ff629f07a524c48074f07f81 (patch)
treeacc409ce12bfd86fad42fa50c4c693a74f9b9062 /net
parent22fd2a52f715550930938fc79140defc098287d6 (diff)
netlink: Only check file credentials for implicit destinations
It was possible to get a setuid root or setcap executable to write to it's stdout or stderr (which has been set made a netlink socket) and inadvertently reconfigure the networking stack. To prevent this we check that both the creator of the socket and the currentl applications has permission to reconfigure the network stack. Unfortunately this breaks Zebra which always uses sendto/sendmsg and creates it's socket without any privileges. To keep Zebra working don't bother checking if the creator of the socket has privilege when a destination address is specified. Instead rely exclusively on the privileges of the sender of the socket. Note from Andy: This is exactly Eric's code except for some comment clarifications and formatting fixes. Neither I nor, I think, anyone else is thrilled with this approach, but I'm hesitant to wait on a better fix since 3.15 is almost here. Note to stable maintainers: This is a mess. An earlier series of patches in 3.15 fix a rather serious security issue (CVE-2014-0181), but they did so in a way that breaks Zebra. The offending series includes: commit aa4cf9452f469f16cea8c96283b641b4576d4a7b Author: Eric W. Biederman <ebiederm@xmission.com> Date: Wed Apr 23 14:28:03 2014 -0700 net: Add variants of capable for use on netlink messages If a given kernel version is missing that series of fixes, it's probably worth backporting it and this patch. if that series is present, then this fix is critical if you care about Zebra. Cc: stable@vger.kernel.org Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Andy Lutomirski <luto@amacapital.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/netlink/af_netlink.c7
1 files changed, 6 insertions, 1 deletions
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)) {