xref: /xnu-11417.140.69/tests/posix_spawnattr_set_crash_behavior_np.c (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
1*43a90889SApple OSS Distributions #include <stdio.h>
2*43a90889SApple OSS Distributions #include <sys/sysctl.h>
3*43a90889SApple OSS Distributions #include <spawn_private.h>
4*43a90889SApple OSS Distributions #include <signal.h>
5*43a90889SApple OSS Distributions #include <sys/reason.h>
6*43a90889SApple OSS Distributions 
7*43a90889SApple OSS Distributions #ifdef T_NAMESPACE
8*43a90889SApple OSS Distributions #undef T_NAMESPACE
9*43a90889SApple OSS Distributions #endif
10*43a90889SApple OSS Distributions #include <darwintest.h>
11*43a90889SApple OSS Distributions #include <darwintest_utils.h>
12*43a90889SApple OSS Distributions 
13*43a90889SApple OSS Distributions T_GLOBAL_META(
14*43a90889SApple OSS Distributions 	T_META_RADAR_COMPONENT_NAME("xnu"),
15*43a90889SApple OSS Distributions 	T_META_RADAR_COMPONENT_VERSION("spawn"),
16*43a90889SApple OSS Distributions 	T_META_NAMESPACE("xnu.spawn"));
17*43a90889SApple OSS Distributions 
18*43a90889SApple OSS Distributions extern char **environ;
19*43a90889SApple OSS Distributions 
20*43a90889SApple OSS Distributions #define SYSCTL_CRASH_BEHAVIOR_TEST_MODE "kern.crash_behavior_test_mode=1"
21*43a90889SApple OSS Distributions #define SYSCTL_CRASH_BEHAVIOR_WOULD_PANIC "kern.crash_behavior_test_would_panic"
22*43a90889SApple OSS Distributions 
23*43a90889SApple OSS Distributions #define TEST_REASON_CODE 5
24*43a90889SApple OSS Distributions 
25*43a90889SApple OSS Distributions static void
_do_set_crash_behavior_test(char * child_mode,int signal,uint32_t flags,bool expect_panic)26*43a90889SApple OSS Distributions _do_set_crash_behavior_test(char *child_mode, int signal, uint32_t flags, bool expect_panic)
27*43a90889SApple OSS Distributions {
28*43a90889SApple OSS Distributions 	bool should_wait = (strcmp(child_mode, "wait") == 0);
29*43a90889SApple OSS Distributions 	bool reason = (strcmp(child_mode, "reason") == 0);
30*43a90889SApple OSS Distributions 	bool reason_signal = (strcmp(child_mode, "reason_signal") == 0);
31*43a90889SApple OSS Distributions 	bool dirty = (strcmp(child_mode, "dirty") == 0);
32*43a90889SApple OSS Distributions 	bool shutdown = (strcmp(child_mode, "clean") == 0) || dirty;
33*43a90889SApple OSS Distributions 	uint64_t deadline = mach_continuous_time();
34*43a90889SApple OSS Distributions 
35*43a90889SApple OSS Distributions 	// 0. clear SYSCTL_CRASH_BEHAVIOR_WOULD_PANIC
36*43a90889SApple OSS Distributions 	int would_panic = 0;
37*43a90889SApple OSS Distributions 	size_t length = sizeof(would_panic);
38*43a90889SApple OSS Distributions 	int ret = sysctlbyname(SYSCTL_CRASH_BEHAVIOR_WOULD_PANIC, NULL, 0, &would_panic, length);
39*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "Clearing SYSCTL_CRASH_BEHAVIOR_WOULD_PANIC");
40*43a90889SApple OSS Distributions 
41*43a90889SApple OSS Distributions 	// 1. posix_spawn a child process
42*43a90889SApple OSS Distributions 	char *test_program = "./posix_spawnattr_set_crash_behavior_np_child";
43*43a90889SApple OSS Distributions 	char *child_args[3];
44*43a90889SApple OSS Distributions 
45*43a90889SApple OSS Distributions 	posix_spawnattr_t attrs;
46*43a90889SApple OSS Distributions 	posix_spawnattr_init(&attrs);
47*43a90889SApple OSS Distributions 
48*43a90889SApple OSS Distributions 	ret = posix_spawnattr_set_crash_behavior_np(&attrs, flags);
49*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ret, "posix_spawnattr_set_crash_behavior_np");
50*43a90889SApple OSS Distributions 
51*43a90889SApple OSS Distributions 
52*43a90889SApple OSS Distributions 	if (should_wait) {
53*43a90889SApple OSS Distributions 		// For the purpose of the test we set the deadline to be now to avoid
54*43a90889SApple OSS Distributions 		// making the test wait
55*43a90889SApple OSS Distributions 		ret = posix_spawnattr_set_crash_behavior_deadline_np(&attrs, deadline, flags);
56*43a90889SApple OSS Distributions 		T_ASSERT_POSIX_ZERO(ret, "posix_spawnattr_set_crash_behavior_deadline_np: %lld", deadline);
57*43a90889SApple OSS Distributions 	}
58*43a90889SApple OSS Distributions 
59*43a90889SApple OSS Distributions 	child_args[0] = test_program;
60*43a90889SApple OSS Distributions 	child_args[1] = child_mode;
61*43a90889SApple OSS Distributions 	child_args[2] = NULL;
62*43a90889SApple OSS Distributions 
63*43a90889SApple OSS Distributions 	pid_t child_pid = 0;
64*43a90889SApple OSS Distributions 	ret = posix_spawn(&child_pid, child_args[0], NULL, &attrs, &child_args[0], environ);
65*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_ZERO(ret, "posix_spawn");
66*43a90889SApple OSS Distributions 	posix_spawnattr_destroy(&attrs);
67*43a90889SApple OSS Distributions 
68*43a90889SApple OSS Distributions 	if (should_wait) {
69*43a90889SApple OSS Distributions 		while (mach_continuous_time() <= deadline) {
70*43a90889SApple OSS Distributions 			usleep(1);
71*43a90889SApple OSS Distributions 		}
72*43a90889SApple OSS Distributions 	}
73*43a90889SApple OSS Distributions 
74*43a90889SApple OSS Distributions 	if (signal != 0) {
75*43a90889SApple OSS Distributions 		ret = kill(child_pid, signal);
76*43a90889SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(ret, "kill(%d, %d)", child_pid, signal);
77*43a90889SApple OSS Distributions 	}
78*43a90889SApple OSS Distributions 
79*43a90889SApple OSS Distributions 	if (reason) {
80*43a90889SApple OSS Distributions 		ret = terminate_with_reason(child_pid, OS_REASON_TEST, TEST_REASON_CODE,
81*43a90889SApple OSS Distributions 		    "Test forcing crash", OS_REASON_FLAG_CONSISTENT_FAILURE | OS_REASON_FLAG_NO_CRASH_REPORT);
82*43a90889SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(ret, "terminate_with_reason(%d)", child_pid);
83*43a90889SApple OSS Distributions 	} else if (reason_signal) {
84*43a90889SApple OSS Distributions 		ret = terminate_with_reason(child_pid, OS_REASON_SIGNAL, SIGABRT,
85*43a90889SApple OSS Distributions 		    "Test forcing crash with signal", OS_REASON_FLAG_CONSISTENT_FAILURE | OS_REASON_FLAG_NO_CRASH_REPORT);
86*43a90889SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(ret, "terminate_with_reason_signal(%d)", child_pid);
87*43a90889SApple OSS Distributions 	}
88*43a90889SApple OSS Distributions 
89*43a90889SApple OSS Distributions 	if (dirty) {
90*43a90889SApple OSS Distributions 		ret = proc_set_dirty(child_pid, true);
91*43a90889SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(ret, "proc_set_dirty(%d)", child_pid);
92*43a90889SApple OSS Distributions 	}
93*43a90889SApple OSS Distributions 
94*43a90889SApple OSS Distributions 	if (shutdown) {
95*43a90889SApple OSS Distributions 		ret = proc_terminate(child_pid, &signal);
96*43a90889SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(ret, "proc_terminate(%d, %d)", child_pid, signal);
97*43a90889SApple OSS Distributions 	}
98*43a90889SApple OSS Distributions 
99*43a90889SApple OSS Distributions 	// 2. Wait for the child to exit
100*43a90889SApple OSS Distributions 	int child_status;
101*43a90889SApple OSS Distributions 	ret = wait4(-1, &child_status, 0, NULL);
102*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "wait4");
103*43a90889SApple OSS Distributions 
104*43a90889SApple OSS Distributions 	// 3. Check if we would have panic'ed
105*43a90889SApple OSS Distributions 	would_panic = 0;
106*43a90889SApple OSS Distributions 	length = sizeof(would_panic);
107*43a90889SApple OSS Distributions 	ret = sysctlbyname(SYSCTL_CRASH_BEHAVIOR_WOULD_PANIC, &would_panic, &length, NULL, 0);
108*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "SYSCTL_CRASH_BEHAVIOR_WOULD_PANIC");
109*43a90889SApple OSS Distributions 
110*43a90889SApple OSS Distributions 	T_EXPECT_EQ(would_panic, expect_panic, NULL);
111*43a90889SApple OSS Distributions }
112*43a90889SApple OSS Distributions 
113*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_crash_with_crash,
114*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_crash_with_crash",
115*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
116*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
117*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
118*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("crash", 0, POSIX_SPAWN_PANIC_ON_CRASH, true);
119*43a90889SApple OSS Distributions }
120*43a90889SApple OSS Distributions 
121*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_crash_with_exit,
122*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_crash_with_exit",
123*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
124*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
125*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
126*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("exit", 0, POSIX_SPAWN_PANIC_ON_CRASH, false);
127*43a90889SApple OSS Distributions }
128*43a90889SApple OSS Distributions 
129*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_crash_with_success,
130*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_crash_with_success",
131*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
132*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
133*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
134*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("success", 0, POSIX_SPAWN_PANIC_ON_CRASH, false);
135*43a90889SApple OSS Distributions }
136*43a90889SApple OSS Distributions 
137*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_nonzero_with_crash,
138*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_nonzero_with_crash",
139*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
140*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
141*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
142*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("crash", 0, POSIX_SPAWN_PANIC_ON_NON_ZERO_EXIT, false);
143*43a90889SApple OSS Distributions }
144*43a90889SApple OSS Distributions 
145*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_nonzero_with_exit,
146*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_nonzero_with_exit",
147*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
148*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
149*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
150*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("exit", 0, POSIX_SPAWN_PANIC_ON_NON_ZERO_EXIT, true);
151*43a90889SApple OSS Distributions }
152*43a90889SApple OSS Distributions 
153*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_nonzero_with_success,
154*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_nonzero_with_success",
155*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
156*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
157*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
158*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("success", 0, POSIX_SPAWN_PANIC_ON_NON_ZERO_EXIT, false);
159*43a90889SApple OSS Distributions }
160*43a90889SApple OSS Distributions 
161*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_crash_cancelled,
162*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_crash_cancelled",
163*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
164*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
165*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
166*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("wait", SIGUSR1, POSIX_SPAWN_PANIC_ON_CRASH, false);
167*43a90889SApple OSS Distributions }
168*43a90889SApple OSS Distributions 
169*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_crash_sigterm,
170*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_crash_sigterm",
171*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
172*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
173*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
174*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("spin", SIGTERM, POSIX_SPAWN_PANIC_ON_CRASH, false);
175*43a90889SApple OSS Distributions }
176*43a90889SApple OSS Distributions 
177*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_crash_sigkill,
178*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_crash_sigkill",
179*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
180*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
181*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
182*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("spin", SIGKILL, POSIX_SPAWN_PANIC_ON_CRASH, false);
183*43a90889SApple OSS Distributions }
184*43a90889SApple OSS Distributions 
185*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_crash_terminate_with_reason,
186*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_crash_terminate_with_reason",
187*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
188*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
189*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
190*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("reason", 0, POSIX_SPAWN_PANIC_ON_CRASH, true);
191*43a90889SApple OSS Distributions }
192*43a90889SApple OSS Distributions 
193*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_crash_terminate_with_reason_signal,
194*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_crash_terminate_with_reason_signal",
195*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
196*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
197*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
198*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("reason_signal", 0, POSIX_SPAWN_PANIC_ON_CRASH, true);
199*43a90889SApple OSS Distributions }
200*43a90889SApple OSS Distributions 
201*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_crash_proc_terminate_clean,
202*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_crash_proc_terminate_clean",
203*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
204*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
205*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
206*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("clean", 0, POSIX_SPAWN_PANIC_ON_CRASH, false);
207*43a90889SApple OSS Distributions }
208*43a90889SApple OSS Distributions 
209*43a90889SApple OSS Distributions T_DECL(set_crash_behavior_panic_on_crash_proc_terminate_dirty,
210*43a90889SApple OSS Distributions     "set_crash_behavior_panic_on_crash_proc_terminate_dirty",
211*43a90889SApple OSS Distributions     T_META_SYSCTL_INT(SYSCTL_CRASH_BEHAVIOR_TEST_MODE),
212*43a90889SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("kern.development", 1),
213*43a90889SApple OSS Distributions     T_META_TAG_VM_PREFERRED) {
214*43a90889SApple OSS Distributions 	_do_set_crash_behavior_test("dirty", 0, POSIX_SPAWN_PANIC_ON_CRASH, false);
215*43a90889SApple OSS Distributions }
216