From owner-svn-src-projects@FreeBSD.ORG Tue Jun 1 15:24:19 2010 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E476F1065672; Tue, 1 Jun 2010 15:24:19 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (unknown [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D2EEA8FC1F; Tue, 1 Jun 2010 15:24:19 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o51FOJki069639; Tue, 1 Jun 2010 15:24:19 GMT (envelope-from rwatson@svn.freebsd.org) Received: (from rwatson@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o51FOJhB069635; Tue, 1 Jun 2010 15:24:19 GMT (envelope-from rwatson@svn.freebsd.org) Message-Id: <201006011524.o51FOJhB069635@svn.freebsd.org> From: Robert Watson Date: Tue, 1 Jun 2010 15:24:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r208710 - projects/capabilities8/lib/libcapsicum X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Jun 2010 15:24:20 -0000 Author: rwatson Date: Tue Jun 1 15:24:19 2010 New Revision: 208710 URL: http://svn.freebsd.org/changeset/base/208710 Log: Merge c177191, c177355, c177356, 178149 from the p4 TrustedBSD Capabilities branch to capabilities8: Various libcapsicum improvements: Talk about 'executable' rather than 'binary' in the FD list. Added lc_fdlist_print(). Create LD_PRELOAD for sanbdox. Added lc_fdlist_find(), changed whitespace in lc_fdlist_lookup() for clarity. Submitted by: jona Modified: projects/capabilities8/lib/libcapsicum/libcapsicum.h projects/capabilities8/lib/libcapsicum/libcapsicum_fdlist.c projects/capabilities8/lib/libcapsicum/libcapsicum_host.c Modified: projects/capabilities8/lib/libcapsicum/libcapsicum.h ============================================================================== --- projects/capabilities8/lib/libcapsicum/libcapsicum.h Tue Jun 1 15:11:29 2010 (r208709) +++ projects/capabilities8/lib/libcapsicum/libcapsicum.h Tue Jun 1 15:24:19 2010 (r208710) @@ -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.h#12 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum.h#15 $ */ #ifndef _LIBCAPSICUM_H_ @@ -52,6 +52,7 @@ struct lc_fdlist *lc_fdlist_new(void); struct lc_fdlist *lc_fdlist_global(void); struct lc_fdlist *lc_fdlist_dup(struct lc_fdlist *lfp_orig); void lc_fdlist_free(struct lc_fdlist *lfp); +void lc_fdlist_print(struct lc_fdlist *lfp, int outFD); /* * Size of an FD list in bytes, including all associated string data. @@ -89,6 +90,19 @@ int lc_fdlist_addcap(struct lc_fdlist *l cap_rights_t rights); /* + * Open a stored file descriptor. + * + * Given a filename '/foo/bar/fubar', this function will attempt to find the file + * in the FD list. If that fails, it will attempt to find a parent directory in the + * FD list and supply a filename relative to that FD (which will be a pointer to a + * location within the supplied filename - do NOT free it!). + */ +int +lc_fdlist_find(struct lc_fdlist *lfp, const char *subsystem, + const char *classname, const char *filename, + const char **relative_name); + +/* * Look up a file descriptor. * * Multiple entries with the same classname are allowed, so iterating through Modified: projects/capabilities8/lib/libcapsicum/libcapsicum_fdlist.c ============================================================================== --- projects/capabilities8/lib/libcapsicum/libcapsicum_fdlist.c Tue Jun 1 15:11:29 2010 (r208709) +++ projects/capabilities8/lib/libcapsicum/libcapsicum_fdlist.c Tue Jun 1 15:24:19 2010 (r208710) @@ -31,12 +31,13 @@ * 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#11 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_fdlist.c#13 $ */ #include #include +#define _WITH_DPRINTF #include #include #include @@ -202,6 +203,24 @@ lc_fdlist_free(struct lc_fdlist *lfp) free(lfp); } +void +lc_fdlist_print(struct lc_fdlist *lfp, int outFD) +{ + dprintf(outFD, "FD List:\n"); + for(int i = 0; ; ) + { + char *subsystem, *classname, *name; + int fd; + + if (lc_fdlist_getentry(lfp, &subsystem, &classname, &name, &fd, &i) + < 0) + break; + + dprintf(outFD, "% 3d:\t'%s'.'%s': '%s'\n", + fd, subsystem, classname, name); + } +} + int lc_fdlist_add(struct lc_fdlist *lfp, const char *subsystem, const char *classname, const char *name, int fd) @@ -248,7 +267,6 @@ lc_fdlist_add(struct lc_fdlist *lfp, con memcpy(lc_fdlist_storage_names(lfsp_copy), tmp, lfsp_copy->namelen); - free(lfsp); lfsp = lfp->lf_storage = lfsp_copy; free(tmp); } @@ -375,6 +393,60 @@ lc_fdlist_addcap(struct lc_fdlist *fdlis } int +lc_fdlist_find(struct lc_fdlist *lfp, const char *subsystem, + const char *classname, const char *filename, + const char **relative_name) +{ + int pos = 0; + int fd = -1; + + /* try to find the file itself in the FD list */ + size_t len = strlen(filename); + *relative_name = filename + len; + + while (fd == -1) + { + char *dirname; + + if (lc_fdlist_lookup(lfp, subsystem, classname, + &dirname, &fd, &pos) == -1) + break; + + if (strncmp(dirname, filename, len + 1)) fd = -1; + free(dirname); + } + + if (fd >= 0) return fd; + + + /* now try to find a parent directory and a relative filename */ + *relative_name = NULL; + pos = 0; + + while (fd == -1) + { + char *dirname; + + if (lc_fdlist_lookup(lfp, subsystem, classname, + &dirname, &fd, &pos) == -1) + return (-1); + + len = strlen(dirname); + if (strncmp(dirname, filename, len)) fd = -1; + else + { + *relative_name = filename + len; + if (**relative_name == '/') (*relative_name)++; + } + + free(dirname); + } + + return fd; +} + + +int lc_fdlist_lookup(struct lc_fdlist *lfp, const char *subsystem, const char *classname, char **name, int *fdp, int *pos) { @@ -394,28 +466,30 @@ lc_fdlist_lookup(struct lc_fdlist *lfp, for (u_int i = (pos ? *pos : 0); i < lfsp->count; i++) { struct lc_fdlist_entry *entry = lfsp->entries + i; - if ((!subsystem || - !strncmp(subsystem, names + entry->sysoff, - entry->syslen + 1)) - && (!classname || !strncmp(classname, names + - entry->classoff, entry->classnamelen + 1))) { - + if ((!subsystem + || !strncmp(subsystem, names + entry->sysoff, + entry->syslen + 1)) + && (!classname + || !strncmp(classname, names + entry->classoff, + entry->classnamelen + 1))) + { /* found a matching entry! */ + successful = 1; + *fdp = entry->fd; + if (name) { *name = malloc(entry->namelen + 1); strncpy(*name, names + entry->nameoff, entry->namelen + 1); } - - *fdp = entry->fd; - if (pos != NULL) *pos = i + 1; - successful = 1; + if (pos) *pos = i + 1; break; } } UNLOCK(lfp); if (successful) return (0); + errno = ENOENT; return (-1); } Modified: projects/capabilities8/lib/libcapsicum/libcapsicum_host.c ============================================================================== --- projects/capabilities8/lib/libcapsicum/libcapsicum_host.c Tue Jun 1 15:11:29 2010 (r208709) +++ projects/capabilities8/lib/libcapsicum/libcapsicum_host.c Tue Jun 1 15:24:19 2010 (r208710) @@ -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#17 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_host.c#19 $ */ #include @@ -41,6 +41,7 @@ #include #include +#define _WITH_DPRINTF #include #include #include @@ -67,6 +68,8 @@ #define LIBCAPSICUM_CAPMASK_FDLIST CAP_READ | CAP_WRITE | CAP_FTRUNCATE \ | CAP_FSTAT | CAP_MMAP +#define LIBCAPSICUM_CAPMASK_STDOUT CAP_WRITE | CAP_SEEK | CAP_FSTAT + extern char **environ; #define LD_ELF_CAP_SO "ld-elf-cap.so.1" @@ -123,12 +126,12 @@ lch_sandbox(int fd_sock, int fd_binary, if (lc_fdlist_addcap(fds, LIBCAPSICUM_FQNAME, "stdout", "", STDOUT_FILENO, - (flags & LCH_PERMIT_STDOUT) ? CAP_WRITE | CAP_SEEK : 0) < 0) + (flags & LCH_PERMIT_STDOUT) ? LIBCAPSICUM_CAPMASK_STDOUT : 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) + (flags & LCH_PERMIT_STDERR) ? LIBCAPSICUM_CAPMASK_STDOUT : 0) < 0) err(-1, "Error in lc_fdlist_addcap(stderr)"); if (lc_fdlist_addcap(fds, LIBCAPSICUM_FQNAME, "socket", "", @@ -143,13 +146,10 @@ lch_sandbox(int fd_sock, int fd_binary, fd_rtld, LIBCAPSICUM_CAPMASK_LDSO) < 0) err(-1, "Error in lc_fdlist_addcap(fd_rtld)"); - if (lc_fdlist_addcap(fds, RTLD_CAP_FQNAME, "binary", "", + if (lc_fdlist_addcap(fds, RTLD_CAP_FQNAME, "Executable", binname, 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()"); - /* * Ask RTLD for library path descriptors. * @@ -170,15 +170,23 @@ lch_sandbox(int fd_sock, int fd_binary, break; } - for (int j = 0; j < size; j++) - if (lc_fdlist_addcap(fds, RTLD_CAP_FQNAME, "libdir", "", + for (int j = 0; j < size; j++) { + if (lc_fdlist_addcap(fds, RTLD_CAP_FQNAME, "LibraryDirectory", "", libdirs[j], LIBCAPSICUM_CAPMASK_LIBDIR) < 0) err(-1, "Error in lc_fdlist_addcap(libdirs[%d]: %d)", j, libdirs[j]); + } + + /* Append user FD list and reorder the descriptors */ + if (lc_fdlist_append(fds, userfds) < 0) + err(-1, "Error in lc_fdlist_append()"); if (lc_fdlist_reorder(fds) < 0) err(-1, "Error in lc_fdlist_reorder()"); + + + /* * Find the fdlist shared memory segment. */ @@ -219,16 +227,16 @@ lch_sandbox(int fd_sock, int fd_binary, /* * Find the binary for RTLD. */ - if (lc_fdlist_lookup(fds, RTLD_CAP_FQNAME, "binary", NULL, + if (lc_fdlist_lookup(fds, RTLD_CAP_FQNAME, "Executable", NULL, &fd_binary, NULL) < 0) - err(-1, "Error in lc_fdlist_lookup(RTLD binary)"); + err(-1, "Error in lc_fdlist_lookup(Executable)"); sprintf(tmp, "%d", fd_binary); if (setenv("LD_BINARY", tmp, 1) != 0) err(-1, "Error in setenv(LD_BINARY)"); /* - * Build LD_LIBRARY_DIRS for RTLD. + * Build LD_LIBRARY_DIRS and LD_PRELOAD for RTLD. * * NOTE: This is FreeBSD-specific; porting to other operating systems * will require dynamic linkers capable of operating on file @@ -240,8 +248,9 @@ lch_sandbox(int fd_sock, int fd_binary, { int fd; - while (lc_fdlist_lookup(fds, RTLD_CAP_FQNAME, "libdir", NULL, - &fd, &pos) >= 0) + pos = 0; + while (lc_fdlist_lookup(fds, RTLD_CAP_FQNAME, "LibraryDirectory", + NULL, &fd, &pos) >= 0) sbuf_printf(sbufp, "%d:", fd); } @@ -252,10 +261,30 @@ lch_sandbox(int fd_sock, int fd_binary, err(-1, "Error in setenv(LD_LIBRARY_DIRS)"); sbuf_delete(sbufp); + sbufp = sbuf_new_auto(); + if (sbufp == NULL) + err(-1, "Error in sbuf_new_auto()"); + + { + int fd; + pos = 0; + while (lc_fdlist_lookup(fds, RTLD_CAP_FQNAME, "PreloadLibrary", + NULL, &fd, &pos) >= 0) + sbuf_printf(sbufp, "%d:", fd); + } + + sbuf_finish(sbufp); + if (sbuf_overflowed(sbufp)) + err(-1, "sbuf_overflowed()"); + if (setenv("LD_PRELOAD", sbuf_data(sbufp), 1) == -1) + err(-1, "Error in setenv(LD_PRELOAD)"); + sbuf_delete(sbufp); + if (cap_enter() < 0) err(-1, "cap_enter() failed"); (void)fexecve(fd_rtld, argv, environ); + dprintf(2, "ERROR: fexecve() failed; errno = %d\n", errno); } int