xref: /xnu-11417.101.15/tests/libmalloc_apple_array.c (revision e3723e1f17661b24996789d8afc084c0c3303b26)
1*e3723e1fSApple OSS Distributions #include <errno.h>
2*e3723e1fSApple OSS Distributions #include <stdlib.h>
3*e3723e1fSApple OSS Distributions #include <libgen.h>
4*e3723e1fSApple OSS Distributions #include <limits.h>
5*e3723e1fSApple OSS Distributions #include <mach-o/dyld.h>
6*e3723e1fSApple OSS Distributions #include <sys/types.h>
7*e3723e1fSApple OSS Distributions #include <sys/sysctl.h>
8*e3723e1fSApple OSS Distributions #include <xlocale.h>
9*e3723e1fSApple OSS Distributions 
10*e3723e1fSApple OSS Distributions #include <darwintest.h>
11*e3723e1fSApple OSS Distributions #include <darwintest_utils.h>
12*e3723e1fSApple OSS Distributions 
13*e3723e1fSApple OSS Distributions #include "drop_priv.h"
14*e3723e1fSApple OSS Distributions #include "test_utils.h"
15*e3723e1fSApple OSS Distributions 
16*e3723e1fSApple OSS Distributions #if ENTITLED
17*e3723e1fSApple OSS Distributions #define SET_TREATMENT_ID set_treatment_id_entitled
18*e3723e1fSApple OSS Distributions #define SET_TREATMENT_ID_DESCR "Can set treatment id with entitlement"
19*e3723e1fSApple OSS Distributions #else /* ENTITLED */
20*e3723e1fSApple OSS Distributions #define SET_TREATMENT_ID set_treatment_id_unentitled
21*e3723e1fSApple OSS Distributions #define SET_TREATMENT_ID_DESCR "Can't set treatment id without entitlement"
22*e3723e1fSApple OSS Distributions #endif /* ENTITLED */
23*e3723e1fSApple OSS Distributions 
24*e3723e1fSApple OSS Distributions T_DECL(SET_TREATMENT_ID, "Verifies that EXPERIMENT sysctls can only be set with the entitlement", T_META_ASROOT(false))
25*e3723e1fSApple OSS Distributions {
26*e3723e1fSApple OSS Distributions #define TEST_STR "testing"
27*e3723e1fSApple OSS Distributions #define IDENTIFIER_LENGTH 36
28*e3723e1fSApple OSS Distributions 
29*e3723e1fSApple OSS Distributions 	int ret;
30*e3723e1fSApple OSS Distributions 	errno_t err;
31*e3723e1fSApple OSS Distributions 	char val[IDENTIFIER_LENGTH + 1] = {0};
32*e3723e1fSApple OSS Distributions 	size_t len = sizeof(val);
33*e3723e1fSApple OSS Distributions 	char new_val[IDENTIFIER_LENGTH + 1] = {0};
34*e3723e1fSApple OSS Distributions 
35*e3723e1fSApple OSS Distributions 	if (!is_development_kernel()) {
36*e3723e1fSApple OSS Distributions 		T_SKIP("skipping test on release kernel");
37*e3723e1fSApple OSS Distributions 	}
38*e3723e1fSApple OSS Distributions 
39*e3723e1fSApple OSS Distributions 	strlcpy(new_val, TEST_STR, sizeof(new_val));
40*e3723e1fSApple OSS Distributions 	if (running_as_root()) {
41*e3723e1fSApple OSS Distributions 		drop_priv();
42*e3723e1fSApple OSS Distributions 	}
43*e3723e1fSApple OSS Distributions 
44*e3723e1fSApple OSS Distributions 	ret = sysctlbyname("kern.trial_treatment_id", val, &len, new_val, strlen(new_val));
45*e3723e1fSApple OSS Distributions 	err = errno;
46*e3723e1fSApple OSS Distributions #if ENTITLED
47*e3723e1fSApple OSS Distributions 	len = sizeof(val);
48*e3723e1fSApple OSS Distributions 	memset(new_val, 0, sizeof(new_val));
49*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "set kern.trial_treatment_id");
50*e3723e1fSApple OSS Distributions 	/* Cleanup. Set it back to the empty string. */
51*e3723e1fSApple OSS Distributions 	ret = sysctlbyname("kern.trial_treatment_id", val, &len, new_val, 1);
52*e3723e1fSApple OSS Distributions 	T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "reset kern.trial_treatment_id");
53*e3723e1fSApple OSS Distributions #else
54*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(ret, EPERM, "set kern.trial_treatment_id");
55*e3723e1fSApple OSS Distributions #endif /* ENTITLED */
56*e3723e1fSApple OSS Distributions }
57*e3723e1fSApple OSS Distributions 
58*e3723e1fSApple OSS Distributions #if ENTITLED
59*e3723e1fSApple OSS Distributions /* Check min and max value limits on numeric factors */
60*e3723e1fSApple OSS Distributions T_DECL(experiment_factor_numeric_limits,
61*e3723e1fSApple OSS Distributions     "Can only set factors within the legal range.",
62*e3723e1fSApple OSS Distributions     T_META_ASROOT(false))
63*e3723e1fSApple OSS Distributions {
64*e3723e1fSApple OSS Distributions #define kMinVal 5 /* The min value allowed for the testing factor. */
65*e3723e1fSApple OSS Distributions #define kMaxVal 10 /* The max value allowed for the testing factor. */
66*e3723e1fSApple OSS Distributions 	errno_t err;
67*e3723e1fSApple OSS Distributions 	int ret;
68*e3723e1fSApple OSS Distributions 	unsigned int current_val;
69*e3723e1fSApple OSS Distributions 	size_t len = sizeof(current_val);
70*e3723e1fSApple OSS Distributions 	unsigned int new_val;
71*e3723e1fSApple OSS Distributions 
72*e3723e1fSApple OSS Distributions 	if (running_as_root()) {
73*e3723e1fSApple OSS Distributions 		drop_priv();
74*e3723e1fSApple OSS Distributions 	}
75*e3723e1fSApple OSS Distributions 	new_val = kMinVal - 1;
76*e3723e1fSApple OSS Distributions 	ret = sysctlbyname("kern.testing_experiment_factor", &current_val, &len, &new_val, sizeof(new_val));
77*e3723e1fSApple OSS Distributions 	err = errno;
78*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(ret, EINVAL, "set kern.testing_experiment_factor below range.");
79*e3723e1fSApple OSS Distributions 
80*e3723e1fSApple OSS Distributions 	new_val = kMaxVal + 1;
81*e3723e1fSApple OSS Distributions 	ret = sysctlbyname("kern.testing_experiment_factor", &current_val, &len, &new_val, sizeof(new_val));
82*e3723e1fSApple OSS Distributions 	err = errno;
83*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_FAILURE(ret, EINVAL, "set kern.testing_experiment_factor above range.");
84*e3723e1fSApple OSS Distributions 
85*e3723e1fSApple OSS Distributions 	new_val = kMaxVal;
86*e3723e1fSApple OSS Distributions 	ret = sysctlbyname("kern.testing_experiment_factor", &current_val, &len, &new_val, sizeof(new_val));
87*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "set kern.testing_experiment_factor at top of range.");
88*e3723e1fSApple OSS Distributions 
89*e3723e1fSApple OSS Distributions 	new_val = kMinVal;
90*e3723e1fSApple OSS Distributions 	ret = sysctlbyname("kern.testing_experiment_factor", &current_val, &len, &new_val, sizeof(new_val));
91*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "set kern.testing_experiment_factor at bottom of range.");
92*e3723e1fSApple OSS Distributions }
93*e3723e1fSApple OSS Distributions 
94*e3723e1fSApple OSS Distributions static uint64_t original_libmalloc_experiment_value = 0;
95*e3723e1fSApple OSS Distributions 
96*e3723e1fSApple OSS Distributions static void
reset_libmalloc_experiment(void)97*e3723e1fSApple OSS Distributions reset_libmalloc_experiment(void)
98*e3723e1fSApple OSS Distributions {
99*e3723e1fSApple OSS Distributions 	int ret = sysctlbyname("kern.libmalloc_experiments", NULL, NULL, &original_libmalloc_experiment_value, sizeof(original_libmalloc_experiment_value));
100*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "reset kern.libmalloc_experiments");
101*e3723e1fSApple OSS Distributions }
102*e3723e1fSApple OSS Distributions 
103*e3723e1fSApple OSS Distributions static void
set_libmalloc_experiment(uint64_t val)104*e3723e1fSApple OSS Distributions set_libmalloc_experiment(uint64_t val)
105*e3723e1fSApple OSS Distributions {
106*e3723e1fSApple OSS Distributions 	T_LOG("Setting kern.libmalloc_experiments to %llu", val);
107*e3723e1fSApple OSS Distributions 	size_t len = sizeof(original_libmalloc_experiment_value);
108*e3723e1fSApple OSS Distributions 	int ret = sysctlbyname("kern.libmalloc_experiments", &original_libmalloc_experiment_value, &len, &val, sizeof(val));
109*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "set kern.libmalloc_experiments");
110*e3723e1fSApple OSS Distributions 	T_ATEND(reset_libmalloc_experiment);
111*e3723e1fSApple OSS Distributions }
112*e3723e1fSApple OSS Distributions 
113*e3723e1fSApple OSS Distributions #define PRINT_APPLE_ARRAY_TOOL "tools/print_apple_array"
114*e3723e1fSApple OSS Distributions /*
115*e3723e1fSApple OSS Distributions  * Spawns a new binary and returns the contents of its apple array
116*e3723e1fSApple OSS Distributions  * (after libsystem initialization).
117*e3723e1fSApple OSS Distributions  */
118*e3723e1fSApple OSS Distributions static char **
get_apple_array(size_t * num_array_entries,const char * filename)119*e3723e1fSApple OSS Distributions get_apple_array(size_t *num_array_entries, const char * filename)
120*e3723e1fSApple OSS Distributions {
121*e3723e1fSApple OSS Distributions 	if (filename == NULL) {
122*e3723e1fSApple OSS Distributions 		filename = PRINT_APPLE_ARRAY_TOOL;
123*e3723e1fSApple OSS Distributions 	}
124*e3723e1fSApple OSS Distributions 	int ret;
125*e3723e1fSApple OSS Distributions 	char stdout_path[MAXPATHLEN] = "apple_array.txt";
126*e3723e1fSApple OSS Distributions 	dt_resultfile(stdout_path, MAXPATHLEN);
127*e3723e1fSApple OSS Distributions 	int exit_status = 0, signum = 0;
128*e3723e1fSApple OSS Distributions 	char binary_path[MAXPATHLEN], binary_dir[MAXPATHLEN];
129*e3723e1fSApple OSS Distributions 	char *char_ret;
130*e3723e1fSApple OSS Distributions 	const static size_t kMaxNumArguments = 256;
131*e3723e1fSApple OSS Distributions 	size_t linecap = 0;
132*e3723e1fSApple OSS Distributions 	ssize_t linelen = 0;
133*e3723e1fSApple OSS Distributions 	char **apple_array;
134*e3723e1fSApple OSS Distributions 	char **line = NULL;
135*e3723e1fSApple OSS Distributions 	size_t num_lines = 0;
136*e3723e1fSApple OSS Distributions 	FILE *stdout_f = NULL;
137*e3723e1fSApple OSS Distributions 	uint32_t name_size = MAXPATHLEN;
138*e3723e1fSApple OSS Distributions 
139*e3723e1fSApple OSS Distributions 	ret = _NSGetExecutablePath(binary_path, &name_size);
140*e3723e1fSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(ret, 0, "_NSGetExecutablePath");
141*e3723e1fSApple OSS Distributions 	char_ret = dirname_r(binary_path, binary_dir);
142*e3723e1fSApple OSS Distributions 	T_QUIET; T_ASSERT_TRUE(char_ret != NULL, "dirname_r");
143*e3723e1fSApple OSS Distributions 	snprintf(binary_path, MAXPATHLEN, "%s/%s", binary_dir, filename);
144*e3723e1fSApple OSS Distributions 
145*e3723e1fSApple OSS Distributions 	char *launch_tool_args[] = {
146*e3723e1fSApple OSS Distributions 		binary_path,
147*e3723e1fSApple OSS Distributions 		NULL
148*e3723e1fSApple OSS Distributions 	};
149*e3723e1fSApple OSS Distributions 	pid_t child_pid;
150*e3723e1fSApple OSS Distributions 	ret = dt_launch_tool(&child_pid, launch_tool_args, false, stdout_path, NULL);
151*e3723e1fSApple OSS Distributions 	T_WITH_ERRNO; T_ASSERT_EQ(ret, 0, "dt_launch_tool: %s", binary_path);
152*e3723e1fSApple OSS Distributions 
153*e3723e1fSApple OSS Distributions 	ret = dt_waitpid(child_pid, &exit_status, &signum, 60 * 5);
154*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ(ret, 1, "dt_waitpid");
155*e3723e1fSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(exit_status, 0, "dt_waitpid: exit_status");
156*e3723e1fSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(signum, 0, "dt_waitpid: signum");
157*e3723e1fSApple OSS Distributions 
158*e3723e1fSApple OSS Distributions 	stdout_f = fopen(stdout_path, "r");
159*e3723e1fSApple OSS Distributions 	T_WITH_ERRNO; T_ASSERT_NOTNULL(stdout_f, "open(%s)", stdout_path);
160*e3723e1fSApple OSS Distributions 	apple_array = calloc(kMaxNumArguments, sizeof(char *));
161*e3723e1fSApple OSS Distributions 	T_QUIET; T_ASSERT_NOTNULL(apple_array, "calloc: %lu\n", sizeof(char *) * kMaxNumArguments);
162*e3723e1fSApple OSS Distributions 	while (num_lines < kMaxNumArguments) {
163*e3723e1fSApple OSS Distributions 		line = &(apple_array[num_lines++]);
164*e3723e1fSApple OSS Distributions 		linecap = 0;
165*e3723e1fSApple OSS Distributions 		linelen = getline(line, &linecap, stdout_f);
166*e3723e1fSApple OSS Distributions 		if (linelen == -1) {
167*e3723e1fSApple OSS Distributions 			break;
168*e3723e1fSApple OSS Distributions 		}
169*e3723e1fSApple OSS Distributions 	}
170*e3723e1fSApple OSS Distributions 	*num_array_entries = num_lines - 1;
171*e3723e1fSApple OSS Distributions 
172*e3723e1fSApple OSS Distributions 	ret = fclose(stdout_f);
173*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(ret, "fclose(%s)", stdout_path);
174*e3723e1fSApple OSS Distributions 
175*e3723e1fSApple OSS Distributions 	return apple_array;
176*e3723e1fSApple OSS Distributions }
177*e3723e1fSApple OSS Distributions 
178*e3723e1fSApple OSS Distributions #define LIBMALLOC_EXPERIMENT_FACTORS_KEY "MallocExperiment="
179*e3723e1fSApple OSS Distributions 
180*e3723e1fSApple OSS Distributions #define HARDENED_RUNTIME_KEY "HardenedRuntime="
181*e3723e1fSApple OSS Distributions 
182*e3723e1fSApple OSS Distributions #define HARDENED_HEAP_KEY "hardened_heap="
183*e3723e1fSApple OSS Distributions 
184*e3723e1fSApple OSS Distributions 
185*e3723e1fSApple OSS Distributions /*
186*e3723e1fSApple OSS Distributions  * Get the value of the key in the apple array.
187*e3723e1fSApple OSS Distributions  * Returns true iff the key is present.
188*e3723e1fSApple OSS Distributions  */
189*e3723e1fSApple OSS Distributions static bool
get_apple_array_key(char ** apple_array,size_t num_array_entries,uint64_t * factors,const char * key)190*e3723e1fSApple OSS Distributions get_apple_array_key(char **apple_array, size_t num_array_entries, uint64_t *factors, const char *key)
191*e3723e1fSApple OSS Distributions {
192*e3723e1fSApple OSS Distributions 	bool found = false;
193*e3723e1fSApple OSS Distributions 	for (size_t i = 0; i < num_array_entries; i++) {
194*e3723e1fSApple OSS Distributions 		char *str = apple_array[i];
195*e3723e1fSApple OSS Distributions 		if (strstr(str, key)) {
196*e3723e1fSApple OSS Distributions 			found = true;
197*e3723e1fSApple OSS Distributions 			if (factors != NULL) {
198*e3723e1fSApple OSS Distributions 				str = strchr(str, '=');
199*e3723e1fSApple OSS Distributions 				T_ASSERT_NOTNULL(str, "skip over =");
200*e3723e1fSApple OSS Distributions 				++str;
201*e3723e1fSApple OSS Distributions 				*factors = strtoull_l(str, NULL, 16, NULL);
202*e3723e1fSApple OSS Distributions 			}
203*e3723e1fSApple OSS Distributions 			break;
204*e3723e1fSApple OSS Distributions 		}
205*e3723e1fSApple OSS Distributions 	}
206*e3723e1fSApple OSS Distributions 	return found;
207*e3723e1fSApple OSS Distributions }
208*e3723e1fSApple OSS Distributions 
209*e3723e1fSApple OSS Distributions /* libmalloc relies on these values not changing. If they change,
210*e3723e1fSApple OSS Distributions  * you need to update the values in that project as well */
211*e3723e1fSApple OSS Distributions __options_decl(HR_flags_t, uint32_t, {
212*e3723e1fSApple OSS Distributions 	BrowserHostEntitlementMask       = 0x01,
213*e3723e1fSApple OSS Distributions 	BrowserGPUEntitlementMask        = 0x02,
214*e3723e1fSApple OSS Distributions 	BrowserNetworkEntitlementMask    = 0x04,
215*e3723e1fSApple OSS Distributions 	BrowserWebContentEntitlementMask = 0x08,
216*e3723e1fSApple OSS Distributions });
217*e3723e1fSApple OSS Distributions 
218*e3723e1fSApple OSS Distributions T_DECL(libmalloc_hardened_binary_present,
219*e3723e1fSApple OSS Distributions     "hardened binary flags show up in apple array",
220*e3723e1fSApple OSS Distributions     T_META_ASROOT(false))
221*e3723e1fSApple OSS Distributions {
222*e3723e1fSApple OSS Distributions 	uint64_t apple_array_val = 0;
223*e3723e1fSApple OSS Distributions 	size_t num_array_entries = 0;
224*e3723e1fSApple OSS Distributions 	char **apple_array;
225*e3723e1fSApple OSS Distributions 	bool found = false;
226*e3723e1fSApple OSS Distributions 
227*e3723e1fSApple OSS Distributions 	/* These are the entitlements on the HR1 binary */
228*e3723e1fSApple OSS Distributions 	uint32_t mask_val = BrowserHostEntitlementMask | BrowserGPUEntitlementMask | BrowserWebContentEntitlementMask;
229*e3723e1fSApple OSS Distributions 	apple_array = get_apple_array(&num_array_entries, "tools/print_apple_array_HR1");
230*e3723e1fSApple OSS Distributions 	found = get_apple_array_key(apple_array, num_array_entries, &apple_array_val, HARDENED_RUNTIME_KEY);
231*e3723e1fSApple OSS Distributions 	T_ASSERT_TRUE(found, "Found " HARDENED_RUNTIME_KEY " in apple array");
232*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ(apple_array_val, mask_val, "Bitmask value matches");
233*e3723e1fSApple OSS Distributions 	free(apple_array);
234*e3723e1fSApple OSS Distributions 
235*e3723e1fSApple OSS Distributions 	/* These are the entitlements on the HR2 binary */
236*e3723e1fSApple OSS Distributions 	mask_val = BrowserGPUEntitlementMask | BrowserNetworkEntitlementMask;
237*e3723e1fSApple OSS Distributions 	apple_array = get_apple_array(&num_array_entries, "tools/print_apple_array_HR2");
238*e3723e1fSApple OSS Distributions 	found = get_apple_array_key(apple_array, num_array_entries, &apple_array_val, HARDENED_RUNTIME_KEY);
239*e3723e1fSApple OSS Distributions 	T_ASSERT_TRUE(found, "Found " HARDENED_RUNTIME_KEY " in apple array");
240*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ(apple_array_val, mask_val, "Bitmask value matches");
241*e3723e1fSApple OSS Distributions 	free(apple_array);
242*e3723e1fSApple OSS Distributions }
243*e3723e1fSApple OSS Distributions 
244*e3723e1fSApple OSS Distributions T_DECL(libmalloc_hardened_heap_entitlements,
245*e3723e1fSApple OSS Distributions     "hardened heap enablement via hardened process and hardened heap entitlements",
246*e3723e1fSApple OSS Distributions     T_META_ASROOT(false))
247*e3723e1fSApple OSS Distributions {
248*e3723e1fSApple OSS Distributions 	uint64_t apple_array_val = 0;
249*e3723e1fSApple OSS Distributions 	size_t num_array_entries = 0;
250*e3723e1fSApple OSS Distributions 	char **apple_array;
251*e3723e1fSApple OSS Distributions 	bool found = false;
252*e3723e1fSApple OSS Distributions 
253*e3723e1fSApple OSS Distributions 	uint32_t mask_val = 1;
254*e3723e1fSApple OSS Distributions 	apple_array = get_apple_array(&num_array_entries, "tools/print_apple_array_hardened_proc");
255*e3723e1fSApple OSS Distributions 	found = get_apple_array_key(apple_array, num_array_entries, &apple_array_val, HARDENED_HEAP_KEY);
256*e3723e1fSApple OSS Distributions 	T_ASSERT_FALSE(found, "Didn't find " HARDENED_HEAP_KEY " in apple array");
257*e3723e1fSApple OSS Distributions 	free(apple_array);
258*e3723e1fSApple OSS Distributions 
259*e3723e1fSApple OSS Distributions 	apple_array = get_apple_array(&num_array_entries, "tools/print_apple_array_hardened_heap_disable");
260*e3723e1fSApple OSS Distributions 	found = get_apple_array_key(apple_array, num_array_entries, &apple_array_val, HARDENED_HEAP_KEY);
261*e3723e1fSApple OSS Distributions 	T_ASSERT_FALSE(found, "Didn't find " HARDENED_HEAP_KEY " in apple array");
262*e3723e1fSApple OSS Distributions 	free(apple_array);
263*e3723e1fSApple OSS Distributions 
264*e3723e1fSApple OSS Distributions 	apple_array = get_apple_array(&num_array_entries, "tools/print_apple_array_hardened_heap");
265*e3723e1fSApple OSS Distributions 	found = get_apple_array_key(apple_array, num_array_entries, &apple_array_val, HARDENED_HEAP_KEY);
266*e3723e1fSApple OSS Distributions 	T_ASSERT_TRUE(found, "Found " HARDENED_HEAP_KEY " in apple array");
267*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ(apple_array_val, mask_val, "Bitmask value matches");
268*e3723e1fSApple OSS Distributions 	free(apple_array);
269*e3723e1fSApple OSS Distributions 
270*e3723e1fSApple OSS Distributions 	apple_array = get_apple_array(&num_array_entries, "tools/print_apple_array_hardened_proc_all_subfeatures");
271*e3723e1fSApple OSS Distributions 	found = get_apple_array_key(apple_array, num_array_entries, &apple_array_val, HARDENED_HEAP_KEY);
272*e3723e1fSApple OSS Distributions 	T_ASSERT_TRUE(found, "Found " HARDENED_HEAP_KEY " in apple array");
273*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ(apple_array_val, mask_val, "Bitmask value matches");
274*e3723e1fSApple OSS Distributions 	free(apple_array);
275*e3723e1fSApple OSS Distributions }
276*e3723e1fSApple OSS Distributions 
277*e3723e1fSApple OSS Distributions 
278*e3723e1fSApple OSS Distributions T_DECL(libmalloc_hardened_binary_absent,
279*e3723e1fSApple OSS Distributions     "hardened binary flags do not show up in apple array for normal third party processes",
280*e3723e1fSApple OSS Distributions     T_META_ASROOT(false))
281*e3723e1fSApple OSS Distributions {
282*e3723e1fSApple OSS Distributions 	uint64_t new_val, apple_array_val = 0;
283*e3723e1fSApple OSS Distributions 	size_t num_array_entries = 0;
284*e3723e1fSApple OSS Distributions 	char **apple_array;
285*e3723e1fSApple OSS Distributions 	bool found = false;
286*e3723e1fSApple OSS Distributions 	apple_array = get_apple_array(&num_array_entries, NULL); // todo apple_array_3p?
287*e3723e1fSApple OSS Distributions 	found = get_apple_array_key(apple_array, num_array_entries, &apple_array_val, HARDENED_RUNTIME_KEY);
288*e3723e1fSApple OSS Distributions 	T_ASSERT_TRUE(!found, "Did not find " HARDENED_RUNTIME_KEY " in apple array");
289*e3723e1fSApple OSS Distributions 	free(apple_array);
290*e3723e1fSApple OSS Distributions }
291*e3723e1fSApple OSS Distributions 
292*e3723e1fSApple OSS Distributions T_DECL(libmalloc_experiment,
293*e3723e1fSApple OSS Distributions     "libmalloc experiment flags show up in apple array if we're doing an experiment",
294*e3723e1fSApple OSS Distributions     T_META_ASROOT(false))
295*e3723e1fSApple OSS Distributions {
296*e3723e1fSApple OSS Distributions 	uint64_t new_val, apple_array_val = 0;
297*e3723e1fSApple OSS Distributions 	size_t num_array_entries = 0;
298*e3723e1fSApple OSS Distributions 	char **apple_array;
299*e3723e1fSApple OSS Distributions 	bool found = false;
300*e3723e1fSApple OSS Distributions 
301*e3723e1fSApple OSS Distributions 	if (running_as_root()) {
302*e3723e1fSApple OSS Distributions 		drop_priv();
303*e3723e1fSApple OSS Distributions 	}
304*e3723e1fSApple OSS Distributions 	new_val = (1ULL << 63) - 1;
305*e3723e1fSApple OSS Distributions 	set_libmalloc_experiment(new_val);
306*e3723e1fSApple OSS Distributions 
307*e3723e1fSApple OSS Distributions 	apple_array = get_apple_array(&num_array_entries, NULL);
308*e3723e1fSApple OSS Distributions 	found = get_apple_array_key(apple_array, num_array_entries, &apple_array_val, LIBMALLOC_EXPERIMENT_FACTORS_KEY);
309*e3723e1fSApple OSS Distributions 	T_ASSERT_TRUE(found, "Found " LIBMALLOC_EXPERIMENT_FACTORS_KEY " in apple array");
310*e3723e1fSApple OSS Distributions 	T_ASSERT_EQ(apple_array_val, new_val, "Experiment value matches");
311*e3723e1fSApple OSS Distributions 	free(apple_array);
312*e3723e1fSApple OSS Distributions }
313*e3723e1fSApple OSS Distributions 
314*e3723e1fSApple OSS Distributions T_DECL(libmalloc_experiment_not_in_array,
315*e3723e1fSApple OSS Distributions     "libmalloc experiment flags do not show up in apple array if we're not doing an experiment",
316*e3723e1fSApple OSS Distributions     T_META_ASROOT(false))
317*e3723e1fSApple OSS Distributions {
318*e3723e1fSApple OSS Distributions 	size_t num_array_entries = 0;
319*e3723e1fSApple OSS Distributions 	char **apple_array;
320*e3723e1fSApple OSS Distributions 	bool found = false;
321*e3723e1fSApple OSS Distributions 
322*e3723e1fSApple OSS Distributions 	if (running_as_root()) {
323*e3723e1fSApple OSS Distributions 		drop_priv();
324*e3723e1fSApple OSS Distributions 	}
325*e3723e1fSApple OSS Distributions 	set_libmalloc_experiment(0);
326*e3723e1fSApple OSS Distributions 
327*e3723e1fSApple OSS Distributions 	apple_array = get_apple_array(&num_array_entries, NULL);
328*e3723e1fSApple OSS Distributions 	found = get_apple_array_key(apple_array, num_array_entries, NULL, LIBMALLOC_EXPERIMENT_FACTORS_KEY);
329*e3723e1fSApple OSS Distributions 	T_ASSERT_TRUE(!found, "Did not find " LIBMALLOC_EXPERIMENT_FACTORS_KEY " in apple array");
330*e3723e1fSApple OSS Distributions 	free(apple_array);
331*e3723e1fSApple OSS Distributions }
332*e3723e1fSApple OSS Distributions #endif /* ENTITLED */
333