aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--executor/common_bsd.h74
-rw-r--r--executor/executor.cc6
-rw-r--r--executor/executor_bsd.h19
-rw-r--r--pkg/csource/generated.go70
-rw-r--r--pkg/host/host_openbsd.go1
5 files changed, 151 insertions, 19 deletions
diff --git a/executor/common_bsd.h b/executor/common_bsd.h
index 9c61917d7..53ffc8668 100644
--- a/executor/common_bsd.h
+++ b/executor/common_bsd.h
@@ -267,10 +267,42 @@ static long syz_extract_tcp_res(long a0, long a1, long a2)
#endif
#endif // GOOS_freebsd || GOOS_openbsd
+#if SYZ_EXECUTOR || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NONE
+
+#include <sys/resource.h>
+#include <unistd.h>
+
+static void sandbox_common()
+{
+ if (setsid() == -1)
+ fail("setsid failed");
+
+ // Some minimal sandboxing.
+ struct rlimit rlim;
+#ifndef GOOS_openbsd
+ // Documented bug in OpenBSD.
+ // This causes frequent random aborts on netbsd. Reason unknown.
+ rlim.rlim_cur = rlim.rlim_max = 128 << 20;
+ setrlimit(RLIMIT_AS, &rlim);
+#endif
+ rlim.rlim_cur = rlim.rlim_max = 8 << 20;
+ setrlimit(RLIMIT_MEMLOCK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_FSIZE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_STACK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ setrlimit(RLIMIT_CORE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 256; // see kMaxFd
+ setrlimit(RLIMIT_NOFILE, &rlim);
+}
+#endif // SYZ_EXECUTOR || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NONE
+
#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE
static void loop();
static int do_sandbox_none(void)
{
+ sandbox_common();
#if (GOOS_freebsd || GOOS_openbsd) && (SYZ_EXECUTOR || SYZ_TUN_ENABLE)
initialize_tun(procid);
#endif
@@ -278,3 +310,45 @@ static int do_sandbox_none(void)
return 0;
}
#endif // SYZ_EXECUTOR || SYZ_SANDBOX_NONE
+
+#if SYZ_EXECUTOR || SYZ_SANDBOX_SETUID
+
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static int wait_for_loop(int pid)
+{
+ if (pid < 0)
+ fail("sandbox fork failed");
+ debug("spawned loop pid %d\n", pid);
+ int status = 0;
+ while (waitpid(-1, &status, WUNTRACED) != pid) {
+ }
+ return WEXITSTATUS(status);
+}
+
+#define SYZ_HAVE_SANDBOX_SETUID 1
+static int do_sandbox_setuid(void)
+{
+ int pid = fork();
+ if (pid != 0)
+ return wait_for_loop(pid);
+
+ sandbox_common();
+#if (GOOS_freebsd || GOOS_openbsd) && (SYZ_EXECUTOR || SYZ_TUN_ENABLE)
+ initialize_tun(procid);
+#endif
+
+ const int nobody = 65534;
+ if (setgroups(0, NULL))
+ fail("failed to setgroups");
+ if (setresgid(nobody, nobody, nobody))
+ fail("failed to setresgid");
+ if (setresuid(nobody, nobody, nobody))
+ fail("failed to setresuid");
+
+ loop();
+ doexit(1);
+}
+#endif // SYZ_EXECUTOR || SYZ_SANDBOX_SETUID
diff --git a/executor/executor.cc b/executor/executor.cc
index 6569326d3..d6e7b75b3 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -12,6 +12,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/resource.h>
#include <time.h>
#include <unistd.h>
@@ -422,6 +423,11 @@ int main(int argc, char** argv)
void setup_control_pipes()
{
+ // Makes sure the file descriptor limit is sufficient.
+ struct rlimit rlim;
+ rlim.rlim_cur = rlim.rlim_max = kMaxFd;
+ setrlimit(RLIMIT_NOFILE, &rlim);
+
if (dup2(0, kInPipeFd) < 0)
fail("dup2(0, kInPipeFd) failed");
if (dup2(1, kOutPipeFd) < 0)
diff --git a/executor/executor_bsd.h b/executor/executor_bsd.h
index 7119a3992..8f364ca13 100644
--- a/executor/executor_bsd.h
+++ b/executor/executor_bsd.h
@@ -21,25 +21,6 @@ static void os_init(int argc, char** argv, void* data, size_t data_size)
if (mmap(data, data_size, prot, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) != data)
fail("mmap of data segment failed");
-
- // Some minimal sandboxing.
- // TODO: this should go into common_bsd.h because csource needs this too.
- struct rlimit rlim;
-#if GOOS_netbsd
- // This causes frequent random aborts on netbsd. Reason unknown.
- rlim.rlim_cur = rlim.rlim_max = 128 << 20;
- setrlimit(RLIMIT_AS, &rlim);
-#endif
- rlim.rlim_cur = rlim.rlim_max = 8 << 20;
- setrlimit(RLIMIT_MEMLOCK, &rlim);
- rlim.rlim_cur = rlim.rlim_max = 1 << 20;
- setrlimit(RLIMIT_FSIZE, &rlim);
- rlim.rlim_cur = rlim.rlim_max = 1 << 20;
- setrlimit(RLIMIT_STACK, &rlim);
- rlim.rlim_cur = rlim.rlim_max = 0;
- setrlimit(RLIMIT_CORE, &rlim);
- rlim.rlim_cur = rlim.rlim_max = 256; // see kMaxFd
- setrlimit(RLIMIT_NOFILE, &rlim);
}
static long execute_syscall(const call_t* c, long a[kMaxArgs])
diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go
index 0c3ecb4e8..73b050355 100644
--- a/pkg/csource/generated.go
+++ b/pkg/csource/generated.go
@@ -636,10 +636,38 @@ static long syz_extract_tcp_res(long a0, long a1, long a2)
#endif
#endif
+#if SYZ_EXECUTOR || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NONE
+
+#include <sys/resource.h>
+#include <unistd.h>
+
+static void sandbox_common()
+{
+ if (setsid() == -1)
+ fail("setsid failed");
+ struct rlimit rlim;
+#ifndef GOOS_openbsd
+ rlim.rlim_cur = rlim.rlim_max = 128 << 20;
+ setrlimit(RLIMIT_AS, &rlim);
+#endif
+ rlim.rlim_cur = rlim.rlim_max = 8 << 20;
+ setrlimit(RLIMIT_MEMLOCK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_FSIZE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_STACK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ setrlimit(RLIMIT_CORE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 256;
+ setrlimit(RLIMIT_NOFILE, &rlim);
+}
+#endif
+
#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE
static void loop();
static int do_sandbox_none(void)
{
+ sandbox_common();
#if (GOOS_freebsd || GOOS_openbsd) && (SYZ_EXECUTOR || SYZ_TUN_ENABLE)
initialize_tun(procid);
#endif
@@ -648,6 +676,48 @@ static int do_sandbox_none(void)
}
#endif
+#if SYZ_EXECUTOR || SYZ_SANDBOX_SETUID
+
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static int wait_for_loop(int pid)
+{
+ if (pid < 0)
+ fail("sandbox fork failed");
+ debug("spawned loop pid %d\n", pid);
+ int status = 0;
+ while (waitpid(-1, &status, WUNTRACED) != pid) {
+ }
+ return WEXITSTATUS(status);
+}
+
+#define SYZ_HAVE_SANDBOX_SETUID 1
+static int do_sandbox_setuid(void)
+{
+ int pid = fork();
+ if (pid != 0)
+ return wait_for_loop(pid);
+
+ sandbox_common();
+#if (GOOS_freebsd || GOOS_openbsd) && (SYZ_EXECUTOR || SYZ_TUN_ENABLE)
+ initialize_tun(procid);
+#endif
+
+ const int nobody = 65534;
+ if (setgroups(0, NULL))
+ fail("failed to setgroups");
+ if (setresgid(nobody, nobody, nobody))
+ fail("failed to setresgid");
+ if (setresuid(nobody, nobody, nobody))
+ fail("failed to setresuid");
+
+ loop();
+ doexit(1);
+}
+#endif
+
#elif GOOS_fuchsia
#include <fcntl.h>
diff --git a/pkg/host/host_openbsd.go b/pkg/host/host_openbsd.go
index f750929a5..35e8a0298 100644
--- a/pkg/host/host_openbsd.go
+++ b/pkg/host/host_openbsd.go
@@ -14,4 +14,5 @@ func isSupported(c *prog.Syscall, sandbox string) (bool, string) {
func init() {
checkFeature[FeatureCoverage] = unconditionallyEnabled
checkFeature[FeatureNetworkInjection] = unconditionallyEnabled
+ checkFeature[FeatureSandboxSetuid] = unconditionallyEnabled
}