svn commit: r203379 - in projects/capabilities8: lib/libc/gen
lib/libcapsicum libexec/rtld-elf libexec/rtld-elf-cap usr.bin/gzip
Robert Watson
rwatson at FreeBSD.org
Tue Feb 2 16:12:40 UTC 2010
Author: rwatson
Date: Tue Feb 2 16:12:39 2010
New Revision: 203379
URL: http://svn.freebsd.org/changeset/base/203379
Log:
Merge c174076, c174092, c174095, c174096, and c174128 from the p4 TrustedBSD
capabilities branch to capabilities8:
Added the weak symbol ld_libdirs()
ld_libdirs(int**) => ld_libdirs(int*,int*)
Implementation of ld_libdirs()
Ensure that the argument to add_libdir_paths() is not NULL
Use lc_fdlist for sandbox configuration. No more need for
ld_libcache, and libcapsicum has been simplified somewhat.
Submitted by: Jonathan Anderson <jonathan.anderson at cl.cam.ac.uk>
Added:
projects/capabilities8/lib/libc/gen/ld_libdirs.c
Deleted:
projects/capabilities8/libexec/rtld-elf-cap/rtld_libcache.c
projects/capabilities8/libexec/rtld-elf-cap/rtld_libcache.h
Modified:
projects/capabilities8/lib/libc/gen/Makefile.inc
projects/capabilities8/lib/libc/gen/Symbol.map
projects/capabilities8/lib/libcapsicum/libcapsicum.3
projects/capabilities8/lib/libcapsicum/libcapsicum.c
projects/capabilities8/lib/libcapsicum/libcapsicum.h
projects/capabilities8/lib/libcapsicum/libcapsicum_fdlist.c
projects/capabilities8/lib/libcapsicum/libcapsicum_host.c
projects/capabilities8/lib/libcapsicum/libcapsicum_internal.h
projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox.c
projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox_api.h
projects/capabilities8/libexec/rtld-elf-cap/Makefile
projects/capabilities8/libexec/rtld-elf/Symbol.map
projects/capabilities8/libexec/rtld-elf/rtld.c
projects/capabilities8/usr.bin/gzip/gzsandbox.c
Modified: projects/capabilities8/lib/libc/gen/Makefile.inc
==============================================================================
--- projects/capabilities8/lib/libc/gen/Makefile.inc Tue Feb 2 16:02:09 2010 (r203378)
+++ projects/capabilities8/lib/libc/gen/Makefile.inc Tue Feb 2 16:12:39 2010 (r203379)
@@ -20,7 +20,7 @@ SRCS+= __getosreldate.c __xuname.c \
getpeereid.c getprogname.c getpwent.c getttyent.c \
getusershell.c getvfsbyname.c glob.c \
initgroups.c isatty.c isinf.c isnan.c jrand48.c lcong48.c \
- ld_libcache.c ld_sandbox.c \
+ ld_libcache.c ld_libdirs.c ld_sandbox.c \
lockf.c lrand48.c mrand48.c nftw.c nice.c \
nlist.c nrand48.c opendir.c \
pause.c pmadvise.c popen.c posix_spawn.c \
Modified: projects/capabilities8/lib/libc/gen/Symbol.map
==============================================================================
--- projects/capabilities8/lib/libc/gen/Symbol.map Tue Feb 2 16:02:09 2010 (r203378)
+++ projects/capabilities8/lib/libc/gen/Symbol.map Tue Feb 2 16:12:39 2010 (r203379)
@@ -343,6 +343,7 @@ FBSD_1.1 {
ld_libcache_add;
ld_libcache_lookup;
ld_insandbox;
+ ld_libdirs;
posix_spawn;
posix_spawn_file_actions_addclose;
posix_spawn_file_actions_adddup2;
Added: projects/capabilities8/lib/libc/gen/ld_libdirs.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/capabilities8/lib/libc/gen/ld_libdirs.c Tue Feb 2 16:12:39 2010 (r203379)
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 2010 Jonathan Anderson
+ * 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.
+ */
+
+#include <errno.h>
+
+#pragma weak ld_libdirs
+int
+ld_libdirs(int *fds, int *fdlen)
+{
+
+ errno = EOPNOTSUPP;
+ return (-1);
+}
+
Modified: projects/capabilities8/lib/libcapsicum/libcapsicum.3
==============================================================================
--- projects/capabilities8/lib/libcapsicum/libcapsicum.3 Tue Feb 2 16:02:09 2010 (r203378)
+++ projects/capabilities8/lib/libcapsicum/libcapsicum.3 Tue Feb 2 16:12:39 2010 (r203379)
@@ -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 @@ file descriptor list API, described in
.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 ,
Modified: projects/capabilities8/lib/libcapsicum/libcapsicum.c
==============================================================================
--- projects/capabilities8/lib/libcapsicum/libcapsicum.c Tue Feb 2 16:02:09 2010 (r203378)
+++ projects/capabilities8/lib/libcapsicum/libcapsicum.c Tue Feb 2 16:12:39 2010 (r203379)
@@ -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 @@ 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 *
+ char cmsgbuf[CMSG_SPACE(LIBCAPSICUM_SANDBOX_API_MAXRIGHTS *
sizeof(int))];
struct cmsghdr *cmsg;
struct msghdr msghdr;
@@ -170,7 +170,7 @@ _lc_send_rights(int fd, const void *msg,
return (-1);
}
- if (fdcount > LIBCAPABILITY_SANDBOX_API_MAXRIGHTS) {
+ if (fdcount > LIBCAPSICUM_SANDBOX_API_MAXRIGHTS) {
errno = EMSGSIZE;
return (-1);
}
@@ -224,7 +224,7 @@ 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 *
+ char cmsgbuf[CMSG_SPACE(LIBCAPSICUM_SANDBOX_API_MAXRIGHTS *
sizeof(int))];
struct msghdr msghdr;
struct iovec iov;
@@ -238,7 +238,7 @@ _lc_recv_rights(int fd, void *buf, size_
return (-1);
}
- if (*fdcountp > LIBCAPABILITY_SANDBOX_API_MAXRIGHTS) {
+ if (*fdcountp > LIBCAPSICUM_SANDBOX_API_MAXRIGHTS) {
errno = EMSGSIZE;
return (-1);
}
Modified: projects/capabilities8/lib/libcapsicum/libcapsicum.h
==============================================================================
--- projects/capabilities8/lib/libcapsicum/libcapsicum.h Tue Feb 2 16:02:09 2010 (r203378)
+++ projects/capabilities8/lib/libcapsicum/libcapsicum.h Tue Feb 2 16:12:39 2010 (r203379)
@@ -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#4 $
+ * $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 @@ u_int lc_fdlist_size(struct lc_fdlist *l
* 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_autosandbox_isenabled(const char
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);
/*
@@ -222,6 +221,11 @@ int lcs_sendrpc_rights(struct lc_host *l
*/
int ld_libcache_lookup(const char *libname, int *fdp);
int ld_insandbox(void);
+/*
+ * If this call fails because the buffer 'fds' is too small, 'fdlen' will contain
+ * the size of the array which is actually required.
+ */
+int ld_libdirs(int *fds, int *fdlen);
/* If this call is successful, the caller is responsible for freeing 'fds'. */
int ld_libdirs(int **fds);
@@ -235,4 +239,4 @@ int cap_main(int argc, char *argv[]);
__END_DECLS
-#endif /* !_LIBCAPABILITY_H_ */
+#endif /* !_LIBCAPSICUM_H_ */
Modified: projects/capabilities8/lib/libcapsicum/libcapsicum_fdlist.c
==============================================================================
--- projects/capabilities8/lib/libcapsicum/libcapsicum_fdlist.c Tue Feb 2 16:02:09 2010 (r203378)
+++ projects/capabilities8/lib/libcapsicum/libcapsicum_fdlist.c Tue Feb 2 16:12:39 2010 (r203379)
@@ -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#4 $
+ * $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 @@ lc_fdlist_global(void)
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 @@ lc_fdlist_global(void)
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 @@ lc_fdlist_global(void)
* 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,6 +310,13 @@ int
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) {
@@ -401,7 +409,7 @@ lc_fdlist_lookup(struct lc_fdlist *lfp,
}
*fdp = entry->fd;
- if (pos) *pos = i + 1;
+ if (pos != NULL) *pos = i + 1;
successful = 1;
break;
}
@@ -421,14 +429,14 @@ lc_fdlist_getentry(struct lc_fdlist *lfp
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 @@ lc_fdlist_getentry(struct lc_fdlist *lfp
*fdp = entry->fd;
UNLOCK(lfp);
- (*pos)++;
+ if (pos) (*pos)++;
+
return (0);
}
@@ -536,3 +545,9 @@ lc_fdlist_storage_names(struct lc_fdlist
return (((char *) lfsp) + lc_fdlist_storage_size(lfsp) -
lfsp->namecapacity);
}
+
+void*
+_lc_fdlist_getstorage(struct lc_fdlist* lfp) {
+ return lfp->lf_storage;
+}
+
Modified: projects/capabilities8/lib/libcapsicum/libcapsicum_host.c
==============================================================================
--- projects/capabilities8/lib/libcapsicum/libcapsicum_host.c Tue Feb 2 16:02:09 2010 (r203378)
+++ projects/capabilities8/lib/libcapsicum/libcapsicum_host.c Tue Feb 2 16:12:39 2010 (r203379)
@@ -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#6 $
+ * $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)
-{
- u_int i;
- int highestfd;
- if (fd_count == 0)
- return (0);
+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)
+{
+ struct sbuf *sbufp;
+ int shmfd = -1;
+ size_t fdlistsize;
+ struct lc_fdlist *fds;
+ void *shm;
/*
- * 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.
+ * Inform the run-time linked of the binary's name.
*/
- highestfd = fds[0];
- for (i = 1; i < fd_count; i++) {
- if (fds[i] > highestfd)
- highestfd = fds[i];
- }
- highestfd++; /* Don't tread on the highest */
+ if (setenv("LD_BINNAME", binname, 1) == -1)
+ err(-1, "Error in setenv(LD_BINNAME)");
/*
- * First, move all our descriptors up the range.
+ * Create an anonymous shared memory segment for the FD list.
*/
- for (i = 0; i < fd_count; i++) {
- if (dup2(fds[i], highestfd + i) < 0)
- return (-1);
- }
+ shmfd = open("/tmp/jon-foo"/*SHM_ANON*/, O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if (shmfd < 0)
+ err(-1, "Error creating shared memory segment");
/*
- * Now put them back.
+ * Create and fill up the FD list.
*/
- for (i = 0; i < fd_count; i++) {
- if (dup2(highestfd + i, 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()");
/*
- * Close the descriptors that we moved, as well as any others that
- * were left open by the caller.
+ * 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.
*/
- closefrom(fd_count);
- return (0);
-}
+ 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()");
-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;
/*
- * Create an anonymous shared memory segment for the FD list.
+ * Find the fdlist shared memory segment.
*/
- 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;
+ int pos = 0;
+ if (lc_fdlist_lookup(fds, LIBCAPSICUM_FQNAME, "fdlist", NULL,
+ &shmfd, &pos) < 0)
+ err(-1, "Error in lc_fdlist_lookup(fdlist)");
+
+ char tmp[8];
+ sprintf(tmp, "%d", shmfd);
+ if (setenv(LIBCAPSICUM_SANDBOX_FDLIST, tmp, 1) == -1)
+ err(-1, "Error in setenv(LIBCAPSICUM_SANDBOX_FDLIST)");
/*
* Map it and copy the list.
*/
+ fdlistsize = lc_fdlist_size(fds);
+ if (ftruncate(shmfd, fdlistsize) < 0)
+ err(-1, "Error in ftruncate(shmfd)");
+
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;
-
- fdnum = 10;
- if (shmfd != -1)
- fdnum++;
-
- fdcount = fdnum + lcl_count;
- fd_array = malloc(fdcount * sizeof(int));
- if (fd_array == NULL)
- return;
-
- 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;
- }
+ /*
+ * Find RTLD.
+ */
+ if (lc_fdlist_lookup(fds, RTLD_CAP_FQNAME, "rtld", NULL, &fd_rtld,
+ NULL) < 0)
+ err(-1, "Error in lc_fdlist_lookup(RTLD)");
- if (lch_installfds(fdcount, fd_array) < 0)
- return;
+ /*
+ * 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)");
+
+ 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.
+ *
+ * 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 @@ lch_startfd_libs(int fd_sandbox, const c
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 @@ lch_startfd_libs(int fd_sandbox, const c
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 @@ lch_startfd_libs(int fd_sandbox, const c
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 @@ lch_startfd_libs(int fd_sandbox, const c
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 @@ lch_startfd_libs(int fd_sandbox, const c
close(fd_libsbuf);
close(fd_libcapsicum);
close(fd_libc);
- close(fd_ldso);
+ close(fd_rtld);
#endif
close(fd_sockpair[1]);
@@ -414,8 +369,8 @@ out_error:
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 @@ out_error:
}
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 @@ lch_start(const char *sandbox, char *con
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
Modified: projects/capabilities8/lib/libcapsicum/libcapsicum_internal.h
==============================================================================
--- projects/capabilities8/lib/libcapsicum/libcapsicum_internal.h Tue Feb 2 16:02:09 2010 (r203378)
+++ projects/capabilities8/lib/libcapsicum/libcapsicum_internal.h Tue Feb 2 16:12:39 2010 (r203379)
@@ -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#2 $
+ * $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 @@ struct lc_sandbox {
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(int fd, const void *msg
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_ */
Modified: projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox.c
==============================================================================
--- projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox.c Tue Feb 2 16:02:09 2010 (r203378)
+++ projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox.c Tue Feb 2 16:12:39 2010 (r203379)
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <limits.h>
+#include <stdio.h> /* TODO: temporary */
#include <stdlib.h>
#include <string.h>
@@ -54,9 +55,7 @@ static struct lc_host lch_global;
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 @@ lcs_get(struct lc_host **lchpp)
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);
}
Modified: projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox_api.h
==============================================================================
--- projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox_api.h Tue Feb 2 16:02:09 2010 (r203378)
+++ projects/capabilities8/lib/libcapsicum/libcapsicum_sandbox_api.h Tue Feb 2 16:12:39 2010 (r203379)
@@ -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"
/*
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list