Date: Wed, 10 Jun 2009 11:31:29 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 163973 for review Message-ID: <200906101131.n5ABVTGI044046@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=163973 Change 163973 by rwatson@rwatson_freebsd_capabilities on 2009/06/10 11:31:01 Break out host-specific portions of libcapability.c into libcapability_host.c. Affected files ... .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/Makefile#4 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#3 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#1 add Differences ... ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/Makefile#4 (text+ko) ==== @@ -4,7 +4,8 @@ SRCS= \ libcapability.c \ - libcapability_agent.c + libcapability_agent.c \ + libcapability_host.c INCS= libcapability.h ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.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/libcapability/libcapability.c#2 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#3 $ */ #include <sys/types.h> @@ -47,39 +47,7 @@ #include <unistd.h> #include "libcapability.h" -#include "libcapability_agent_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_SEEK | CAP_FSTATFS | \ - CAP_FEXECVE | CAP_MMAP | \ - CAP_MAPEXEC) -#define LIBCAPABILITY_CAPMASK_AGENT LIBCAPABILITY_CAPMASK_BIN -#define LIBCAPABILITY_CAPMASK_LDSO LIBCAPABILITY_CAPMASK_BIN -#define LIBCAPABILITY_CAPMASK_LIBC LIBCAPABILITY_CAPMASK_BIN -#define LIBCAPABILITY_CAPMASK_LIBZ LIBCAPABILITY_CAPMASK_BIN - -#define _PATH_LIB "/lib" -#define LIBC_SO "libc.so.7" -#define LIBZ_SO "libz.so.4" -extern char **environ; - -#define LD_ELF_CAP_SO "/libexec/ld-elf-cap.so.1" -char *ldso_argv[] = { - __DECONST(char *, LD_ELF_CAP_SO), - NULL, -}; - -int closefrom(int lowfd); - -struct lc_agent { - int lca_fd_sock; - int lca_fd_procdesc; - pid_t lca_pid; -}; - int lc_limitfd(int fd, cap_rights_t rights) { @@ -98,254 +66,3 @@ close(fd_cap); return (0); } - -/* - * 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(int fd_count, int *fds) -{ - int i; - - /* - * First, move all our descriptors up the range. - */ - for (i = 0; i < fd_count; i++) { - if (dup2(fds[i], fd_count + i) < 0) - return (-1); - } - - /* - * Now put them back. - */ - for (i = 0; i < fd_count; i++) { - if (dup2(fd_count + i, fds[i]) < 0) - return (-1); - } - - /* - * Close the descriptors that we moved, as well as any others that - * were left open by the caller. - */ - if (closefrom(fd_count) < 0) - return (-1); - - return (0); -} - -static void -lch_agent(int fd_sock, int fd_agent, int fd_ldso, int fd_libc, int fd_libz) -{ - char *env_caplibindex, *env_libcapability_agent_api; - int fd_array[8], fd_devnull; - - fd_devnull = open(_PATH_DEVNULL, O_RDWR); - if (fd_devnull < 0) - return; - - if (lc_limitfd(fd_devnull, LIBCAPABILITY_CAPMASK_DEVNULL) < 0) - return; - if (lc_limitfd(fd_agent, LIBCAPABILITY_CAPMASK_AGENT) < 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_ldso, LIBCAPABILITY_CAPMASK_LIBC) < 0) - return; - - fd_array[0] = fd_devnull; - fd_array[1] = fd_devnull; - fd_array[2] = fd_devnull; - fd_array[3] = fd_agent; - fd_array[4] = fd_sock; - fd_array[5] = fd_ldso; - fd_array[6] = fd_libc; - - if (lch_installfds(7, fd_array) < 0) - return; - - /* - * Pass library list into rtld-elf-cap. - */ - if (asprintf(&env_caplibindex, "%d:%s,%d:%s", fd_libc, LIBC_SO, - fd_libz, LIBZ_SO) == -1) - return; - if (setenv("LD_CAPLIBINDEX", env_caplibindex, 1) == -1) - return; - free(env_caplibindex); - - /* - * Make sure that libcapability in the sandbox knows that its API - * assumptions hold. - */ - if (asprintf(&env_libcapability_agent_api, "%s:%d", - LIBCAPABILITY_AGENT_API_SOCK, fd_sock) == -1) - return; - if (setenv(LIBCAPABILITY_AGENT_API_ENV, env_libcapability_agent_api, - 1) == -1) - return; - free(env_libcapability_agent_api); - - if (cap_enter() < 0) - return; - - (void)fexecve(fd_ldso, ldso_argv, environ); -} - -int -lch_start(const char *agent, struct lc_agent **lcapp) -{ - struct lc_agent *lcap; - int fd_agent, fd_ldso, fd_libc, fd_libz, fd_procdesc, fd_sockpair[2]; - int error, val; - pid_t pid; - - fd_agent = fd_ldso = fd_libc = fd_libz = fd_procdesc = - fd_sockpair[0] = fd_sockpair[1] = -1; - - lcap = malloc(sizeof(*lcap)); - if (lcap == NULL) - return (-1); - bzero(lcap, sizeof(*lcap)); - - /* Try the agent first so that ENOENT most likely refers to it. */ - fd_agent = open(agent, O_RDONLY); - if (fd_agent < 0) - goto out_error; - - fd_ldso = open(LD_ELF_CAP_SO, O_RDONLY); - if (fd_ldso < 0) - goto out_error; - - fd_libc = open(_PATH_LIB "/" LIBC_SO, O_RDONLY); - if (fd_libc < 0) - goto out_error; - - fd_libz = open(_PATH_LIB "/" LIBZ_SO, O_RDONLY); - if (fd_libz < 0) - goto out_error; - - if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd_sockpair) < 0) - goto out_error; - - val = 1; - if (setsockopt(fd_sockpair[0], SOL_SOCKET, SO_NOSIGPIPE, &val, - sizeof(val)) < 0) { - fd_sockpair[0] = fd_sockpair[1] = -1; - goto out_error; - } - - pid = pdfork(&fd_procdesc); - if (pid < 0) { - fd_procdesc = -1; - goto out_error; - } - if (pid == 0) { - lch_agent(fd_sockpair[1], fd_agent, fd_ldso, fd_libc, - fd_libz); - exit(-1); - } - close(fd_libz); - close(fd_libc); - close(fd_ldso); - close(fd_agent); - close(fd_sockpair[1]); - - lcap->lca_fd_procdesc = fd_procdesc; - lcap->lca_fd_sock = fd_sockpair[0]; - lcap->lca_pid = pid; - *lcapp = lcap; - - return (0); - -out_error: - error = errno; - if (fd_sockpair[0] != -1) - close(fd_sockpair[0]); - if (fd_sockpair[1] != -1) - close(fd_sockpair[1]); - if (fd_libz != -1) - close(fd_libz); - if (fd_libc != -1) - close(fd_libc); - if (fd_ldso != -1) - close(fd_ldso); - if (fd_agent != -1) - close(fd_agent); - if (lcap != NULL) - free(lcap); - errno = error; - return (-1); -} - -void -lch_stop(struct lc_agent *lcap) -{ - - close(lcap->lca_fd_sock); - close(lcap->lca_fd_procdesc); - lcap->lca_fd_sock = -1; - lcap->lca_fd_procdesc = -1; - lcap->lca_pid = -1; -} - -int -lch_getsock(struct lc_agent *lcap, int *fdp) -{ - - *fdp = lcap->lca_fd_sock; - return (0); -} - -int -lch_getpid(struct lc_agent *lcap, pid_t *pidp) -{ - - *pidp = lcap->lca_pid; - return (0); -} - -int -lch_getprocdesc(struct lc_agent *lcap, int *fdp) -{ - - *fdp = lcap->lca_fd_procdesc; - return (0); -} - -/* - * Simple I/O wrappers for capability sockets. Possibly more keeping an eye - * on the worker should take place here. - */ -ssize_t -lch_send(struct lc_agent *lcap, const void *msg, size_t len, int flags) -{ - - if (lcap->lca_fd_sock == -1 || - lcap->lca_fd_sock == 0) { - errno = ESRCH; - return (-1); - } - return (send(lcap->lca_fd_sock, msg, len, flags)); -} - -ssize_t -lch_recv(struct lc_agent *lcap, void *buf, size_t len, int flags) -{ - - if (lcap->lca_fd_sock == -1 || - lcap->lca_fd_sock == 0) { - errno = ESRCH; - return (-1); - } - return (recv(lcap->lca_fd_sock, buf, len, flags)); -}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906101131.n5ABVTGI044046>