aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/csource
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/csource')
-rw-r--r--pkg/csource/common.go54
-rw-r--r--pkg/csource/generated.go121
-rw-r--r--pkg/csource/options.go4
-rw-r--r--pkg/csource/options_test.go22
4 files changed, 167 insertions, 34 deletions
diff --git a/pkg/csource/common.go b/pkg/csource/common.go
index 99537b233..80ce02ef6 100644
--- a/pkg/csource/common.go
+++ b/pkg/csource/common.go
@@ -19,9 +19,10 @@ import (
const (
linux = "linux"
- sandboxNone = "none"
- sandboxSetuid = "setuid"
- sandboxNamespace = "namespace"
+ sandboxNone = "none"
+ sandboxSetuid = "setuid"
+ sandboxNamespace = "namespace"
+ sandboxAndroidUntrustedApp = "android_untrusted_app"
)
func createCommonHeader(p, mmapProg *prog.Prog, replacements map[string]string, opts Options) ([]byte, error) {
@@ -64,29 +65,30 @@ func defineList(p, mmapProg *prog.Prog, opts Options) (defines []string) {
sysTarget := targets.Get(p.Target.OS, p.Target.Arch)
bitmasks, csums := prog.RequiredFeatures(p)
enabled := map[string]bool{
- "GOOS_" + p.Target.OS: true,
- "GOARCH_" + p.Target.Arch: true,
- "SYZ_USE_BITMASKS": bitmasks,
- "SYZ_USE_CHECKSUMS": csums,
- "SYZ_SANDBOX_NONE": opts.Sandbox == sandboxNone,
- "SYZ_SANDBOX_SETUID": opts.Sandbox == sandboxSetuid,
- "SYZ_SANDBOX_NAMESPACE": opts.Sandbox == sandboxNamespace,
- "SYZ_THREADED": opts.Threaded,
- "SYZ_COLLIDE": opts.Collide,
- "SYZ_REPEAT": opts.Repeat,
- "SYZ_REPEAT_TIMES": opts.RepeatTimes > 1,
- "SYZ_PROCS": opts.Procs > 1,
- "SYZ_FAULT_INJECTION": opts.Fault,
- "SYZ_TUN_ENABLE": opts.EnableTun,
- "SYZ_ENABLE_CGROUPS": opts.EnableCgroups,
- "SYZ_ENABLE_NETDEV": opts.EnableNetdev,
- "SYZ_RESET_NET_NAMESPACE": opts.ResetNet,
- "SYZ_USE_TMP_DIR": opts.UseTmpDir,
- "SYZ_HANDLE_SEGV": opts.HandleSegv,
- "SYZ_REPRO": opts.Repro,
- "SYZ_TRACE": opts.Trace,
- "SYZ_EXECUTOR_USES_SHMEM": sysTarget.ExecutorUsesShmem,
- "SYZ_EXECUTOR_USES_FORK_SERVER": sysTarget.ExecutorUsesForkServer,
+ "GOOS_" + p.Target.OS: true,
+ "GOARCH_" + p.Target.Arch: true,
+ "SYZ_USE_BITMASKS": bitmasks,
+ "SYZ_USE_CHECKSUMS": csums,
+ "SYZ_SANDBOX_NONE": opts.Sandbox == sandboxNone,
+ "SYZ_SANDBOX_SETUID": opts.Sandbox == sandboxSetuid,
+ "SYZ_SANDBOX_NAMESPACE": opts.Sandbox == sandboxNamespace,
+ "SYZ_SANDBOX_ANDROID_UNTRUSTED_APP": opts.Sandbox == sandboxAndroidUntrustedApp,
+ "SYZ_THREADED": opts.Threaded,
+ "SYZ_COLLIDE": opts.Collide,
+ "SYZ_REPEAT": opts.Repeat,
+ "SYZ_REPEAT_TIMES": opts.RepeatTimes > 1,
+ "SYZ_PROCS": opts.Procs > 1,
+ "SYZ_FAULT_INJECTION": opts.Fault,
+ "SYZ_TUN_ENABLE": opts.EnableTun,
+ "SYZ_ENABLE_CGROUPS": opts.EnableCgroups,
+ "SYZ_ENABLE_NETDEV": opts.EnableNetdev,
+ "SYZ_RESET_NET_NAMESPACE": opts.ResetNet,
+ "SYZ_USE_TMP_DIR": opts.UseTmpDir,
+ "SYZ_HANDLE_SEGV": opts.HandleSegv,
+ "SYZ_REPRO": opts.Repro,
+ "SYZ_TRACE": opts.Trace,
+ "SYZ_EXECUTOR_USES_SHMEM": sysTarget.ExecutorUsesShmem,
+ "SYZ_EXECUTOR_USES_FORK_SERVER": sysTarget.ExecutorUsesForkServer,
}
for def, ok := range enabled {
if ok {
diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go
index 7b5d05f63..475982ae5 100644
--- a/pkg/csource/generated.go
+++ b/pkg/csource/generated.go
@@ -393,6 +393,7 @@ void child()
#if SYZ_EXECUTOR
#define do_sandbox_setuid() 0
#define do_sandbox_namespace() 0
+#define do_sandbox_android_untrusted_app() 0
#endif
#elif GOOS_freebsd || GOOS_netbsd || GOOS_openbsd
@@ -411,6 +412,7 @@ static int do_sandbox_none(void)
#if SYZ_EXECUTOR
#define do_sandbox_setuid() 0
#define do_sandbox_namespace() 0
+#define do_sandbox_android_untrusted_app() 0
#endif
#if GOOS_openbsd
@@ -682,6 +684,7 @@ static int do_sandbox_none(void)
#if SYZ_EXECUTOR
#define do_sandbox_setuid() 0
#define do_sandbox_namespace() 0
+#define do_sandbox_android_untrusted_app() 0
#endif
#define CAST(f) ({void* p = (void*)f; p; })
@@ -1177,7 +1180,7 @@ static long syz_open_pts(long a0, long a1)
#endif
#if SYZ_EXECUTOR || __NR_syz_init_net_socket
-#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NAMESPACE
+#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NAMESPACE || SYZ_SANDBOX_ANDROID_UNTRUSTED_APP
#include <fcntl.h>
#include <sched.h>
#include <sys/stat.h>
@@ -2983,7 +2986,7 @@ static void setup_binfmt_misc()
}
#endif
-#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NAMESPACE
+#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NAMESPACE || SYZ_SANDBOX_ANDROID_UNTRUSTED_APP
#include <errno.h>
#include <sys/mount.h>
@@ -2997,9 +3000,7 @@ static void setup_common()
setup_binfmt_misc();
#endif
}
-#endif
-#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NAMESPACE
#include <sched.h>
#include <sys/prctl.h>
#include <sys/resource.h>
@@ -3255,6 +3256,113 @@ static int do_sandbox_namespace(void)
}
#endif
+#if SYZ_EXECUTOR || SYZ_SANDBOX_ANDROID_UNTRUSTED_APP
+#include <fcntl.h>
+#include <grp.h>
+#include <sys/xattr.h>
+
+#define AID_NET_BT_ADMIN 3001
+#define AID_NET_BT 3002
+#define AID_INET 3003
+#define AID_EVERYBODY 9997
+#define AID_APP 10000
+
+#define UNTRUSTED_APP_UID AID_APP + 999
+#define UNTRUSTED_APP_GID AID_APP + 999
+
+const char* SELINUX_CONTEXT_UNTRUSTED_APP = "u:r:untrusted_app:s0:c512,c768";
+const char* SELINUX_LABEL_APP_DATA_FILE = "u:object_r:app_data_file:s0:c512,c768";
+const char* SELINUX_CONTEXT_FILE = "/proc/thread-self/attr/current";
+const char* SELINUX_XATTR_NAME = "security.selinux";
+
+const gid_t UNTRUSTED_APP_GROUPS[] = {UNTRUSTED_APP_GID, AID_NET_BT_ADMIN, AID_NET_BT, AID_INET, AID_EVERYBODY};
+const size_t UNTRUSTED_APP_NUM_GROUPS = sizeof(UNTRUSTED_APP_GROUPS) / sizeof(UNTRUSTED_APP_GROUPS[0]);
+static void syz_getcon(char* context, size_t context_size)
+{
+ int fd = open(SELINUX_CONTEXT_FILE, O_RDONLY);
+
+ if (fd < 0)
+ fail("getcon: Couldn't open %s", SELINUX_CONTEXT_FILE);
+
+ ssize_t nread = read(fd, context, context_size);
+
+ close(fd);
+
+ if (nread <= 0)
+ fail("getcon: Failed to read from %s", SELINUX_CONTEXT_FILE);
+ if (context[nread - 1] == '\n')
+ context[nread - 1] = '\0';
+}
+static void syz_setcon(const char* context)
+{
+ char new_context[512];
+ int fd = open(SELINUX_CONTEXT_FILE, O_WRONLY);
+
+ if (fd < 0)
+ fail("setcon: Could not open %s", SELINUX_CONTEXT_FILE);
+
+ ssize_t bytes_written = write(fd, context, strlen(context));
+ close(fd);
+
+ if (bytes_written != (ssize_t)strlen(context))
+ fail("setcon: Could not write entire context. Wrote %zi, expected %zu", bytes_written, strlen(context));
+ syz_getcon(new_context, sizeof(new_context));
+
+ if (strcmp(context, new_context) != 0)
+ fail("setcon: Failed to change to %s, context is %s", context, new_context);
+}
+static int syz_getfilecon(const char* path, char* context, size_t context_size)
+{
+ int length = getxattr(path, SELINUX_XATTR_NAME, context, context_size);
+
+ if (length == -1)
+ fail("getfilecon: getxattr failed");
+
+ return length;
+}
+static void syz_setfilecon(const char* path, const char* context)
+{
+ char new_context[512];
+
+ if (setxattr(path, SELINUX_XATTR_NAME, context, strlen(context) + 1, 0) != 0)
+ fail("setfilecon: setxattr failed");
+
+ if (syz_getfilecon(path, new_context, sizeof(new_context)) != 0)
+ fail("setfilecon: getfilecon failed");
+
+ if (strcmp(context, new_context) != 0)
+ fail("setfilecon: could not set context to %s, currently %s", context, new_context);
+}
+
+static int do_sandbox_android_untrusted_app(void)
+{
+ setup_common();
+ sandbox_common();
+
+ if (setgroups(UNTRUSTED_APP_NUM_GROUPS, UNTRUSTED_APP_GROUPS) != 0)
+ fail("setgroups failed");
+
+ if (setresgid(UNTRUSTED_APP_GID, UNTRUSTED_APP_GID, UNTRUSTED_APP_GID) != 0)
+ fail("setresgid failed");
+
+ if (setresuid(UNTRUSTED_APP_UID, UNTRUSTED_APP_UID, UNTRUSTED_APP_UID) != 0)
+ fail("setresuid failed");
+
+ syz_setfilecon(".", SELINUX_LABEL_APP_DATA_FILE);
+ syz_setcon(SELINUX_CONTEXT_UNTRUSTED_APP);
+
+#if SYZ_EXECUTOR || SYZ_TUN_ENABLE
+ initialize_tun();
+#endif
+#if SYZ_EXECUTOR || SYZ_ENABLE_NETDEV
+ initialize_netdevices();
+#endif
+
+ loop();
+ doexit(1);
+}
+#endif
+
#if SYZ_EXECUTOR || SYZ_REPEAT && SYZ_USE_TMP_DIR
#include <dirent.h>
#include <errno.h>
@@ -3623,6 +3731,7 @@ static int do_sandbox_none(void)
#if SYZ_EXECUTOR
#define do_sandbox_setuid() 0
#define do_sandbox_namespace() 0
+#define do_sandbox_android_untrusted_app() 0
#endif
#elif GOOS_windows
@@ -3739,6 +3848,7 @@ static int do_sandbox_none(void)
#if SYZ_EXECUTOR
#define do_sandbox_setuid() 0
#define do_sandbox_namespace() 0
+#define do_sandbox_android_untrusted_app() 0
#endif
#elif GOOS_test
@@ -3794,6 +3904,7 @@ static int do_sandbox_none(void)
#if SYZ_EXECUTOR
#define do_sandbox_setuid() 0
#define do_sandbox_namespace() 0
+#define do_sandbox_android_untrusted_app() 0
#endif
#else
@@ -4015,7 +4126,7 @@ static void loop(void)
[[RESULTS]]
-#if SYZ_THREADED || SYZ_REPEAT || SYZ_SANDBOX_NONE || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NAMESPACE
+#if SYZ_THREADED || SYZ_REPEAT || SYZ_SANDBOX_NONE || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NAMESPACE || SYZ_SANDBOX_ANDROID_UNTRUSTED_APP
#if SYZ_THREADED
void execute_call(int call)
#elif SYZ_REPEAT
diff --git a/pkg/csource/options.go b/pkg/csource/options.go
index a43774bf6..6dc3a249e 100644
--- a/pkg/csource/options.go
+++ b/pkg/csource/options.go
@@ -45,7 +45,7 @@ type Options struct {
// Invalid combinations must not be passed to Write.
func (opts Options) Check(OS string) error {
switch opts.Sandbox {
- case "", sandboxNone, sandboxNamespace, sandboxSetuid:
+ case "", sandboxNone, sandboxNamespace, sandboxSetuid, sandboxAndroidUntrustedApp:
default:
return fmt.Errorf("unknown sandbox %v", opts.Sandbox)
}
@@ -107,7 +107,7 @@ func (opts Options) checkLinuxOnly(OS string) error {
if opts.ResetNet {
return fmt.Errorf("ResetNet is not supported on %v", OS)
}
- if opts.Sandbox == sandboxNamespace || opts.Sandbox == sandboxSetuid {
+ if opts.Sandbox == sandboxNamespace || opts.Sandbox == sandboxSetuid || opts.Sandbox == sandboxAndroidUntrustedApp {
return fmt.Errorf("Sandbox=%v is not supported on %v", opts.Sandbox, OS)
}
if opts.Fault {
diff --git a/pkg/csource/options_test.go b/pkg/csource/options_test.go
index 61ebe5827..d8e8a217e 100644
--- a/pkg/csource/options_test.go
+++ b/pkg/csource/options_test.go
@@ -47,6 +47,26 @@ func TestParseOptionsCanned(t *testing.T) {
HandleSegv: true,
Repro: true,
},
+ `{"threaded":true,"collide":true,"repeat":true,"procs":10,"sandbox":"android_untrusted_app",
+ "fault":true,"fault_call":1,"fault_nth":2,"tun":true,"tmpdir":true,"cgroups":true,
+ "netdev":true,"resetnet":true,
+ "segv":true,"waitrepeat":true,"debug":true,"repro":true}`: {
+ Threaded: true,
+ Collide: true,
+ Repeat: true,
+ Procs: 10,
+ Sandbox: "android_untrusted_app",
+ Fault: true,
+ FaultCall: 1,
+ FaultNth: 2,
+ EnableTun: true,
+ UseTmpDir: true,
+ EnableCgroups: true,
+ EnableNetdev: true,
+ ResetNet: true,
+ HandleSegv: true,
+ Repro: true,
+ },
"{Threaded:true Collide:true Repeat:true Procs:1 Sandbox:none Fault:false FaultCall:-1 FaultNth:0 EnableTun:true UseTmpDir:true HandleSegv:true WaitRepeat:true Debug:false Repro:false}": {
Threaded: true,
Collide: true,
@@ -140,7 +160,7 @@ func enumerateField(OS string, opt Options, field int) []Options {
fldName := s.Type().Field(field).Name
fld := s.Field(field)
if fldName == "Sandbox" {
- for _, sandbox := range []string{"", "none", "setuid", "namespace"} {
+ for _, sandbox := range []string{"", "none", "setuid", "namespace", "android_untrusted_app"} {
fld.SetString(sandbox)
opts = append(opts, opt)
}