From patchwork Fri Jul 25 08:22:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Yufen X-Patchwork-Id: 373608 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 2DFC81400A0 for ; Fri, 25 Jul 2014 18:24:41 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759925AbaGYIYg (ORCPT ); Fri, 25 Jul 2014 04:24:36 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:35719 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759919AbaGYIYd (ORCPT ); Fri, 25 Jul 2014 04:24:33 -0400 Received: from 172.24.2.119 (EHLO szxeml421-hub.china.huawei.com) ([172.24.2.119]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id ASB58026; Fri, 25 Jul 2014 16:24:23 +0800 (CST) Received: from localhost (10.177.25.231) by szxeml421-hub.china.huawei.com (10.82.67.160) with Microsoft SMTP Server id 14.3.158.1; Fri, 25 Jul 2014 16:24:16 +0800 From: Wangyufen To: CC: , "Eric W. Biederman" , , Andy Lutomirski , Wang Yufen Subject: [PATCH v2 8/8] netlink: Only check file credentials for implicit destinations Date: Fri, 25 Jul 2014 16:22:29 +0800 Message-ID: <1406276549-6616-9-git-send-email-wangyufen@huawei.com> X-Mailer: git-send-email 1.8.1.msysgit.1 In-Reply-To: <1406276549-6616-1-git-send-email-wangyufen@huawei.com> References: <1406276549-6616-1-git-send-email-wangyufen@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.25.231] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020208.53D21438.00FB,ss=1,re=0.000,fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2011-05-27 18:58:46 X-Mirapoint-Loop-Id: 2599eb021b73b014ee3f601e4b95f637 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: "Eric W. Biederman" 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 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" Signed-off-by: Andy Lutomirski Signed-off-by: David S. Miller Signed-off-by: Wang Yufen --- include/linux/netlink.h | 3 ++- net/netlink/af_netlink.c | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index f4b56b7..dbf29e5 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -166,9 +166,10 @@ struct netlink_skb_parms { struct ucred creds; /* Skb credentials */ __u32 pid; __u32 dst_group; + __u32 flags; struct sock *ssk; }; - +#define NETLINK_SKB_DST 0x8 /* Dst set in sendto or sendmsg */ #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) #define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 41d345b..231249e 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -603,7 +603,9 @@ retry: bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, struct user_namespace *user_ns, int cap) { - return sk_ns_capable(nsp->ssk, user_ns, cap); + return ((nsp->flags & NETLINK_SKB_DST) || + file_ns_capable(nsp->ssk->sk_socket->file, user_ns, cap)) && + ns_capable(user_ns, cap); } EXPORT_SYMBOL(__netlink_ns_capable); @@ -1402,6 +1404,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; @@ -1423,6 +1426,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, if ((dst_group || dst_pid) && !netlink_allowed(sock, NL_NONROOT_SEND)) goto out; + netlink_skb_flags |= NETLINK_SKB_DST; } else { dst_pid = nlk->dst_pid; dst_group = nlk->dst_group; @@ -1444,6 +1448,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, NETLINK_CB(skb).pid = nlk->pid; NETLINK_CB(skb).dst_group = dst_group; + NETLINK_CB(skb).flags = netlink_skb_flags; memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); err = -EFAULT;