aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/csource/akaros_common.go7
-rw-r--r--pkg/csource/freebsd_common.go7
-rw-r--r--pkg/csource/linux_common.go52
-rw-r--r--pkg/csource/netbsd_common.go7
-rw-r--r--pkg/host/host_akaros.go2
-rw-r--r--pkg/host/host_freebsd.go2
-rw-r--r--pkg/host/host_fuchsia.go2
-rw-r--r--pkg/host/host_linux.go47
-rw-r--r--pkg/host/host_linux_test.go4
-rw-r--r--pkg/host/host_netbsd.go2
-rw-r--r--pkg/host/host_windows.go2
11 files changed, 90 insertions, 44 deletions
diff --git a/pkg/csource/akaros_common.go b/pkg/csource/akaros_common.go
index 5fc46dc29..c0984ed99 100644
--- a/pkg/csource/akaros_common.go
+++ b/pkg/csource/akaros_common.go
@@ -109,9 +109,10 @@ const int kRetryStatus = 69;
const int kErrorStatus = 68;
#endif
-#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
- defined(SYZ_USE_TMP_DIR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_SANDBOX_NAMESPACE) || \
- defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(__NR_syz_kvm_setup_cpu)
+#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
+ defined(SYZ_USE_TMP_DIR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_SANDBOX_NAMESPACE) || \
+ defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(__NR_syz_kvm_setup_cpu) || \
+ defined(__NR_syz_init_net_socket)
NORETURN PRINTF static void fail(const char* msg, ...)
{
int e = errno;
diff --git a/pkg/csource/freebsd_common.go b/pkg/csource/freebsd_common.go
index 8265e7013..1e6597bbc 100644
--- a/pkg/csource/freebsd_common.go
+++ b/pkg/csource/freebsd_common.go
@@ -100,9 +100,10 @@ const int kRetryStatus = 69;
const int kErrorStatus = 68;
#endif
-#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
- defined(SYZ_USE_TMP_DIR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_SANDBOX_NAMESPACE) || \
- defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(__NR_syz_kvm_setup_cpu)
+#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
+ defined(SYZ_USE_TMP_DIR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_SANDBOX_NAMESPACE) || \
+ defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(__NR_syz_kvm_setup_cpu) || \
+ defined(__NR_syz_init_net_socket)
NORETURN PRINTF static void fail(const char* msg, ...)
{
int e = errno;
diff --git a/pkg/csource/linux_common.go b/pkg/csource/linux_common.go
index 5b630e4fe..ee92f9fe5 100644
--- a/pkg/csource/linux_common.go
+++ b/pkg/csource/linux_common.go
@@ -113,11 +113,19 @@ var commonHeaderLinux = `
#include <sys/ioctl.h>
#include <sys/stat.h>
#endif
+#if defined(SYZ_EXECUTOR) || defined(__NR_syz_init_net_socket)
+#include <fcntl.h>
+#include <sched.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
defined(SYZ_USE_TMP_DIR) || defined(SYZ_HANDLE_SEGV) || defined(SYZ_TUN_ENABLE) || \
defined(SYZ_SANDBOX_NAMESPACE) || defined(SYZ_SANDBOX_SETUID) || \
- defined(SYZ_SANDBOX_NONE) || defined(SYZ_FAULT_INJECTION) || defined(__NR_syz_kvm_setup_cpu)
+ defined(SYZ_SANDBOX_NONE) || defined(SYZ_FAULT_INJECTION) || \
+ defined(__NR_syz_kvm_setup_cpu) || defined(__NR_syz_init_net_socket)
__attribute__((noreturn)) static void doexit(int status)
{
volatile unsigned i;
@@ -193,9 +201,10 @@ const int kRetryStatus = 69;
const int kErrorStatus = 68;
#endif
-#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
- defined(SYZ_USE_TMP_DIR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_SANDBOX_NAMESPACE) || \
- defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(__NR_syz_kvm_setup_cpu)
+#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
+ defined(SYZ_USE_TMP_DIR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_SANDBOX_NAMESPACE) || \
+ defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(__NR_syz_kvm_setup_cpu) || \
+ defined(__NR_syz_init_net_socket)
NORETURN PRINTF static void fail(const char* msg, ...)
{
int e = errno;
@@ -797,6 +806,32 @@ static uintptr_t syz_fuseblk_mount(uintptr_t a0, uintptr_t a1, uintptr_t a2, uin
}
#endif
+#if defined(SYZ_EXECUTOR) || defined(__NR_syz_init_net_socket)
+#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(SYZ_SANDBOX_NAMESPACE)
+const int kInitNetNsFd = 253;
+static uintptr_t syz_init_net_socket(uintptr_t domain, uintptr_t type, uintptr_t proto)
+{
+ int netns = open("/proc/self/ns/net", O_RDONLY);
+ if (netns == -1)
+ return netns;
+ if (setns(kInitNetNsFd, 0))
+ return -1;
+ int sock = syscall(__NR_socket, domain, type, proto);
+ int err = errno;
+ if (setns(netns, 0))
+ fail("setns(netns) failed");
+ close(netns);
+ errno = err;
+ return sock;
+}
+#else
+static uintptr_t syz_init_net_socket(uintptr_t domain, uintptr_t type, uintptr_t proto)
+{
+ return syscall(__NR_socket, domain, type, proto);
+}
+#endif
+#endif
+
#if defined(SYZ_EXECUTOR) || defined(__NR_syz_kvm_setup_cpu)
#if defined(__x86_64__)
@@ -1771,6 +1806,15 @@ static void sandbox_common()
setpgrp();
setsid();
+#if defined(SYZ_EXECUTOR) || defined(__NR_syz_init_net_socket)
+ int netns = open("/proc/self/ns/net", O_RDONLY);
+ if (netns == -1)
+ fail("open(/proc/self/ns/net) failed");
+ if (dup2(netns, kInitNetNsFd) < 0)
+ fail("dup2(netns, kInitNetNsFd) failed");
+ close(netns);
+#endif
+
struct rlimit rlim;
rlim.rlim_cur = rlim.rlim_max = 128 << 20;
setrlimit(RLIMIT_AS, &rlim);
diff --git a/pkg/csource/netbsd_common.go b/pkg/csource/netbsd_common.go
index 9d3885d46..3714f29da 100644
--- a/pkg/csource/netbsd_common.go
+++ b/pkg/csource/netbsd_common.go
@@ -100,9 +100,10 @@ const int kRetryStatus = 69;
const int kErrorStatus = 68;
#endif
-#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
- defined(SYZ_USE_TMP_DIR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_SANDBOX_NAMESPACE) || \
- defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(__NR_syz_kvm_setup_cpu)
+#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
+ defined(SYZ_USE_TMP_DIR) || defined(SYZ_TUN_ENABLE) || defined(SYZ_SANDBOX_NAMESPACE) || \
+ defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(__NR_syz_kvm_setup_cpu) || \
+ defined(__NR_syz_init_net_socket)
NORETURN PRINTF static void fail(const char* msg, ...)
{
int e = errno;
diff --git a/pkg/host/host_akaros.go b/pkg/host/host_akaros.go
index 6c3fbb6d3..91ee49a7d 100644
--- a/pkg/host/host_akaros.go
+++ b/pkg/host/host_akaros.go
@@ -10,7 +10,7 @@ import (
)
// DetectSupportedSyscalls returns list on supported syscalls on host.
-func DetectSupportedSyscalls(target *prog.Target) (map[*prog.Syscall]bool, error) {
+func DetectSupportedSyscalls(target *prog.Target, sandbox string) (map[*prog.Syscall]bool, error) {
supported := make(map[*prog.Syscall]bool)
for _, c := range target.Syscalls {
supported[c] = true
diff --git a/pkg/host/host_freebsd.go b/pkg/host/host_freebsd.go
index d2745e376..39e8655c4 100644
--- a/pkg/host/host_freebsd.go
+++ b/pkg/host/host_freebsd.go
@@ -8,7 +8,7 @@ import (
)
// DetectSupportedSyscalls returns list on supported syscalls on host.
-func DetectSupportedSyscalls(target *prog.Target) (map[*prog.Syscall]bool, error) {
+func DetectSupportedSyscalls(target *prog.Target, sandbox string) (map[*prog.Syscall]bool, error) {
supported := make(map[*prog.Syscall]bool)
for _, c := range target.Syscalls {
supported[c] = true
diff --git a/pkg/host/host_fuchsia.go b/pkg/host/host_fuchsia.go
index 37cf8b847..b145961df 100644
--- a/pkg/host/host_fuchsia.go
+++ b/pkg/host/host_fuchsia.go
@@ -10,7 +10,7 @@ import (
)
// DetectSupportedSyscalls returns list on supported syscalls on host.
-func DetectSupportedSyscalls(target *prog.Target) (map[*prog.Syscall]bool, error) {
+func DetectSupportedSyscalls(target *prog.Target, sandbox string) (map[*prog.Syscall]bool, error) {
supported := make(map[*prog.Syscall]bool)
for _, c := range target.Syscalls {
supported[c] = true
diff --git a/pkg/host/host_linux.go b/pkg/host/host_linux.go
index fd3dc5bb8..57ce3e79e 100644
--- a/pkg/host/host_linux.go
+++ b/pkg/host/host_linux.go
@@ -17,7 +17,7 @@ import (
)
// DetectSupportedSyscalls returns list on supported syscalls on host.
-func DetectSupportedSyscalls(target *prog.Target) (map[*prog.Syscall]bool, error) {
+func DetectSupportedSyscalls(target *prog.Target, sandbox string) (map[*prog.Syscall]bool, error) {
// There are 3 possible strategies:
// 1. Executes all syscalls with presumably invalid arguments and check for ENOprog.
// But not all syscalls are safe to execute. For example, pause will hang,
@@ -31,23 +31,20 @@ func DetectSupportedSyscalls(target *prog.Target) (map[*prog.Syscall]bool, error
kallsyms, _ := ioutil.ReadFile("/proc/kallsyms")
supported := make(map[*prog.Syscall]bool)
for _, c := range target.Syscalls {
- if isSupported(kallsyms, c) {
+ if isSupported(sandbox, kallsyms, c) {
supported[c] = true
}
}
return supported, nil
}
-func isSupported(kallsyms []byte, c *prog.Syscall) bool {
+func isSupported(sandbox string, kallsyms []byte, c *prog.Syscall) bool {
if strings.HasPrefix(c.CallName, "syz_") {
- return isSupportedSyzkall(c)
+ return isSupportedSyzkall(sandbox, c)
}
if strings.HasPrefix(c.Name, "socket$") {
return isSupportedSocket(c)
}
- if strings.HasPrefix(c.Name, "open$") {
- return isSupportedOpen(c)
- }
if strings.HasPrefix(c.Name, "openat$") {
return isSupportedOpenAt(c)
}
@@ -69,7 +66,7 @@ var kallsymsMap = map[string]string{
"umount2": "umount",
}
-func isSupportedSyzkall(c *prog.Syscall) bool {
+func isSupportedSyzkall(sandbox string, c *prog.Syscall) bool {
switch c.CallName {
case "syz_open_dev":
if _, ok := c.Args[0].(*prog.ConstType); ok {
@@ -81,7 +78,7 @@ func isSupportedSyzkall(c *prog.Syscall) bool {
if !ok {
panic("first open arg is not a pointer to string const")
}
- if syscall.Getuid() != 0 {
+ if syscall.Getuid() != 0 || sandbox == "setuid" {
return false
}
var check func(dev string) bool
@@ -102,15 +99,21 @@ func isSupportedSyzkall(c *prog.Syscall) bool {
case "syz_open_pts":
return true
case "syz_fuse_mount":
+ if syscall.Getuid() != 0 || sandbox == "setuid" {
+ return false
+ }
return osutil.IsExist("/dev/fuse")
case "syz_fuseblk_mount":
- return osutil.IsExist("/dev/fuse") && syscall.Getuid() == 0
+ if syscall.Getuid() != 0 || sandbox == "setuid" {
+ return false
+ }
+ return osutil.IsExist("/dev/fuse")
case "syz_emit_ethernet", "syz_extract_tcp_res":
fd, err := syscall.Open("/dev/net/tun", syscall.O_RDWR, 0)
if err == nil {
syscall.Close(fd)
}
- return err == nil && syscall.Getuid() == 0
+ return err == nil
case "syz_kvm_setup_cpu":
switch c.Name {
case "syz_kvm_setup_cpu$x86":
@@ -118,6 +121,15 @@ func isSupportedSyzkall(c *prog.Syscall) bool {
case "syz_kvm_setup_cpu$arm64":
return runtime.GOARCH == "arm64"
}
+ case "syz_init_net_socket":
+ // Unfortunately this only works with sandbox none at the moment.
+ // The problem is that setns of a network namespace requires CAP_SYS_ADMIN
+ // in the target namespace, and we've lost all privs in the init namespace
+ // during creation of a user namespace.
+ if syscall.Getuid() != 0 || sandbox != "none" {
+ return false
+ }
+ return isSupportedSocket(c)
}
panic("unknown syzkall: " + c.Name)
}
@@ -125,7 +137,6 @@ func isSupportedSyzkall(c *prog.Syscall) bool {
func isSupportedSocket(c *prog.Syscall) bool {
af, ok := c.Args[0].(*prog.ConstType)
if !ok {
- println(c.Name)
panic("socket family is not const")
}
fd, err := syscall.Socket(int(af.Val), 0, 0)
@@ -135,18 +146,6 @@ func isSupportedSocket(c *prog.Syscall) bool {
return err != syscall.ENOSYS && err != syscall.EAFNOSUPPORT
}
-func isSupportedOpen(c *prog.Syscall) bool {
- fname, ok := extractStringConst(c.Args[0])
- if !ok {
- return true
- }
- fd, err := syscall.Open(fname, syscall.O_RDONLY, 0)
- if fd != -1 {
- syscall.Close(fd)
- }
- return err == nil
-}
-
func isSupportedOpenAt(c *prog.Syscall) bool {
fname, ok := extractStringConst(c.Args[1])
if !ok {
diff --git a/pkg/host/host_linux_test.go b/pkg/host/host_linux_test.go
index e32fe09cc..9deda69bc 100644
--- a/pkg/host/host_linux_test.go
+++ b/pkg/host/host_linux_test.go
@@ -21,7 +21,7 @@ func TestLog(t *testing.T) {
t.Fatal(err)
}
// Dump for manual inspection.
- supp, err := DetectSupportedSyscalls(target)
+ supp, err := DetectSupportedSyscalls(target, "none")
if err != nil {
t.Skipf("skipping: %v", err)
}
@@ -54,7 +54,7 @@ func TestSupportedSyscalls(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- supp, err := DetectSupportedSyscalls(target)
+ supp, err := DetectSupportedSyscalls(target, "none")
if err != nil {
t.Skipf("skipping: %v", err)
}
diff --git a/pkg/host/host_netbsd.go b/pkg/host/host_netbsd.go
index d2745e376..39e8655c4 100644
--- a/pkg/host/host_netbsd.go
+++ b/pkg/host/host_netbsd.go
@@ -8,7 +8,7 @@ import (
)
// DetectSupportedSyscalls returns list on supported syscalls on host.
-func DetectSupportedSyscalls(target *prog.Target) (map[*prog.Syscall]bool, error) {
+func DetectSupportedSyscalls(target *prog.Target, sandbox string) (map[*prog.Syscall]bool, error) {
supported := make(map[*prog.Syscall]bool)
for _, c := range target.Syscalls {
supported[c] = true
diff --git a/pkg/host/host_windows.go b/pkg/host/host_windows.go
index d2745e376..39e8655c4 100644
--- a/pkg/host/host_windows.go
+++ b/pkg/host/host_windows.go
@@ -8,7 +8,7 @@ import (
)
// DetectSupportedSyscalls returns list on supported syscalls on host.
-func DetectSupportedSyscalls(target *prog.Target) (map[*prog.Syscall]bool, error) {
+func DetectSupportedSyscalls(target *prog.Target, sandbox string) (map[*prog.Syscall]bool, error) {
supported := make(map[*prog.Syscall]bool)
for _, c := range target.Syscalls {
supported[c] = true