From patchwork Mon Sep 14 22:54:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Zhou X-Patchwork-Id: 517605 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (li376-54.members.linode.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3999014012C for ; Tue, 15 Sep 2015 08:54:43 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 307B21090C; Mon, 14 Sep 2015 15:54:34 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 9A78C10907 for ; Mon, 14 Sep 2015 15:54:32 -0700 (PDT) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id E998A420391 for ; Mon, 14 Sep 2015 16:54:31 -0600 (MDT) X-ASG-Debug-ID: 1442271271-09eadd48f81104a0001-byXFYA Received: from mx1-pf2.cudamail.com ([192.168.24.2]) by bar5.cudamail.com with ESMTP id jKBG5dyBygnfPSWI (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 14 Sep 2015 16:54:31 -0600 (MDT) X-Barracuda-Envelope-From: azhou@nicira.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.2 Received: from unknown (HELO mail-pa0-f52.google.com) (209.85.220.52) by mx1-pf2.cudamail.com with ESMTPS (RC4-SHA encrypted); 14 Sep 2015 22:54:31 -0000 Received-SPF: unknown (mx1-pf2.cudamail.com: Multiple SPF records returned) X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.52 Received: by padhk3 with SMTP id hk3so155854206pad.3 for ; Mon, 14 Sep 2015 15:54:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KRlm+OXVun2rBx66OKjAYUA7SMCpi4z/Sdv82dBZ2Iw=; b=eooTxmjBOZ9Soi7HiDfU6240d12ANJwUI95ODCdR1QjSTWubrk3mkzptxgVt6289IL xJ0+O0RmqInHWck/kx20TW3FfJIwVm4UHxsC88UNyt6k5X1FNSZveQ/ZdDF+Dbaq3Xzz qCzBWxZ+8pbZpQPjlxPzJUmPCcS1L124MWKjIgSxYtWpA+Y6DPp0Gbb5lUn2MuetCi5D +C+jK1W4piVPVHPRO34rzmvbUbGPxryzw6k3U72uT1s6ZCG0zsPJasePpsF7oJXeVKIc spQTrJysCJOTpAzMhVtFK2CMIsNmcXcCdeq2sHrxOsTm3NvOtkpwTxweHsXn10CTeXB7 b/IA== X-Gm-Message-State: ALoCoQmANL1Nd/KjuP15+sMygGY3cIq2vCSk6ZE20AUid2hHyH8HXq8MYWBkZ9IDvxQb+gIbUFSx X-Received: by 10.68.254.136 with SMTP id ai8mr39679752pbd.98.1442271270329; Mon, 14 Sep 2015 15:54:30 -0700 (PDT) Received: from ubuntu.localdomain ([208.91.1.34]) by smtp.gmail.com with ESMTPSA id ox2sm18121426pbb.87.2015.09.14.15.54.29 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 14 Sep 2015 15:54:29 -0700 (PDT) X-CudaMail-Envelope-Sender: azhou@nicira.com X-Barracuda-Apparent-Source-IP: 208.91.1.34 From: Andy Zhou To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-E2-913097420 X-CudaMail-DTE: 091415 X-CudaMail-Originating-IP: 209.85.220.52 Date: Mon, 14 Sep 2015 15:54:07 -0700 X-ASG-Orig-Subj: [##CM-E2-913097420##][v3 03/10] lib/daemon: add option to retain CAP_NET_ADMIN capability Message-Id: <1442271254-27897-4-git-send-email-azhou@nicira.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1442271254-27897-1-git-send-email-azhou@nicira.com> References: <1442271254-27897-1-git-send-email-azhou@nicira.com> X-Barracuda-Connect: UNKNOWN[192.168.24.2] X-Barracuda-Start-Time: 1442271271 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [v3 03/10] lib/daemon: add option to retain CAP_NET_ADMIN capability X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" This patch adds an argument to daemon_become_new_user() API for the caller specify whether the capability of accessing the kernel datapath is needed. On Linux, daemons access the kernel datapath need to retain some root privileges, such as CAP_NET_ADMIN. Current implementation (of retaining CAP_NET_ADMIN) requires libcap-ng. This implementation only covers the Linux. Other Unix platforms currently do not support kernel based datapath. (but supports --user options for all daemons.) On Windows, daemon_become_new_user() is a stub function that does nothing. Signed-off-by: Andy Zhou --- lib/daemon-unix.c | 38 +++++++++++++++++++++++++++++++++++--- lib/daemon.h | 5 ++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/lib/daemon-unix.c b/lib/daemon-unix.c index f175037..f361165 100644 --- a/lib/daemon-unix.c +++ b/lib/daemon-unix.c @@ -27,6 +27,9 @@ #include #include #include +#if HAVE_LIBCAPNG +#include +#endif #include "command-line.h" #include "fatal-signal.h" #include "dirs.h" @@ -748,8 +751,28 @@ daemon_switch_user(const uid_t real, const uid_t effective, const uid_t saved, } } +static void +daemon_become_new_user_with_datapath_capability(void) +{ +#if HAVE_LIBCAPNG + if (capng_have_capabilities(CAPNG_SELECT_CAPS) > CAPNG_NONE) { + capng_clear(CAPNG_SELECT_BOTH); + capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, + CAP_NET_ADMIN); + if (capng_change_id(uid, gid, + CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING)) { + VLOG_FATAL("%s: libcap-ng fail to switch to user and group " + "%d:%d, aborting", pidfile, uid, gid); + } + } +#else + VLOG_FATAL("%s: fail to downgrade user using libcap-ng. (libcap-ng is " + "not configured at compile time.) aborting", pidfile); +#endif +} + void -daemon_become_new_user(void) +daemon_become_new_user(bool access_kernel_datapath) { /* "Setuid Demystified" by Hao Chen, etc outlines some caveats of * around unix system call setuid() and friends. This implementation @@ -769,11 +792,20 @@ daemon_become_new_user(void) * according to the paper above.) */ if (switch_to_new_user) { + + if (access_kernel_datapath) { + daemon_become_new_user_with_datapath_capability(); + return; + } + + /* Using more portable APIs to switch uid:gid, when datapath + * access is not required. On Linux systems, all capabilities + * will be dropped. */ daemon_switch_group(gid, gid, gid); if (user && initgroups(user, gid) == -1) { - VLOG_FATAL("%s: fail to add supplementary group gid %d, aborting", - pidfile, gid); + VLOG_FATAL("%s: fail to add supplementary group gid %d, " + "aborting", pidfile, gid); } daemon_switch_user(uid, uid, uid, user); } diff --git a/lib/daemon.h b/lib/daemon.h index fdd7b6a..f98ef16 100644 --- a/lib/daemon.h +++ b/lib/daemon.h @@ -76,7 +76,7 @@ void set_detach(void); void daemon_set_monitor(void); void set_no_chdir(void); void ignore_existing_pidfile(void); -void daemon_become_new_user(void); +void daemon_become_new_user(bool access_kernel_datapath); pid_t read_pidfile(const char *name); #else #define DAEMON_OPTION_ENUMS \ @@ -120,11 +120,10 @@ void control_handler(DWORD request); void set_pipe_handle(const char *pipe_handle); static inline void -daemon_become_new_user(void) +daemon_become_new_user(bool access_kernel_datapath OVS_UNUSED) { /* Not implemented. */ } - #endif /* _WIN32 */ bool get_detach(void);