Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Feb 2010 22:57:42 GMT
From:      Jonathan Anderson <jona@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 174128 for review
Message-ID:  <201002012257.o11Mvg2s039029@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/chv.cgi?CH=174128

Change 174128 by jona@jona-belle-freebsd8 on 2010/02/01 22:57:19

	Use lc_fdlist for sandbox configuration. No more need for ld_libcache, and libcapsicum has been simplified somewhat.

Affected files ...

.. //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum.3#3 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum.c#3 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum.h#11 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_fdlist.c#9 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_host.c#10 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_internal.h#5 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_sandbox.c#3 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_sandbox_api.h#3 edit
.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/Makefile#21 edit
.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/rtld_libcache.c#5 delete
.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/rtld_libcache.h#4 delete
.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/rtld.c#34 edit
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/ld_libdirs/Makefile#1 add
.. //depot/projects/trustedbsd/capabilities/src/tools/cap/ld_libdirs/ld_libdirs.c#1 add
.. //depot/projects/trustedbsd/capabilities/src/usr.bin/gzip/gzsandbox.c#12 edit

Differences ...

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum.3#3 (text+ko) ====

@@ -34,7 +34,7 @@
 .\"
 .Dd June 11, 2009
 .Os
-.Dt LIBCAPABILITY 3
+.Dt LIBCAPSICUM 3
 .Sh NAME
 .Nm libcapsicum
 .Nd "library interface to capability-mode services"
@@ -89,7 +89,7 @@
 .Xr libcapsicum_fdlist 3 ,
 may be used to manage the delegation of file descriptors/capabilities to
 sandboxes using a namespace.
-.Sh CAPABILITY API
+.Sh CAPSICUM API
 .Fn lc_limitfd
 is a wrapper around
 .Xr cap_new 2 ,

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum.c#3 (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/libcapsicum/libcapsicum.c#2 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum.c#3 $
  */
 
 #include <sys/types.h>
@@ -154,7 +154,7 @@
 _lc_send_rights(int fd, const void *msg, size_t len, int flags, int lc_flags,
     int *fdp, int fdcount)
 {
-	char cmsgbuf[CMSG_SPACE(LIBCAPABILITY_SANDBOX_API_MAXRIGHTS *
+	char cmsgbuf[CMSG_SPACE(LIBCAPSICUM_SANDBOX_API_MAXRIGHTS *
 	    sizeof(int))];
 	struct cmsghdr *cmsg;
 	struct msghdr msghdr;
@@ -170,7 +170,7 @@
 		return (-1);
 	}
 
-	if (fdcount > LIBCAPABILITY_SANDBOX_API_MAXRIGHTS) {
+	if (fdcount > LIBCAPSICUM_SANDBOX_API_MAXRIGHTS) {
 		errno = EMSGSIZE;
 		return (-1);
 	}
@@ -224,7 +224,7 @@
 _lc_recv_rights(int fd, void *buf, size_t len, int flags, int lc_flags,
     int *fdp, int *fdcountp)
 {
-	char cmsgbuf[CMSG_SPACE(LIBCAPABILITY_SANDBOX_API_MAXRIGHTS *
+	char cmsgbuf[CMSG_SPACE(LIBCAPSICUM_SANDBOX_API_MAXRIGHTS *
 	    sizeof(int))];
 	struct msghdr msghdr;
 	struct iovec iov;
@@ -238,7 +238,7 @@
 		return (-1);
 	}
 
-	if (*fdcountp > LIBCAPABILITY_SANDBOX_API_MAXRIGHTS) {
+	if (*fdcountp > LIBCAPSICUM_SANDBOX_API_MAXRIGHTS) {
 		errno = EMSGSIZE;
 		return (-1);
 	}

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum.h#11 (text+ko) ====

@@ -30,11 +30,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum.h#10 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum.h#11 $
  */
 
-#ifndef _LIBCAPABILITY_H_
-#define	_LIBCAPABILITY_H_
+#ifndef _LIBCAPSICUM_H_
+#define	_LIBCAPSICUM_H_
 
 #include <sys/cdefs.h>
 #include <sys/capability.h>
@@ -73,7 +73,7 @@
  * Add a file descriptor to the list.
  *
  * lfp		the list to add to
- * subsystem	a software component name, e.g. "org.freebsd.rtld-elf"
+ * subsystem	a software component name, e.g. "org.freebsd.rtld-elf-cap"
  * classname	a class name, e.g. "libdir" or "library"
  * name		an instance name, e.g. "system library dir" or "libc.so.6"
  * fd		the file descriptor
@@ -141,13 +141,12 @@
 int	lch_start(const char *sandbox, char *const argv[], u_int flags,
 	    struct lc_fdlist *fds, struct lc_sandbox **lcspp);
 int	lch_start_libs(const char *sandbox, char *const argv[], u_int flags,
-	    struct lc_library *lclp, u_int lcl_count, struct lc_fdlist *fds,
-	    struct lc_sandbox **lcspp);
+	    struct lc_fdlist *fds, struct lc_sandbox **lcspp);
 int	lch_startfd(int fd_sandbox, const char *binname, char *const argv[],
 	    u_int flags, struct lc_fdlist *fds, struct lc_sandbox **lcspp);
 int	lch_startfd_libs(int fd_sandbox, const char *binname,
-	    char *const argv[], u_int flags, struct lc_library *lclp,
-	    u_int lcl_count, struct lc_fdlist *fds, struct lc_sandbox **lcspp);
+	    char *const argv[], u_int flags, struct lc_fdlist *fds,
+	    struct lc_sandbox **lcspp);
 void	lch_stop(struct lc_sandbox *lcsp);
 
 /*
@@ -237,4 +236,4 @@
 
 __END_DECLS
 
-#endif /* !_LIBCAPABILITY_H_ */
+#endif /* !_LIBCAPSICUM_H_ */

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_fdlist.c#9 (text+ko) ====

@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_fdlist.c#8 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_fdlist.c#9 $
  */
 
 #include <sys/mman.h>
@@ -45,6 +45,7 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "libcapsicum_internal.h"
 #include "libcapsicum_sandbox_api.h"
 
 struct lc_fdlist_entry {
@@ -99,7 +100,7 @@
 		return (&global_fdlist);
 	}
 
-	env = getenv(LIBCAPABILITY_SANDBOX_FDLIST);
+	env = getenv(LIBCAPSICUM_SANDBOX_FDLIST);
 	if ((env != NULL) && (strnlen(env, 8) < 7)) {
 		struct lc_fdlist_storage *lfsp;
 		struct stat sb;
@@ -118,7 +119,7 @@
 			goto fail;
 		lfsp = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
 		    MAP_NOSYNC | MAP_SHARED, fd, 0);
-		if (lfsp == NULL)
+		if (lfsp == MAP_FAILED)
 			goto fail;
 
 		/*
@@ -126,8 +127,8 @@
 		 * to make sure sizes/etc are internally consistent.
 		 */
 		global_fdlist.lf_storage = lfsp;
+		return (&global_fdlist);
 	}
-	return (&global_fdlist);
 
 fail:
 	/* XXX: We don't always set errno before returning. */
@@ -309,7 +310,14 @@
 lc_fdlist_append(struct lc_fdlist *to, struct lc_fdlist *from)
 {
 	int pos = 0;
+	if (to == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
 
+	if (from == NULL)
+		return (0);
+
 	/* Use address to order lc_fdlist locks. */
 	if ((uintptr_t)to < (uintptr_t)from) {
 		LOCK(to);
@@ -401,7 +409,7 @@
 			}
 
 			*fdp = entry->fd;
-			if (pos) *pos = i + 1;
+			if (pos != NULL) *pos = i + 1;
 			successful = 1;
 			break;
 		}
@@ -421,14 +429,14 @@
 
 	LOCK(lfp);
 	lfsp = lfp->lf_storage;
-	if ((pos == NULL) || (*pos < 0) || (*pos >= (int) lfsp->count)
-	    || (subsystem == NULL) || (classname == NULL)
-	    || (name == NULL) || (fdp == NULL)) {
+
+	if ((subsystem == NULL) || (classname == NULL) || (name == NULL)
+	    || (fdp == NULL) || ((pos != NULL) && (*pos >= (int) lfsp->count))) {
 		errno = EINVAL;
 		return (-1);
 	}
 
-	struct lc_fdlist_entry *entry = lfsp->entries + *pos;
+	struct lc_fdlist_entry *entry = lfsp->entries + (pos ? *pos : 0);
 	char *names = lc_fdlist_storage_names(lfsp);
 	int size = entry->syslen + entry->classnamelen + entry->namelen;
 	char *head = malloc(size);
@@ -448,7 +456,8 @@
 	*fdp = entry->fd;
 	UNLOCK(lfp);
 
-	(*pos)++;
+	if (pos) (*pos)++;
+
 	return (0);
 }
 
@@ -536,3 +545,9 @@
 	return (((char *) lfsp) + lc_fdlist_storage_size(lfsp) -
 	    lfsp->namecapacity);
 }
+
+void*
+_lc_fdlist_getstorage(struct lc_fdlist* lfp) {
+	return lfp->lf_storage;
+}
+

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_host.c#10 (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/libcapsicum/libcapsicum_host.c#9 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_host.c#10 $
  */
 
 #include <sys/param.h>
@@ -41,6 +41,7 @@
 #include <sys/socket.h>
 #include <sys/uio.h>
 
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <libgen.h>
@@ -54,275 +55,230 @@
 #include "libcapsicum_internal.h"
 #include "libcapsicum_sandbox_api.h"
 
-#define	LIBCAPABILITY_CAPMASK_DEVNULL	(CAP_EVENT | CAP_READ | CAP_WRITE)
-#define	LIBCAPABILITY_CAPMASK_SOCK	(CAP_EVENT | CAP_READ | CAP_WRITE)
-#define	LIBCAPABILITY_CAPMASK_BIN	(CAP_READ | CAP_EVENT | CAP_FSTAT | \
+#define	LIBCAPSICUM_CAPMASK_DEVNULL	(CAP_EVENT | CAP_READ | CAP_WRITE)
+#define	LIBCAPSICUM_CAPMASK_SOCK	(CAP_EVENT | CAP_READ | CAP_WRITE)
+#define	LIBCAPSICUM_CAPMASK_BIN	(CAP_READ | CAP_EVENT | CAP_FSTAT | \
 					    CAP_FSTATFS | \
 					    CAP_FEXECVE | CAP_MMAP | \
 					    CAP_MAPEXEC)
-#define	LIBCAPABILITY_CAPMASK_SANDBOX	LIBCAPABILITY_CAPMASK_BIN
-#define	LIBCAPABILITY_CAPMASK_LDSO	LIBCAPABILITY_CAPMASK_BIN
-#define	LIBCAPABILITY_CAPMASK_LIB	LIBCAPABILITY_CAPMASK_BIN
+#define	LIBCAPSICUM_CAPMASK_SANDBOX	LIBCAPSICUM_CAPMASK_BIN
+#define	LIBCAPSICUM_CAPMASK_LDSO	LIBCAPSICUM_CAPMASK_BIN
+#define	LIBCAPSICUM_CAPMASK_LIB		LIBCAPSICUM_CAPMASK_BIN
+#define LIBCAPSICUM_CAPMASK_LIBDIR	LIBCAPSICUM_CAPMASK_LIB \
+					 | CAP_LOOKUP | CAP_ATBASE
+#define LIBCAPSICUM_CAPMASK_FDLIST	CAP_READ | CAP_WRITE | CAP_FTRUNCATE \
+					 | CAP_FSTAT | CAP_MMAP
 
 #define	_PATH_LIB	"/lib"
 #define	_PATH_USR_LIB	"/usr/lib"
-#define	LIBC_SO	"libc.so.7"
-#define	LIBCAPABILITY_SO	"libcapsicum.so.1"
+#define	LIBC_SO		"libc.so.7"
+#define	LIBCAPSICUM_SO	"libcapsicum.so.1"
 #define	LIBSBUF_SO	"libsbuf.so.5"
 
 extern char **environ;
 
 #define LD_ELF_CAP_SO		"ld-elf-cap.so.1"
 #define	PATH_LD_ELF_CAP_SO	"/libexec"
-char *ldso_argv[] = {
-	__DECONST(char *, PATH_LD_ELF_CAP_SO "/" LD_ELF_CAP_SO),
-	NULL,
-};
 
 int
 lch_autosandbox_isenabled(__unused const char *servicename)
 {
 
-	if (getenv("LIBCAPABILITY_NOAUTOSANDBOX") != NULL)
+	if (getenv("LIBCAPSICUM_NOAUTOSANDBOX") != NULL)
 		return (0);
 	return (1);
 }
 
-/*
- * Install an array of file descriptors using the array index of each
- * descriptor in the array as its destination file descriptor number.  All
- * other existing file descriptors will be closed when this function returns,
- * leaving a pristine vector.  If calls fail, then we return (-1), but there
- * are no guarantees about the state of the file descriptor array for the
- * process, so it's a throw-away.
- *
- * It would be nice not to shuffle descriptors that already have the right
- * number.
- */
-static int
-lch_installfds(u_int fd_count, int *fds)
+
+static void
+lch_sandbox(int fd_sock, int fd_binary, int fd_rtld, int fd_devnull, u_int flags,
+    const char *binname, char *const argv[], __unused struct lc_fdlist *userfds)
 {
-	u_int i;
-	int highestfd;
+	struct sbuf *sbufp;
+	int shmfd = -1;
+	size_t fdlistsize;
+	struct lc_fdlist *fds;
+	void *shm;
 
-	if (fd_count == 0)
-		return (0);
+	/*
+	 * Inform the run-time linked of the binary's name.
+	 */
+	if (setenv("LD_BINNAME", binname, 1) == -1)
+		err(-1, "Error in setenv(LD_BINNAME)");
 
 	/*
-	 * Identify the highest source file descriptor we care about so that
-	 * when we play the dup2() rearranging game, we don't overwrite any
-	 * we care about.
+	 * Create an anonymous shared memory segment for the FD list.
 	 */
-	highestfd = fds[0];
-	for (i = 1; i < fd_count; i++) {
-		if (fds[i] > highestfd)
-			highestfd = fds[i];
-	}
-	highestfd++;	/* Don't tread on the highest */
+	shmfd = open("/tmp/jon-foo"/*SHM_ANON*/, O_RDWR | O_CREAT | O_TRUNC, 0600);
+	if (shmfd < 0)
+		err(-1, "Error creating shared memory segment");
 
 	/*
-	 * First, move all our descriptors up the range.
+	 * Create and fill up the FD list.
 	 */
-	for (i = 0; i < fd_count; i++) {
-		if (dup2(fds[i], highestfd + i) < 0)
-			return (-1);
-	}
+	fds = lc_fdlist_new();
+	if (fds == NULL)
+		err(-1, "Error in lc_fdlist_new()");
+
+	if (lc_fdlist_addcap(fds, LIBCAPSICUM_FQNAME, "stdin", "",
+		STDIN_FILENO, 0) < 0)
+		err(-1, "Error in lc_fdlist_addcap(stdin)");
+
+	if (lc_fdlist_addcap(fds, LIBCAPSICUM_FQNAME, "stdout", "",
+		STDOUT_FILENO,
+		(flags & LCH_PERMIT_STDOUT) ? CAP_WRITE | CAP_SEEK : 0) < 0)
+		err(-1, "Error in lc_fdlist_addcap(stdout)");
+
+	if (lc_fdlist_addcap(fds, LIBCAPSICUM_FQNAME, "stderr", "",
+		STDERR_FILENO,
+		(flags & LCH_PERMIT_STDERR) ? CAP_WRITE | CAP_SEEK : 0) < 0)
+		err(-1, "Error in lc_fdlist_addcap(stderr)");
+
+	if (lc_fdlist_addcap(fds, LIBCAPSICUM_FQNAME, "socket", "",
+	                     fd_sock, LIBCAPSICUM_CAPMASK_SOCK) < 0)
+		err(-1, "Error in lc_fdlist_addcap(fd_sock)");
+
+	if (lc_fdlist_addcap(fds, LIBCAPSICUM_FQNAME, "/dev/null", "",
+	                     fd_devnull, LIBCAPSICUM_CAPMASK_DEVNULL) < 0)
+		err(-1, "Error in lc_fdlist_addcap(fd_devnull)");
+
+	if (lc_fdlist_addcap(fds, LIBCAPSICUM_FQNAME, "fdlist", "",
+	                     shmfd, LIBCAPSICUM_CAPMASK_FDLIST) < 0)
+		err(-1, "Error in lc_fdlist_addcap(shmfd)");
+
+	if (lc_fdlist_addcap(fds, RTLD_CAP_FQNAME, "rtld", "",
+	                     fd_rtld, LIBCAPSICUM_CAPMASK_LDSO) < 0)
+		err(-1, "Error in lc_fdlist_addcap(fd_rtld)");
+
+	if (lc_fdlist_addcap(fds, RTLD_CAP_FQNAME, "binary", "",
+	                     fd_binary, LIBCAPSICUM_CAPMASK_SANDBOX) < 0)
+		err(-1, "Error in lc_fdlist_addcap(fd_binary)");
+
+	if (lc_fdlist_append(fds, userfds) < 0)
+		err(-1, "Error in lc_fdlist_append()");
 
 	/*
-	 * Now put them back.
+	 * Ask RTLD for library path descriptors.
+	 *
+	 * NOTE: This is FreeBSD-specific; porting to other operating systems will
+	 *       require dynamic linkers capable of answering similar queries.
 	 */
-	for (i = 0; i < fd_count; i++) {
-		if (dup2(highestfd + i, i) < 0)
-			return (-1);
+	int size = 16;
+	int *libdirs;
+
+	while (1) {
+		libdirs = malloc(size * sizeof(int));
+
+		if (ld_libdirs(libdirs, &size) < 0) {
+			free(libdirs);
+
+			if (size > 0) continue;
+			else err(-1, "Error in ld_libdirs()");
+		}
+		else break;
 	}
 
+
+	for (int j = 0; j < size; j++)
+		if (lc_fdlist_addcap(fds, RTLD_CAP_FQNAME, "libdir", "",
+	        	libdirs[j], LIBCAPSICUM_CAPMASK_LIBDIR) < 0)
+			err(-1, "Error in lc_fdlist_addcap(libdirs[%d]: %d)",
+			    j, libdirs[j]);
+
+	if (lc_fdlist_reorder(fds) < 0)
+		err(-1, "Error in lc_fdlist_reorder()");
+
+
 	/*
-	 * Close the descriptors that we moved, as well as any others that
-	 * were left open by the caller.
+	 * Find the fdlist shared memory segment.
 	 */
-	closefrom(fd_count);
-	return (0);
-}
+	int pos = 0;
+	if (lc_fdlist_lookup(fds, LIBCAPSICUM_FQNAME, "fdlist", NULL,
+	                     &shmfd, &pos) < 0)
+		err(-1, "Error in lc_fdlist_lookup(fdlist)");
 
-static void
-lch_sandbox(int fd_sock, int fd_sandbox, int fd_ldso, int fd_libc,
-    int fd_libcapsicum, int fd_libsbuf, int fd_devnull, u_int flags,
-    struct lc_library *lclp, u_int lcl_count, const char *binname,
-    char *const argv[], struct lc_fdlist *fds)
-{
-	int *fd_array, fdcount, fdnum;
-	struct sbuf *sbufp;
-	int shmfd = -1;
-	size_t fdlistsize;
-	void *shm;
-	char fdliststr[8];
-	u_int i;
+	char tmp[8];
+	sprintf(tmp, "%d", shmfd);
+	if (setenv(LIBCAPSICUM_SANDBOX_FDLIST, tmp, 1) == -1)
+		err(-1, "Error in setenv(LIBCAPSICUM_SANDBOX_FDLIST)");
 
 	/*
-	 * Create an anonymous shared memory segment for the FD list.
+	 * Map it and copy the list.
 	 */
-	if (fds == NULL) fds = lc_fdlist_new();
-
-	shmfd = shm_open(SHM_ANON, O_RDWR, 0600);
-	if (shmfd < 0)
-		return;
 	fdlistsize = lc_fdlist_size(fds);
 	if (ftruncate(shmfd, fdlistsize) < 0)
-		return;
+		err(-1, "Error in ftruncate(shmfd)");
 
-	/*
-	 * Map it and copy the list.
-	 */
 	shm = mmap(NULL, fdlistsize, PROT_READ | PROT_WRITE,
 	    MAP_NOSYNC | MAP_SHARED, shmfd, 0);
 	if (shm == MAP_FAILED)
-		return;
-	memcpy(shm, fds, fdlistsize);
+		err(-1, "Error mapping fdlist SHM");
+
+	memcpy(shm, _lc_fdlist_getstorage(fds), fdlistsize);
 	if (munmap(shm, fdlistsize))
-		return;
+		err(-1, "Error in munmap(shm, fdlistsize)");
 
-	if (lc_fdlist_addcap(fds, "org.freebsd.libcapsicum", "/dev/null", "",
-	                     fd_devnull, LIBCAPABILITY_CAPMASK_DEVNULL) < 0)
-		return;
-	if (lc_fdlist_addcap(fds, "org.freebsd.libcapsicum", "sandbox", "",
-	                     fd_sandbox, LIBCAPABILITY_CAPMASK_SANDBOX) < 0)
-		return;
-	if (lc_fdlist_addcap(fds, "org.freebsd.libcapsicum", "socket", "",
-	                     fd_sock, LIBCAPABILITY_CAPMASK_SOCK) < 0)
-		return;
-	if (lc_fdlist_addcap(fds, "org.freebsd.rtld-elf-cap", "ldso", "",
-	                     fd_ldso, LIBCAPABILITY_CAPMASK_LDSO) < 0)
-		return;
-	if (lc_fdlist_addcap(fds, "org.freebsd.rtld-elf-cap", "lib", "libc",
-	                     fd_libc, LIBCAPABILITY_CAPMASK_LIB) < 0)
-		return;
-	if (lc_fdlist_addcap(fds, "org.freebsd.rtld-elf-cap", "lib", "libcapsicum",
-	                     fd_libcapsicum, LIBCAPABILITY_CAPMASK_LIB) < 0)
-		return;
-	if (lc_fdlist_addcap(fds, "org.freebsd.rtld-elf-cap", "lib", "libsbuf",
-	                     fd_libsbuf, LIBCAPABILITY_CAPMASK_LIB) < 0)
-		return;
-/*
-	{
-		int pos = 0;
-		char *subsystem;
-		char *class;
-		char *name;
-		int fd;
 
-		while (lc_fdlist_getentry(fds, &subsystem, &class, &name, &fd, &pos)
-		        >= 0) {
-			printf("%d\t'%s'.'%s': '%s' (%d)\n",
-			       pos, subsystem, class, name, fd);
-		}
-	}
-*/
-	if (lc_limitfd(fd_devnull, LIBCAPABILITY_CAPMASK_DEVNULL) < 0)
-		return;
-	if (lc_limitfd(fd_sandbox, LIBCAPABILITY_CAPMASK_SANDBOX) < 0)
-		return;
-	if (lc_limitfd(fd_sock, LIBCAPABILITY_CAPMASK_SOCK) < 0)
-		return;
-	if (lc_limitfd(fd_ldso, LIBCAPABILITY_CAPMASK_LDSO) < 0)
-		return;
-	if (lc_limitfd(fd_libc, LIBCAPABILITY_CAPMASK_LIB) < 0)
-		return;
-	if (lc_limitfd(fd_libcapsicum, LIBCAPABILITY_CAPMASK_LIB) < 0)
-		return;
-	if (lc_limitfd(fd_libsbuf, LIBCAPABILITY_CAPMASK_LIB) < 0)
-		return;
+	/*
+	 * Find RTLD.
+	 */
+	if (lc_fdlist_lookup(fds, RTLD_CAP_FQNAME, "rtld", NULL, &fd_rtld,
+	                     NULL) < 0)
+		err(-1, "Error in lc_fdlist_lookup(RTLD)");
 
-	fdnum = 10;
-	if (shmfd != -1)
-		fdnum++;
+	/*
+	 * Find the binary for RTLD.
+	 */
+	if (lc_fdlist_lookup(fds, RTLD_CAP_FQNAME, "binary", NULL, &fd_binary,
+	                     NULL) < 0)
+		err(-1, "Error in lc_fdlist_lookup(RTLD binary)");
 
-	fdcount = fdnum + lcl_count;
-	fd_array = malloc(fdcount * sizeof(int));
-	if (fd_array == NULL)
-		return;
+	sprintf(tmp, "%d", fd_binary);
+	if (setenv("LD_BINARY", tmp, 1) != 0)
+		err(-1, "Error in setenv(LD_BINARY)");
 
-	fd_array[0] = fd_devnull;
-	if (flags & LCH_PERMIT_STDOUT) {
-		if (lc_limitfd(STDOUT_FILENO, CAP_SEEK | CAP_WRITE) < 0)
-			return;
-		fd_array[1] = STDOUT_FILENO;
-	} else
-		fd_array[1] = 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_libcapsicum;
-	fd_array[8] = fd_libsbuf;
-	fd_array[9] = fd_devnull;
-	if (shmfd != -1)
-		fd_array[10] = shmfd;
-	for (i = 0; i < lcl_count; i++) {
-		if (lc_limitfd(lclp->lcl_fd, LIBCAPABILITY_CAPMASK_LIB) < 0)
-			return;
-		fd_array[i + fdnum] = lclp[i].lcl_fd;
-	}
-
-	if (lch_installfds(fdcount, fd_array) < 0)
-		return;
-
+	/*
+	 * Build LD_LIBRARY_DIRS for RTLD.
+	 *
+	 * NOTE: This is FreeBSD-specific; porting to other operating systems will
+	 *       require dynamic linkers capable of operating on file descriptors.
+	 */
 	sbufp = sbuf_new_auto();
 	if (sbufp == NULL)
-		return;
-	(void)sbuf_printf(sbufp, "%d:%s,%d:%s,%d:%s,%d:%s,%d:%s,%d:%s",
-	    3, binname, 5, LD_ELF_CAP_SO, 6, LIBC_SO, 7, LIBCAPABILITY_SO,
-	    8, LIBSBUF_SO, 9, _PATH_DEVNULL);
-	for (i = 0; i < lcl_count; i++)
-		(void)sbuf_printf(sbufp, ",%d:%s", i + fdnum,
-		    lclp[i].lcl_libname);
-	sbuf_finish(sbufp);
-	if (sbuf_overflowed(sbufp))
-		return;
-	if (setenv("LD_LIBCACHE", sbuf_data(sbufp), 1) == -1)
-		return;
-	sbuf_delete(sbufp);
+		err(-1, "Error in sbuf_new_auto()");
+
+	{
+		int fd;
+		while (lc_fdlist_lookup(fds, RTLD_CAP_FQNAME, "libdir",
+		                        NULL, &fd, &pos) >= 0)
+			sbuf_printf(sbufp, "%d:", fd);
+	}
 
-	sbufp = sbuf_new_auto();
-	if (sbufp == NULL)
-		return;
-	(void)sbuf_printf(sbufp, "%s:%d", LIBCAPABILITY_SANDBOX_API_SOCK, 4);
 	sbuf_finish(sbufp);
 	if (sbuf_overflowed(sbufp))
-		return;
-	if (setenv(LIBCAPABILITY_SANDBOX_API_ENV, sbuf_data(sbufp), 1) == -1)
-		return;
+		err(-1, "sbuf_overflowed()");
+	if (setenv("LD_LIBRARY_DIRS", sbuf_data(sbufp), 1) == -1)
+		err(-1, "Error in setenv(LD_LIBRARY_DIRS)");
 	sbuf_delete(sbufp);
 
-	if (shmfd != -1) {
-		sprintf(fdliststr, "%d", 10);
-		if (setenv(LIBCAPABILITY_SANDBOX_FDLIST, fdliststr, 1) == -1)
-			return;
-	}
 
 	if (cap_enter() < 0)
-		return;
+		err(-1, "cap_enter() failed");
 
-	(void)fexecve(5, argv, environ);
+	(void)fexecve(fd_rtld, argv, environ);
 }
 
 int
-lch_startfd_libs(int fd_sandbox, const char *binname, char *const argv[],
-    u_int flags, struct lc_library *lclp, u_int lcl_count,
-    struct lc_fdlist *fds, struct lc_sandbox **lcspp)
+lch_startfd_libs(int fd_binary, const char *binname, char *const argv[],
+    u_int flags, struct lc_fdlist *fds, struct lc_sandbox **lcspp)
 {
 	struct lc_sandbox *lcsp;
-	int fd_devnull, fd_ldso, fd_libc, fd_libcapsicum, fd_libsbuf;
+	int fd_devnull, fd_rtld, fd_libc, fd_libcapsicum, fd_libsbuf;
 	int fd_procdesc, fd_sockpair[2];
 	int error, val;
 	pid_t pid;
 
-	fd_devnull = fd_ldso = fd_libc = fd_libcapsicum = fd_libsbuf =
+	fd_devnull = fd_rtld = fd_libc = fd_libcapsicum = fd_libsbuf =
 	    fd_procdesc = fd_sockpair[0] = fd_sockpair[1] = -1;
 
 	lcsp = malloc(sizeof(*lcsp));
@@ -331,11 +287,11 @@
 	bzero(lcsp, sizeof(*lcsp));
 
 	if (ld_insandbox()) {
-		if (ld_libcache_lookup(LD_ELF_CAP_SO, &fd_ldso) < 0)
+		if (ld_libcache_lookup(LD_ELF_CAP_SO, &fd_rtld) < 0)
 			goto out_error;
 		if (ld_libcache_lookup(LIBC_SO, &fd_libc) < 0)
 			goto out_error;
-		if (ld_libcache_lookup(LIBCAPABILITY_SO,
+		if (ld_libcache_lookup(LIBCAPSICUM_SO,
 		    &fd_libcapsicum) < 0)
 			goto out_error;
 		if (ld_libcache_lookup(LIBSBUF_SO, &fd_libsbuf) < 0)
@@ -343,9 +299,9 @@
 		if (ld_libcache_lookup(_PATH_DEVNULL, &fd_devnull) < 0)
 			goto out_error;
 	} else {
-		fd_ldso = open(PATH_LD_ELF_CAP_SO "/" LD_ELF_CAP_SO,
+		fd_rtld = open(PATH_LD_ELF_CAP_SO "/" LD_ELF_CAP_SO,
 		    O_RDONLY);
-		if (fd_ldso < 0)
+		if (fd_rtld < 0)
 			goto out_error;
 		fd_libc = open(_PATH_LIB "/" LIBC_SO, O_RDONLY);
 		if (fd_libc < 0)
@@ -353,7 +309,7 @@
 		fd_libsbuf = open(_PATH_LIB "/" LIBSBUF_SO, O_RDONLY);
 		if (fd_libsbuf < 0)
 			goto out_error;
-		fd_libcapsicum = open(_PATH_USR_LIB "/" LIBCAPABILITY_SO,
+		fd_libcapsicum = open(_PATH_USR_LIB "/" LIBCAPSICUM_SO,
 		    O_RDONLY);
 		if (fd_libcapsicum < 0)
 			goto out_error;
@@ -378,9 +334,8 @@
 		goto out_error;
 	}
 	if (pid == 0) {
-		lch_sandbox(fd_sockpair[1], fd_sandbox, fd_ldso, fd_libc,
-		    fd_libcapsicum, fd_libsbuf, fd_devnull, flags, lclp,
-		    lcl_count, binname, argv, fds);
+		lch_sandbox(fd_sockpair[1], fd_binary, fd_rtld, fd_devnull, flags,
+		    binname, argv, fds);
 		exit(-1);
 	}
 #ifndef IN_CAP_MODE
@@ -388,7 +343,7 @@
 	close(fd_libsbuf);
 	close(fd_libcapsicum);
 	close(fd_libc);
-	close(fd_ldso);
+	close(fd_rtld);
 #endif
 	close(fd_sockpair[1]);
 
@@ -414,8 +369,8 @@
 		close(fd_libcapsicum);
 	if (fd_libc != -1)
 		close(fd_libc);
-	if (fd_ldso != -1)
-		close(fd_ldso);
+	if (fd_rtld != -1)
+		close(fd_rtld);
 #endif
 	if (lcsp != NULL)
 		free(lcsp);
@@ -424,33 +379,31 @@
 }
 
 int
-lch_startfd(int fd_sandbox, const char *binname, char *const argv[],
+lch_startfd(int fd_binary, const char *binname, char *const argv[],
     u_int flags, __unused struct lc_fdlist *fds, struct lc_sandbox **lcspp)
 {
 
-	return (lch_startfd_libs(fd_sandbox, binname, argv, flags, NULL, 0,
+	return (lch_startfd_libs(fd_binary, binname, argv, flags,
 	    fds, lcspp));
 }
 
 int
 lch_start_libs(const char *sandbox, char *const argv[], u_int flags,
-    struct lc_library *lclp, u_int lcl_count, struct lc_fdlist *fds,
-    struct lc_sandbox **lcspp)
+    struct lc_fdlist *fds, struct lc_sandbox **lcspp)
 {
 	char binname[MAXPATHLEN];
-	int error, fd_sandbox, ret;
+	int error, fd_binary, ret;
 
 	if (basename_r(sandbox, binname) == NULL)
 		return (-1);
 
-	fd_sandbox = open(sandbox, O_RDONLY);
-	if (fd_sandbox < 0)
+	fd_binary = open(sandbox, O_RDONLY);
+	if (fd_binary < 0)
 		return (-1);
 
-	ret = lch_startfd_libs(fd_sandbox, binname, argv, flags, lclp,
-	    lcl_count, fds, lcspp);
+	ret = lch_startfd_libs(fd_binary, binname, argv, flags, fds, lcspp);
 	error = errno;
-	close(fd_sandbox);
+	close(fd_binary);
 	errno = error;
 	return (ret);
 }
@@ -460,7 +413,7 @@
     struct lc_fdlist *fds, struct lc_sandbox **lcspp)
 {
 
-	return (lch_start_libs(sandbox, argv, flags, NULL, 0, fds, lcspp));
+	return (lch_start_libs(sandbox, argv, flags, fds, lcspp));
 }
 
 void

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_internal.h#5 (text+ko) ====

@@ -30,11 +30,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_internal.h#4 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_internal.h#5 $
  */
 
-#ifndef _LIBCAPABILITY_INTERNAL_H_
-#define	_LIBCAPABILITY_INTERNAL_H_
+#ifndef _LIBCAPSICUM_INTERNAL_H_
+#define	_LIBCAPSICUM_INTERNAL_H_
+
+#define LIBCAPSICUM_FQNAME	"org.freebsd.libcapsicum"
+#define RTLD_CAP_FQNAME		"org.freebsd.rtld-elf-cap"
 
 struct lc_host {
 	int	lch_fd_sock;
@@ -46,6 +49,8 @@
 	pid_t	lcs_pid;
 };
 
+void*	_lc_fdlist_getstorage(struct lc_fdlist*);
+
 /*
  * Communications flags for recv/send calls (lc_flags).
  */
@@ -63,4 +68,4 @@
 ssize_t	_lc_send_rights(int fd, const void *msg, size_t len, int flags,
 	    int lc_flags, int *fdp, int fdcount);
 
-#endif /* !_LIBCAPABILITY_INTERNAL_H_ */
+#endif /* !_LIBCAPSICUM_INTERNAL_H_ */

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_sandbox.c#3 (text+ko) ====

@@ -41,6 +41,7 @@
 
 #include <errno.h>
 #include <limits.h>
+#include <stdio.h>   /* TODO: temporary */
 #include <stdlib.h>
 #include <string.h>
 
@@ -54,9 +55,7 @@
 int
 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;
@@ -68,39 +67,16 @@
 		return (-1);
 	}
 
-	env = getenv(LIBCAPABILITY_SANDBOX_API_ENV);
-	if (env == NULL) {
-		errno = EINVAL;		/* XXXRW: Better errno? */
+	struct lc_fdlist *fds = lc_fdlist_global();
+	if (lc_fdlist_lookup(fds, LIBCAPSICUM_FQNAME, "socket", NULL,
+	                     &fd_sock, NULL) < 0)
 		return (-1);
-	}
-
-	env_dup = env_dup_free = strdup(env);
-	if (env_dup == NULL)
+	if (fd_sock == -1)
 		return (-1);
 
-	fd_sock = -1;
-	while ((token = strsep(&env_dup, ",")) != 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)
-				continue;
-			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;
-	free(env_dup_free);
 	return (0);
 }
 

==== //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_sandbox_api.h#3 (text+ko) ====

@@ -30,25 +30,25 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_sandbox_api.h#2 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_sandbox_api.h#3 $
  */
 
-#ifndef _LIBCAPABILITY_SANDBOX_API_H_
-#define	_LIBCAPABILITY_SANDBOX_API_H_
+#ifndef _LIBCAPSICUM_SANDBOX_API_H_
+#define	_LIBCAPSICUM_SANDBOX_API_H_
 
 /*
  * This include file captures the assumptions libcapsicum sandboxs will
  * make about the runtime environment set up by libcapsicum hosts.
  */
-#define	LIBCAPABILITY_SANDBOX_API_ENV	"LIBCAPABILITY_SANDBOX"
-#define LIBCAPABILITY_SANDBOX_FDLIST	"LIBCAPABILITY_FDLIST"
-#define	LIBCAPABILITY_SANDBOX_API_SOCK	"sock"
+#define	LIBCAPSICUM_SANDBOX_API_ENV	"LIBCAPSICUM_SANDBOX"
+#define LIBCAPSICUM_SANDBOX_FDLIST	"LIBCAPSICUM_FDLIST"
+#define	LIBCAPSICUM_SANDBOX_API_SOCK	"sock"
 
 /*
  * Maximum number of file descriptor rights we will ever send as part of an
  * RPC.
  */
-#define	LIBCAPABILITY_SANDBOX_API_MAXRIGHTS	16
+#define	LIBCAPSICUM_SANDBOX_API_MAXRIGHTS	16
 
 /*
  * Simple libcapsicum RPC facility (lcrpc) definitions.
@@ -79,4 +79,4 @@
 	u_int64_t	_lcrpc_rephdr_spare0;
 } __packed;
 
-#endif /* !_LIBCAPABILITY_H_ */
+#endif /* !_LIBCAPSICUM_H_ */

==== //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/Makefile#21 (text+ko) ====

@@ -1,5 +1,5 @@
 # $FreeBSD$
-# $P4: //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/Makefile#20 $
+# $P4: //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/Makefile#21 $
 
 .include <bsd.own.mk>
 MK_SSP=		no
@@ -8,7 +8,7 @@
 SRCS=		rtld_start.S \
 		reloc.c rtld.c rtld_lock.c map_object.c \
 		malloc.c xmalloc.c debug.c \
-		crtbrand.c rtld_libcache.c rtld_sandbox.c
+		crtbrand.c rtld_sandbox.c
 MAN=		rtld-elf-cap.1
 CSTD?=		gnu99
 CFLAGS+=	-Wall -DFREEBSD_ELF -DIN_RTLD -DIN_RTLD_CAP -g

==== //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/rtld.c#34 (text+ko) ====

@@ -60,7 +60,6 @@
 #include "rtld_tls.h"
 
 #ifdef IN_RTLD_CAP
-#include "rtld_libcache.h"
 #include "rtld_sandbox.h"
 #endif
 
@@ -119,6 +118,7 @@
 static void init_rtld(caddr_t);
 static void initlist_add_neededs(Needed_Entry *, Objlist *);
 static void initlist_add_objects(Obj_Entry *, Obj_Entry **, Objlist *);
+static void init_libdirs(void);
 static bool is_exported(const Elf_Sym *);

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002012257.o11Mvg2s039029>