3 #include <darwintest.h>
4 #include <mach-o/dyld.h>
10 static int binprefs_child_is_64
= 0;
13 signal_handler(__unused
int sig
)
15 binprefs_child_is_64
= 1;
19 T_DECL(no32exec_bootarg_with_spawn
, "make sure the no32exec boot-arg is honored, using posix_spawn", T_META_BOOTARGS_SET("-no32exec"))
23 uint32_t size
= sizeof(path
);
25 T_QUIET
; T_ASSERT_EQ(_NSGetExecutablePath(path
, &size
), 0, NULL
);
26 T_QUIET
; T_ASSERT_LT(strlcat(path
, "_helper", size
), size
, NULL
);
28 spawn_ret
= posix_spawn(&pid
, path
, NULL
, NULL
, NULL
, NULL
);
31 waitpid(pid
, &wait_ret
, 0);
32 T_ASSERT_FALSE(WIFEXITED(wait_ret
), "i386 helper should not run");
34 T_ASSERT_EQ(spawn_ret
, EBADARCH
, NULL
);
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"))
41 posix_spawnattr_t spawnattr
;
42 cpu_type_t cpuprefs
[] = { CPU_TYPE_X86
, CPU_TYPE_X86_64
};
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
);
49 T_QUIET
; T_ASSERT_NE(signal(SIGUSR1
, signal_handler
), SIG_ERR
, "signal");
51 ret
= posix_spawnattr_init(&spawnattr
);
52 T_QUIET
; T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawnattr_init");
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");
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");
61 ret
= kill(pid
, SIGUSR1
); // ping helper; helper should ping back if running 64-bit
62 T_QUIET
; T_ASSERT_POSIX_SUCCESS(ret
, "kill");
65 T_QUIET
; T_ASSERT_EQ(ret
, pid
, "child pid");
67 T_ASSERT_EQ(binprefs_child_is_64
, 1, "child process should be running in 64-bit mode");
69 ret
= posix_spawnattr_destroy(&spawnattr
);
70 T_QUIET
; T_ASSERT_EQ(ret
, 0, "posix_spawnattr_destroy");
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"))
77 uint32_t size
= sizeof(path
);
79 T_QUIET
; T_ASSERT_EQ(_NSGetExecutablePath(path
, &size
), 0, NULL
);
80 T_QUIET
; T_ASSERT_LT(strlcat(path
, "_helper", size
), size
, NULL
);
83 T_QUIET
; T_ASSERT_POSIX_SUCCESS(pid
, "fork");
85 if (pid
== 0) { /* child */
86 execve(path
, NULL
, NULL
); /* this should fail, resulting in the call to exit below */
90 waitpid(pid
, &wait_ret
, 0);
91 T_ASSERT_EQ(WEXITSTATUS(wait_ret
), EBADARCH
, "execve should set errno = EBADARCH");