PERFORCE change 163973 for review
Robert Watson
rwatson at FreeBSD.org
Wed Jun 10 11:31:32 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163973
Change 163973 by rwatson at rwatson_freebsd_capabilities on 2009/06/10 11:31:01
Break out host-specific portions of libcapability.c into
libcapability_host.c.
Affected files ...
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/Makefile#4 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#3 edit
.. //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability_host.c#1 add
Differences ...
==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/Makefile#4 (text+ko) ====
@@ -4,7 +4,8 @@
SRCS= \
libcapability.c \
- libcapability_agent.c
+ libcapability_agent.c \
+ libcapability_host.c
INCS= libcapability.h
==== //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#3 (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.c#2 $
+ * $P4: //depot/projects/trustedbsd/capabilities/src/lib/libcapability/libcapability.c#3 $
*/
#include <sys/types.h>
@@ -47,39 +47,7 @@
#include <unistd.h>
#include "libcapability.h"
-#include "libcapability_agent_api.h"
-
-#define LIBCAPABILITY_CAPMASK_DEVNULL (CAP_EVENT | CAP_READ | CAP_WRITE)
-#define LIBCAPABILITY_CAPMASK_SOCK (CAP_EVENT | CAP_READ | CAP_WRITE)
-#define LIBCAPABILITY_CAPMASK_BIN (CAP_READ | CAP_EVENT | CAP_FSTAT | \
- CAP_SEEK | CAP_FSTATFS | \
- CAP_FEXECVE | CAP_MMAP | \
- CAP_MAPEXEC)
-#define LIBCAPABILITY_CAPMASK_AGENT LIBCAPABILITY_CAPMASK_BIN
-#define LIBCAPABILITY_CAPMASK_LDSO LIBCAPABILITY_CAPMASK_BIN
-#define LIBCAPABILITY_CAPMASK_LIBC LIBCAPABILITY_CAPMASK_BIN
-#define LIBCAPABILITY_CAPMASK_LIBZ LIBCAPABILITY_CAPMASK_BIN
-
-#define _PATH_LIB "/lib"
-#define LIBC_SO "libc.so.7"
-#define LIBZ_SO "libz.so.4"
-extern char **environ;
-
-#define LD_ELF_CAP_SO "/libexec/ld-elf-cap.so.1"
-char *ldso_argv[] = {
- __DECONST(char *, LD_ELF_CAP_SO),
- NULL,
-};
-
-int closefrom(int lowfd);
-
-struct lc_agent {
- int lca_fd_sock;
- int lca_fd_procdesc;
- pid_t lca_pid;
-};
-
int
lc_limitfd(int fd, cap_rights_t rights)
{
@@ -98,254 +66,3 @@
close(fd_cap);
return (0);
}
-
-/*
- * Install an array of file descriptors using the array index of each
- * descriptor in the array as its destination file descriptor number. All
- * other existing file descriptors will be closed when this function returns,
- * leaving a pristine vector. If calls fail, then we return (-1), but there
- * are no guarantees about the state of the file descriptor array for the
- * process, so it's a throw-away.
- *
- * It would be nice not to shuffle descriptors that already have the right
- * number.
- */
-static int
-lch_installfds(int fd_count, int *fds)
-{
- int i;
-
- /*
- * First, move all our descriptors up the range.
- */
- for (i = 0; i < fd_count; i++) {
- if (dup2(fds[i], fd_count + i) < 0)
- return (-1);
- }
-
- /*
- * Now put them back.
- */
- for (i = 0; i < fd_count; i++) {
- if (dup2(fd_count + i, fds[i]) < 0)
- return (-1);
- }
-
- /*
- * Close the descriptors that we moved, as well as any others that
- * were left open by the caller.
- */
- if (closefrom(fd_count) < 0)
- return (-1);
-
- return (0);
-}
-
-static void
-lch_agent(int fd_sock, int fd_agent, int fd_ldso, int fd_libc, int fd_libz)
-{
- char *env_caplibindex, *env_libcapability_agent_api;
- int fd_array[8], fd_devnull;
-
- fd_devnull = open(_PATH_DEVNULL, O_RDWR);
- if (fd_devnull < 0)
- return;
-
- if (lc_limitfd(fd_devnull, LIBCAPABILITY_CAPMASK_DEVNULL) < 0)
- return;
- if (lc_limitfd(fd_agent, LIBCAPABILITY_CAPMASK_AGENT) < 0)
- return;
- if (lc_limitfd(fd_sock, LIBCAPABILITY_CAPMASK_SOCK) < 0)
- return;
- if (lc_limitfd(fd_ldso, LIBCAPABILITY_CAPMASK_LDSO) < 0)
- return;
- if (lc_limitfd(fd_ldso, LIBCAPABILITY_CAPMASK_LIBC) < 0)
- return;
-
- fd_array[0] = fd_devnull;
- fd_array[1] = fd_devnull;
- fd_array[2] = fd_devnull;
- fd_array[3] = fd_agent;
- fd_array[4] = fd_sock;
- fd_array[5] = fd_ldso;
- fd_array[6] = fd_libc;
-
- if (lch_installfds(7, fd_array) < 0)
- return;
-
- /*
- * Pass library list into rtld-elf-cap.
- */
- if (asprintf(&env_caplibindex, "%d:%s,%d:%s", fd_libc, LIBC_SO,
- fd_libz, LIBZ_SO) == -1)
- return;
- if (setenv("LD_CAPLIBINDEX", env_caplibindex, 1) == -1)
- return;
- free(env_caplibindex);
-
- /*
- * Make sure that libcapability in the sandbox knows that its API
- * assumptions hold.
- */
- if (asprintf(&env_libcapability_agent_api, "%s:%d",
- LIBCAPABILITY_AGENT_API_SOCK, fd_sock) == -1)
- return;
- if (setenv(LIBCAPABILITY_AGENT_API_ENV, env_libcapability_agent_api,
- 1) == -1)
- return;
- free(env_libcapability_agent_api);
-
- if (cap_enter() < 0)
- return;
-
- (void)fexecve(fd_ldso, ldso_argv, environ);
-}
-
-int
-lch_start(const char *agent, struct lc_agent **lcapp)
-{
- struct lc_agent *lcap;
- int fd_agent, fd_ldso, fd_libc, fd_libz, fd_procdesc, fd_sockpair[2];
- int error, val;
- pid_t pid;
-
- fd_agent = fd_ldso = fd_libc = fd_libz = fd_procdesc =
- fd_sockpair[0] = fd_sockpair[1] = -1;
-
- lcap = malloc(sizeof(*lcap));
- if (lcap == NULL)
- return (-1);
- bzero(lcap, sizeof(*lcap));
-
- /* Try the agent first so that ENOENT most likely refers to it. */
- fd_agent = open(agent, O_RDONLY);
- if (fd_agent < 0)
- goto out_error;
-
- fd_ldso = open(LD_ELF_CAP_SO, O_RDONLY);
- if (fd_ldso < 0)
- goto out_error;
-
- fd_libc = open(_PATH_LIB "/" LIBC_SO, O_RDONLY);
- if (fd_libc < 0)
- goto out_error;
-
- fd_libz = open(_PATH_LIB "/" LIBZ_SO, O_RDONLY);
- if (fd_libz < 0)
- goto out_error;
-
- if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd_sockpair) < 0)
- goto out_error;
-
- val = 1;
- if (setsockopt(fd_sockpair[0], SOL_SOCKET, SO_NOSIGPIPE, &val,
- sizeof(val)) < 0) {
- fd_sockpair[0] = fd_sockpair[1] = -1;
- goto out_error;
- }
-
- pid = pdfork(&fd_procdesc);
- if (pid < 0) {
- fd_procdesc = -1;
- goto out_error;
- }
- if (pid == 0) {
- lch_agent(fd_sockpair[1], fd_agent, fd_ldso, fd_libc,
- fd_libz);
- exit(-1);
- }
- close(fd_libz);
- close(fd_libc);
- close(fd_ldso);
- close(fd_agent);
- close(fd_sockpair[1]);
-
- lcap->lca_fd_procdesc = fd_procdesc;
- lcap->lca_fd_sock = fd_sockpair[0];
- lcap->lca_pid = pid;
- *lcapp = lcap;
-
- return (0);
-
-out_error:
- error = errno;
- if (fd_sockpair[0] != -1)
- close(fd_sockpair[0]);
- if (fd_sockpair[1] != -1)
- close(fd_sockpair[1]);
- if (fd_libz != -1)
- close(fd_libz);
- if (fd_libc != -1)
- close(fd_libc);
- if (fd_ldso != -1)
- close(fd_ldso);
- if (fd_agent != -1)
- close(fd_agent);
- if (lcap != NULL)
- free(lcap);
- errno = error;
- return (-1);
-}
-
-void
-lch_stop(struct lc_agent *lcap)
-{
-
- close(lcap->lca_fd_sock);
- close(lcap->lca_fd_procdesc);
- lcap->lca_fd_sock = -1;
- lcap->lca_fd_procdesc = -1;
- lcap->lca_pid = -1;
-}
-
-int
-lch_getsock(struct lc_agent *lcap, int *fdp)
-{
-
- *fdp = lcap->lca_fd_sock;
- return (0);
-}
-
-int
-lch_getpid(struct lc_agent *lcap, pid_t *pidp)
-{
-
- *pidp = lcap->lca_pid;
- return (0);
-}
-
-int
-lch_getprocdesc(struct lc_agent *lcap, int *fdp)
-{
-
- *fdp = lcap->lca_fd_procdesc;
- return (0);
-}
-
-/*
- * Simple I/O wrappers for capability sockets. Possibly more keeping an eye
- * on the worker should take place here.
- */
-ssize_t
-lch_send(struct lc_agent *lcap, const void *msg, size_t len, int flags)
-{
-
- if (lcap->lca_fd_sock == -1 ||
- lcap->lca_fd_sock == 0) {
- errno = ESRCH;
- return (-1);
- }
- return (send(lcap->lca_fd_sock, msg, len, flags));
-}
-
-ssize_t
-lch_recv(struct lc_agent *lcap, void *buf, size_t len, int flags)
-{
-
- if (lcap->lca_fd_sock == -1 ||
- lcap->lca_fd_sock == 0) {
- errno = ESRCH;
- return (-1);
- }
- return (recv(lcap->lca_fd_sock, buf, len, flags));
-}
More information about the p4-projects
mailing list