Date: Wed, 4 Sep 2013 18:22:04 GMT From: dpl@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r256903 - soc2013/dpl/head/lib/libzcap Message-ID: <201309041822.r84IM4xA095362@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dpl Date: Wed Sep 4 18:22:03 2013 New Revision: 256903 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=256903 Log: First draft of the new sandboxing. Take a look at caspicum.[ch]. Modified: soc2013/dpl/head/lib/libzcap/capsicum.c soc2013/dpl/head/lib/libzcap/capsicum.h soc2013/dpl/head/lib/libzcap/commands.c soc2013/dpl/head/lib/libzcap/commands.h Modified: soc2013/dpl/head/lib/libzcap/capsicum.c ============================================================================== --- soc2013/dpl/head/lib/libzcap/capsicum.c Wed Sep 4 17:48:41 2013 (r256902) +++ soc2013/dpl/head/lib/libzcap/capsicum.c Wed Sep 4 18:22:03 2013 (r256903) @@ -1,32 +1,61 @@ #include "capsicum.h" #include "zlib.h" -#include <nv.h> +#include <sys/queue.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> +#include <nv.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <err.h> -pid_t pid = 0; -int sv[2]; +external struct sandbox; +external struct slisthead sandboxes; int startChild(void); void killChild(void); void suicide(int signal); nvlist_t * sendCommand(nvlist_t *nvl); -int -startChild(void) +bool slist_initiated = 0; + +nvlist_t * +sendCommand(nvlist_t *nvl, int socket) +{ + nvlist_t *new; + if( nvlist_send(socket, nvl) != 0 ) + err(1, "zcaplib: nvlist_send() Went wrong"); + if ((new = nvlist_recv(socket)) == NULL) + err(1, "nvlist_recv(): nvlist_t is NULL"); + return (new); +} + +void killChild(void) { + kill(pid, SIGKILL); +} +void suicide(int signal) { + kill(getpid(), SIGKILL); +} + +void +startChild(void *data) { + int procd, sv[2]; + struct sandbox *newsandbox; + + if ((newsandbox = malloc(sizeof (struct sandbox)) == NULL) + err(1, "Couldn't allocate memory for sandboxes"); + + sv[0] = sv[1] = 0; if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) < 0 ) perror("zcaplib: socketpair()"); - if( (pid = fork()) == 0 ){ + procd = pdfork(); + if (pid == 0 ){ if (cap_rights_limit(STDIN_FILENO, CAP_READ) < 0) err(1, "Couldn't limit rights"); if (cap_rights_limit(STDOUT_FILENO, CAP_WRITE|CAP_FSTAT) < 0) @@ -43,28 +72,87 @@ err(1, "Couldn't find zlibworker."); } exit(0); + } else if (pid == -1) { + err(1, "Couldn't fork"); } else { + close(sv[1]); signal(SIGCHLD, suicide); atexit(killChild); + sandbox->dataptr = data; + sandbox->pd = procd; + sandbox->socket = sv[0]; } - - return pid; } -nvlist_t * -sendCommand( nvlist_t *nvl ) +/* + * This function should be called only by: + * - gzopen() + * - deflateInit() + * - inflateInit() + */ +struct sandbox * +startSandbox(void *data) { - nvlist_t *new; - if( nvlist_send(sv[1], nvl) != 0 ) - err(1, "zcaplib: nvlist_send() Went wrong"); - if ((new = nvlist_recv(sv[1])) == NULL) - err(1, "nvlist_recv(): nvlist_t is NULL"); - return (new); + struct sandbox *newsandbox; + + if (!slist_initiated) { + SLIST_INIT(&sandboxes); + slist_initiated = 1; + } + + /* Here we add a sandbox used for non-structure related stuff */ + /* This will be the first sandbox always */ + if (SLIST_EMPTY(&sandboxes)) { + newsandbox = startChild(newsandbox, NULL); + SLIST_INSERT_HEAD(&sandboxes, newsandbox, entries); + } + + /* Create and add the real sandbox */ + newsandbox = startChild(data); + SLIST_INSERT_HEAD(&sandboxes, newsandbox, entries); + + return (newsandbox); } -void killChild(void) { - kill(pid, SIGKILL); +/* + * Kills the sandbox, and deletes + * the associated struct sandbox. + */ +int +stopSandbox(struct sandbox *sandbox) +{ + int sandboxpid; + + if ((sandboxpid = pdgetpid(sandbox->pd)) < 0) + err(1, "Couldn't get child PID"); + + if (kill(SIGKILL, sandboxpid) < 0) + err(1, "Couldn't kill child"); + + SLIST_REMOVE(&sandboxes, sandbox, entry, entries); + free(sandbox); } -void suicide(int signal) { - kill(getpid(), SIGKILL); + +/* + * Finds the struct sandbox for + * a pointer to the data structure + * the sandbox is related to. + * Returns NULL if not found. + */ +struct sandbox * +findsanbox(void *ptr) +{ + struct sandbox *sandbox; + + sandbox = NULL; + + if (ptr == NULL) + return (SLIST_FIRST(&sandboxes)); + + SLIST_FOREACH(sandbox, &sandboxes, entries) + if (sandbox->dataptr == ptr) + return (sandbox); + + /* Not found */ + return (NULL); } \ No newline at end of file Modified: soc2013/dpl/head/lib/libzcap/capsicum.h ============================================================================== --- soc2013/dpl/head/lib/libzcap/capsicum.h Wed Sep 4 17:48:41 2013 (r256902) +++ soc2013/dpl/head/lib/libzcap/capsicum.h Wed Sep 4 18:22:03 2013 (r256903) @@ -1,5 +1,5 @@ /* - * With Capsicum, we get a compartmentalized, and securer lib. + * We're using Capsicum! */ #define CAPSICUM #include <sys/capability.h> @@ -20,7 +20,22 @@ extern int pid; extern int sv[2]; +extern struct sandbox * sandboxes; extern int startChild(void); extern void killChild(void); extern nvlist_t * sendCommand(nvlist_t *nvl); + +/* head of singly-linked list. */ +SLIST_HEAD(slisthead, sandbox) sandboxes = SLIST_HEAD_INITIALIZER(head); + +/* + * This structure holds a relation of structs of data structs, + * and its related process descriptor (pd). + */ +struct sandbox { + void * dataptr; /* Pointer to the data structure of the lib */ + int pd; /* Process descriptor */ + int socket; /* Socket we have to pass the data through */ + SLIST_ENTRY(entry) entries; /* Singly-linked list. */ +} Modified: soc2013/dpl/head/lib/libzcap/commands.c ============================================================================== --- soc2013/dpl/head/lib/libzcap/commands.c Wed Sep 4 17:48:41 2013 (r256902) +++ soc2013/dpl/head/lib/libzcap/commands.c Wed Sep 4 18:22:03 2013 (r256903) @@ -82,7 +82,6 @@ uLong zcapcmd_crc32_combine(uLong crc1, uLong crc2, z_off64_t len2); -extern pid_t pid; extern nvlist_t *sendCommand(nvlist_t *); extern void *data; @@ -92,13 +91,15 @@ size_t zstreamsize = sizeof(z_stream); -static void -initializeCommand() { - if (pid == 0) - startChild(); +static sandbox_s* +initializeCommand(void *ptr) { + sandbox_s *sanbox; + sandbox = findSandbox(ptr); if( (args = nvlist_create(0)) == NULL || (nvl = nvlist_create(0)) == NULL ) err(1, "zcaplib: nvlist_create"); + + return sandbox; } static void Modified: soc2013/dpl/head/lib/libzcap/commands.h ============================================================================== --- soc2013/dpl/head/lib/libzcap/commands.h Wed Sep 4 17:48:41 2013 (r256902) +++ soc2013/dpl/head/lib/libzcap/commands.h Wed Sep 4 18:22:03 2013 (r256903) @@ -13,8 +13,6 @@ */ -#define SOCKETFILENO 3 - #define ZCAPCMD_DEFLATEINIT 0 #define ZCAPCMD_DEFLATE 1 #define ZCAPCMD_DEFLATEEND 2
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201309041822.r84IM4xA095362>