Skip to content
Permalink
Browse files

executor: add setuid sandbox for openbsd

* executor/common_bsd: add setuid sandbox

Fixes #833

cc @mptre

* Reduced duplications, resolved TODO.
  • Loading branch information...
blackgnezdo authored and dvyukov committed Dec 10, 2018
1 parent 96cc4c5 commit 6565f24da9f4eb36702339ba290213995fcc902f
Showing with 145 additions and 19 deletions.
  1. +74 −0 executor/common_bsd.h
  2. +0 −19 executor/executor_bsd.h
  3. +70 −0 pkg/csource/generated.go
  4. +1 −0 pkg/host/host_openbsd.go
@@ -267,14 +267,88 @@ 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.

This comment has been minimized.

Copy link
@mptre

mptre Dec 10, 2018

Collaborator

Either the comment or the ifndef is wrong. Is this applicable to both {Net,Open}BSD?

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
loop();
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
@@ -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])
@@ -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>
@@ -14,4 +14,5 @@ func isSupported(c *prog.Syscall, sandbox string) (bool, string) {
func init() {
checkFeature[FeatureCoverage] = unconditionallyEnabled
checkFeature[FeatureNetworkInjection] = unconditionallyEnabled
checkFeature[FeatureSandboxSetuid] = unconditionallyEnabled
}

0 comments on commit 6565f24

Please sign in to comment.
You can’t perform that action at this time.