xref: /xnu-12377.61.12/tests/test_utils.c (revision 4d495c6e23c53686cf65f45067f79024cf5dcee8) !
1*4d495c6eSApple OSS Distributions #include <dispatch/dispatch.h>
2*4d495c6eSApple OSS Distributions #include <mach-o/dyld.h>
3*4d495c6eSApple OSS Distributions #include <signal.h>
4*4d495c6eSApple OSS Distributions #include <sys/code_signing.h>
5*4d495c6eSApple OSS Distributions #include <sys/kern_sysctl.h>
6*4d495c6eSApple OSS Distributions #include <sys/sysctl.h>
7*4d495c6eSApple OSS Distributions #include <sys/kern_memorystatus.h>
8*4d495c6eSApple OSS Distributions 
9*4d495c6eSApple OSS Distributions #include <darwintest.h>
10*4d495c6eSApple OSS Distributions #include <darwintest_utils.h>
11*4d495c6eSApple OSS Distributions 
12*4d495c6eSApple OSS Distributions #include "test_utils.h"
13*4d495c6eSApple OSS Distributions 
14*4d495c6eSApple OSS Distributions bool
is_development_kernel(void)15*4d495c6eSApple OSS Distributions is_development_kernel(void)
16*4d495c6eSApple OSS Distributions {
17*4d495c6eSApple OSS Distributions 	static dispatch_once_t is_development_once;
18*4d495c6eSApple OSS Distributions 	static bool is_development;
19*4d495c6eSApple OSS Distributions 
20*4d495c6eSApple OSS Distributions 	dispatch_once(&is_development_once, ^{
21*4d495c6eSApple OSS Distributions 		int dev;
22*4d495c6eSApple OSS Distributions 		size_t dev_size = sizeof(dev);
23*4d495c6eSApple OSS Distributions 
24*4d495c6eSApple OSS Distributions 		T_QUIET;
25*4d495c6eSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(sysctlbyname("kern.development", &dev,
26*4d495c6eSApple OSS Distributions 		&dev_size, NULL, 0), NULL);
27*4d495c6eSApple OSS Distributions 		is_development = (dev != 0);
28*4d495c6eSApple OSS Distributions 	});
29*4d495c6eSApple OSS Distributions 
30*4d495c6eSApple OSS Distributions 	return is_development;
31*4d495c6eSApple OSS Distributions }
32*4d495c6eSApple OSS Distributions 
33*4d495c6eSApple OSS Distributions bool
is_sptm_enabled(void)34*4d495c6eSApple OSS Distributions is_sptm_enabled(void)
35*4d495c6eSApple OSS Distributions {
36*4d495c6eSApple OSS Distributions 	static dispatch_once_t is_sptm_enabled_once;
37*4d495c6eSApple OSS Distributions 	static bool is_sptm_enabled;
38*4d495c6eSApple OSS Distributions 
39*4d495c6eSApple OSS Distributions 	dispatch_once(&is_sptm_enabled_once, ^{
40*4d495c6eSApple OSS Distributions 		int page_protection_type;
41*4d495c6eSApple OSS Distributions 		size_t size = sizeof(page_protection_type);
42*4d495c6eSApple OSS Distributions 		int err = sysctlbyname("kern.page_protection_type", &page_protection_type, &size, NULL, 0);
43*4d495c6eSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(err, "sysctl(\"kern.page_protection_type\");");
44*4d495c6eSApple OSS Distributions 		is_sptm_enabled = (page_protection_type == 2);
45*4d495c6eSApple OSS Distributions 	});
46*4d495c6eSApple OSS Distributions 
47*4d495c6eSApple OSS Distributions 	return is_sptm_enabled;
48*4d495c6eSApple OSS Distributions }
49*4d495c6eSApple OSS Distributions 
50*4d495c6eSApple OSS Distributions bool
is_map_jit_allowed(void)51*4d495c6eSApple OSS Distributions is_map_jit_allowed(void)
52*4d495c6eSApple OSS Distributions {
53*4d495c6eSApple OSS Distributions 	static dispatch_once_t is_map_jit_allowed_once;
54*4d495c6eSApple OSS Distributions 	static bool is_map_jit_allowed;
55*4d495c6eSApple OSS Distributions 
56*4d495c6eSApple OSS Distributions 	dispatch_once(&is_map_jit_allowed_once, ^{
57*4d495c6eSApple OSS Distributions 		code_signing_config_t cs_config = 0;
58*4d495c6eSApple OSS Distributions 		size_t cs_config_size = sizeof(cs_config);
59*4d495c6eSApple OSS Distributions 
60*4d495c6eSApple OSS Distributions 		/* Query the code signing configuration information */
61*4d495c6eSApple OSS Distributions 		int err = sysctlbyname("security.codesigning.config", &cs_config, &cs_config_size, NULL, 0);
62*4d495c6eSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(err, "sysctl(\"security.codesigning.config\");");
63*4d495c6eSApple OSS Distributions 
64*4d495c6eSApple OSS Distributions 		is_map_jit_allowed = !!(cs_config & CS_CONFIG_MAP_JIT);
65*4d495c6eSApple OSS Distributions 	});
66*4d495c6eSApple OSS Distributions 
67*4d495c6eSApple OSS Distributions 	return is_map_jit_allowed;
68*4d495c6eSApple OSS Distributions }
69*4d495c6eSApple OSS Distributions 
70*4d495c6eSApple OSS Distributions bool
process_is_translated()71*4d495c6eSApple OSS Distributions process_is_translated()
72*4d495c6eSApple OSS Distributions {
73*4d495c6eSApple OSS Distributions 	static dispatch_once_t is_translated_once;
74*4d495c6eSApple OSS Distributions 	static bool is_translated;
75*4d495c6eSApple OSS Distributions 
76*4d495c6eSApple OSS Distributions 	dispatch_once(&is_translated_once, ^{
77*4d495c6eSApple OSS Distributions 		int out_value = 0;
78*4d495c6eSApple OSS Distributions 		size_t inout_size = sizeof(out_value);
79*4d495c6eSApple OSS Distributions 		if (sysctlbyname("sysctl.proc_translated", &out_value, &inout_size, NULL, 0) != 0) {
80*4d495c6eSApple OSS Distributions 		        /*
81*4d495c6eSApple OSS Distributions 		         * ENOENT means the sysctl is not present and therefore
82*4d495c6eSApple OSS Distributions 		         * this process is not translated. Any other error is bad.
83*4d495c6eSApple OSS Distributions 		         */
84*4d495c6eSApple OSS Distributions 		        T_QUIET; T_ASSERT_POSIX_ERROR(errno, ENOENT, "sysctlbyname(sysctl.proc_translated)");
85*4d495c6eSApple OSS Distributions 		        is_translated = false;
86*4d495c6eSApple OSS Distributions 		} else {
87*4d495c6eSApple OSS Distributions 		        T_QUIET; T_ASSERT_GE(inout_size, sizeof(out_value), "sysctlbyname(sysctl.proc_translated)");
88*4d495c6eSApple OSS Distributions 		        is_translated = (bool)out_value;
89*4d495c6eSApple OSS Distributions 		}
90*4d495c6eSApple OSS Distributions 	});
91*4d495c6eSApple OSS Distributions 	return is_translated;
92*4d495c6eSApple OSS Distributions }
93*4d495c6eSApple OSS Distributions 
94*4d495c6eSApple OSS Distributions 
95*4d495c6eSApple OSS Distributions pid_t
launch_background_helper(const char * variant,bool start_suspended,bool memorystatus_managed)96*4d495c6eSApple OSS Distributions launch_background_helper(
97*4d495c6eSApple OSS Distributions 	const char* variant,
98*4d495c6eSApple OSS Distributions 	bool start_suspended,
99*4d495c6eSApple OSS Distributions 	bool memorystatus_managed)
100*4d495c6eSApple OSS Distributions {
101*4d495c6eSApple OSS Distributions 	pid_t pid;
102*4d495c6eSApple OSS Distributions 	char **launch_tool_args;
103*4d495c6eSApple OSS Distributions 	char testpath[PATH_MAX];
104*4d495c6eSApple OSS Distributions 	char *variant_cpy = strdup(variant);
105*4d495c6eSApple OSS Distributions 	uint32_t testpath_buf_size;
106*4d495c6eSApple OSS Distributions 	int ret;
107*4d495c6eSApple OSS Distributions 
108*4d495c6eSApple OSS Distributions 	testpath_buf_size = sizeof(testpath);
109*4d495c6eSApple OSS Distributions 	ret = _NSGetExecutablePath(testpath, &testpath_buf_size);
110*4d495c6eSApple OSS Distributions 	launch_tool_args = (char *[]){
111*4d495c6eSApple OSS Distributions 		testpath,
112*4d495c6eSApple OSS Distributions 		"-n",
113*4d495c6eSApple OSS Distributions 		variant_cpy,
114*4d495c6eSApple OSS Distributions 		NULL
115*4d495c6eSApple OSS Distributions 	};
116*4d495c6eSApple OSS Distributions 	ret = dt_launch_tool(&pid, launch_tool_args, start_suspended, NULL, NULL);
117*4d495c6eSApple OSS Distributions 	if (ret != 0) {
118*4d495c6eSApple OSS Distributions 		T_LOG("dt_launch tool returned %d with error code %d", ret, errno);
119*4d495c6eSApple OSS Distributions 	}
120*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "dt_launch_tool");
121*4d495c6eSApple OSS Distributions 	if (memorystatus_managed) {
122*4d495c6eSApple OSS Distributions 		set_process_memorystatus_managed(pid);
123*4d495c6eSApple OSS Distributions 	}
124*4d495c6eSApple OSS Distributions 	free(variant_cpy);
125*4d495c6eSApple OSS Distributions 	return pid;
126*4d495c6eSApple OSS Distributions }
127*4d495c6eSApple OSS Distributions 
128*4d495c6eSApple OSS Distributions void
set_process_memorystatus_managed(pid_t pid)129*4d495c6eSApple OSS Distributions set_process_memorystatus_managed(pid_t pid)
130*4d495c6eSApple OSS Distributions {
131*4d495c6eSApple OSS Distributions 	kern_return_t ret = memorystatus_control(MEMORYSTATUS_CMD_SET_PROCESS_IS_MANAGED, pid, 1, NULL, 0);
132*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "memorystatus_control");
133*4d495c6eSApple OSS Distributions }
134