]>
Commit | Line | Data |
---|---|---|
5ba3f43e A |
1 | #include <stdio.h> |
2 | #include <errno.h> | |
3 | #include <string.h> | |
4 | #include <unistd.h> | |
5 | #include <mach/clock_types.h> | |
6 | #include <sys/mman.h> | |
7 | #include <sys/timex.h> | |
8 | #include <spawn.h> | |
9 | #include <darwintest.h> | |
10 | #include <darwintest_utils.h> | |
11 | ||
12 | #if CONFIG_EMBEDDED | |
13 | #include <sys/types.h> | |
14 | #include <pwd.h> | |
15 | #include <uuid/uuid.h> | |
16 | #endif | |
17 | ||
18 | #define EXIT_FAIL() exit((__LINE__ % 255) + 1) | |
19 | ||
20 | /* | |
21 | * This test expects the entitlement or root privileges for a process to | |
22 | * set the time using settimeofday syscall. | |
23 | */ | |
24 | ||
25 | #define DAY 86400 //1 day in sec | |
26 | ||
27 | /* | |
28 | * To run without root privileges | |
29 | * <rdar://problem/28315048> libdarwintest should run leaks even without root | |
30 | */ | |
31 | static void drop_priv(void){ | |
32 | /* determine the less-privileged UID and GID */ | |
33 | ||
34 | unsigned long lower_uid = 0; | |
35 | unsigned long lower_gid = 0; | |
36 | ||
37 | #if CONFIG_EMBEDDED | |
38 | struct passwd *pw = getpwnam("mobile"); | |
39 | if (!pw) { | |
40 | printf("child: error: get_pwname(\"mobile\") failed %d: %s\n", errno, strerror(errno)); | |
41 | EXIT_FAIL(); | |
42 | } | |
43 | ||
44 | lower_uid = pw->pw_uid; | |
45 | lower_gid = pw->pw_gid; | |
46 | #else | |
47 | char *sudo_gid_str = getenv("SUDO_GID"); | |
48 | if (!sudo_gid_str) { | |
49 | printf("child: error: SUDO_GID environment variable unset (not run under sudo)\n"); | |
50 | EXIT_FAIL(); | |
51 | } | |
52 | ||
53 | char *sudo_uid_str = getenv("SUDO_UID"); | |
54 | if (!sudo_uid_str) { | |
55 | printf("child: error: SUDO_UID environment variable unset (not run under sudo)\n"); | |
56 | EXIT_FAIL(); | |
57 | } | |
58 | ||
59 | char *end = sudo_gid_str; | |
60 | lower_gid = strtoul(sudo_gid_str, &end, 10); | |
61 | if (sudo_gid_str == end && sudo_gid_str[0] != '\0') { | |
62 | printf("child: error: SUDO_GID (%s) could not be converted to an integer\n", sudo_gid_str); | |
63 | EXIT_FAIL(); | |
64 | } | |
65 | if (lower_gid == 0) { | |
66 | printf("child: error: less-privileged GID invalid\n"); | |
67 | EXIT_FAIL(); | |
68 | } | |
69 | ||
70 | end = sudo_uid_str; | |
71 | lower_uid = strtoul(sudo_uid_str, &end, 10); | |
72 | if (sudo_uid_str == end && sudo_uid_str[0] != '\0') { | |
73 | printf("child: error: SUDO_UID (%s) could not be converted to an integer\n", sudo_uid_str); | |
74 | EXIT_FAIL(); | |
75 | } | |
76 | if (lower_gid == 0) { | |
77 | printf("child: error: less-privileged UID invalid\n"); | |
78 | EXIT_FAIL(); | |
79 | } | |
80 | #endif | |
81 | ||
82 | if (setgid(lower_gid) == -1) { | |
83 | printf("child: error: could not change group to %lu\n", lower_gid); | |
84 | EXIT_FAIL(); | |
85 | } | |
86 | if (setuid(lower_uid) == -1) { | |
87 | printf("child: error: could not change user to %lu\n", lower_uid); | |
88 | EXIT_FAIL(); | |
89 | } | |
90 | } | |
91 | ||
92 | T_DECL(settime_32089962_not_entitled_root, | |
93 | "Verify that root privileges can allow to change the time", | |
94 | T_META_ASROOT(true), T_META_CHECK_LEAKS(NO)) | |
95 | { | |
96 | struct timeval settimeofdaytime; | |
97 | struct timeval adj_time; | |
98 | struct timex ntptime; | |
99 | ||
100 | if (geteuid() != 0){ | |
101 | T_SKIP("settimeofday_root_29193041 test requires root privileges to run."); | |
102 | } | |
103 | ||
104 | /* test settimeofday */ | |
105 | T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&settimeofdaytime, NULL), NULL); | |
106 | T_ASSERT_POSIX_ZERO(settimeofday(&settimeofdaytime, NULL), NULL); | |
107 | ||
108 | /* test adjtime */ | |
109 | adj_time.tv_sec = 1; | |
110 | adj_time.tv_usec = 0; | |
111 | T_ASSERT_POSIX_ZERO(adjtime(&adj_time, NULL),NULL); | |
112 | ||
113 | /* test ntp_adjtime */ | |
114 | memset(&ntptime, 0, sizeof(ntptime)); | |
115 | ntptime.modes |= MOD_STATUS; | |
116 | ntptime.status = TIME_OK; | |
117 | ||
118 | T_ASSERT_EQ(ntp_adjtime(&ntptime), TIME_OK, NULL); | |
119 | } | |
120 | ||
121 | T_DECL(settime_32089962_not_entitled_not_root, | |
122 | "Verify that the \"com.apple.settime\" entitlement can allow to change the time", | |
123 | T_META_ASROOT(false), T_META_CHECK_LEAKS(NO)) | |
124 | { | |
125 | struct timeval settimeofdaytime; | |
126 | struct timeval adj_time; | |
127 | struct timex ntptime; | |
128 | int res; | |
129 | ||
130 | drop_priv(); | |
131 | ||
132 | if (geteuid() == 0){ | |
133 | T_SKIP("settimeofday_29193041 test requires no root privileges to run."); | |
134 | } | |
135 | ||
136 | T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&settimeofdaytime, NULL), NULL); | |
137 | ||
138 | /* test settimeofday */ | |
139 | #if TARGET_OS_EMBEDDED | |
140 | T_ASSERT_POSIX_ZERO(settimeofday(&settimeofdaytime, NULL), NULL); | |
141 | #else | |
142 | res = settimeofday(&settimeofdaytime, NULL); | |
143 | T_ASSERT_EQ(res, -1, NULL); | |
144 | #endif | |
145 | ||
146 | /* test adjtime */ | |
147 | adj_time.tv_sec = 1; | |
148 | adj_time.tv_usec = 0; | |
149 | res = adjtime(&adj_time, NULL); | |
150 | T_ASSERT_EQ(res, -1, NULL); | |
151 | ||
152 | /* test ntp_adjtime */ | |
153 | memset(&ntptime, 0, sizeof(ntptime)); | |
154 | ntptime.modes |= MOD_STATUS; | |
155 | ntptime.status = TIME_OK; | |
156 | res = ntp_adjtime(&ntptime); | |
157 | T_ASSERT_EQ(res, -1, NULL); | |
158 | } | |
159 | ||
160 | T_DECL(settimeofday_29193041_not_entitled_root, | |
161 | "Verify that root privileges can allow to change the time", | |
162 | T_META_ASROOT(true), T_META_CHECK_LEAKS(NO)) | |
163 | { | |
164 | struct timeval time; | |
165 | long new_time; | |
166 | ||
167 | if (geteuid() != 0){ | |
168 | T_SKIP("settimeofday_root_29193041 test requires root privileges to run."); | |
169 | } | |
170 | ||
171 | T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&time, NULL), NULL); | |
172 | ||
173 | /* increment the time of one day */ | |
174 | new_time = time.tv_sec + DAY; | |
175 | ||
176 | time.tv_sec = new_time; | |
177 | time.tv_usec = 0; | |
178 | ||
179 | T_ASSERT_POSIX_ZERO(settimeofday(&time, NULL), NULL); | |
180 | ||
181 | T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&time, NULL), NULL); | |
182 | ||
183 | /* expext to be past new_time */ | |
184 | T_EXPECT_GE_LONG(time.tv_sec, new_time, "Time changed with root and without entitlement"); | |
185 | ||
186 | time.tv_sec -= DAY; | |
187 | T_QUIET;T_ASSERT_POSIX_ZERO(settimeofday(&time, NULL), NULL); | |
188 | } | |
189 | ||
190 | T_DECL(settimeofday_29193041_not_entitled_not_root, | |
191 | "Verify that the \"com.apple.settime\" entitlement can allow to change the time", | |
192 | T_META_ASROOT(false), T_META_CHECK_LEAKS(NO)) | |
193 | { | |
194 | struct timeval time; | |
195 | long new_time; | |
196 | ||
197 | drop_priv(); | |
198 | ||
199 | if (geteuid() == 0){ | |
200 | T_SKIP("settimeofday_29193041 test requires no root privileges to run."); | |
201 | } | |
202 | ||
203 | T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&time, NULL), NULL); | |
204 | ||
205 | /* increment the time of one day */ | |
206 | new_time = time.tv_sec + DAY; | |
207 | ||
208 | time.tv_sec = new_time; | |
209 | time.tv_usec = 0; | |
210 | ||
211 | #if TARGET_OS_EMBEDDED | |
212 | T_ASSERT_POSIX_ZERO(settimeofday(&time, NULL), NULL); | |
213 | #else | |
214 | int res = settimeofday(&time, NULL); | |
215 | T_ASSERT_EQ(res, -1, NULL); | |
216 | #endif | |
217 | ||
218 | T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&time, NULL), NULL); | |
219 | ||
220 | #if TARGET_OS_EMBEDDED | |
221 | /* expext to be past new_time */ | |
222 | T_EXPECT_GE_LONG(time.tv_sec, new_time, "Time successfully changed without root and without entitlement"); | |
223 | time.tv_sec -= DAY; | |
224 | T_QUIET; T_ASSERT_POSIX_ZERO(settimeofday(&time, NULL), NULL); | |
225 | #else | |
226 | T_EXPECT_LT_LONG(time.tv_sec, new_time, "Not permitted to change time without root and without entitlement"); | |
227 | #endif | |
228 | ||
229 | } |