svn commit: r208710 - projects/capabilities8/lib/libcapsicum
Robert Watson
rwatson at FreeBSD.org
Tue Jun 1 15:24:20 UTC 2010
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 <sys/mman.h>
#include <sys/stat.h>
+#define _WITH_DPRINTF
#include <errno.h>
#include <libcapsicum.h>
#include <pthread.h>
@@ -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 <sys/param.h>
@@ -41,6 +41,7 @@
#include <sys/socket.h>
#include <sys/uio.h>
+#define _WITH_DPRINTF
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -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
More information about the svn-src-projects
mailing list