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>