Date: Sat, 30 Jan 2010 20:28:39 +0000 (UTC) From: Robert Watson <rwatson@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r203243 - in projects/capabilities8: lib lib/libc/sys lib/libcapability lib/libcapsicum usr.bin/gzip Message-ID: <201001302028.o0UKSdIk099655@svn.freebsd.org>
index | next in thread | raw e-mail
Author: rwatson Date: Sat Jan 30 20:28:39 2010 New Revision: 203243 URL: http://svn.freebsd.org/changeset/base/203243 Log: Merge c173835 from the p4 TrustedBSD Capabilities branch to capabilities8: libcapability => libcapsicum Submitted by: Jonathan Anderson <jonathan.anderson at cl.cam.ac.uk> Added: projects/capabilities8/lib/libcapsicum/ projects/capabilities8/lib/libcapsicum/libcapsicum.3 projects/capabilities8/lib/libcapsicum/libcapsicum.c projects/capabilities8/lib/libcapsicum/libcapsicum.h projects/capabilities8/lib/libcapsicum/libcapsicum_host.3 projects/capabilities8/lib/libcapsicum/libcapsicum_host.c projects/capabilities8/lib/libcapsicum/libcapsicum_host_io.c projects/capabilities8/lib/libcapsicum/libcapsicum_internal.h projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox.3 projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox.c projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox_api.h projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox_io.c projects/capabilities8/lib/libcapsicum/libscapsicum_sandbox.c Deleted: projects/capabilities8/lib/libcapability/ Modified: projects/capabilities8/lib/Makefile projects/capabilities8/lib/libc/sys/cap_enter.2 projects/capabilities8/lib/libc/sys/cap_new.2 projects/capabilities8/usr.bin/gzip/Makefile projects/capabilities8/usr.bin/gzip/gzsandbox.c Modified: projects/capabilities8/lib/Makefile ============================================================================== --- projects/capabilities8/lib/Makefile Sat Jan 30 20:06:52 2010 (r203242) +++ projects/capabilities8/lib/Makefile Sat Jan 30 20:28:39 2010 (r203243) @@ -32,7 +32,7 @@ SUBDIR= ${_csu} libc libbsm libauditd li ncurses ${_libnetgraph} libradius librpcsvc libsbuf \ libtacplus libutil ${_libypclnt} libalias libarchive ${_libatm} \ libbegemot ${_libbluetooth} ${_libbsnmp} libbz2 \ - libcalendar libcam libcapability libcompat \ + libcalendar libcam libcapsicum libcompat \ libdevinfo libdevstat \ libdisk \ libdwarf libedit libexpat libfetch libftpio libgeom ${_libgpib} \ Modified: projects/capabilities8/lib/libc/sys/cap_enter.2 ============================================================================== --- projects/capabilities8/lib/libc/sys/cap_enter.2 Sat Jan 30 20:06:52 2010 (r203242) +++ projects/capabilities8/lib/libc/sys/cap_enter.2 Sat Jan 30 20:28:39 2010 (r203243) @@ -68,7 +68,7 @@ When combined with capabilities created may be used to create kernel-enforced sandboxes in which appropriately-crafted applications or application components may be run. Most sandboxes will be created and managed using the -.Xr libcapability +.Xr libcapsicum library, rather than using system calls directly. .Pp .Fn cap_getmode @@ -97,7 +97,7 @@ acquired rights as possible. .Sh SEE ALSO .Xr cap_new 2 , .Xr fexecve 2 , -.Xr libcapability 3 +.Xr libcapsicum 3 .Sh HISTORY Support for capabilities and capabilities mode was developed as part of the .Tn TrustedBSD Modified: projects/capabilities8/lib/libc/sys/cap_new.2 ============================================================================== --- projects/capabilities8/lib/libc/sys/cap_new.2 Sat Jan 30 20:06:52 2010 (r203242) +++ projects/capabilities8/lib/libc/sys/cap_new.2 Sat Jan 30 20:28:39 2010 (r203243) @@ -88,7 +88,7 @@ descriptor, including open file flags, b Many applications will prefer to use the .Xr cap_limitfd 3 library call, part of -.Xr libcapability 3 , +.Xr libcapsicum 3 , as it offers a more convenient interface. .Pp .Fn cap_getrights @@ -455,7 +455,7 @@ argument is not a capability. .Xr unlinkat 2 , .Xr write 2 , .Xr cap_limitfd 3 , -.Xr libcapability 3 , +.Xr libcapsicum 3 , .Xr sem_getvalue 3 , .Xr sem_post 3 , .Xr sem_trywait 3 , Added: projects/capabilities8/lib/libcapsicum/libcapsicum.3 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/capabilities8/lib/libcapsicum/libcapsicum.3 Sat Jan 30 20:28:39 2010 (r203243) @@ -0,0 +1,116 @@ +.\" +.\" Copyright (c) 2009 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" WARNING: THIS IS EXPERIMENTAL SECURITY SOFTWARE THAT MUST NOT BE RELIED +.\" ON IN PRODUCTION SYSTEMS. IT WILL BREAK YOUR SOFTWARE IN NEW AND +.\" UNEXPECTED WAYS. +.\" +.\" This software was developed at the University of Cambridge Computer +.\" Laboratory with support from a grant from Google, Inc. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 11, 2009 +.Os +.Dt LIBCAPABILITY 3 +.Sh NAME +.Nm libcapsicum +.Nd "library interface to capability-mode services" +.Sh LIBRARY +.Lb libcapsicum +.Sh SYNOPSIS +.In sys/types.h +.In sys/capability.h +.In libcapsicum.h +.Ft int +.Fn lc_limitfd "int fd" "cap_rights_t rights" +.Sh DESCRIPTION +.Nm +implements APIs that allow applications to create, manage, and interact with +sandboxed software services running in capability mode, described in +.Xr cap_enter 2 . +Applications linked against +.Nm +will use one or both of "host" and "sandbox" APIs, depending on whether they +consume or produce sandboxed services. +.Nm +will start sandboxed components using a sandbox-specific run-time linker, +.Xr rtld-elf-cap 1 , +rather than the standard +.Xr rtld-elf 1 . +.Pp +Host processes use the +.Nm +host API, +described in +.Xr libcapsicum_host 3 , +to launch compartmentalized components in sandboxes. +They may also use +.Nm +to communication with the sandboxed service based on socket I/O or remote +procedure call (RPC). +.Pp +Sandbox processes run in capability mode, and are only able to use resources +either assigned to the sandbox during creation, or later explicitly passed to +the process. +Sandbox processes use the +.Nm +sandbox API, +described in +.Xr libcapsicum_sandbox 3 . +Sandboxed processes themselves may launch software components in further +sandboxes, so a single program may use both host and sandbox APIs. +.Sh CAPABILITY API +.Fn lc_limitfd +is a wrapper around +.Xr cap_new 2 , +.Xr dup2 2 , +and +.Xr close 2 . +which takes an existing file descriptor and replaces it with a capability +with the requested rights mask. +.Sh SEE ALSO +.Xr rpcgen 1 , +.Xr rtld-elf 1 , +.Xr rtld-elf-cap 1 , +.Xr cap_enter 2 , +.Xr cap_new 2 , +.Xr close 2 , +.Xr dup2 2 , +.Xr libcapsicum_host 3 , +.Xr libcapsicum_sandbox 3 , +.Xr unix 4 +.Sh HISTORY +Support for capabilities and capabilities mode was developed as part of the +.Tn TrustedBSD +Project. +.Sh BUGS +WARNING: THIS IS EXPERIMENTAL SECURITY SOFTWARE THAT MUST NOT BE RELIED ON IN +PRODUCTION SYSTEMS. IT WILL BREAK YOUR SOFTWARE IN NEW AND UNEXPECTED WAYS. +.Sh AUTHORS +These functions and the capability facility were created by +.An "Robert N. M. Watson" +at the University of Cambridge Computer Laboratory with support from a grant +from Google, Inc. Added: projects/capabilities8/lib/libcapsicum/libcapsicum.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/capabilities8/lib/libcapsicum/libcapsicum.c Sat Jan 30 20:28:39 2010 (r203243) @@ -0,0 +1,268 @@ +/*- + * Copyright (c) 2009 Robert N. M. Watson + * All rights reserved. + * + * WARNING: THIS IS EXPERIMENTAL SECURITY SOFTWARE THAT MUST NOT BE RELIED + * ON IN PRODUCTION SYSTEMS. IT WILL BREAK YOUR SOFTWARE IN NEW AND + * UNEXPECTED WAYS. + * + * This software was developed at the University of Cambridge Computer + * Laboratory with support from a grant from Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * 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#1 $ + */ + +#include <sys/types.h> +#include <sys/capability.h> +#include <sys/socket.h> + +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include "libcapsicum.h" +#include "libcapsicum_internal.h" +#include "libcapsicum_sandbox_api.h" + +int +lc_limitfd(int fd, cap_rights_t rights) +{ + int fd_cap; + int error; + + fd_cap = cap_new(fd, rights); + if (fd_cap < 0) + return (-1); + if (dup2(fd_cap, fd) < 0) { + error = errno; + close(fd_cap); + errno = error; + return (-1); + } + close(fd_cap); + return (0); +} + +void +_lc_dispose_rights(int *fdp, int fdcount) +{ + int i; + + for (i = 0; i < fdcount; i++) + close(fdp[i]); +} + +/* + * Given a 'struct msghdr' returned by a successful call to recvmsg(), + * extract up to the desired number of file descriptors (or clean up the + * mess if something goes wrong). + */ +int +_lc_receive_rights(struct msghdr *msg, int *fdp, int *fdcountp) +{ + int *cmsg_fdp, fdcount, i, scmrightscount; + struct cmsghdr *cmsg; + + /* + * Walk the complete control message chain to count received control + * messages and rights. If there is more than one rights message or + * there are too many file descriptors, re-walk and close them all + * and return an error. + */ + fdcount = 0; + scmrightscount = 0; + for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(msg, cmsg)) { + if (cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_RIGHTS) + continue; + fdcount += (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); + scmrightscount++; + } + if (scmrightscount > 1 || fdcount > *fdcountp) { + for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(msg, cmsg)) { + if (cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_RIGHTS) + continue; + cmsg_fdp = (int *)CMSG_DATA(cmsg); + fdcount = (cmsg->cmsg_len - CMSG_LEN(0)) / + sizeof(int); + _lc_dispose_rights(cmsg_fdp, fdcount); + } + errno = EBADMSG; + return (-1); + } + + /* + * Re-walk the control messages and copy out the file descriptor + * numbers, return success. No need to recalculate fdcount. + */ + for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(msg, cmsg)) { + if (cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_RIGHTS) + continue; + cmsg_fdp = (int *)CMSG_DATA(cmsg); + for (i = 0; i < fdcount; i++) + fdp[i] = cmsg_fdp[i]; + } + *fdcountp = fdcount; + return (0); +} + +ssize_t +_lc_send(int fd, const void *msg, size_t len, int flags, int lc_flags) +{ + ssize_t retlen; + + if (fd == -1 || fd == 0) { + errno = ECHILD; + return (-1); + } + if (lc_flags & LC_IGNOREEINTR) { + do { + retlen = send(fd, msg, len, flags); + } while (retlen < 0 && errno == EINTR); + } else + retlen = send(fd, msg, len, flags); + return (retlen); +} + +ssize_t +_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 * + sizeof(int))]; + struct cmsghdr *cmsg; + struct msghdr msghdr; + struct iovec iov; + ssize_t retlen; + int i; + + if (fdcount == 0) + return (_lc_send(fd, msg, len, flags, lc_flags)); + + if (fd == -1 || fd == 0) { + errno = ECHILD; + return (-1); + } + + if (fdcount > LIBCAPABILITY_SANDBOX_API_MAXRIGHTS) { + errno = EMSGSIZE; + return (-1); + } + + bzero(&iov, sizeof(iov)); + iov.iov_base = __DECONST(void *, msg); + iov.iov_len = len; + + bzero(&cmsgbuf, sizeof(cmsgbuf)); + cmsg = (struct cmsghdr *)cmsgbuf; + cmsg->cmsg_len = CMSG_SPACE(fdcount * sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + for (i = 0; i < fdcount; i++) + ((int *)CMSG_DATA(cmsg))[i] = fdp[i]; + + bzero(&msghdr, sizeof(msghdr)); + msghdr.msg_iov = &iov; + msghdr.msg_iovlen = 1; + msghdr.msg_control = cmsg; + msghdr.msg_controllen = cmsg->cmsg_len; + + if (lc_flags & LC_IGNOREEINTR) { + do { + retlen = sendmsg(fd, &msghdr, flags); + } while (retlen < 0 && errno == EINTR); + } else + retlen = sendmsg(fd, &msghdr, flags); + return (retlen); +} + +ssize_t +_lc_recv(int fd, void *buf, size_t len, int flags, int lc_flags) +{ + ssize_t retlen; + + if (fd == -1 || fd == 0) { + errno = ESRCH; + return (-1); + } + if (lc_flags & LC_IGNOREEINTR) { + do { + retlen = recv(fd, buf, len, flags); + } while (retlen < 0 && errno == EINTR); + return (retlen); + } else + return (recv(fd, buf, len, flags)); +} + +ssize_t +_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 * + sizeof(int))]; + struct msghdr msghdr; + struct iovec iov; + ssize_t retlen; + + if (*fdcountp == 0) + return (_lc_recv(fd, buf, len, flags, lc_flags)); + + if (fd == -1 || fd == 0) { + errno = ECHILD; + return (-1); + } + + if (*fdcountp > LIBCAPABILITY_SANDBOX_API_MAXRIGHTS) { + errno = EMSGSIZE; + return (-1); + } + + bzero(&iov, sizeof(iov)); + iov.iov_base = buf; + iov.iov_len = len; + + bzero(cmsgbuf, sizeof(cmsgbuf)); + bzero(&msghdr, sizeof(msghdr)); + msghdr.msg_iov = &iov; + msghdr.msg_iovlen = 1; + msghdr.msg_control = cmsgbuf; + msghdr.msg_controllen = sizeof(cmsgbuf); + + if (lc_flags & LC_IGNOREEINTR) { + do { + retlen = recvmsg(fd, &msghdr, flags); + } while (retlen < 0 && errno == EINTR); + } else + retlen = recvmsg(fd, &msghdr, flags); + if (retlen < 0) + return (-1); + if (_lc_receive_rights(&msghdr, fdp, fdcountp) < 0) + return (-1); + return (retlen); +} Added: projects/capabilities8/lib/libcapsicum/libcapsicum.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/capabilities8/lib/libcapsicum/libcapsicum.h Sat Jan 30 20:28:39 2010 (r203243) @@ -0,0 +1,212 @@ +/*- + * Copyright (c) 2009 Robert N. M. Watson + * All rights reserved. + * + * WARNING: THIS IS EXPERIMENTAL SECURITY SOFTWARE THAT MUST NOT BE RELIED + * ON IN PRODUCTION SYSTEMS. IT WILL BREAK YOUR SOFTWARE IN NEW AND + * UNEXPECTED WAYS. + * + * This software was developed at the University of Cambridge Computer + * Laboratory with support from a grant from Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * 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#1 $ + */ + +#ifndef _LIBCAPABILITY_H_ +#define _LIBCAPABILITY_H_ + +#include <sys/cdefs.h> +#include <sys/capability.h> + +__BEGIN_DECLS + +struct lc_sandbox; +struct lc_host; + +/* + * Description of a library passed to lch_start_libs(). + */ +struct lc_library { + const char *lcl_libpath; + const char *lcl_libname; + int lcl_fd; +}; + + +/* A list of file descriptors, which can be passed around in shared memory */ +struct lc_fdlist; + + +struct lc_fdlist* lc_fdlist_new(void); +struct lc_fdlist* lc_fdlist_dup(struct lc_fdlist *orig); +void lc_fdlist_free(struct lc_fdlist *l); + +/* Size of an FD list in bytes, including all associated string data */ +int lc_fdlist_size(struct lc_fdlist *l); + + +/* + * Add a file descriptor to the list. + * + * l the list to add to + * subsystem a software component name, e.g. "org.freebsd.rtld-elf" + * 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 + */ +int lc_fdlist_add(struct lc_fdlist **l, + const char *subsystem, const char *classname, + const char *name, int fd); + +/* + * Like lc_fdlist_add(), but allows capability rights to be specified. The file + * descriptor will be wrapped in a capability with the given rights (so if the + * descriptor *is* a capability, its rights will be constrained according to this + * rights mask) + */ +int lc_fdlist_addcap(struct lc_fdlist **l, + const char *subsystem, const char *classname, + const char *name, int fd, cap_rights_t rights); + +/* + * Look up a file descriptor. + * + * Multiple entries with the same classname are allowed, so iterating through + * all instances of a class is done by supplying an integer 'pos' which is used + * internally to skip entries which have already been seen. If 'pos' is 0 or NULL, + * the first matching entry will be returned. + */ +int lc_fdlist_lookup(struct lc_fdlist *l, + const char *subsystem, const char *classname, + char **name, int *fdp, int *pos); + +/* + * Capability interfaces. + */ +int lc_limitfd(int fd, cap_rights_t rights); + +/* + * Global policy interface to ask whether we should, in fact, sandbox a + * particular optionally sandboxed service, by name. + */ +int lch_autosandbox_isenabled(const char *servicename); + +/* + * Interfaces to start and stop capability mode sandboxs. + */ +int lch_start(const char *sandbox, char *const argv[], u_int flags, + 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_sandbox **lcspp); +int lch_startfd(int fd_sandbox, const char *binname, char *const argv[], + u_int flags, 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_sandbox **lcspp); +void lch_stop(struct lc_sandbox *lcsp); + +/* + * Flags to lch_start_flags: + */ +#define LCH_PERMIT_STDERR 0x00000001 +#define LCH_PERMIT_STDOUT 0x00000002 + +/* + * Interfaces to query state about capability mode sandboxs. + */ +int lch_getsock(struct lc_sandbox *lcsp, int *fdp); +int lch_getpid(struct lc_sandbox *lcsp, pid_t *pidp); +int lch_getprocdesc(struct lc_sandbox *lcsp, int *fdp); + +/* + * Message-passing APIs for the host environment. + */ +struct iovec; +ssize_t lch_recv(struct lc_sandbox *lcsp, void *buf, size_t len, int flags); +ssize_t lch_recv_rights(struct lc_sandbox *lcsp, void *buf, size_t len, + int flags, int *fdp, int *fdcountp); +ssize_t lch_send(struct lc_sandbox *lcsp, const void *msg, size_t len, + int flags); +ssize_t lch_send_rights(struct lc_sandbox *lcsp, const void *msg, size_t len, + int flags, int *fdp, int fdcount); + +/* + * RPC APIs for the host environment. + */ +int lch_rpc(struct lc_sandbox *lcsp, u_int32_t opno, struct iovec *req, + int reqcount, struct iovec *rep, int repcount, size_t *replenp); +int lch_rpc_rights(struct lc_sandbox *lcsp, u_int32_t opno, + struct iovec *req, int reqcount, int *req_fdp, int req_fdcount, + struct iovec *rep, int repcount, size_t *replenp, int *rep_fdp, + int *rep_fdcountp); + +/* + * Interfaces to query state from within capability mode sandboxes. + */ +int lcs_get(struct lc_host **lchpp); +int lcs_getsock(struct lc_host *lchp, int *fdp); + +/* + * Message-passing APIs for the sandbox environment. + */ +ssize_t lcs_recv(struct lc_host *lchp, void *buf, size_t len, int flags); +ssize_t lcs_recv_rights(struct lc_host *lchp, void *buf, size_t len, + int flags, int *fdp, int *fdcountp); +ssize_t lcs_send(struct lc_host *lchp, const void *msg, size_t len, + int flags); +ssize_t lcs_send_rights(struct lc_host *lchp, const void *msg, size_t len, + int flags, int *fdp, int fdcount); + +/* + * RPC APIs for the sandbox environment. + */ +int lcs_recvrpc(struct lc_host *lchp, u_int32_t *opnop, + u_int32_t *seqnop, u_char **bufferp, size_t *lenp); +int lcs_recvrpc_rights(struct lc_host *lchp, u_int32_t *opnop, + u_int32_t *seqnop, u_char **bufferp, size_t *lenp, int *fdp, + int *fdcountp); +int lcs_sendrpc(struct lc_host *lchp, u_int32_t opno, u_int32_t seqno, + struct iovec *rep, int repcount); +int lcs_sendrpc_rights(struct lc_host *lchp, u_int32_t opno, + u_int32_t seqno, struct iovec *rep, int repcount, int *fdp, + int fdcount); + +/* + * Actually an rtld-elf-cap symbol, but declared here so it is available to + * applications. + */ +int ld_libcache_lookup(const char *libname, int *fdp); +int ld_insandbox(void); + +/* + * Applications may declare an alternative entry point to the default ELF + * entry point for their binary, which will be used in preference to 'main' + * in the sandbox environment. + */ +int cap_main(int argc, char *argv[]); + +__END_DECLS + +#endif /* !_LIBCAPABILITY_H_ */ Added: projects/capabilities8/lib/libcapsicum/libcapsicum_host.3 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/capabilities8/lib/libcapsicum/libcapsicum_host.3 Sat Jan 30 20:28:39 2010 (r203243) @@ -0,0 +1,236 @@ +.\" +.\" Copyright (c) 2009 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" WARNING: THIS IS EXPERIMENTAL SECURITY SOFTWARE THAT MUST NOT BE RELIED +.\" ON IN PRODUCTION SYSTEMS. IT WILL BREAK YOUR SOFTWARE IN NEW AND +.\" UNEXPECTED WAYS. +.\" +.\" This software was developed at the University of Cambridge Computer +.\" Laboratory with support from a grant from Google, Inc. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 11, 2009 +.Os +.Dt LIBCAPABILITY_HOST 3 +.Sh NAME +.Nm libcapsicum +.Nd "library interface to capability-mode services" +.Sh LIBRARY +.Lb libcapsicum +.Sh SYNOPSIS +.In sys/types.h +.In sys/capability.h +.In libcapsicum.h +.Ft int +.Fn lch_start "const char *sandbox" "char *const argv[]" "u_int flags" "struct lc_sandbox **lcsp" +.Ft int +.Fn lch_startfd "int fd_sandbox" "char *const argv[]" "u_int flags" "struct lc_sandbox **lcsp" +.Ft void +.Fn lch_stop "struct lc_sandbox *lcsp" +.Ft int +.Fn lch_autosandbox_isenabled "const char *servicename" +.Ft int +.Fn lch_getsock "struct lc_sandbox *lcsp" "int *fdp" +.Ft int +.Fn lch_getpid "struct lc_sandbox *lcsp" "pid_t *pidp" +.Ft int +.Fn lch_getprocdesc "struct lc_sandbox *lcsp" "int *fdp" +.Ft ssize_t +.Fn lch_recv "struct lc_sandbox *lcsp, void *buf" "size_t len" "int flags" +.Ft ssize_t +.Fn lch_recv_rights "struct lc_sandbox *lcsp" "void *buf" "size_t len" "int flags" "int *fdp" "int *fdcountp" +.Ft int +.Fn lch_rpc "struct lc_sandbox *lcsp" "u_int32_t opno" "struct iovec *req" "int reqcount" "struct iovec *rep" "int repcount" "size_t *replenp" +.Ft int +.Fn lch_rpc_rights "struct lc_sandbox *lcsp" "u_int32_t opno" "struct iovec *req" "int reqcount" "int *req_fdp" "int req_fdcount" "struct iovec *rep" "int repcount" "size_t *replenp" "int *rep_fdp" "int *rep_fdcountp" +.Ft ssize_t +.Fn lch_send "struct lc_sandbox *lcsp" "const void *msg" "size_t len" "int flags" +.Ft ssize_t +.Fn lch_send_rights "struct lc_sandbox *lcsp" "const void *msg" "size_t len" "int flags" "int *fdp" "int fdcount" +.Sh DESCRIPTION +The +.Nm +library routines provide services for processes hosting or running in +capability mode. +Depending on the requirements of the host and sandbox, the API can simply be +used to set up and stop sandboxes, used to manage I/O using a +.Xr unix 4 +domain socket connection to the sandbox, or can provide a basic remote +procedure call (RPC) facility. +Applications may also use RPC generators such as +.Xr rpcgen 1 +to build event handling and marshaling code. +.Pp +This man page describes the host API. +General information on +.Nm +may be found in +.Xr libcapsicum 3 . +Information on the sandbox API may be found in +.Xr libcapsicum_sandbox 3 . +.Sh HOST API +The +.Nm +host API allows processes to start, stop, and manage sandboxes running in +capability mode. +Host API functions can be identified by their function name prefix, +.Dv lch_ . +.Pp +Each executing sandbox instance is described by an opaque +.Dt "struct lc_sandbox *" , +which is returned by +.Fn lch_start +for successfully started sandboxes, and passed into other APIs to indicate +which sandbox should be acted on. +.Fn lch_start +creates a new executing sandboxes, given the name of the sandbox binary via +.Va sandbox , +and command line arguments +.Va argv , +and optional flags +.Va flags +to fine-tune aspects of sandbox operation; the only currently defined flag is +.Dv LCH_PERMIT_STDERR , +which allows the sandbox to write to the current process's +.Dv stderr . +By default, this is not permitted. +.Pp +.Fn lch_startfd +accept a file descriptor argument, +.Va fd_sandbox , +rather than a path, so is appropriate for use within a sandbox. +.Pp +Executing sandboxes may be stopped (and all state freed) using +.Fn lch_stop . +Following a call to +.Fn lch_stop , +the +.Va lchp +argument will no longer be valid. +.Pp +Libraries and tools performing self-compartmentalization can use the +interface +.Nm lch_autosandbox_isenabled +along with a unique string identifying their service to determine whether or +not a global policy affecting the service requires sandboxing to be enabled +or not. +.Pp +Properties of the sandbox, such as the socket used to communicate with it, +the proces descriptor for the sandbox process, and the pid, may be queried +using +.Fn lch_getsock , +.Fn lch_getprocdesc , +and +.Fn lch_getpid . +.Pp +.Nm +implements a number of I/O functions as part of the host API, which are +documented in +.Xr libcapsicum_host 3 . +.Fn lch_recv +and +.Fn lch_send +provide simple wrappers around +.Xr recv 2 +and +.Xr send 2 +to avoid sandbox consumers from having to query sandbox socket file +descriptors before use. +.Pp +.Fn lch_recv_rights +and +.Fn lch_send_rights +are similar, but allow file descriptors to be attached the the messages +received and sent. +Both accept a pointer to a file descriptor array, +.Va fdp . +Callers to +.Fn lch_recv_rights +will pass in the length of the array via +.Va fdcountp , +whose value will be changed to the actual number of file descriptors +received. +Callers to +.Fn lch_send_rights +will pass in the number of file descriptors in the array via +.Va fdcount . +.Pp +.Fn lch_rpc +provides a simple synchronous RPC facility, and is intended to be used in +coordination with the +.Fn lcs_recvrpc +and +.Fn lcs_sendrpc +sandbox APIs. +The host provides an operation number meaningful to the sandbox, +.Va opno, +RPC arguments represented by +.Va req +and +.Va reqcount +using an +.Vt iovec +in the style of +.Xr writev 2 , +and similar receive buffers passed via +.Va rep +and +.Va repcount . +If the RPC fails, -1 will be returned, or 0 and the size of any reply will be +returned by reference using +.Va replenp . +.Nm lch_rpc_rights +allows the sending and receiving of file descriptors as part of the RPC +operation. +.Sh SEE ALSO +.Xr rpcgen 1 , +.Xr recv 2 , +.Xr send 2 , +.Xr writev 2 , +.Xr free 3 , +.Xr libcapsicum 3 , +.Xr libcapsicum_sandbox 3 , +.Xr malloc 3 , +.Xr unix 4 +.Sh HISTORY +Support for capabilities and capabilities mode was developed as part of the +.Tn TrustedBSD +Project. +.Sh BUGS +WARNING: THIS IS EXPERIMENTAL SECURITY SOFTWARE THAT MUST NOT BE RELIED ON IN +PRODUCTION SYSTEMS. IT WILL BREAK YOUR SOFTWARE IN NEW AND UNEXPECTED WAYS. +.Pp +All sequence numbers will always have the value 0. +This is fine from a retransmission perspective, as generally no +retransmission should be required, but consumers should serialize use of the +RPC service when consuming it from concurrent callers (such as multiple +threads or multiple processes) to prevent I/O interlacing from corrupting the +RPC stream. +.Sh AUTHORS +These functions and the capability facility were created by +.An "Robert N. M. Watson" +at the University of Cambridge Computer Laboratory with support from a grant +from Google, Inc. Added: projects/capabilities8/lib/libcapsicum/libcapsicum_host.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/capabilities8/lib/libcapsicum/libcapsicum_host.c Sat Jan 30 20:28:39 2010 (r203243) @@ -0,0 +1,422 @@ +/*- + * Copyright (c) 2009 Robert N. M. Watson + * All rights reserved. + * + * WARNING: THIS IS EXPERIMENTAL SECURITY SOFTWARE THAT MUST NOT BE RELIED + * ON IN PRODUCTION SYSTEMS. IT WILL BREAK YOUR SOFTWARE IN NEW AND + * UNEXPECTED WAYS. + * + * This software was developed at the University of Cambridge Computer + * Laboratory with support from a grant from Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * 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#1 $ + */ + +#include <sys/param.h> +#include <sys/capability.h> +#include <sys/procdesc.h> +#include <sys/sbuf.h> +#include <sys/socket.h> +#include <sys/uio.h> + +#include <errno.h> +#include <fcntl.h> +#include <libgen.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "libcapsicum.h" +#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 | \ + 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 _PATH_LIB "/lib" +#define _PATH_USR_LIB "/usr/lib" +#define LIBC_SO "libc.so.7" +#define LIBCAPABILITY_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) + 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) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001302028.o0UKSdIk099655>
