]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/darwintests/settimeofday_29193041_entitled.c
a68c6cac880365bd03d85a092a7357a5e282762b
[apple/xnu.git] / tools / tests / darwintests / settimeofday_29193041_entitled.c
1 #include <stdio.h>
2 #include <errno.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <sys/mman.h>
6 #include <mach/clock_types.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_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("settime_32089962_entitled_root 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_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
126 struct timeval settimeofdaytime;
127 struct timeval adj_time;
128 struct timex ntptime;
129
130 drop_priv();
131
132 if (geteuid() == 0){
133 T_SKIP("settime_32089962_entitled_root test requires no root privileges to run.");
134 }
135
136 /* test settimeofday */
137 T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&settimeofdaytime, NULL), NULL);
138 T_ASSERT_POSIX_ZERO(settimeofday(&settimeofdaytime, NULL), NULL);
139
140 /* test adjtime */
141 adj_time.tv_sec = 1;
142 adj_time.tv_usec = 0;
143 T_ASSERT_POSIX_ZERO(adjtime(&adj_time, NULL),NULL);
144
145 /* test ntp_adjtime */
146 memset(&ntptime, 0, sizeof(ntptime));
147 ntptime.modes |= MOD_STATUS;
148 ntptime.status = TIME_OK;
149
150 T_ASSERT_EQ(ntp_adjtime(&ntptime), TIME_OK, NULL);
151
152 }
153
154 T_DECL(settimeofday_29193041_entitled_root,
155 "Verify that root privileges can allow to change the time",
156 T_META_ASROOT(true), T_META_CHECK_LEAKS(NO))
157 {
158 struct timeval time;
159 long new_time;
160
161 if (geteuid() != 0){
162 T_SKIP("settimeofday_root_29193041 test requires root privileges to run.");
163 }
164
165 T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&time, NULL), NULL);
166
167 /* increment the time of one day */
168 new_time = time.tv_sec + DAY;
169
170 time.tv_sec = new_time;
171 time.tv_usec = 0;
172
173 T_ASSERT_POSIX_ZERO(settimeofday(&time, NULL), NULL);
174
175 T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&time, NULL), NULL);
176
177 /* expext to be past new_time */
178 T_EXPECT_GE_LONG(time.tv_sec, new_time, "Time changed with root and entitlement");
179
180 time.tv_sec -= DAY;
181 T_QUIET;T_ASSERT_POSIX_ZERO(settimeofday(&time, NULL), NULL);
182 }
183
184 T_DECL(settimeofday_29193041_entitled_not_root,
185 "Verify that the \"com.apple.settime\" entitlement can allow to change the time",
186 T_META_ASROOT(false), T_META_CHECK_LEAKS(NO))
187 {
188 struct timeval time;
189 long new_time;
190
191 drop_priv();
192
193 if (geteuid() == 0){
194 T_SKIP("settimeofday_29193041 test requires no root privileges to run.");
195 }
196
197 T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&time, NULL), NULL);
198
199 /* increment the time of one day */
200 new_time = time.tv_sec + DAY;
201
202 time.tv_sec = new_time;
203 time.tv_usec = 0;
204
205 T_ASSERT_POSIX_ZERO(settimeofday(&time, NULL), NULL);
206
207 T_QUIET; T_ASSERT_POSIX_ZERO(gettimeofday(&time, NULL), NULL);
208
209 /* expext to be past new_time */
210 T_EXPECT_GE_LONG(time.tv_sec, new_time, "Time successfully changed without root and with entitlement");
211
212 time.tv_sec -= DAY;
213 T_QUIET; T_ASSERT_POSIX_ZERO(settimeofday(&time, NULL), NULL);
214 }