From owner-p4-projects@FreeBSD.ORG Fri Jun 12 14:48:28 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B4E6F106567C; Fri, 12 Jun 2009 14:48:28 +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 67F83106567A for ; Fri, 12 Jun 2009 14:48:28 +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 52F6F8FC40 for ; Fri, 12 Jun 2009 14:48:28 +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 n5CEmSZk081182 for ; Fri, 12 Jun 2009 14:48:28 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 n5CEmSf6081180 for perforce@freebsd.org; Fri, 12 Jun 2009 14:48:28 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Fri, 12 Jun 2009 14:48:28 GMT Message-Id: <200906121448.n5CEmSf6081180@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 164176 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: Fri, 12 Jun 2009 14:48:29 -0000 http://perforce.freebsd.org/chv.cgi?CH=164176 Change 164176 by rwatson@rwatson_freebsd_capabilities on 2009/06/12 14:48:05 Add lch_startfd() and lch_startfd_flags(), which accept a file descriptor instead of a path string for the binary to launch in a sandbox. Add a new variation on libcapability, libcapabilitym, which is intended for use in sandboxes. It shares the same code, but (a) doesn't expose the path-based sandbox start routines and (b) knows how to use rtld-elf-cap's library descriptor cache rather than the file system to load dependencies for sub-sandboxes. Update man pages. Affected files ... .. //depot/projects/trustedbsd/capabilities/src/lib/Makefile#7 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/Makefile#7 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.3#15 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#6 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#12 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#9 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapabilitym/Makefile#1 add Differences ... ==== //depot/projects/trustedbsd/capabilities/src/lib/Makefile#7 (text+ko) ==== @@ -32,7 +32,8 @@ ncurses ${_libnetgraph} libradius librpcsvc libsbuf \ libtacplus libutil ${_libypclnt} libalias libarchive ${_libatm} \ libbegemot ${_libbluetooth} ${_libbsnmp} libbz2 \ - libcalendar libcam libcapability libcompat libdevinfo libdevstat \ + libcalendar libcam libcapability libcapabilitym libcompat \ + libdevinfo libdevstat \ libdisk \ libdwarf libedit libexpat libfetch libftpio libgeom ${_libgpib} \ ${_libgssapi} ${_librpcsec_gss} libipsec \ ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/Makefile#7 (text+ko) ==== @@ -16,5 +16,6 @@ WARNS?= 6 MAN= libcapability.3 +MLINKS= libcapability.3 libcapabilitym.3 .include ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.3#15 (text+ko) ==== @@ -50,6 +50,10 @@ .Fn lch_start "const char *sandbox" "char *const argv[]" "struct lc_sandbox **lcsp" .Ft int .Fn lch_start_flags "const char *sandbox" "char *const argv[]" "u_int flags" "struct lc_sandbox **lcsp" +.Ft int +.Fn lch_startfd "int fd_sandbox" "char *const argv[]" "struct lc_sandbox **lcsp" +.Ft int +.Fn lch_startfd_flags "int fd_sandbox" "char *const argv[]" "u_int flags" "struct lc_sandbox **lcsp" .Ft void .Fn lch_stop "struct lc_sandbox *lcsp" .Ft int @@ -89,6 +93,29 @@ Applications may also use RPC generators such as .Xr rpcgen 1 to build event handling and marshaling code. +The +.Nm +library comes in two variations: +.Pp +.Nm libcapability +loads binaries, and supporting libraries, for sandboxes from the UNIX +filesystem namespace by path. +It implements four start functions: +.Fn lch_start , +.Fn lch_start_flags , +.Fn lch_startfd , +and +.Fn lch_startfd_flags . +.Pp +.Nm libcapabilitym +loads binaries, and supporting libraries, for sandboxes from the library +descriptor cache maintained by +.Xr rtld-elf-cap 1 +It implements only the two start functions accepting file descriptor +arguments: +.Fn lch_startfd , +and +.Fn lch_startfd_flags . .Sh CAPABILITY API .Fn lc_limitfd is a wrapper around @@ -127,6 +154,14 @@ .Dv stderr . By default, this is not permitted. .Pp +Two further variations to start sandboxes are also defined, +.Fn lch_startfd +and +.Fn lch_startfd_flags , +which accept a file descriptor argument, +.Va fd_sandbox , +rather than a path. +.Pp Executing sandboxes may be stopped (and all state freed) using .Fn lch_stop . Following a call to ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#6 (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.c#5 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#6 $ */ #include ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#12 (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#11 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#12 $ */ #ifndef _LIBCAPABILITY_H_ @@ -51,6 +51,10 @@ struct lc_sandbox **lcspp); int lch_start_flags(const char *sandbox, char *const argv[], u_int flags, struct lc_sandbox **lcspp); +int lch_startfd(int fd_sandbox, char *const argv[], + struct lc_sandbox **lcspp); +int lch_startfd_flags(int fd_sandbox, char *const argv[], u_int flags, + struct lc_sandbox **lcspp); void lch_stop(struct lc_sandbox *lcsp); /* ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#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_host.c#8 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#9 $ */ #include @@ -144,14 +144,11 @@ static void lch_sandbox(int fd_sock, int fd_sandbox, int fd_ldso, int fd_libc, - int fd_libz, int fd_libcapability, u_int flags, char *const argv[]) + int fd_libz, int fd_libcapability, int fd_devnull, u_int flags, + char *const argv[]) { char *env_caplibindex, *env_libcapability_sandbox_api; - int fd_array[8], fd_devnull; - - fd_devnull = open(_PATH_DEVNULL, O_RDWR); - if (fd_devnull < 0) - return; + int fd_array[10]; if (lc_limitfd(fd_devnull, LIBCAPABILITY_CAPMASK_DEVNULL) < 0) return; @@ -183,15 +180,16 @@ fd_array[6] = fd_libc; fd_array[7] = fd_libz; fd_array[8] = fd_libcapability; + fd_array[9] = fd_devnull; - if (lch_installfds(9, fd_array) < 0) + if (lch_installfds(10, fd_array) < 0) return; /* * Pass library list into rtld-elf-cap. */ - if (asprintf(&env_caplibindex, "%d:%s,%d:%s,%d:%s", 6, LIBC_SO, 7, - LIBZ_SO, 8, LIBCAPABILITY_SO) == -1) + if (asprintf(&env_caplibindex, "%d:%s,%d:%s,%d:%s,%d:%s", 6, LIBC_SO, + 7, LIBZ_SO, 8, LIBCAPABILITY_SO, 9, _PATH_DEVNULL) == -1) return; if (setenv("LD_CAPLIBINDEX", env_caplibindex, 1) == -1) return; @@ -216,16 +214,16 @@ } int -lch_start_flags(const char *sandbox, char *const argv[], u_int flags, +lch_startfd_flags(int fd_sandbox, char *const argv[], u_int flags, struct lc_sandbox **lcapp) { struct lc_sandbox *lcap; - int fd_sandbox, fd_ldso, fd_libc, fd_libcapability, fd_libz; + int fd_devnull, 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_libcapability = + fd_devnull = fd_ldso = fd_libc = fd_libz = fd_libcapability = fd_procdesc = fd_sockpair[0] = fd_sockpair[1] = -1; lcap = malloc(sizeof(*lcap)); @@ -233,11 +231,18 @@ return (-1); bzero(lcap, sizeof(*lcap)); - /* Try the sandbox first so that ENOENT most likely refers to it. */ - fd_sandbox = open(sandbox, O_RDONLY); - if (fd_sandbox < 0) +#ifdef IN_CAP_MODE + if (ld_caplibindex_lookup(LD_ELF_CAP_SO, &fd_ldso) < 0) + goto out_error; + if (ld_caplibindex_lookup(LIBC_SO, &fd_libc) < 0) + goto out_error; + if (ld_caplibindex_lookup(LIBZ_SO, &fd_libz) < 0) + goto out_error; + if (ld_caplibindex_lookup(LIBCAPABILITY_SO, &fd_libcapability) < 0) + goto out_error; + if (ld_caplibindex_lookup(_PATH_DEVNULL, &fd_libcapability) < 0) goto out_error; - +#else fd_ldso = open(LD_ELF_CAP_SO, O_RDONLY); if (fd_ldso < 0) goto out_error; @@ -255,6 +260,11 @@ if (fd_libcapability < 0) goto out_error; + fd_devnull = open(_PATH_DEVNULL, O_RDWR); + if (fd_devnull < 0) + goto out_error; +#endif + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd_sockpair) < 0) goto out_error; @@ -272,14 +282,16 @@ } if (pid == 0) { lch_sandbox(fd_sockpair[1], fd_sandbox, fd_ldso, fd_libc, - fd_libz, fd_libcapability, flags, argv); + fd_libz, fd_libcapability, fd_devnull, flags, argv); exit(-1); } +#ifndef IN_CAP_MODE + close(fd_devnull); close(fd_libcapability); close(fd_libz); close(fd_libc); close(fd_ldso); - close(fd_sandbox); +#endif close(fd_sockpair[1]); lcap->lcs_fd_procdesc = fd_procdesc; @@ -295,6 +307,9 @@ close(fd_sockpair[0]); if (fd_sockpair[1] != -1) close(fd_sockpair[1]); +#ifndef IN_CAP_MODE + if (fd_devnull != -1) + close(fd_devnull); if (fd_libcapability != -1) close(fd_libcapability); if (fd_libz != -1) @@ -303,8 +318,7 @@ close(fd_libc); if (fd_ldso != -1) close(fd_ldso); - if (fd_sandbox != -1) - close(fd_sandbox); +#endif if (lcap != NULL) free(lcap); errno = error; @@ -312,11 +326,37 @@ } int +lch_startfd(int fd_sandbox, char *const argv[], struct lc_sandbox **lcapp) +{ + + return (lch_startfd_flags(fd_sandbox, argv, 0, lcapp)); +} + +#ifndef IN_CAP_MODE +int +lch_start_flags(const char *sandbox, char *const argv[], u_int flags, + struct lc_sandbox **lcapp) +{ + int error, fd_sandbox, ret; + + fd_sandbox = open(sandbox, O_RDONLY); + if (fd_sandbox < 0) + return (-1); + + ret = lch_startfd_flags(fd_sandbox, argv, flags, lcapp); + error = errno; + close(fd_sandbox); + errno = error; + return (ret); +} + +int lch_start(const char *sandbox, char *const argv[], struct lc_sandbox **lcapp) { return (lch_start_flags(sandbox, argv, 0, lcapp)); } +#endif void lch_stop(struct lc_sandbox *lcap)