]>
Commit | Line | Data |
---|---|---|
f427ee49 A |
1 | #include <stdlib.h> |
2 | #include <unistd.h> | |
3 | #include <sys/sysctl.h> | |
4 | ||
5 | #include <darwintest.h> | |
6 | #include <darwintest_utils.h> | |
7 | ||
8 | T_GLOBAL_META(T_META_RUN_CONCURRENTLY(false)); | |
9 | ||
10 | static int after_regions = 0; | |
11 | ||
12 | /* | |
13 | * No system(3c) on watchOS, so provide our own. | |
14 | */ | |
15 | static int | |
16 | my_system(const char *command) | |
17 | { | |
18 | pid_t pid; | |
19 | int status = 0; | |
20 | const char *argv[] = { | |
21 | "/bin/sh", | |
22 | "-c", | |
23 | command, | |
24 | NULL | |
25 | }; | |
26 | ||
27 | if (dt_launch_tool(&pid, (char **)(void *)argv, FALSE, NULL, NULL)) { | |
28 | return -1; | |
29 | } | |
30 | sleep(2); /* let the child start running */ | |
31 | ||
32 | size_t size = sizeof(after_regions); | |
33 | int ret = sysctlbyname("vm.shared_region_pager_count", &after_regions, &size, NULL, 0); | |
34 | T_QUIET; T_EXPECT_POSIX_SUCCESS(ret, "get shared_region_pager_count after"); | |
35 | ||
36 | if (!dt_waitpid(pid, &status, NULL, 30)) { | |
37 | if (status != 0) { | |
38 | return status; | |
39 | } | |
40 | return -1; | |
41 | } | |
42 | return status; | |
43 | } | |
44 | ||
45 | /* | |
46 | * If shared regions by entitlement was not originally active, turn it back off. | |
47 | */ | |
48 | static int orig_setting = 0; | |
49 | static void | |
50 | cleanup(void) | |
51 | { | |
52 | int ret; | |
53 | int off = 0; | |
54 | size_t size_off = sizeof(off); | |
55 | ||
56 | if (orig_setting == 0) { | |
57 | ret = sysctlbyname("vm.vm_shared_region_by_entitlement", NULL, NULL, &off, size_off); | |
58 | T_QUIET; T_EXPECT_POSIX_SUCCESS(ret, "turning sysctl back off"); | |
59 | } | |
60 | } | |
61 | ||
62 | /* | |
63 | * This test: | |
64 | * - looks at the number of shared region pagers, | |
65 | * - launches a helper app that has entitlement for unique signing | |
66 | * - gets the number of shared region pagers again. | |
67 | * It expects to see additional shared region pager(s) to exist. | |
68 | * | |
69 | */ | |
70 | T_DECL(sr_entitlement, "shared region by entitlement test") | |
71 | { | |
72 | int ret; | |
73 | size_t size; | |
74 | int before_regions = 0; | |
75 | int on = 1; | |
76 | size_t size_on = sizeof(on); | |
77 | ||
2a1bd2d3 | 78 | #if !__arm64e__ |
f427ee49 | 79 | T_SKIP("No pointer authentication support"); |
2a1bd2d3 | 80 | #endif |
f427ee49 A |
81 | |
82 | /* | |
83 | * Check if the sysctl vm_shared_region_by_entitlement exists and if so make | |
84 | * sure it is set. | |
85 | */ | |
86 | size = sizeof(orig_setting); | |
87 | ret = sysctlbyname("vm.vm_shared_region_by_entitlement", &orig_setting, &size, &on, size_on); | |
88 | if (ret != 0) { | |
89 | T_SKIP("No pointer authentication support"); | |
90 | } | |
91 | ||
92 | T_ATEND(cleanup); | |
93 | ||
94 | size = sizeof(before_regions); | |
95 | ret = sysctlbyname("vm.shared_region_pager_count", &before_regions, &size, NULL, 0); | |
96 | T_QUIET; T_EXPECT_POSIX_SUCCESS(ret, "get shared_region_pager_count before"); | |
97 | T_QUIET; T_EXPECT_GE_INT(before_regions, 1, "invalid before number of regions"); | |
98 | ||
99 | ret = my_system("./sr_entitlement_helper"); | |
100 | if (ret != 0) { | |
101 | T_ASSERT_FAIL("Couldn't run helper first time ret = %d", ret); | |
102 | } | |
103 | ||
104 | T_EXPECT_GT_INT(after_regions, before_regions, "expected additional SR pagers after running helper"); | |
105 | } |