From owner-p4-projects@FreeBSD.ORG Wed Jun 10 21:34:12 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3E9AB1065702; Wed, 10 Jun 2009 21:34:12 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EF1301065700 for ; Wed, 10 Jun 2009 21:34:11 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id D2A748FC12 for ; Wed, 10 Jun 2009 21:34:11 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5ALYBEW078286 for ; Wed, 10 Jun 2009 21:34:11 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5ALYBa9078284 for perforce@freebsd.org; Wed, 10 Jun 2009 21:34:11 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Wed, 10 Jun 2009 21:34:11 GMT Message-Id: <200906102134.n5ALYBa9078284@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Cc: Subject: PERFORCE change 164051 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Jun 2009 21:34:13 -0000 http://perforce.freebsd.org/chv.cgi?CH=164051 Change 164051 by rwatson@rwatson_freebsd_capabilities on 2009/06/10 21:34:04 Add lch_start_flags(), a version of lch_start() that accepts a flags field. Define flag LCH_PERMIT_STDERR, which allows the sandboxed process to write to stderr (normally STERR_FILENO is hooked up to /dev/null for sandboxes). Pass libcapability.so.1 into sandboxes. Fix parsing of socket number from LIBCAPABILITY_SANDBOX_API_ENV so that host<->sandbox communications work. Affected files ... .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#9 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#7 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_sandbox.c#3 edit Differences ... ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#9 (text+ko) ==== @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#8 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#9 $ */ #ifndef _LIBCAPABILITY_H_ @@ -49,9 +49,16 @@ */ int lch_start(const char *sandbox, char *const argv[], struct lc_sandbox **lcspp); +int lch_start_flags(const char *sandbox, char *const argv[], u_int flags, + struct lc_sandbox **lcspp); void lch_stop(struct lc_sandbox *lcsp); /* + * Flags to lch_start_flags: + */ +#define LCH_PERMIT_STDERR 0x00000001 + +/* * Interfaces to query state about capability mode sandboxs. */ int lch_getsock(struct lc_sandbox *lcsp, int *fdp); ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#7 (text+ko) ==== @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#6 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#7 $ */ #include @@ -58,11 +58,14 @@ #define LIBCAPABILITY_CAPMASK_SANDBOX LIBCAPABILITY_CAPMASK_BIN #define LIBCAPABILITY_CAPMASK_LDSO LIBCAPABILITY_CAPMASK_BIN #define LIBCAPABILITY_CAPMASK_LIBC LIBCAPABILITY_CAPMASK_BIN +#define LIBCAPABILITY_CAPMASK_LIBCAPABILITY LIBCAPABILITY_CAPMASK_BIN #define LIBCAPABILITY_CAPMASK_LIBZ LIBCAPABILITY_CAPMASK_BIN #define _PATH_LIB "/lib" +#define _PATH_USR_LIB "/usr/lib" #define LIBC_SO "libc.so.7" #define LIBZ_SO "libz.so.4" +#define LIBCAPABILITY_SO "libcapability.so.1" extern char **environ; @@ -140,7 +143,7 @@ static void lch_sandbox(int fd_sock, int fd_sandbox, int fd_ldso, int fd_libc, - int fd_libz, char *const argv[]) + int fd_libz, int fd_libcapability, u_int flags, char *const argv[]) { char *env_caplibindex, *env_libcapability_sandbox_api; int fd_array[8], fd_devnull; @@ -161,24 +164,33 @@ return; if (lc_limitfd(fd_libz, LIBCAPABILITY_CAPMASK_LIBZ) < 0) return; + if (lc_limitfd(fd_libcapability, LIBCAPABILITY_CAPMASK_LIBCAPABILITY) + < 0) + return; fd_array[0] = fd_devnull; fd_array[1] = fd_devnull; - fd_array[2] = fd_devnull; + if (flags & LCH_PERMIT_STDERR) { + if (lc_limitfd(STDERR_FILENO, CAP_SEEK | CAP_WRITE) < 0) + return; + fd_array[2] = STDERR_FILENO; + } else + fd_array[2] = fd_devnull; fd_array[3] = fd_sandbox; fd_array[4] = fd_sock; fd_array[5] = fd_ldso; fd_array[6] = fd_libc; fd_array[7] = fd_libz; + fd_array[8] = fd_libcapability; - if (lch_installfds(8, fd_array) < 0) + if (lch_installfds(9, fd_array) < 0) return; /* * Pass library list into rtld-elf-cap. */ - if (asprintf(&env_caplibindex, "%d:%s,%d:%s", 6, LIBC_SO, 7, - LIBZ_SO) == -1) + if (asprintf(&env_caplibindex, "%d:%s,%d:%s,%d:%s", 6, LIBC_SO, 7, + LIBZ_SO, 8, LIBCAPABILITY_SO) == -1) return; if (setenv("LD_CAPLIBINDEX", env_caplibindex, 1) == -1) return; @@ -203,16 +215,17 @@ } int -lch_start(const char *sandbox, char *const argv[], struct lc_sandbox **lcapp) +lch_start_flags(const char *sandbox, char *const argv[], u_int flags, + struct lc_sandbox **lcapp) { struct lc_sandbox *lcap; - int fd_sandbox, fd_ldso, fd_libc, fd_libz, fd_procdesc; - int fd_sockpair[2]; + int fd_sandbox, fd_ldso, fd_libc, fd_libcapability, fd_libz; + int fd_procdesc, fd_sockpair[2]; int error, val; pid_t pid; - fd_sandbox = fd_ldso = fd_libc = fd_libz = fd_procdesc = - fd_sockpair[0] = fd_sockpair[1] = -1; + fd_sandbox = fd_ldso = fd_libc = fd_libz = fd_libcapability = + fd_procdesc = fd_sockpair[0] = fd_sockpair[1] = -1; lcap = malloc(sizeof(*lcap)); if (lcap == NULL) @@ -236,6 +249,11 @@ if (fd_libz < 0) goto out_error; + fd_libcapability = open(_PATH_USR_LIB "/" LIBCAPABILITY_SO, + O_RDONLY); + if (fd_libcapability < 0) + goto out_error; + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd_sockpair) < 0) goto out_error; @@ -253,9 +271,10 @@ } if (pid == 0) { lch_sandbox(fd_sockpair[1], fd_sandbox, fd_ldso, fd_libc, - fd_libz, argv); + fd_libz, fd_libcapability, flags, argv); exit(-1); } + close(fd_libcapability); close(fd_libz); close(fd_libc); close(fd_ldso); @@ -275,6 +294,8 @@ close(fd_sockpair[0]); if (fd_sockpair[1] != -1) close(fd_sockpair[1]); + if (fd_libcapability != -1) + close(fd_libcapability); if (fd_libz != -1) close(fd_libz); if (fd_libc != -1) @@ -289,6 +310,13 @@ return (-1); } +int +lch_start(const char *sandbox, char *const argv[], struct lc_sandbox **lcapp) +{ + + return (lch_start_flags(sandbox, argv, 0, lcapp)); +} + void lch_stop(struct lc_sandbox *lcap) { ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_sandbox.c#3 (text+ko) ==== @@ -57,8 +57,8 @@ lcs_get(struct lc_host **lchpp) { char *endp, *env, *env_dup, *env_dup_free, *name, *token, *value; + int error, fd_sock; long long ll; - int fd_sock; if (lch_initialized) { *lchpp = &lch_global; @@ -77,10 +77,10 @@ fd_sock = -1; while ((token = strsep(&env_dup, ",")) != NULL) { - name = token; - value = strsep(&token, ":"); - if (value == NULL) + name = strsep(&token, ":"); + if (name == NULL) continue; + value = token; if (strcmp(name, LIBCAPABILITY_SANDBOX_API_SOCK) == 0) { ll = strtoll(value, &endp, 10); if (*endp != '\0' || ll < 0 || ll > INT_MAX) @@ -88,6 +88,12 @@ fd_sock = ll; } } + if (fd_sock == -1) { + error = errno; + free(env_dup_free); + errno = error; + return (-1); + } lch_global.lch_fd_sock = fd_sock; lch_initialized = 1; *lchpp = &lch_global;