Home | History | Annotate | Download | only in tests
      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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    120 TEST(pwd, getpwnam_system_id_root) {
    121   check_get_passwd("root", 0, TYPE_SYSTEM);
    122 }
    123 
    124 TEST(pwd, getpwnam_system_id_system) {
    125   check_get_passwd("system", 1000, TYPE_SYSTEM);
    126 }
    127 
    128 TEST(pwd, getpwnam_app_id_radio) {
    129   check_get_passwd("radio", 1001, TYPE_SYSTEM);
    130 }
    131 
    132 TEST(pwd, getpwnam_oem_id_5000) {
    133   check_get_passwd("oem_5000", 5000, TYPE_SYSTEM);
    134 }
    135 
    136 TEST(pwd, getpwnam_oem_id_5999) {
    137   check_get_passwd("oem_5999", 5999, TYPE_SYSTEM);
    138 }
    139 
    140 TEST(pwd, getpwnam_oem_id_2900) {
    141   check_get_passwd("oem_2900", 2900, TYPE_SYSTEM);
    142 }
    143 
    144 TEST(pwd, getpwnam_oem_id_2999) {
    145   check_get_passwd("oem_2999", 2999, TYPE_SYSTEM);
    146 }
    147 
    148 TEST(pwd, getpwnam_app_id_nobody) {
    149   check_get_passwd("nobody", 9999, TYPE_SYSTEM);
    150 }
    151 
    152 TEST(pwd, getpwnam_app_id_u0_a0) {
    153   check_get_passwd("u0_a0", 10000, TYPE_APP);
    154 }
    155 
    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.
    161 TEST(pwd, getpwnam_app_id_u0_a49999) {
    162   check_get_passwd("u0_a49999", 59999, TYPE_APP);
    163 }
    164 
    165 TEST(pwd, getpwnam_app_id_u0_i1) {
    166   check_get_passwd("u0_i1", 99001, TYPE_APP);
    167 }
    168 
    169 TEST(pwd, getpwnam_app_id_u1_root) {
    170   check_get_passwd("u1_root", 100000, TYPE_SYSTEM);
    171 }
    172 
    173 TEST(pwd, getpwnam_app_id_u1_radio) {
    174   check_get_passwd("u1_radio", 101001, TYPE_SYSTEM);
    175 }
    176 
    177 TEST(pwd, getpwnam_app_id_u1_a0) {
    178   check_get_passwd("u1_a0", 110000, TYPE_APP);
    179 }
    180 
    181 TEST(pwd, getpwnam_app_id_u1_a40000) {
    182   check_get_passwd("u1_a40000", 150000, TYPE_APP);
    183 }
    184 
    185 TEST(pwd, getpwnam_app_id_u1_i0) {
    186   check_get_passwd("u1_i0", 199000, TYPE_APP);
    187 }
    188 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    295 static void check_get_group(const char*, gid_t) {
    296   print_no_getgrnam_test_info();
    297 }
    298 
    299 #endif
    300 
    301 TEST(grp, getgrnam_system_id_root) {
    302   check_get_group("root", 0);
    303 }
    304 
    305 TEST(grp, getgrnam_system_id_system) {
    306   check_get_group("system", 1000);
    307 }
    308 
    309 TEST(grp, getgrnam_app_id_radio) {
    310   check_get_group("radio", 1001);
    311 }
    312 
    313 TEST(grp, getgrnam_oem_id_5000) {
    314   check_get_group("oem_5000", 5000);
    315 }
    316 
    317 TEST(grp, getgrnam_oem_id_5999) {
    318   check_get_group("oem_5999", 5999);
    319 }
    320 
    321 TEST(grp, getgrnam_oem_id_2900) {
    322   check_get_group("oem_2900", 2900);
    323 }
    324 
    325 TEST(grp, getgrnam_oem_id_2999) {
    326   check_get_group("oem_2999", 2999);
    327 }
    328 
    329 TEST(grp, getgrnam_app_id_nobody) {
    330   check_get_group("nobody", 9999);
    331 }
    332 
    333 TEST(grp, getgrnam_app_id_u0_a0) {
    334   check_get_group("u0_a0", 10000);
    335 }
    336 
    337 TEST(grp, getgrnam_app_id_u0_a1234) {
    338   check_get_group("u0_a1234", 11234);
    339 }
    340 
    341 TEST(grp, getgrnam_app_id_u0_a9999) {
    342   check_get_group("u0_a9999", 19999);
    343 }
    344 
    345 TEST(getgrnam, app_id_u0_a0_cache) {
    346   check_get_group("u0_a0_cache", 20000);
    347 }
    348 
    349 TEST(getgrnam, app_id_u0_a1234_cache) {
    350   check_get_group("u0_a1234_cache", 21234);
    351 }
    352 
    353 TEST(getgrnam, app_id_u0_a9999_cache) {
    354   check_get_group("u0_a9999_cache", 29999);
    355 }
    356 
    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.
    362 TEST(grp, getgrnam_app_id_all_a9999) {
    363   check_get_group("all_a9999", 59999);
    364 }
    365 
    366 TEST(grp, getgrnam_app_id_u0_i1) {
    367   check_get_group("u0_i1", 99001);
    368 }
    369 
    370 TEST(grp, getgrnam_app_id_u1_root) {
    371   check_get_group("u1_root", 100000);
    372 }
    373 
    374 TEST(grp, getgrnam_app_id_u1_radio) {
    375   check_get_group("u1_radio", 101001);
    376 }
    377 
    378 TEST(grp, getgrnam_app_id_u1_a0) {
    379   check_get_group("u1_a0", 110000);
    380 }
    381 
    382 TEST(grp, getgrnam_app_id_u1_a40000) {
    383   check_get_group("u1_a40000", 150000);
    384 }
    385 
    386 TEST(grp, getgrnam_app_id_u1_i0) {
    387   check_get_group("u1_i0", 199000);
    388 }
    389 
    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 
    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 
    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 
    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