Date: Wed, 3 Feb 2010 11:22:03 +0000 (UTC) From: Robert Watson <rwatson@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r203425 - in projects/capabilities8: lib/libcapsicum libexec/rtld-elf Message-ID: <201002031122.o13BM3Mr078200@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rwatson Date: Wed Feb 3 11:22:03 2010 New Revision: 203425 URL: http://svn.freebsd.org/changeset/base/203425 Log: Merge c174211, c174213, c174214, and c174218 from the p4 TrustedBSD Capabilities branch to capabilities8: There's no IN_CAP_MODE definition for libcapsicum, so just test for a negative fd_rtld before closing. Improve style alignment of capability-related code with existing rtld style (which isn't style(9)). Add missing free of string and explicit NULL return on error. Keep a running count of valid file descriptors in the directory length array, rather than marking unused ones as (-1). This avoids several loops. While here, fix a (+ sizeof(int)) into a (* sizeof(int)) and a few other nits. Sponsored by: Google, Inc. Modified: projects/capabilities8/lib/libcapsicum/libcapsicum_host.c projects/capabilities8/libexec/rtld-elf/rtld.c Modified: projects/capabilities8/lib/libcapsicum/libcapsicum_host.c ============================================================================== --- projects/capabilities8/lib/libcapsicum/libcapsicum_host.c Wed Feb 3 11:12:03 2010 (r203424) +++ projects/capabilities8/lib/libcapsicum/libcapsicum_host.c Wed Feb 3 11:22:03 2010 (r203425) @@ -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#15 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapsicum/libcapsicum_host.c#16 $ */ #include <sys/param.h> @@ -312,9 +312,8 @@ lch_startfd(int fd_binary, const char *b binname, argv, fds); exit(-1); } -#ifndef IN_CAP_MODE - close(fd_rtld); -#endif + if (fd_rtld != -1) + close(fd_rtld); close(fd_sockpair[1]); lcsp->lcs_fd_procdesc = fd_procdesc; @@ -330,10 +329,8 @@ out_error: close(fd_sockpair[0]); if (fd_sockpair[1] != -1) close(fd_sockpair[1]); -#ifndef IN_CAP_MODE if (fd_rtld != -1) close(fd_rtld); -#endif if (lcsp != NULL) free(lcsp); errno = error; Modified: projects/capabilities8/libexec/rtld-elf/rtld.c ============================================================================== --- projects/capabilities8/libexec/rtld-elf/rtld.c Wed Feb 3 11:12:03 2010 (r203424) +++ projects/capabilities8/libexec/rtld-elf/rtld.c Wed Feb 3 11:22:03 2010 (r203425) @@ -188,7 +188,9 @@ static bool dangerous_ld_env; /* True if static char *ld_bind_now; /* Environment variable for immediate binding */ static char *ld_debug; /* Environment variable for debugging */ static int *ld_library_dirs = NULL; /* File descriptors of lib path (end: -1) */ +static int ld_library_dirs_done; /* ld_library_dirs has been initialized */ static int ld_library_dirlen; /* Capacity of ld_library_dirs */ +static int ld_library_dircount; /* Number of entries in ld_library_dirs */ #ifndef IN_RTLD_CAP static char *ld_library_path; /* Environment variable for search path */ static char *ld_preload; /* Environment variable for libraries to @@ -251,7 +253,6 @@ static func_ptr_type exports[] = { (func_ptr_type) &ld_insandbox, #endif (func_ptr_type) &ld_libdirs, - NULL }; @@ -836,19 +837,19 @@ origin_subst(const char *real, const cha static void * find_capstart(const Obj_Entry *obj) { - const char *capstart_str = "_capstart"; - const Elf_Sym *def; - const Obj_Entry *defobj; - unsigned long hash; + const char *capstart_str = "_capstart"; + const Elf_Sym *def; + const Obj_Entry *defobj; + unsigned long hash; - hash = elf_hash(capstart_str); - def = symlook_default(capstart_str, hash, obj, &defobj, NULL, - SYMLOOK_IN_PLT); - if (def == NULL) - return (NULL); - if (ELF_ST_TYPE(def->st_info) != STT_FUNC) - return (NULL); - return (make_function_pointer(def, defobj)); + hash = elf_hash(capstart_str); + def = symlook_default(capstart_str, hash, obj, &defobj, NULL, + SYMLOOK_IN_PLT); + if (def == NULL) + return (NULL); + if (ELF_ST_TYPE(def->st_info) != STT_FUNC) + return (NULL); + return (make_function_pointer(def, defobj)); } #endif @@ -1236,23 +1237,24 @@ elf_hash(const char *name) #ifdef IN_RTLD_CAP /* - * Find the library with the given name, and return an open file descriptor to it. + * Find the library with the given name, and return an open file descriptor + * to it. */ static int -find_library_fd(const char *name) { - - if (ld_library_dirs == NULL) - init_libdirs(); - - for (int i = 0; (i < ld_library_dirlen) && (ld_library_dirs[i] != -1); i++) { +find_library_fd(const char *name) +{ + int fd, i; - int fd = openat(ld_library_dirs[i], name, O_RDONLY); + if (!ld_library_dirs_done) + init_libdirs(); + for (i = 0; i < ld_library_dircount); i++) { + fd = openat(ld_library_dirs[i], name, O_RDONLY); if (fd >= 0) - return fd; + return (fd); } - return (-1); } + #else /* * Find the library with the given name, and return its full pathname. @@ -1664,26 +1666,26 @@ load_object(const char *name, const Obj_ path = xstrdup(name); if ((fd = find_library_fd(path)) < 0) { _rtld_error("Unable to find \"%s\" in LD_LIBRARY_DIRS", path); + free(path); + return NULL; } #else - if (fd == -1) { - path = find_library(name, refobj); - if (path == NULL) + path = find_library(name, refobj); + if (path == NULL) return NULL; - /* - * If we didn't find a match by pathname, open the file and check - * again by device and inode. This avoids false mismatches caused - * by multiple links or ".." in pathnames. - * - * To avoid a race, we open the file and use fstat() rather than - * using stat(). - */ - if ((fd = open(path, O_RDONLY)) == -1) { + /* + * If we didn't find a match by pathname, open the file and check + * again by device and inode. This avoids false mismatches caused + * by multiple links or ".." in pathnames. + * + * To avoid a race, we open the file and use fstat() rather than + * using stat(). + */ + if ((fd = open(path, O_RDONLY)) == -1) { _rtld_error("Cannot open \"%s\"", path); free(path); return NULL; - } } #endif if (fstat(fd, &sb) == -1) { @@ -2114,42 +2116,48 @@ search_library_path(const char *name, co /* * Add a file descriptor to ld_library_dirs. + * + * XXX: This may be called from either the rtld startup code, or from + * ld_libdirs. We have no way to distinguish them on error, so die() + * unconditionally. Perhaps the latter case should allow graceful failure. + * + * XXX: Synchronization? */ static void -add_libdir_fd(int fd) { - - if (ld_library_dirs == NULL) { - /* Initialize the FD list. */ - - ld_library_dirlen = INITIAL_FDLEN; - ld_library_dirs = xmalloc(ld_library_dirlen * sizeof(int)); - memset(ld_library_dirs, 0xff, ld_library_dirlen * sizeof(int)); - } - - /* Find the next available FD slot. */ - int i; - for (i = 0; (i < ld_library_dirlen) && (ld_library_dirs[i] != -1); i++) ; - - if (i == ld_library_dirlen) { - /* We need more space. */ - int old_size = ld_library_dirlen + sizeof(int); +add_libdir_fd(int fd) +{ - ld_library_dirlen *= 2; - ld_library_dirs = realloc(ld_library_dirs, 2 * old_size); - memset(ld_library_dirs + old_size, 0xff, old_size); + /* Initialize the FD list. */ + if (!ld_library_dirs_done) { + ld_library_dirlen = INITIAL_FDLEN; + ld_library_dircount = 0; + ld_library_dirs = xmalloc(ld_library_dirlen * sizeof(int)); + ld_library_dirs_done = 1; + } - if (ld_library_dirs == NULL) - err(-1, "realloc() failed"); + /* Do we need to grow? */ + if (ld_library_dirlen == ld_library_dircount) { + ld_library_dirlen *= 2; + ld_library_dirs = realloc(ld_library_dirs, + ld_library_dirlen * sizeof(int)); + if (ld_library_dirs == NULL) { + _rtld_error("add_libdir_fd: realloc failed"); + die(); } + } - ld_library_dirs[i] = fd; + /* Add the new library directory fd to the end. */ + ld_library_dirs[ld_library_dircount] = fd; + ld_library_dircount++; } /* - * Add file descriptors for a path list (e.g. '/lib:/usr/lib') to ld_library_dirs. + * Add file descriptors for a path list (e.g. '/lib:/usr/lib') to + * ld_library_dirs. */ static void -add_libdir_paths(const char *path) { +add_libdir_paths(const char *path) +{ if (path == NULL) return; @@ -2161,24 +2169,22 @@ add_libdir_paths(const char *path) { strncpy(pathcopy, path, pathlen + 1); for (dirname = strtok_r(pathcopy, ":", &tokcontext); dirname; - dirname = strtok_r(NULL, ":", &tokcontext)) { - + dirname = strtok_r(NULL, ":", &tokcontext)) { + struct try_library_args arg; int fd; - struct try_library_args arg; arg.name = ""; arg.namelen = 0; arg.buffer = xmalloc(PATH_MAX); arg.buflen = PATH_MAX; - if (try_library_path(dirname, strnlen(dirname, PATH_MAX), &arg)) + if (try_library_path(dirname, strnlen(dirname, PATH_MAX), &arg)) { fd = open(dirname, O_RDONLY); - - else { + } else { /* 'dirname' is not a directory path; perhaps it's a descriptor? */ fd = (int) strtol(dirname, NULL, 0); if ((fd == 0) && (errno == 0)) - continue; + continue; } if (fd >= 0) @@ -2192,57 +2198,47 @@ add_libdir_paths(const char *path) { * Build the list of library file descriptors. */ static void -init_libdirs(void) { +init_libdirs(void) +{ #ifdef IN_RTLD_CAP - char *envvar = getenv(LD_ "LIBRARY_DIRS"); + if (envvar == NULL) err(-1, "No %s set in capability mode", LD_ "LIBRARY_DIRS"); add_libdir_paths(envvar); - #else /* !IN_RTLD_CAP */ - /* Look for directories a la find_library (TODO: refactor!). */ add_libdir_paths(ld_library_path); add_libdir_paths(gethints()); add_libdir_paths(STANDARD_LIBRARY_PATH); #endif - - /* If all else fails, create an empty array */ - if (ld_library_dirlen == 0) { - ld_library_dirs = malloc(sizeof(int)); - ld_library_dirs[0] = -1; - } } + /* * Return an array of file descriptors for the library search paths. + * + * XXX: synchronization of ld_library_dirs? */ int -ld_libdirs(int *fds, int *fdcount) { - - if (fdcount == NULL) - return (-1); - - else if (fds == NULL) { - *fdcount = -1; - return (-1); - } - - if (ld_library_dirs == NULL) - init_libdirs(); - - int i = 0; - for (i = 0; (i < ld_library_dirlen) && (ld_library_dirs[i] != -1); i++) ; - - if (*fdcount < i) { - *fdcount = i; - return (-1); - } +ld_libdirs(int *fds, int *fdcount) +{ - *fdcount = i; - memcpy(fds, ld_library_dirs, i * sizeof(int)); - return 0; + if (fdcount == NULL) + return (-1); + else if (fds == NULL) { + *fdcount = -1; + return (-1); + } + if (!ld_library_dirs_done) + init_libdirs(); + if (*fdcount < ld_library_dircount) { + *fdcount = ld_library_dircount; + return (-1); + } + *fdcount = ld_library_dircount; + memcpy(fds, ld_library_dirs, ld_library_dircount * sizeof(int)); + return (0); } int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002031122.o13BM3Mr078200>