Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 7 Jun 2009 19:47:14 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 163727 for review
Message-ID:  <200906071947.n57JlEvc076391@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=163727

Change 163727 by rwatson@rwatson_freebsd_capabilities on 2009/06/07 19:46:46

	Rework ifdef'ing of rtld-elf/rtld-elf-cap so that less unnecessary
	code is compiled in in the capability-mode case, avoiding
	unnecessary security exceptions as rtld tries to analyze and search
	library paths.
	
	Add caplibindex, a facility to pass shared libraries into
	capability-mode executables as file descriptors, with an
	environmental variable that maps file descriptors to library names.
	This allows callers to pre-populate the sandboxed rtld environment
	with the libraries a binary needs to run (such as libc).
	
	Always validate MNT_NOEXEC for libraries passed in this way, as this
	is the moral equivalent of LD_LIBRARY_PATH.

Affected files ...

.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/Makefile#15 edit
.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/rtld_caplibindex.c#1 add
.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/rtld_caplibindex.h#1 add
.. //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/rtld.c#14 edit

Differences ...

==== //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/Makefile#15 (text+ko) ====

@@ -1,5 +1,5 @@
 # $FreeBSD$
-# $P4: //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/Makefile#14 $
+# $P4: //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf-cap/Makefile#15 $
 
 WITHOUT_SSP=
 
@@ -9,11 +9,11 @@
 SRCS=		rtld_start.S \
 		reloc.c rtld.c rtld_lock.c map_object.c \
 		malloc.c xmalloc.c debug.c \
-		crtbrand.c
+		crtbrand.c rtld_caplibindex.c
 MAN=		rtld-elf-cap.1
 CSTD?=		gnu99
 CFLAGS+=	-Wall -DFREEBSD_ELF -DIN_RTLD -DIN_RTLD_CAP -g
-CFLAGS+=	-I${.CURDIR}/../rtld-elf/${MACHINE_ARCH} -I${.CURDIR}/../rtld-elf
+CFLAGS+=	-I${.CURDIR} -I${.CURDIR}/../rtld-elf/${MACHINE_ARCH} -I${.CURDIR}/../rtld-elf
 LDFLAGS+=	-nostdlib -Wl,-e,.rtld_start -Wl,-T,${.CURDIR}/rtld-elf-cap.xs
 INSTALLFLAGS=	-C -b
 PRECIOUSPROG=

==== //depot/projects/trustedbsd/capabilities/src/libexec/rtld-elf/rtld.c#14 (text+ko) ====

@@ -59,6 +59,10 @@
 #include "libmap.h"
 #include "rtld_tls.h"
 
+#ifdef IN_RTLD_CAP
+#include "rtld_caplibindex.h"
+#endif
+
 #ifndef COMPAT_32BIT
 #ifdef IN_RTLD_CAP
 #define	PATH_RTLD	"/libexec/ld-elf-cap.so.1"
@@ -114,7 +118,9 @@
 static void linkmap_add(Obj_Entry *);
 static void linkmap_delete(Obj_Entry *);
 static int load_needed_objects(Obj_Entry *);
+#ifndef IN_RTLD_CAP
 static int load_preload_objects(void);
+#endif
 static Obj_Entry *load_object(const char *, const Obj_Entry *);
 static Obj_Entry *obj_from_addr(const void *);
 static void objlist_call_fini(Objlist *, int *lockstate);
@@ -175,12 +181,17 @@
 				   used to affect the libraries loaded */
 static char *ld_bind_now;	/* Environment variable for immediate binding */
 static char *ld_debug;		/* Environment variable for debugging */
+#ifndef IN_RTLD_CAP
 static char *ld_library_path;	/* Environment variable for search path */
 static char *ld_preload;	/* Environment variable for libraries to
 				   load first */
 static char *ld_elf_hints_path;	/* Environment variable for alternative hints path */
+#endif
 static char *ld_tracing;	/* Called from ldd to print libs */
 static char *ld_utrace;		/* Use utrace() to log events. */
+#ifdef IN_RTLD_CAP
+static char *ld_caplibindex;
+#endif
 static Obj_Entry *obj_list;	/* Head of linked list of shared objects */
 static Obj_Entry **obj_tail;	/* Link field of last object in list */
 static Obj_Entry *obj_main;	/* The main program shared object */
@@ -341,9 +352,11 @@
     const char *argv0;
     Objlist_Entry *entry;
     Obj_Entry *obj;
+#ifndef IN_RTLD_CAP
     Obj_Entry **preload_tail;
     Objlist initlist;
     int lockstate;
+#endif
 
     /*
      * On entry, the dynamic linker itself has not been relocated yet.
@@ -409,32 +422,45 @@
      * future processes to honor the potentially un-safe variables.
      */
     if (!trust) {
+#ifndef IN_RTLD_CAP
         unsetenv(LD_ "PRELOAD");
         unsetenv(LD_ "LIBMAP");
         unsetenv(LD_ "LIBRARY_PATH");
         unsetenv(LD_ "LIBMAP_DISABLE");
+#endif
         unsetenv(LD_ "DEBUG");
+#ifndef IN_RTLD_CAP
         unsetenv(LD_ "ELF_HINTS_PATH");
+#endif
+#ifdef IN_RTLD_CAP
+	unsetenv(LD_ "CAPLIBINDEX");
+#endif
     }
     ld_debug = getenv(LD_ "DEBUG");
-#ifndef IN_RTLD_CAP
+#ifdef IN_RTLD_CAP
+    ld_caplibindex = getenv(LD_ "CAPLIBINDEX");
+#else
     libmap_disable = getenv(LD_ "LIBMAP_DISABLE") != NULL;
     libmap_override = getenv(LD_ "LIBMAP");
-#endif
     ld_library_path = getenv(LD_ "LIBRARY_PATH");
     ld_preload = getenv(LD_ "PRELOAD");
     ld_elf_hints_path = getenv(LD_ "ELF_HINTS_PATH");
+#endif
     dangerous_ld_env =
-#ifndef IN_RTLD_CAP
+#ifdef IN_RTLD_CAP
+	1;
+#else
 	libmap_disable || (libmap_override != NULL) ||
-#endif
 	(ld_library_path != NULL) || (ld_preload != NULL) ||
 	(ld_elf_hints_path != NULL);
+#endif
     ld_tracing = getenv(LD_ "TRACE_LOADED_OBJECTS");
     ld_utrace = getenv(LD_ "UTRACE");
 
+#ifndef IN_RTLD_CAP
     if ((ld_elf_hints_path == NULL) || strlen(ld_elf_hints_path) == 0)
 	ld_elf_hints_path = _PATH_ELF_HINTS;
+#endif
 
     if (ld_debug != NULL && *ld_debug != '\0')
 	debug = 1;
@@ -523,15 +549,20 @@
     sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
     sym_zero.st_shndx = SHN_UNDEF;
 
+#ifdef IN_RTLD_CAP
+    if (ld_caplibindex != NULL)
+	ld_caplibindex_init(ld_caplibindex);
+#endif
+
 #ifndef IN_RTLD_CAP
     if (!libmap_disable)
         libmap_disable = (bool)lm_init(libmap_override);
-#endif
 
     dbg("loading LD_PRELOAD libraries");
     if (load_preload_objects() == -1)
 	die();
     preload_tail = obj_tail;
+#endif
 
     dbg("loading needed objects");
     if (load_needed_objects(obj_main) == -1)
@@ -588,16 +619,20 @@
     dbg("initializing thread locks");
     lockdflt_init();
 
+#ifndef IN_RTLD_CAP
     /* Make a list of init functions to call. */
     objlist_init(&initlist);
     initlist_add_objects(obj_list, preload_tail, &initlist);
+#endif
 
     r_debug_state(NULL, &obj_main->linkmap); /* say hello to gdb! */
 
+#ifndef IN_RTLD_CAP
     lockstate = wlock_acquire(rtld_bind_lock);
     objlist_call_init(&initlist, &lockstate);
     objlist_clear(&initlist);
     wlock_release(rtld_bind_lock, lockstate);
+#endif
 
     dbg("transferring control to program entry point = %p", obj_main->entry);
 
@@ -1499,6 +1534,7 @@
     return 0;
 }
 
+#ifndef IN_RTLD_CAP
 static int
 load_preload_objects(void)
 {
@@ -1524,6 +1560,7 @@
     LD_UTRACE(UTRACE_PRELOAD_FINISHED, NULL, NULL, 0, 0, NULL);
     return 0;
 }
+#endif
 
 /*
  * Load a shared object into memory, if it is not already loaded.
@@ -1549,11 +1586,18 @@
 	return NULL;
     }
     path = xstrdup(name);
+    if (ld_caplibindex_lookup(path, &fd) < 0) {
+	_rtld_error("Unable to find \"%s\" in LD_CAPLIBINDEX", path);
+	return NULL;
+    }
+    if (lseek(fd, 0, SEEK_SET) == -1) {
+	_rtld_error("Unable to seek on \"%s\"", path);
+	return NULL;
+    }
 #else
     path = find_library(name, refobj);
     if (path == NULL)
 	return NULL;
-#endif
 
     /*
      * If we didn't find a match by pathname, open the file and check
@@ -1568,22 +1612,29 @@
 	free(path);
 	return NULL;
     }
+#endif
     if (fstat(fd, &sb) == -1) {
 	_rtld_error("Cannot fstat \"%s\"", path);
+#ifndef IN_RTLD_CAP
 	close(fd);
+#endif
 	free(path);
 	return NULL;
     }
     for (obj = obj_list->next;  obj != NULL;  obj = obj->next) {
 	if (obj->ino == sb.st_ino && obj->dev == sb.st_dev) {
+#ifndef IN_RTLD_CAP
 	    close(fd);
+#endif
 	    break;
 	}
     }
     if (obj != NULL) {
 	object_add_name(obj, name);
 	free(path);
+#ifndef IN_RTLD_CAP
 	close(fd);
+#endif
 	return obj;
     }
 
@@ -1591,7 +1642,9 @@
     obj = do_load_object(fd, name, path, &sb);
     if (obj == NULL)
 	free(path);
+#ifndef IN_RTLD_CAP
     close(fd);
+#endif
 
     return obj;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906071947.n57JlEvc076391>