From owner-svn-src-stable@FreeBSD.ORG Sun Jul 3 16:54:27 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E4991106564A; Sun, 3 Jul 2011 16:54:27 +0000 (UTC) (envelope-from trociny@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D1B188FC0A; Sun, 3 Jul 2011 16:54:27 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p63GsR79026477; Sun, 3 Jul 2011 16:54:27 GMT (envelope-from trociny@svn.freebsd.org) Received: (from trociny@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p63GsRWS026471; Sun, 3 Jul 2011 16:54:27 GMT (envelope-from trociny@svn.freebsd.org) Message-Id: <201107031654.p63GsRWS026471@svn.freebsd.org> From: Mikolaj Golub Date: Sun, 3 Jul 2011 16:54:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r223743 - in stable/8/sbin: hastctl hastd X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Jul 2011 16:54:28 -0000 Author: trociny Date: Sun Jul 3 16:54:27 2011 New Revision: 223743 URL: http://svn.freebsd.org/changeset/base/223743 Log: MFC r219847, r221898, r221899, r222224, r223584, r223585: r219847 (pjd): When dropping privileges prefer capsicum over chroot+setgid+setuid. We can use capsicum for secondary worker processes and hastctl. When working as primary we drop privileges using chroot+setgid+setuid still as we need to send ioctl(2)s to ggate device, for which capsicum doesn't allow (yet). r221898 (pjd): When using capsicum to sanbox, still use other methods first, just in case one of them have some problems. r221899 (pjd): Currently we are unable to use capsicum for the primary worker process, because we need to do ioctl(2)s, which are not permitted in the capability mode. What we do now is to chroot(2) to /var/empty, which restricts access to file system name space and we drop privileges to hast user and hast group. This still allows to access to other name spaces, like list of processes, network and sysvipc. To address that, use jail(2) instead of chroot(2). Using jail(2) will restrict access to process table, network (we use ip-less jails) and sysvipc (if security.jail.sysvipc_allowed is turned off). This provides much better separation. r222224 (pjd): To handle BIO_FLUSH and BIO_DELETE requests in secondary worker we need to use ioctl(2). This is why we can't use capsicum for now to sandbox secondary. Capsicum is still used to sandbox hastctl. r223584 (pjd): Log a warning if we cannot sandbox using capsicum, but only under debug level 1. It would be too noisy to log it as a proper warning as CAPABILITIES are not compiled into GENERIC by default. r223585 (pjd): Compile capsicum support only if HAVE_CAPSICUM is defined. Approved by: pjd (mentor) Modified: stable/8/sbin/hastctl/hastctl.c stable/8/sbin/hastd/primary.c stable/8/sbin/hastd/secondary.c stable/8/sbin/hastd/subr.c stable/8/sbin/hastd/subr.h Directory Properties: stable/8/sbin/hastctl/ (props changed) stable/8/sbin/hastd/ (props changed) Modified: stable/8/sbin/hastctl/hastctl.c ============================================================================== --- stable/8/sbin/hastctl/hastctl.c Sun Jul 3 16:32:03 2011 (r223742) +++ stable/8/sbin/hastctl/hastctl.c Sun Jul 3 16:54:27 2011 (r223743) @@ -491,9 +491,8 @@ main(int argc, char *argv[]) cfg->hc_controladdr); } - if (drop_privs() != 0) + if (drop_privs(NULL) != 0) exit(EX_CONFIG); - pjdlog_debug(1, "Privileges successfully dropped."); /* Send the command to the server... */ if (hast_proto_send(NULL, controlconn, nv, NULL, 0) < 0) { Modified: stable/8/sbin/hastd/primary.c ============================================================================== --- stable/8/sbin/hastd/primary.c Sun Jul 3 16:32:03 2011 (r223742) +++ stable/8/sbin/hastd/primary.c Sun Jul 3 16:54:27 2011 (r223743) @@ -906,7 +906,7 @@ hastd_primary(struct hast_resource *res) init_ggate(res); init_environment(res); - if (drop_privs() != 0) { + if (drop_privs(res) != 0) { cleanup(res); exit(EX_CONFIG); } Modified: stable/8/sbin/hastd/secondary.c ============================================================================== --- stable/8/sbin/hastd/secondary.c Sun Jul 3 16:32:03 2011 (r223742) +++ stable/8/sbin/hastd/secondary.c Sun Jul 3 16:54:27 2011 (r223743) @@ -440,7 +440,7 @@ hastd_secondary(struct hast_resource *re init_local(res); init_environment(); - if (drop_privs() != 0) + if (drop_privs(res) != 0) exit(EX_CONFIG); pjdlog_info("Privileges successfully dropped."); Modified: stable/8/sbin/hastd/subr.c ============================================================================== --- stable/8/sbin/hastd/subr.c Sun Jul 3 16:32:03 2011 (r223742) +++ stable/8/sbin/hastd/subr.c Sun Jul 3 16:54:27 2011 (r223743) @@ -31,15 +31,20 @@ #include __FBSDID("$FreeBSD$"); -#include +#ifdef HAVE_CAPSICUM +#include +#endif +#include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -145,12 +150,15 @@ role2str(int role) } int -drop_privs(void) +drop_privs(struct hast_resource *res) { + char jailhost[sizeof(res->hr_name) * 2]; + struct jail jailst; struct passwd *pw; uid_t ruid, euid, suid; gid_t rgid, egid, sgid; gid_t gidset[1]; + bool capsicum, jailed; /* * According to getpwnam(3) we have to clear errno before calling the @@ -170,10 +178,34 @@ drop_privs(void) return (-1); } } - if (chroot(pw->pw_dir) == -1) { - KEEP_ERRNO(pjdlog_errno(LOG_ERR, - "Unable to change root directory to %s", pw->pw_dir)); - return (-1); + + bzero(&jailst, sizeof(jailst)); + jailst.version = JAIL_API_VERSION; + jailst.path = pw->pw_dir; + if (res == NULL) { + (void)snprintf(jailhost, sizeof(jailhost), "hastctl"); + } else { + (void)snprintf(jailhost, sizeof(jailhost), "hastd: %s (%s)", + res->hr_name, role2str(res->hr_role)); + } + jailst.hostname = jailhost; + jailst.jailname = NULL; + jailst.ip4s = 0; + jailst.ip4 = NULL; + jailst.ip6s = 0; + jailst.ip6 = NULL; + if (jail(&jailst) >= 0) { + jailed = true; + } else { + jailed = false; + pjdlog_errno(LOG_WARNING, + "Unable to jail to directory to %s", pw->pw_dir); + if (chroot(pw->pw_dir) == -1) { + KEEP_ERRNO(pjdlog_errno(LOG_ERR, + "Unable to change root directory to %s", + pw->pw_dir)); + return (-1); + } } PJDLOG_VERIFY(chdir("/") == 0); gidset[0] = pw->pw_gid; @@ -195,6 +227,23 @@ drop_privs(void) } /* + * Until capsicum doesn't allow ioctl(2) we cannot use it to sandbox + * primary and secondary worker processes, as primary uses GGATE + * ioctls and secondary uses ioctls to handle BIO_DELETE and BIO_FLUSH. + * For now capsicum is only used to sandbox hastctl. + */ +#ifdef HAVE_CAPSICUM + if (res == NULL) { + capsicum = (cap_enter() == 0); + if (!capsicum) { + pjdlog_common(LOG_DEBUG, 1, errno, + "Unable to sandbox using capsicum"); + } + } else +#endif + capsicum = false; + + /* * Better be sure that everything succeeded. */ PJDLOG_VERIFY(getresuid(&ruid, &euid, &suid) == 0); @@ -209,5 +258,9 @@ drop_privs(void) PJDLOG_VERIFY(getgroups(1, gidset) == 1); PJDLOG_VERIFY(gidset[0] == pw->pw_gid); + pjdlog_debug(1, + "Privileges successfully dropped using %s%s+setgid+setuid.", + capsicum ? "capsicum+" : "", jailed ? "jail" : "chroot"); + return (0); } Modified: stable/8/sbin/hastd/subr.h ============================================================================== --- stable/8/sbin/hastd/subr.h Sun Jul 3 16:32:03 2011 (r223742) +++ stable/8/sbin/hastd/subr.h Sun Jul 3 16:54:27 2011 (r223743) @@ -51,6 +51,6 @@ int snprlcat(char *str, size_t size, con int provinfo(struct hast_resource *res, bool dowrite); const char *role2str(int role); -int drop_privs(void); +int drop_privs(struct hast_resource *res); #endif /* !_SUBR_H_ */