aboutsummaryrefslogtreecommitdiff
path: root/lib/libcasper
diff options
context:
space:
mode:
authorMariusz Zaborski <oshogbo@FreeBSD.org>2021-06-09 21:46:51 +0000
committerMariusz Zaborski <oshogbo@FreeBSD.org>2021-06-10 10:41:29 +0000
commitaa310ebfba3d49a0b6b03a103b969731a8136a73 (patch)
tree98e5d0a07f484a457c08dd2ce560acf1c237af04 /lib/libcasper
parent4ab5c88da28780334f48eae56db52d8e77c871cf (diff)
Diffstat (limited to 'lib/libcasper')
-rw-r--r--lib/libcasper/libcasper/libcasper_impl.c27
-rw-r--r--lib/libcasper/libcasper/libcasper_impl.h1
-rw-r--r--lib/libcasper/libcasper/service.c23
-rw-r--r--lib/libcasper/libcasper/zygote.c15
4 files changed, 50 insertions, 16 deletions
diff --git a/lib/libcasper/libcasper/libcasper_impl.c b/lib/libcasper/libcasper/libcasper_impl.c
index e4411630c8a1..ae28c8769a07 100644
--- a/lib/libcasper/libcasper/libcasper_impl.c
+++ b/lib/libcasper/libcasper/libcasper_impl.c
@@ -32,8 +32,10 @@
* $FreeBSD$
*/
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <paths.h>
#include <stdlib.h>
#include "libcasper_impl.h"
@@ -44,3 +46,28 @@ fd_is_valid(int fd)
return (fcntl(fd, F_GETFL) != -1 || errno != EBADF);
}
+
+void
+fd_fix_environment(int *fdp)
+{
+ int nullfd, nfd;
+
+ if (*fdp > STDERR_FILENO)
+ return;
+
+ nullfd = open(_PATH_DEVNULL, O_RDWR);
+ if (nullfd == -1)
+ errx(1, "Unable to open %s", _PATH_DEVNULL);
+
+ while (*fdp <= STDERR_FILENO) {
+ nfd = dup(*fdp);
+ if (nfd == -1)
+ errx(1, "Unable to secure fd");
+ if (dup2(nullfd, *fdp) == -1)
+ errx(1, "Unable to secure fd");
+ *fdp = nfd;
+ }
+
+ close(nullfd);
+}
+
diff --git a/lib/libcasper/libcasper/libcasper_impl.h b/lib/libcasper/libcasper/libcasper_impl.h
index 11e43f083977..24049a0c07c8 100644
--- a/lib/libcasper/libcasper/libcasper_impl.h
+++ b/lib/libcasper/libcasper/libcasper_impl.h
@@ -44,6 +44,7 @@ struct service;
struct service_connection;
bool fd_is_valid(int fd);
+void fd_fix_environment(int *fdp);
/* Private service functions. */
struct service *service_alloc(const char *name,
diff --git a/lib/libcasper/libcasper/service.c b/lib/libcasper/libcasper/service.c
index 5c1c64d9a9d7..e87d0640347c 100644
--- a/lib/libcasper/libcasper/service.c
+++ b/lib/libcasper/libcasper/service.c
@@ -386,24 +386,27 @@ stdnull(void)
}
static void
-service_clean(int sock, int procfd, uint64_t flags)
+service_clean(int *sockp, int *procfdp, uint64_t flags)
{
int fd, maxfd, minfd;
- assert(sock > STDERR_FILENO);
- assert(procfd > STDERR_FILENO);
- assert(sock != procfd);
+ fd_fix_environment(sockp);
+ fd_fix_environment(procfdp);
+
+ assert(*sockp > STDERR_FILENO);
+ assert(*procfdp > STDERR_FILENO);
+ assert(*sockp != *procfdp);
if ((flags & CASPER_SERVICE_STDIO) == 0)
stdnull();
if ((flags & CASPER_SERVICE_FD) == 0) {
- if (procfd > sock) {
- maxfd = procfd;
- minfd = sock;
+ if (*procfdp > *sockp) {
+ maxfd = *procfdp;
+ minfd = *sockp;
} else {
- maxfd = sock;
- minfd = procfd;
+ maxfd = *sockp;
+ minfd = *procfdp;
}
for (fd = STDERR_FILENO + 1; fd < maxfd; fd++) {
@@ -424,7 +427,7 @@ service_start(struct service *service, int sock, int procfd)
assert(service != NULL);
assert(service->s_magic == SERVICE_MAGIC);
setproctitle("%s", service->s_name);
- service_clean(sock, procfd, service->s_flags);
+ service_clean(&sock, &procfd, service->s_flags);
if (service_connection_add(service, sock, NULL) == NULL)
_exit(1);
diff --git a/lib/libcasper/libcasper/zygote.c b/lib/libcasper/libcasper/zygote.c
index 2b84bb49a695..5cdd139cc134 100644
--- a/lib/libcasper/libcasper/zygote.c
+++ b/lib/libcasper/libcasper/zygote.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <strings.h>
#include <unistd.h>
+#include "libcasper_impl.h"
#include "zygote.h"
/* Zygote info. */
@@ -104,7 +105,7 @@ zygote_clone_service_execute(int *chanfdp, int *procfdp)
* between sandbox and its owner.
*/
static void
-zygote_main(int sock)
+zygote_main(int *sockp)
{
int error, procfd;
int chanfd[2];
@@ -113,12 +114,14 @@ zygote_main(int sock)
zygote_func_t *func;
pid_t pid;
- assert(sock > STDERR_FILENO);
+ fd_fix_environment(sockp);
+
+ assert(*sockp > STDERR_FILENO);
setproctitle("zygote");
for (;;) {
- nvlin = nvlist_recv(sock, 0);
+ nvlin = nvlist_recv(*sockp, 0);
if (nvlin == NULL) {
if (errno == ENOTCONN) {
/* Casper exited. */
@@ -157,7 +160,7 @@ zygote_main(int sock)
break;
case 0:
/* Child. */
- close(sock);
+ close(*sockp);
close(chanfd[0]);
func(chanfd[1]);
/* NOTREACHED */
@@ -179,7 +182,7 @@ send:
nvlist_move_descriptor(nvlout, "chanfd", chanfd[0]);
nvlist_move_descriptor(nvlout, "procfd", procfd);
}
- (void)nvlist_send(sock, nvlout);
+ (void)nvlist_send(*sockp, nvlout);
nvlist_destroy(nvlout);
}
/* NOTREACHED */
@@ -206,7 +209,7 @@ zygote_init(void)
case 0:
/* Child. */
close(sp[0]);
- zygote_main(sp[1]);
+ zygote_main(&sp[1]);
/* NOTREACHED */
abort();
default: