Date: Thu, 18 Jun 2009 15:37:09 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 164668 for review Message-ID: <200906181537.n5IFb99i036447@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=164668 Change 164668 by rwatson@rwatson_freebsd_capabilities on 2009/06/18 15:36:11 Add lch_start_libs() and lch_startfd_libs(), which allow passing in specific lists of libraries to be used by sandboxed components. Affected files ... .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#22 edit .. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#19 edit Differences ... ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#22 (text+ko) ==== @@ -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/libcapability/libcapability.h#21 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.h#22 $ */ #ifndef _LIBCAPABILITY_H_ @@ -40,6 +40,15 @@ struct lc_host; /* + * Description of a library passed to lch_start_libs(). + */ +struct lc_library { + const char *lcl_libpath; + const char *lcl_libname; + int lcl_fd; +}; + +/* * Capability interfaces. */ int lc_limitfd(int fd, cap_rights_t rights); @@ -55,8 +64,14 @@ */ int lch_start(const char *sandbox, char *const argv[], u_int flags, 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_sandbox **lcspp); int lch_startfd(int fd_sandbox, const char *binname, char *const argv[], u_int flags, 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_sandbox **lcspp); void lch_stop(struct lc_sandbox *lcsp); /* ==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#19 (text+ko) ==== @@ -30,12 +30,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#18 $ + * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#19 $ */ #include <sys/param.h> #include <sys/capability.h> #include <sys/procdesc.h> +#include <sys/sbuf.h> #include <sys/socket.h> #include <sys/uio.h> @@ -60,15 +61,13 @@ CAP_MAPEXEC) #define LIBCAPABILITY_CAPMASK_SANDBOX LIBCAPABILITY_CAPMASK_BIN #define LIBCAPABILITY_CAPMASK_LDSO LIBCAPABILITY_CAPMASK_BIN -#define LIBCAPABILITY_CAPMASK_LIBC LIBCAPABILITY_CAPMASK_BIN -#define LIBCAPABILITY_CAPMASK_LIBCAPABILITY LIBCAPABILITY_CAPMASK_BIN -#define LIBCAPABILITY_CAPMASK_LIBBZ2 LIBCAPABILITY_CAPMASK_BIN +#define LIBCAPABILITY_CAPMASK_LIB LIBCAPABILITY_CAPMASK_BIN #define _PATH_LIB "/lib" #define _PATH_USR_LIB "/usr/lib" #define LIBC_SO "libc.so.7" -#define LIBBZ2_SO "libbz2.so.3" #define LIBCAPABILITY_SO "libcapability.so.1" +#define LIBSBUF_SO "libsbuf.so.4" extern char **environ; @@ -150,11 +149,13 @@ static void lch_sandbox(int fd_sock, int fd_sandbox, int fd_ldso, int fd_libc, - int fd_libz, int fd_libbz2, int fd_libcapability, int fd_devnull, - u_int flags, const char *binname, char *const argv[]) + int fd_libcapability, int fd_libsbuf, int fd_devnull, u_int flags, + struct lc_library *lclp, u_int lcl_count, const char *binname, + char *const argv[]) { - char *env_caplibindex, *env_libcapability_sandbox_api; - int fd_array[11]; + int *fd_array, fdcount; + struct sbuf *sbufp; + u_int i; if (lc_limitfd(fd_devnull, LIBCAPABILITY_CAPMASK_DEVNULL) < 0) return; @@ -164,12 +165,16 @@ return; if (lc_limitfd(fd_ldso, LIBCAPABILITY_CAPMASK_LDSO) < 0) return; - if (lc_limitfd(fd_libc, LIBCAPABILITY_CAPMASK_LIBC) < 0) + if (lc_limitfd(fd_libc, LIBCAPABILITY_CAPMASK_LIB) < 0) + return; + if (lc_limitfd(fd_libcapability, LIBCAPABILITY_CAPMASK_LIB) < 0) return; - if (lc_limitfd(fd_libbz2, LIBCAPABILITY_CAPMASK_LIBBZ2) < 0) + if (lc_limitfd(fd_libsbuf, LIBCAPABILITY_CAPMASK_LIB) < 0) return; - if (lc_limitfd(fd_libcapability, - LIBCAPABILITY_CAPMASK_LIBCAPABILITY) < 0) + + fdcount = 10 + lcl_count; + fd_array = malloc(fdcount * sizeof(int)); + if (fd_array == NULL) return; fd_array[0] = fd_devnull; @@ -184,37 +189,44 @@ fd_array[4] = fd_sock; fd_array[5] = fd_ldso; fd_array[6] = fd_libc; - fd_array[7] = fd_libz; - fd_array[8] = fd_libbz2; - fd_array[9] = fd_libcapability; - fd_array[10] = fd_devnull; + fd_array[7] = fd_libcapability; + fd_array[8] = fd_libsbuf; + fd_array[9] = fd_devnull; + for (i = 0; i < lcl_count; i++) { + if (lc_limitfd(lclp->lcl_fd, LIBCAPABILITY_CAPMASK_LIB) < 0) + return; + fd_array[i + 10] = lclp[i].lcl_fd; + } - if (lch_installfds(11, fd_array) < 0) + if (lch_installfds(fdcount, fd_array) < 0) return; - /* - * Pass library list into rtld-elf-cap. - */ - if (asprintf(&env_caplibindex, - "%d:%s,%d:%s,%d:%s,%d:%s,%d:%s,%d:%s,%d:%s", - 3, binname, 5, LD_ELF_CAP_SO, 6, LIBC_SO, 7, - LIBBZ2_SO, 8, LIBCAPABILITY_SO, 9, _PATH_DEVNULL) == -1) + 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 + 10, + lclp[i].lcl_libname); + sbuf_finish(sbufp); + if (sbuf_overflowed(sbufp)) return; - if (setenv("LD_CAPLIBINDEX", env_caplibindex, 1) == -1) + if (setenv("LD_CAPLIBINDEX", sbuf_data(sbufp), 1) == -1) return; - free(env_caplibindex); + sbuf_delete(sbufp); - /* - * Make sure that libcapability in the sandbox knows that its API - * assumptions hold. - */ - if (asprintf(&env_libcapability_sandbox_api, "%s:%d", - LIBCAPABILITY_SANDBOX_API_SOCK, 4) == -1) + 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, - env_libcapability_sandbox_api, 1) == -1) + if (setenv(LIBCAPABILITY_SANDBOX_API_ENV, sbuf_data(sbufp), 1) == -1) return; - free(env_libcapability_sandbox_api); + sbuf_delete(sbufp); if (cap_enter() < 0) return; @@ -223,18 +235,18 @@ } int -lch_startfd(int fd_sandbox, const char *binname, char *const argv[], - u_int flags, struct lc_sandbox **lcspp) +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_sandbox **lcspp) { struct lc_sandbox *lcsp; - int fd_devnull, fd_ldso, fd_libc, fd_libcapability, fd_libz; - int fd_libbz2, fd_procdesc, fd_sockpair[2]; + int fd_devnull, fd_ldso, fd_libc, fd_libcapability, fd_libsbuf; + int fd_procdesc, fd_sockpair[2]; int error, val; pid_t pid; - fd_devnull = fd_ldso = fd_libc = fd_libz = fd_libbz2 = - fd_libcapability = fd_procdesc = fd_sockpair[0] = - fd_sockpair[1] = -1; + fd_devnull = fd_ldso = fd_libc = fd_libcapability = fd_libsbuf = + fd_procdesc = fd_sockpair[0] = fd_sockpair[1] = -1; lcsp = malloc(sizeof(*lcsp)); if (lcsp == NULL) @@ -246,11 +258,11 @@ goto out_error; if (ld_caplibindex_lookup(LIBC_SO, &fd_libc) < 0) goto out_error; - if (ld_caplibindex_lookup(LIBBZ2_SO, &fd_libbz2) < 0) - goto out_error; if (ld_caplibindex_lookup(LIBCAPABILITY_SO, &fd_libcapability) < 0) goto out_error; + if (ld_caplibindex_lookup(LIBSBUF_SO, &fd_libsbuf) < 0) + goto out_error; if (ld_caplibindex_lookup(_PATH_DEVNULL, &fd_devnull) < 0) goto out_error; } else { @@ -261,8 +273,8 @@ fd_libc = open(_PATH_LIB "/" LIBC_SO, O_RDONLY); if (fd_libc < 0) goto out_error; - fd_libbz2 = open(_PATH_USR_LIB "/" LIBBZ2_SO, O_RDONLY); - if (fd_libbz2 < 0) + fd_libsbuf = open(_PATH_LIB "/" LIBSBUF_SO, O_RDONLY); + if (fd_libsbuf < 0) goto out_error; fd_libcapability = open(_PATH_USR_LIB "/" LIBCAPABILITY_SO, O_RDONLY); @@ -290,15 +302,14 @@ } if (pid == 0) { lch_sandbox(fd_sockpair[1], fd_sandbox, fd_ldso, fd_libc, - fd_libz, fd_libbz2, fd_libcapability, fd_devnull, flags, - binname, argv); + fd_libcapability, fd_libsbuf, fd_devnull, flags, lclp, + lcl_count, binname, argv); exit(-1); } #ifndef IN_CAP_MODE close(fd_devnull); + close(fd_libsbuf); close(fd_libcapability); - close(fd_libz); - close(fd_libbz2); close(fd_libc); close(fd_ldso); #endif @@ -320,12 +331,10 @@ #ifndef IN_CAP_MODE if (fd_devnull != -1) close(fd_devnull); + if (fd_libsbuf != -1) + close(fd_libsbuf); if (fd_libcapability != -1) close(fd_libcapability); - if (fd_libz != -1) - close(fd_libz); - if (fd_libbz2 != -1) - close(fd_libbz2); if (fd_libc != -1) close(fd_libc); if (fd_ldso != -1) @@ -338,8 +347,17 @@ } int -lch_start(const char *sandbox, char *const argv[], u_int flags, - struct lc_sandbox **lcspp) +lch_startfd(int fd_sandbox, const char *binname, char *const argv[], + u_int flags, struct lc_sandbox **lcspp) +{ + + return (lch_startfd_libs(fd_sandbox, binname, argv, flags, NULL, 0, + lcspp)); +} + +int +lch_start_libs(const char *sandbox, char *const argv[], u_int flags, + struct lc_library *lclp, u_int lcl_count, struct lc_sandbox **lcspp) { char binname[MAXPATHLEN]; int error, fd_sandbox, ret; @@ -351,13 +369,22 @@ if (fd_sandbox < 0) return (-1); - ret = lch_startfd(fd_sandbox, binname, argv, flags, lcspp); + ret = lch_startfd_libs(fd_sandbox, binname, argv, flags, lclp, + lcl_count, lcspp); error = errno; close(fd_sandbox); errno = error; return (ret); } +int +lch_start(const char *sandbox, char *const argv[], u_int flags, + struct lc_sandbox **lcspp) +{ + + return (lch_start_libs(sandbox, argv, flags, NULL, 0, lcspp)); +} + void lch_stop(struct lc_sandbox *lcsp) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906181537.n5IFb99i036447>