1 /*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18
19 // Below are the header files we want to test.
20 #include <grp.h>
21 #include <pwd.h>
22
23 #include <errno.h>
24 #include <limits.h>
25 #include <sys/cdefs.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28
29 #include <bitset>
30
31 #include <private/android_filesystem_config.h>
32
33 // Generated android_ids array
34 #include "generated_android_ids.h"
35
36 enum uid_type_t {
37 TYPE_SYSTEM,
38 TYPE_APP
39 };
40
41 #if defined(__BIONIC__)
42
check_passwd(const passwd * pwd,const char * username,uid_t uid,uid_type_t uid_type)43 static void check_passwd(const passwd* pwd, const char* username, uid_t uid, uid_type_t uid_type) {
44 ASSERT_TRUE(pwd != NULL);
45 ASSERT_STREQ(username, pwd->pw_name);
46 ASSERT_EQ(uid, pwd->pw_uid);
47 ASSERT_EQ(uid, pwd->pw_gid);
48 ASSERT_EQ(NULL, pwd->pw_passwd);
49 #ifdef __LP64__
50 ASSERT_EQ(NULL, pwd->pw_gecos);
51 #endif
52
53 if (uid_type == TYPE_SYSTEM) {
54 ASSERT_STREQ("/", pwd->pw_dir);
55 } else {
56 ASSERT_STREQ("/data", pwd->pw_dir);
57 }
58 ASSERT_STREQ("/system/bin/sh", pwd->pw_shell);
59 }
60
check_getpwuid(const char * username,uid_t uid,uid_type_t uid_type)61 static void check_getpwuid(const char* username, uid_t uid, uid_type_t uid_type) {
62 errno = 0;
63 passwd* pwd = getpwuid(uid);
64 ASSERT_EQ(0, errno);
65 SCOPED_TRACE("getpwuid");
66 check_passwd(pwd, username, uid, uid_type);
67 }
68
check_getpwnam(const char * username,uid_t uid,uid_type_t uid_type)69 static void check_getpwnam(const char* username, uid_t uid, uid_type_t uid_type) {
70 errno = 0;
71 passwd* pwd = getpwnam(username);
72 ASSERT_EQ(0, errno);
73 SCOPED_TRACE("getpwnam");
74 check_passwd(pwd, username, uid, uid_type);
75 }
76
check_getpwuid_r(const char * username,uid_t uid,uid_type_t uid_type)77 static void check_getpwuid_r(const char* username, uid_t uid, uid_type_t uid_type) {
78 passwd pwd_storage;
79 char buf[512];
80 int result;
81
82 errno = 0;
83 passwd* pwd = NULL;
84 result = getpwuid_r(uid, &pwd_storage, buf, sizeof(buf), &pwd);
85 ASSERT_EQ(0, result);
86 ASSERT_EQ(0, errno);
87 SCOPED_TRACE("getpwuid_r");
88 check_passwd(pwd, username, uid, uid_type);
89 }
90
check_getpwnam_r(const char * username,uid_t uid,uid_type_t uid_type)91 static void check_getpwnam_r(const char* username, uid_t uid, uid_type_t uid_type) {
92 passwd pwd_storage;
93 char buf[512];
94 int result;
95
96 errno = 0;
97 passwd* pwd = NULL;
98 result = getpwnam_r(username, &pwd_storage, buf, sizeof(buf), &pwd);
99 ASSERT_EQ(0, result);
100 ASSERT_EQ(0, errno);
101 SCOPED_TRACE("getpwnam_r");
102 check_passwd(pwd, username, uid, uid_type);
103 }
104
check_get_passwd(const char * username,uid_t uid,uid_type_t uid_type)105 static void check_get_passwd(const char* username, uid_t uid, uid_type_t uid_type) {
106 check_getpwuid(username, uid, uid_type);
107 check_getpwnam(username, uid, uid_type);
108 check_getpwuid_r(username, uid, uid_type);
109 check_getpwnam_r(username, uid, uid_type);
110 }
111
112 #else // !defined(__BIONIC__)
113
check_get_passwd(const char *,uid_t,uid_type_t)114 static void check_get_passwd(const char* /* username */, uid_t /* uid */, uid_type_t /* uid_type */) {
115 GTEST_LOG_(INFO) << "This test is about uid/username translation for Android, which does nothing on libc other than bionic.\n";
116 }
117
118 #endif
119
TEST(pwd,getpwnam_system_id_root)120 TEST(pwd, getpwnam_system_id_root) {
121 check_get_passwd("root", 0, TYPE_SYSTEM);
122 }
123
TEST(pwd,getpwnam_system_id_system)124 TEST(pwd, getpwnam_system_id_system) {
125 check_get_passwd("system", 1000, TYPE_SYSTEM);
126 }
127
TEST(pwd,getpwnam_app_id_radio)128 TEST(pwd, getpwnam_app_id_radio) {
129 check_get_passwd("radio", 1001, TYPE_SYSTEM);
130 }
131
TEST(pwd,getpwnam_oem_id_5000)132 TEST(pwd, getpwnam_oem_id_5000) {
133 check_get_passwd("oem_5000", 5000, TYPE_SYSTEM);
134 }
135
TEST(pwd,getpwnam_oem_id_5999)136 TEST(pwd, getpwnam_oem_id_5999) {
137 check_get_passwd("oem_5999", 5999, TYPE_SYSTEM);
138 }
139
TEST(pwd,getpwnam_oem_id_2900)140 TEST(pwd, getpwnam_oem_id_2900) {
141 check_get_passwd("oem_2900", 2900, TYPE_SYSTEM);
142 }
143
TEST(pwd,getpwnam_oem_id_2999)144 TEST(pwd, getpwnam_oem_id_2999) {
145 check_get_passwd("oem_2999", 2999, TYPE_SYSTEM);
146 }
147
TEST(pwd,getpwnam_app_id_nobody)148 TEST(pwd, getpwnam_app_id_nobody) {
149 check_get_passwd("nobody", 9999, TYPE_SYSTEM);
150 }
151
TEST(pwd,getpwnam_app_id_u0_a0)152 TEST(pwd, getpwnam_app_id_u0_a0) {
153 check_get_passwd("u0_a0", 10000, TYPE_APP);
154 }
155
TEST(pwd,getpwnam_app_id_u0_a1234)156 TEST(pwd, getpwnam_app_id_u0_a1234) {
157 check_get_passwd("u0_a1234", 11234, TYPE_APP);
158 }
159
160 // Test the difference between uid and shared gid.
TEST(pwd,getpwnam_app_id_u0_a49999)161 TEST(pwd, getpwnam_app_id_u0_a49999) {
162 check_get_passwd("u0_a49999", 59999, TYPE_APP);
163 }
164
TEST(pwd,getpwnam_app_id_u0_i1)165 TEST(pwd, getpwnam_app_id_u0_i1) {
166 check_get_passwd("u0_i1", 99001, TYPE_APP);
167 }
168
TEST(pwd,getpwnam_app_id_u1_root)169 TEST(pwd, getpwnam_app_id_u1_root) {
170 check_get_passwd("u1_root", 100000, TYPE_SYSTEM);
171 }
172
TEST(pwd,getpwnam_app_id_u1_radio)173 TEST(pwd, getpwnam_app_id_u1_radio) {
174 check_get_passwd("u1_radio", 101001, TYPE_SYSTEM);
175 }
176
TEST(pwd,getpwnam_app_id_u1_a0)177 TEST(pwd, getpwnam_app_id_u1_a0) {
178 check_get_passwd("u1_a0", 110000, TYPE_APP);
179 }
180
TEST(pwd,getpwnam_app_id_u1_a40000)181 TEST(pwd, getpwnam_app_id_u1_a40000) {
182 check_get_passwd("u1_a40000", 150000, TYPE_APP);
183 }
184
TEST(pwd,getpwnam_app_id_u1_i0)185 TEST(pwd, getpwnam_app_id_u1_i0) {
186 check_get_passwd("u1_i0", 199000, TYPE_APP);
187 }
188
TEST(pwd,getpwent_iterate)189 TEST(pwd, getpwent_iterate) {
190 passwd* pwd;
191 std::bitset<10000> exist;
192 bool application = false;
193
194 exist.reset();
195
196 setpwent();
197 while ((pwd = getpwent()) != NULL) {
198 ASSERT_TRUE(NULL != pwd->pw_name);
199 ASSERT_EQ(pwd->pw_gid, pwd->pw_uid);
200 ASSERT_EQ(NULL, pwd->pw_passwd);
201 #ifdef __LP64__
202 ASSERT_TRUE(NULL == pwd->pw_gecos);
203 #endif
204 ASSERT_TRUE(NULL != pwd->pw_shell);
205 if (pwd->pw_uid >= exist.size()) {
206 ASSERT_STREQ("/data", pwd->pw_dir);
207 application = true;
208 } else {
209 ASSERT_STREQ("/", pwd->pw_dir);
210 ASSERT_FALSE(exist[pwd->pw_uid]);
211 exist[pwd->pw_uid] = true;
212 }
213 }
214 endpwent();
215
216 // Required content
217 for (size_t n = 0; n < android_id_count; ++n) {
218 ASSERT_TRUE(exist[android_ids[n].aid]);
219 }
220 for (size_t n = 2900; n < 2999; ++n) {
221 ASSERT_TRUE(exist[n]);
222 }
223 for (size_t n = 5000; n < 5999; ++n) {
224 ASSERT_TRUE(exist[n]);
225 }
226 ASSERT_TRUE(application);
227 }
228
check_group(const group * grp,const char * group_name,gid_t gid)229 static void check_group(const group* grp, const char* group_name, gid_t gid) {
230 ASSERT_TRUE(grp != NULL);
231 ASSERT_STREQ(group_name, grp->gr_name);
232 ASSERT_EQ(gid, grp->gr_gid);
233 ASSERT_TRUE(grp->gr_mem != NULL);
234 ASSERT_STREQ(group_name, grp->gr_mem[0]);
235 ASSERT_TRUE(grp->gr_mem[1] == NULL);
236 }
237
238 #if defined(__BIONIC__)
239
check_getgrgid(const char * group_name,gid_t gid)240 static void check_getgrgid(const char* group_name, gid_t gid) {
241 errno = 0;
242 group* grp = getgrgid(gid);
243 ASSERT_EQ(0, errno);
244 SCOPED_TRACE("getgrgid");
245 check_group(grp, group_name, gid);
246 }
247
check_getgrnam(const char * group_name,gid_t gid)248 static void check_getgrnam(const char* group_name, gid_t gid) {
249 errno = 0;
250 group* grp = getgrnam(group_name);
251 ASSERT_EQ(0, errno);
252 SCOPED_TRACE("getgrnam");
253 check_group(grp, group_name, gid);
254 }
255
check_getgrgid_r(const char * group_name,gid_t gid)256 static void check_getgrgid_r(const char* group_name, gid_t gid) {
257 group grp_storage;
258 char buf[512];
259 group* grp;
260
261 errno = 0;
262 int result = getgrgid_r(gid, &grp_storage, buf, sizeof(buf), &grp);
263 ASSERT_EQ(0, result);
264 ASSERT_EQ(0, errno);
265 SCOPED_TRACE("getgrgid_r");
266 check_group(grp, group_name, gid);
267 }
268
check_getgrnam_r(const char * group_name,gid_t gid)269 static void check_getgrnam_r(const char* group_name, gid_t gid) {
270 group grp_storage;
271 char buf[512];
272 group* grp;
273
274 errno = 0;
275 int result = getgrnam_r(group_name, &grp_storage, buf, sizeof(buf), &grp);
276 ASSERT_EQ(0, result);
277 ASSERT_EQ(0, errno);
278 SCOPED_TRACE("getgrnam_r");
279 check_group(grp, group_name, gid);
280 }
281
check_get_group(const char * group_name,gid_t gid)282 static void check_get_group(const char* group_name, gid_t gid) {
283 check_getgrgid(group_name, gid);
284 check_getgrnam(group_name, gid);
285 check_getgrgid_r(group_name, gid);
286 check_getgrnam_r(group_name, gid);
287 }
288
289 #else // !defined(__BIONIC__)
290
print_no_getgrnam_test_info()291 static void print_no_getgrnam_test_info() {
292 GTEST_LOG_(INFO) << "This test is about gid/group_name translation for Android, which does nothing on libc other than bionic.\n";
293 }
294
check_get_group(const char *,gid_t)295 static void check_get_group(const char*, gid_t) {
296 print_no_getgrnam_test_info();
297 }
298
299 #endif
300
TEST(grp,getgrnam_system_id_root)301 TEST(grp, getgrnam_system_id_root) {
302 check_get_group("root", 0);
303 }
304
TEST(grp,getgrnam_system_id_system)305 TEST(grp, getgrnam_system_id_system) {
306 check_get_group("system", 1000);
307 }
308
TEST(grp,getgrnam_app_id_radio)309 TEST(grp, getgrnam_app_id_radio) {
310 check_get_group("radio", 1001);
311 }
312
TEST(grp,getgrnam_oem_id_5000)313 TEST(grp, getgrnam_oem_id_5000) {
314 check_get_group("oem_5000", 5000);
315 }
316
TEST(grp,getgrnam_oem_id_5999)317 TEST(grp, getgrnam_oem_id_5999) {
318 check_get_group("oem_5999", 5999);
319 }
320
TEST(grp,getgrnam_oem_id_2900)321 TEST(grp, getgrnam_oem_id_2900) {
322 check_get_group("oem_2900", 2900);
323 }
324
TEST(grp,getgrnam_oem_id_2999)325 TEST(grp, getgrnam_oem_id_2999) {
326 check_get_group("oem_2999", 2999);
327 }
328
TEST(grp,getgrnam_app_id_nobody)329 TEST(grp, getgrnam_app_id_nobody) {
330 check_get_group("nobody", 9999);
331 }
332
TEST(grp,getgrnam_app_id_u0_a0)333 TEST(grp, getgrnam_app_id_u0_a0) {
334 check_get_group("u0_a0", 10000);
335 }
336
TEST(grp,getgrnam_app_id_u0_a1234)337 TEST(grp, getgrnam_app_id_u0_a1234) {
338 check_get_group("u0_a1234", 11234);
339 }
340
TEST(grp,getgrnam_app_id_u0_a9999)341 TEST(grp, getgrnam_app_id_u0_a9999) {
342 check_get_group("u0_a9999", 19999);
343 }
344
TEST(getgrnam,app_id_u0_a0_cache)345 TEST(getgrnam, app_id_u0_a0_cache) {
346 check_get_group("u0_a0_cache", 20000);
347 }
348
TEST(getgrnam,app_id_u0_a1234_cache)349 TEST(getgrnam, app_id_u0_a1234_cache) {
350 check_get_group("u0_a1234_cache", 21234);
351 }
352
TEST(getgrnam,app_id_u0_a9999_cache)353 TEST(getgrnam, app_id_u0_a9999_cache) {
354 check_get_group("u0_a9999_cache", 29999);
355 }
356
TEST(getgrnam,app_id_u10_a1234_cache)357 TEST(getgrnam, app_id_u10_a1234_cache) {
358 check_get_group("u10_a1234_cache", 1021234);
359 }
360
361 // Test the difference between uid and shared gid.
TEST(grp,getgrnam_app_id_all_a9999)362 TEST(grp, getgrnam_app_id_all_a9999) {
363 check_get_group("all_a9999", 59999);
364 }
365
TEST(grp,getgrnam_app_id_u0_i1)366 TEST(grp, getgrnam_app_id_u0_i1) {
367 check_get_group("u0_i1", 99001);
368 }
369
TEST(grp,getgrnam_app_id_u1_root)370 TEST(grp, getgrnam_app_id_u1_root) {
371 check_get_group("u1_root", 100000);
372 }
373
TEST(grp,getgrnam_app_id_u1_radio)374 TEST(grp, getgrnam_app_id_u1_radio) {
375 check_get_group("u1_radio", 101001);
376 }
377
TEST(grp,getgrnam_app_id_u1_a0)378 TEST(grp, getgrnam_app_id_u1_a0) {
379 check_get_group("u1_a0", 110000);
380 }
381
TEST(grp,getgrnam_app_id_u1_a40000)382 TEST(grp, getgrnam_app_id_u1_a40000) {
383 check_get_group("u1_a40000", 150000);
384 }
385
TEST(grp,getgrnam_app_id_u1_i0)386 TEST(grp, getgrnam_app_id_u1_i0) {
387 check_get_group("u1_i0", 199000);
388 }
389
TEST(grp,getgrnam_r_reentrancy)390 TEST(grp, getgrnam_r_reentrancy) {
391 #if defined(__BIONIC__)
392 group grp_storage[2];
393 char buf[2][512];
394 group* grp[3];
395 int result = getgrnam_r("root", &grp_storage[0], buf[0], sizeof(buf[0]), &grp[0]);
396 ASSERT_EQ(0, result);
397 check_group(grp[0], "root", 0);
398 grp[1] = getgrnam("system");
399 check_group(grp[1], "system", 1000);
400 result = getgrnam_r("radio", &grp_storage[1], buf[1], sizeof(buf[1]), &grp[2]);
401 ASSERT_EQ(0, result);
402 check_group(grp[2], "radio", 1001);
403 check_group(grp[0], "root", 0);
404 check_group(grp[1], "system", 1000);
405 #else
406 print_no_getgrnam_test_info();
407 #endif
408 }
409
TEST(grp,getgrgid_r_reentrancy)410 TEST(grp, getgrgid_r_reentrancy) {
411 #if defined(__BIONIC__)
412 group grp_storage[2];
413 char buf[2][512];
414 group* grp[3];
415 int result = getgrgid_r(0, &grp_storage[0], buf[0], sizeof(buf[0]), &grp[0]);
416 ASSERT_EQ(0, result);
417 check_group(grp[0], "root", 0);
418 grp[1] = getgrgid(1000);
419 check_group(grp[1], "system", 1000);
420 result = getgrgid_r(1001, &grp_storage[1], buf[1], sizeof(buf[1]), &grp[2]);
421 ASSERT_EQ(0, result);
422 check_group(grp[2], "radio", 1001);
423 check_group(grp[0], "root", 0);
424 check_group(grp[1], "system", 1000);
425 #else
426 print_no_getgrnam_test_info();
427 #endif
428 }
429
TEST(grp,getgrnam_r_large_enough_suggested_buffer_size)430 TEST(grp, getgrnam_r_large_enough_suggested_buffer_size) {
431 long size = sysconf(_SC_GETGR_R_SIZE_MAX);
432 ASSERT_GT(size, 0);
433 char buf[size];
434 group grp_storage;
435 group* grp;
436 ASSERT_EQ(0, getgrnam_r("root", &grp_storage, buf, size, &grp));
437 check_group(grp, "root", 0);
438 }
439
TEST(grp,getgrent_iterate)440 TEST(grp, getgrent_iterate) {
441 group* grp;
442 std::bitset<10000> exist;
443 bool application = false;
444
445 exist.reset();
446
447 setgrent();
448 while ((grp = getgrent()) != NULL) {
449 ASSERT_TRUE(grp->gr_name != NULL);
450 ASSERT_TRUE(grp->gr_mem != NULL);
451 ASSERT_STREQ(grp->gr_name, grp->gr_mem[0]);
452 ASSERT_TRUE(grp->gr_mem[1] == NULL);
453 if (grp->gr_gid >= exist.size()) {
454 application = true;
455 } else {
456 ASSERT_FALSE(exist[grp->gr_gid]);
457 exist[grp->gr_gid] = true;
458 }
459 }
460 endgrent();
461
462 // Required content
463 for (size_t n = 0; n < android_id_count; ++n) {
464 ASSERT_TRUE(exist[android_ids[n].aid]);
465 }
466 for (size_t n = 2900; n < 2999; ++n) {
467 ASSERT_TRUE(exist[n]);
468 }
469 for (size_t n = 5000; n < 5999; ++n) {
470 ASSERT_TRUE(exist[n]);
471 }
472 ASSERT_TRUE(application);
473 }
474