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