PERFORCE change 163727 for review
Robert Watson
rwatson at FreeBSD.org
Sun Jun 7 19:47:15 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163727
Change 163727 by rwatson at 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;
}
More information about the p4-projects
mailing list