]> git.saurik.com Git - apple/xnu.git/blob - tests/no32exec_35914211.c
b1f87634f9599952a53378cab38a69ade15c165b
[apple/xnu.git] / tests / no32exec_35914211.c
1 #include <spawn.h>
2 #include <sys/wait.h>
3 #include <darwintest.h>
4 #include <mach-o/dyld.h>
5 #include <errno.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <signal.h>
9
10 static int binprefs_child_is_64 = 0;
11
12 static void
13 signal_handler(__unused int sig)
14 {
15 binprefs_child_is_64 = 1;
16 return;
17 }
18
19 T_DECL(no32exec_bootarg_with_spawn, "make sure the no32exec boot-arg is honored, using posix_spawn", T_META_BOOTARGS_SET("-no32exec"))
20 {
21 int spawn_ret, pid;
22 char path[1024];
23 uint32_t size = sizeof(path);
24
25 T_QUIET; T_ASSERT_EQ(_NSGetExecutablePath(path, &size), 0, NULL);
26 T_QUIET; T_ASSERT_LT(strlcat(path, "_helper", size), size, NULL);
27
28 spawn_ret = posix_spawn(&pid, path, NULL, NULL, NULL, NULL);
29 if (spawn_ret == 0) {
30 int wait_ret = 0;
31 waitpid(pid, &wait_ret, 0);
32 T_ASSERT_FALSE(WIFEXITED(wait_ret), "i386 helper should not run");
33 }
34 T_ASSERT_EQ(spawn_ret, EBADARCH, NULL);
35 }
36
37 T_DECL(no32exec_bootarg_with_spawn_binprefs, "make sure the no32exec boot-arg is honored, using posix_spawn"
38 "with binprefs on a fat i386/x86_64 Mach-O", T_META_BOOTARGS_SET("-no32exec"))
39 {
40 int pid, ret;
41 posix_spawnattr_t spawnattr;
42 cpu_type_t cpuprefs[] = { CPU_TYPE_X86, CPU_TYPE_X86_64 };
43
44 char path[1024];
45 uint32_t size = sizeof(path);
46 T_QUIET; T_ASSERT_EQ(_NSGetExecutablePath(path, &size), 0, NULL);
47 T_QUIET; T_ASSERT_LT(strlcat(path, "_helper_binprefs", size), size, NULL);
48
49 T_QUIET; T_ASSERT_NE(signal(SIGUSR1, signal_handler), SIG_ERR, "signal");
50
51 ret = posix_spawnattr_init(&spawnattr);
52 T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "posix_spawnattr_init");
53
54 ret = posix_spawnattr_setbinpref_np(&spawnattr, sizeof(cpuprefs) / sizeof(cpuprefs[0]), cpuprefs, NULL);
55 T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "posix_spawnattr_setbinpref_np");
56
57 ret = posix_spawn(&pid, path, NULL, &spawnattr, NULL, NULL);
58 T_ASSERT_EQ(ret, 0, "posix_spawn should succeed despite 32-bit binpref appearing first");
59
60 sleep(1);
61 ret = kill(pid, SIGUSR1); // ping helper; helper should ping back if running 64-bit
62 T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "kill");
63
64 ret = wait(NULL);
65 T_QUIET; T_ASSERT_EQ(ret, pid, "child pid");
66
67 T_ASSERT_EQ(binprefs_child_is_64, 1, "child process should be running in 64-bit mode");
68
69 ret = posix_spawnattr_destroy(&spawnattr);
70 T_QUIET; T_ASSERT_EQ(ret, 0, "posix_spawnattr_destroy");
71 }
72
73 T_DECL(no32_exec_bootarg_with_exec, "make sure the no32exec boot-arg is honored, using fork and exec", T_META_BOOTARGS_SET("-no32exec"))
74 {
75 int pid;
76 char path[1024];
77 uint32_t size = sizeof(path);
78
79 T_QUIET; T_ASSERT_EQ(_NSGetExecutablePath(path, &size), 0, NULL);
80 T_QUIET; T_ASSERT_LT(strlcat(path, "_helper", size), size, NULL);
81
82 pid = fork();
83 T_QUIET; T_ASSERT_POSIX_SUCCESS(pid, "fork");
84
85 if (pid == 0) { /* child */
86 execve(path, NULL, NULL); /* this should fail, resulting in the call to exit below */
87 exit(errno);
88 } else { /* parent */
89 int wait_ret = 0;
90 waitpid(pid, &wait_ret, 0);
91 T_ASSERT_EQ(WEXITSTATUS(wait_ret), EBADARCH, "execve should set errno = EBADARCH");
92 }
93 }