From patchwork Tue Sep 8 23:17:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Zhou X-Patchwork-Id: 515635 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 7CA7F140180 for ; Wed, 9 Sep 2015 09:17:48 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 78B41106A2; Tue, 8 Sep 2015 16:17:47 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e4.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id C5360106A0 for ; Tue, 8 Sep 2015 16:17:46 -0700 (PDT) Received: from bar2.cudamail.com (unknown [192.168.21.12]) by mx1e4.cudamail.com (Postfix) with ESMTPS id 0A0A21E01E1 for ; Tue, 8 Sep 2015 17:17:46 -0600 (MDT) X-ASG-Debug-ID: 1441754264-03dc531aa0fdab0001-byXFYA Received: from mx1-pf2.cudamail.com ([192.168.24.2]) by bar2.cudamail.com with ESMTP id vWFftbUIFaf3Lsoc (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 08 Sep 2015 17:17:45 -0600 (MDT) X-Barracuda-Envelope-From: azhou@nicira.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.2 Received: from unknown (HELO mail-pa0-f51.google.com) (209.85.220.51) by mx1-pf2.cudamail.com with ESMTPS (RC4-SHA encrypted); 8 Sep 2015 23:17:44 -0000 Received-SPF: unknown (mx1-pf2.cudamail.com: Multiple SPF records returned) X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.51 Received: by pacex6 with SMTP id ex6so136923287pac.0 for ; Tue, 08 Sep 2015 16:17:43 -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; bh=JhZOhb/ejxTE/CWQPPKIe8urgv9OOgx+3UvS3kUbU1M=; b=TD2zOVfcHkm9mCRUKuH6MaHVVFBXvDcrD6WEN+mkrDNk1SqkxKlmw3SFr4bzYNUOj1 MTnjBq8BXdOdGoMtClHWYLci/XgmeX5shqCsvJTtQwlINrThmbAV6dxKCVpqMQC0OWmS fgO6zXY1f97s6QdUm26jyeEjfnQlNMrF8Fxp+JxBtt/D/QSs3j1iDnlHZrHVUGixQ9lg htKPq5RksjS08ngmsG+oaXFgEfbOT7TVIXvfhivjcRrpOPE9fmZsUZSovw9nNWA2WhQU U1FrC3ENfjD0dfE+0WQXbLH87pkQsMlHUhkj/2SiLFWUacoZ+0P6UDUwgs9t6qAUPKVj XdxA== X-Gm-Message-State: ALoCoQmuLaKN43nMFDgPWg8UzHjQ+OMJRJfydYfakbEUHu6LsHkNOtRjsNJRfF/hUFfxjSYokSEV X-Received: by 10.66.141.141 with SMTP id ro13mr54730798pab.68.1441754263576; Tue, 08 Sep 2015 16:17:43 -0700 (PDT) Received: from localhost.localdomain ([208.91.2.3]) by smtp.gmail.com with ESMTPSA id bh16sm4676907pdb.67.2015.09.08.16.17.42 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 08 Sep 2015 16:17:42 -0700 (PDT) X-CudaMail-Envelope-Sender: azhou@nicira.com X-Barracuda-Apparent-Source-IP: 208.91.2.3 From: Andy Zhou To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-E2-907102625 X-CudaMail-DTE: 090815 X-CudaMail-Originating-IP: 209.85.220.51 Date: Tue, 8 Sep 2015 16:17:36 -0700 X-ASG-Orig-Subj: [##CM-E2-907102625##][v2 1/3] lib: add function to switch daemon user at run time Message-Id: <1441754258-9868-1-git-send-email-azhou@nicira.com> X-Mailer: git-send-email 1.9.1 X-Barracuda-Connect: UNKNOWN[192.168.24.2] X-Barracuda-Start-Time: 1441754265 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] [v2 1/3] lib: add function to switch daemon user at run time 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" Added function to drop daemon's root privileges at run time by allowing it to run as a different user. Daemon can still start running as root. Each daemon's implementation can invoke this function when it is ready to drop the root privilege. Future patch will make use of this function. Signed-off-by: Andy Zhou --- v2 : fix typos and white spaces --- lib/daemon-unix.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- lib/daemon.h | 9 ++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/lib/daemon-unix.c b/lib/daemon-unix.c index eb95521..4a2e7b4 100644 --- a/lib/daemon-unix.c +++ b/lib/daemon-unix.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2015 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ #include "daemon-private.h" #include #include +#include #include #include #include @@ -64,6 +65,13 @@ static int daemonize_fd = -1; * it dies due to an error signal? */ static bool monitor; +/* --user: Only root can use this option. Switch to new uid:gid after + * initially running as root. */ +static bool switch_to_new_user = false; +static uid_t uid; +static gid_t gid; +static char *user = NULL; + static void check_already_running(void); static int lock_pidfile(FILE *, int command); static pid_t fork_and_clean_up(void); @@ -684,3 +692,43 @@ should_service_stop(void) { return false; } + +void +daemon_become_new_user(void) +{ + if (switch_to_new_user) { + /* "Setuid Demystified" by Hao Chen, etc outlines some caveats of + * around unix system call setuid() and friends. This implementation + * mostly follow the advice given by the paper. The paper is + * published in 2002, so things could have changed. + */ + + /* Change both real and effective uid and gid will permanently + * drop the process' privilege. "Setuid Demystified" suggested + * that calling getuid() after each setuid() call to verify they + * are actually set, because checking return code alone is not + * sufficient. + * + * Linux also has per process file system uid, i.e. fsuid. Without + * explicitly setting it, it follows the process' effective uid. + * This implementation does not explicitly set fsuid for better + * portability. (Although setresuid() is not available on Solaris, + * according to the paper above.) */ + + if (setregid(gid, gid) == -1 || getgid() != gid || getegid() != gid) { + VLOG_FATAL("%s: fail to switch group to gid as %d, aborting", + pidfile, gid); + } + + if (user && initgroups(user, gid) == -1) { + VLOG_FATAL("%s: fail to add supplementary group gid %d, aborting", + pidfile, gid); + } + + /* Change both real and effective uid and make sure they are set. */ + if (setreuid(uid, uid) == -1 || getuid() != uid || geteuid() != uid) { + VLOG_FATAL("%s: fail to switch to user %s, aborting", + pidfile, user); + } + } +} diff --git a/lib/daemon.h b/lib/daemon.h index 959341d..ccf30f8 100644 --- a/lib/daemon.h +++ b/lib/daemon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2015 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,6 +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); pid_t read_pidfile(const char *name); #else #define DAEMON_OPTION_ENUMS \ @@ -117,6 +118,12 @@ pid_t read_pidfile(const char *name); void control_handler(DWORD request); void set_pipe_handle(const char *pipe_handle); + +static inline void +daemon_become_new_user(void) +{ + /* Not implemented. */ +} #endif /* _WIN32 */ bool get_detach(void);