1 #include <darwintest.h> 2 3 #include <errno.h> 4 #include <libproc.h> 5 #include <signal.h> 6 #include <spawn.h> 7 #include <spawn_private.h> 8 #include <sys/spawn_internal.h> 9 #include <stdbool.h> 10 #include <stdint.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <sys/kauth.h> 15 #include <sys/proc_info.h> 16 #include <sys/sysctl.h> 17 #include <sysexits.h> 18 #include <unistd.h> 19 #include <kern/cs_blobs.h> 20 #include <sys/codesign.h> 21 22 T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true), 23 T_META_RADAR_COMPONENT_NAME("xnu"), 24 T_META_RADAR_COMPONENT_VERSION("codesigning")); 25 26 T_DECL(cs_launch_type_t, "Check posix_spawnattr for launch type", 27 T_META_ASROOT(true)) 28 { 29 posix_spawnattr_t attr; 30 int ret; 31 32 ret = posix_spawnattr_init(&attr); 33 T_QUIET; 34 T_ASSERT_POSIX_ZERO(ret, "posix_spawnattr_init"); 35 36 ret = posix_spawnattr_set_launch_type_np(&attr, CS_LAUNCH_TYPE_SYSTEM_SERVICE); 37 T_QUIET; 38 T_ASSERT_POSIX_ZERO(ret, "posix_spawnattr_set_launch_type_np"); 39 40 41 char * const prog = "/bin/ls"; 42 char * const argv_child[] = { prog, 43 NULL, }; 44 pid_t child_pid; 45 extern char **environ; 46 47 ret = posix_spawn(&child_pid, prog, NULL, &attr, argv_child, environ); 48 T_ASSERT_POSIX_ZERO(ret, "posix_spawn"); 49 50 T_LOG("parent: spawned child with pid %d\n", child_pid); 51 52 ret = posix_spawnattr_destroy(&attr); 53 T_QUIET; 54 T_ASSERT_POSIX_ZERO(ret, "posix_spawnattr_destroy"); 55 56 T_LOG("parent: waiting for child process"); 57 58 int status = 0; 59 int waitpid_result = waitpid(child_pid, &status, 0); 60 T_ASSERT_EQ(waitpid_result, child_pid, "waitpid should return child we spawned"); 61 T_ASSERT_EQ(WIFEXITED(status), 1, "child should have exited normally"); 62 T_ASSERT_EQ(WEXITSTATUS(status), EX_OK, "child should have exited with success"); 63 } 64