blob: 6ced3783bb8f08a21324e8e5b67cb71e4d299969 [file] [log] [blame]
Kenny Root2a54e5e2012-09-13 10:52:52 -07001/*
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
Yabin Cuia04c79b2014-11-18 16:14:54 -080019// Below are the header files we want to test.
20#include <grp.h>
Kenny Root2a54e5e2012-09-13 10:52:52 -070021#include <pwd.h>
Yabin Cuia04c79b2014-11-18 16:14:54 -080022
Kenny Root2a54e5e2012-09-13 10:52:52 -070023#include <errno.h>
24#include <limits.h>
Yabin Cuia04c79b2014-11-18 16:14:54 -080025#include <sys/cdefs.h>
26#include <sys/types.h>
Kenny Root2a54e5e2012-09-13 10:52:52 -070027#include <unistd.h>
28
Elliott Hughes0ec50d82025-05-09 13:58:56 -070029#include <algorithm>
30#include <iterator>
Tom Cherry4362f892017-11-14 08:50:43 -080031#include <set>
Elliott Hughes0ec50d82025-05-09 13:58:56 -070032#include <string>
Tom Cherry4362f892017-11-14 08:50:43 -080033#include <vector>
Mark Salyzyn722ab052016-04-06 10:35:48 -070034
Tom Cherrye88b4082018-05-24 14:44:10 -070035#include <android-base/file.h>
Tom Cherry4362f892017-11-14 08:50:43 -080036#include <android-base/strings.h>
Mark Salyzyn722ab052016-04-06 10:35:48 -070037#include <private/android_filesystem_config.h>
38
Tom Cherry5c941432018-10-09 11:01:28 -070039#if defined(__BIONIC__)
Tom Cherry9da8ff12019-02-19 13:23:49 -080040#include <android/api-level.h>
Tom Cherry5c941432018-10-09 11:01:28 -070041#include <android-base/properties.h>
42#endif
43
Elliott Hughes3f6eee92016-12-13 23:47:25 +000044// Generated android_ids array
45#include "generated_android_ids.h"
46
Elliott Hughes95646e62023-09-21 14:11:19 -070047#include "utils.h"
48
Tom Cherry4362f892017-11-14 08:50:43 -080049using android::base::Join;
Tom Cherrye88b4082018-05-24 14:44:10 -070050using android::base::ReadFileToString;
51using android::base::Split;
52using android::base::StartsWith;
Tom Cherry4362f892017-11-14 08:50:43 -080053
Tom Cherry6b116d12019-04-25 10:34:07 -070054using namespace std::literals;
55
Yabin Cuia04c79b2014-11-18 16:14:54 -080056enum uid_type_t {
Tom Cherryfa5f61c2018-09-27 13:19:02 -070057 TYPE_APP,
Kenny Root2a54e5e2012-09-13 10:52:52 -070058 TYPE_SYSTEM,
Tom Cherryfa5f61c2018-09-27 13:19:02 -070059 TYPE_VENDOR,
Yabin Cuia04c79b2014-11-18 16:14:54 -080060};
Kenny Root2a54e5e2012-09-13 10:52:52 -070061
Yabin Cuia04c79b2014-11-18 16:14:54 -080062#if defined(__BIONIC__)
63
Tom Cherryb4c25c82018-04-04 15:02:55 -070064static void check_passwd(const passwd* pwd, const char* username, uid_t uid, uid_type_t uid_type,
65 bool check_username) {
Yi Kong32bc0fc2018-08-02 17:31:13 -070066 ASSERT_TRUE(pwd != nullptr);
Tom Cherryb4c25c82018-04-04 15:02:55 -070067 if (check_username) {
68 EXPECT_STREQ(username, pwd->pw_name);
69 }
Tom Cherry2c05c0f2017-11-10 10:57:21 -080070 EXPECT_EQ(uid, pwd->pw_uid);
71 EXPECT_EQ(uid, pwd->pw_gid);
Yi Kong32bc0fc2018-08-02 17:31:13 -070072 EXPECT_EQ(nullptr, pwd->pw_passwd);
Calin Juravlec7688742014-05-09 21:50:53 +010073#ifdef __LP64__
Yi Kong32bc0fc2018-08-02 17:31:13 -070074 EXPECT_EQ(nullptr, pwd->pw_gecos);
Calin Juravlec7688742014-05-09 21:50:53 +010075#endif
Kenny Root2a54e5e2012-09-13 10:52:52 -070076
Tom Cherryfa5f61c2018-09-27 13:19:02 -070077 if (uid_type == TYPE_APP) {
Tom Cherry2c05c0f2017-11-10 10:57:21 -080078 EXPECT_STREQ("/data", pwd->pw_dir);
Tom Cherryfa5f61c2018-09-27 13:19:02 -070079 } else {
80 EXPECT_STREQ("/", pwd->pw_dir);
Kenny Root2a54e5e2012-09-13 10:52:52 -070081 }
Tom Cherryfa5f61c2018-09-27 13:19:02 -070082
Tom Cherryb9fa04d2020-07-10 10:40:21 -070083 // This has changed over time and that causes new GSI + old vendor images testing to fail.
84 // This parameter doesn't matter on Android, so simply ignore its value for older vendor images.
85 if (android::base::GetIntProperty("ro.product.first_api_level", 0) >= 30) {
86 EXPECT_STREQ("/bin/sh", pwd->pw_shell);
87 }
Kenny Root2a54e5e2012-09-13 10:52:52 -070088}
Yabin Cuia04c79b2014-11-18 16:14:54 -080089
Tom Cherryb4c25c82018-04-04 15:02:55 -070090static void check_getpwuid(const char* username, uid_t uid, uid_type_t uid_type,
91 bool check_username) {
Yabin Cuia04c79b2014-11-18 16:14:54 -080092 errno = 0;
93 passwd* pwd = getpwuid(uid);
Elliott Hughes95646e62023-09-21 14:11:19 -070094 ASSERT_ERRNO(0);
Yabin Cuia04c79b2014-11-18 16:14:54 -080095 SCOPED_TRACE("getpwuid");
Tom Cherryb4c25c82018-04-04 15:02:55 -070096 check_passwd(pwd, username, uid, uid_type, check_username);
Yabin Cuia04c79b2014-11-18 16:14:54 -080097}
98
Tom Cherryb4c25c82018-04-04 15:02:55 -070099static void check_getpwnam(const char* username, uid_t uid, uid_type_t uid_type,
100 bool check_username) {
Yabin Cuia04c79b2014-11-18 16:14:54 -0800101 errno = 0;
102 passwd* pwd = getpwnam(username);
Elliott Hughes95646e62023-09-21 14:11:19 -0700103 ASSERT_ERRNO(0);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800104 SCOPED_TRACE("getpwnam");
Tom Cherryb4c25c82018-04-04 15:02:55 -0700105 check_passwd(pwd, username, uid, uid_type, check_username);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800106}
107
Tom Cherryb4c25c82018-04-04 15:02:55 -0700108static void check_getpwuid_r(const char* username, uid_t uid, uid_type_t uid_type,
109 bool check_username) {
Yabin Cuia04c79b2014-11-18 16:14:54 -0800110 passwd pwd_storage;
111 char buf[512];
112 int result;
113
114 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700115 passwd* pwd = nullptr;
Yabin Cuia04c79b2014-11-18 16:14:54 -0800116 result = getpwuid_r(uid, &pwd_storage, buf, sizeof(buf), &pwd);
117 ASSERT_EQ(0, result);
Elliott Hughes95646e62023-09-21 14:11:19 -0700118 ASSERT_ERRNO(0);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800119 SCOPED_TRACE("getpwuid_r");
Tom Cherryb4c25c82018-04-04 15:02:55 -0700120 check_passwd(pwd, username, uid, uid_type, check_username);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800121}
122
Tom Cherryb4c25c82018-04-04 15:02:55 -0700123static void check_getpwnam_r(const char* username, uid_t uid, uid_type_t uid_type,
124 bool check_username) {
Yabin Cuia04c79b2014-11-18 16:14:54 -0800125 passwd pwd_storage;
126 char buf[512];
127 int result;
128
129 errno = 0;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700130 passwd* pwd = nullptr;
Yabin Cuia04c79b2014-11-18 16:14:54 -0800131 result = getpwnam_r(username, &pwd_storage, buf, sizeof(buf), &pwd);
132 ASSERT_EQ(0, result);
Elliott Hughes95646e62023-09-21 14:11:19 -0700133 ASSERT_ERRNO(0);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800134 SCOPED_TRACE("getpwnam_r");
Tom Cherryb4c25c82018-04-04 15:02:55 -0700135 check_passwd(pwd, username, uid, uid_type, check_username);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800136}
137
Tom Cherryb4c25c82018-04-04 15:02:55 -0700138static void check_get_passwd(const char* username, uid_t uid, uid_type_t uid_type,
139 bool check_username = true) {
Tom Cherry6b116d12019-04-25 10:34:07 -0700140 SCOPED_TRACE("username '"s + username + "'");
Tom Cherryb4c25c82018-04-04 15:02:55 -0700141 check_getpwuid(username, uid, uid_type, check_username);
142 check_getpwnam(username, uid, uid_type, check_username);
143 check_getpwuid_r(username, uid, uid_type, check_username);
144 check_getpwnam_r(username, uid, uid_type, check_username);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800145}
146
Tom Cherry6b116d12019-04-25 10:34:07 -0700147static void expect_no_passwd_id(uid_t uid) {
148 SCOPED_TRACE("uid '" + std::to_string(uid) + "'");
149 errno = 0;
150 passwd* passwd = nullptr;
151 passwd = getpwuid(uid);
152 EXPECT_EQ(nullptr, passwd) << "name = '" << passwd->pw_name << "'";
Elliott Hughes95646e62023-09-21 14:11:19 -0700153 EXPECT_ERRNO(ENOENT);
Tom Cherry6b116d12019-04-25 10:34:07 -0700154
155 struct passwd passwd_storage;
156 char buf[512];
157 EXPECT_EQ(ENOENT, getpwuid_r(uid, &passwd_storage, buf, sizeof(buf), &passwd));
158 EXPECT_EQ(nullptr, passwd) << "name = '" << passwd->pw_name << "'";
159}
160
161static void expect_no_passwd_name(const char* username) {
162 SCOPED_TRACE("username '"s + username + "'");
163 errno = 0;
164 passwd* passwd = nullptr;
165 passwd = getpwnam(username);
166 EXPECT_EQ(nullptr, passwd) << "name = '" << passwd->pw_name << "'";
Elliott Hughes95646e62023-09-21 14:11:19 -0700167 EXPECT_ERRNO(ENOENT);
Tom Cherry6b116d12019-04-25 10:34:07 -0700168
169 struct passwd passwd_storage;
170 char buf[512];
171 EXPECT_EQ(ENOENT, getpwnam_r(username, &passwd_storage, buf, sizeof(buf), &passwd));
172 EXPECT_EQ(nullptr, passwd) << "name = '" << passwd->pw_name << "'";
173}
174
Yabin Cuia04c79b2014-11-18 16:14:54 -0800175#else // !defined(__BIONIC__)
176
Tom Cherryb4c25c82018-04-04 15:02:55 -0700177static void check_get_passwd(const char* /* username */, uid_t /* uid */, uid_type_t /* uid_type */,
178 bool /* check_username */) {
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800179 GTEST_SKIP() << "bionic-only test";
Tom Cherryb4c25c82018-04-04 15:02:55 -0700180}
181
Josh Gao2fe10342018-02-27 14:05:53 -0800182static void check_get_passwd(const char* /* username */, uid_t /* uid */, uid_type_t /* uid_type */) {
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800183 GTEST_SKIP() << "bionic-only test";
Josh Gao2fe10342018-02-27 14:05:53 -0800184}
185
Tom Cherry6b116d12019-04-25 10:34:07 -0700186static void expect_no_passwd_id(uid_t /* uid */) {
187 GTEST_SKIP() << "bionic-only test";
188}
189
190static void expect_no_passwd_name(const char* /* username */) {
191 GTEST_SKIP() << "bionic-only test";
192}
193
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800194#endif
Kenny Root2a54e5e2012-09-13 10:52:52 -0700195
Tom Cherry6b116d12019-04-25 10:34:07 -0700196TEST(pwd, getpwnam_platform_ids) {
Yabin Cuia04c79b2014-11-18 16:14:54 -0800197 check_get_passwd("root", 0, TYPE_SYSTEM);
Tom Cherry6b116d12019-04-25 10:34:07 -0700198 check_get_passwd("daemon", 1, TYPE_SYSTEM);
199 check_get_passwd("bin", 2, TYPE_SYSTEM);
Kenny Root2a54e5e2012-09-13 10:52:52 -0700200
Yabin Cuia04c79b2014-11-18 16:14:54 -0800201 check_get_passwd("system", 1000, TYPE_SYSTEM);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800202 check_get_passwd("radio", 1001, TYPE_SYSTEM);
Kenny Root2a54e5e2012-09-13 10:52:52 -0700203
Tom Cherry6b116d12019-04-25 10:34:07 -0700204 check_get_passwd("shell", 2000, TYPE_SYSTEM);
Jorge Lucangeli Obesa39e3012015-09-22 11:46:43 -0700205
Yabin Cuia04c79b2014-11-18 16:14:54 -0800206 check_get_passwd("nobody", 9999, TYPE_SYSTEM);
Kenny Root8a05a012012-09-13 14:31:50 -0700207}
208
Tom Cherry6b116d12019-04-25 10:34:07 -0700209TEST(pwd, getpwnam_oem_ids) {
210 check_get_passwd("oem_2900", 2900, TYPE_VENDOR, false);
211 check_get_passwd("oem_2945", 2945, TYPE_VENDOR, false);
212 check_get_passwd("oem_2999", 2999, TYPE_VENDOR, false);
213 check_get_passwd("oem_5000", 5000, TYPE_VENDOR, false);
214 check_get_passwd("oem_5454", 5454, TYPE_VENDOR, false);
215 check_get_passwd("oem_5999", 5999, TYPE_VENDOR, false);
216}
217
218TEST(pwd, getpwnam_non_exist) {
219 expect_no_passwd_id(999); // End of the system reserved range, unallocated.
220 expect_no_passwd_id(1999); // End of the system reserved range, unallocated.
221 expect_no_passwd_id(2899); // End of the system reserved range, unallocated.
222
223 // These ranges are for GIDs only.
224 expect_no_passwd_id(20000);
225 expect_no_passwd_id(30000);
226 expect_no_passwd_id(40000);
227 expect_no_passwd_id(50000);
228
229 // These should not be parsed as users, only as groups.
230 expect_no_passwd_name("u0_a9999_cache");
231 expect_no_passwd_name("u0_a9999_ext");
232 expect_no_passwd_name("u0_a9999_ext_cache");
233 expect_no_passwd_name("all_a9999");
234}
235
236TEST(pwd, getpwnam_u0_app_ids) {
Yabin Cuia04c79b2014-11-18 16:14:54 -0800237 check_get_passwd("u0_a0", 10000, TYPE_APP);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800238 check_get_passwd("u0_a1234", 11234, TYPE_APP);
Tom Cherry6b116d12019-04-25 10:34:07 -0700239 check_get_passwd("u0_a9999", 19999, TYPE_APP);
Kenny Root2a54e5e2012-09-13 10:52:52 -0700240
Martijn Coenenf9d22992019-01-16 16:25:40 +0100241 check_get_passwd("u0_i1", 90001, TYPE_APP);
Tom Cherry6b116d12019-04-25 10:34:07 -0700242 check_get_passwd("u0_i4545", 94545, TYPE_APP);
243 check_get_passwd("u0_i9999", 99999, TYPE_APP);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800244}
245
Tom Cherry6b116d12019-04-25 10:34:07 -0700246TEST(pwd, getpwnam_app_id_u1_ids) {
247 check_get_passwd("u1_system", 101000, TYPE_SYSTEM);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800248 check_get_passwd("u1_radio", 101001, TYPE_SYSTEM);
Kenny Root2a54e5e2012-09-13 10:52:52 -0700249
Yabin Cuia04c79b2014-11-18 16:14:54 -0800250 check_get_passwd("u1_a0", 110000, TYPE_APP);
Tom Cherry6b116d12019-04-25 10:34:07 -0700251 check_get_passwd("u1_a1234", 111234, TYPE_APP);
252 check_get_passwd("u1_a9999", 119999, TYPE_APP);
253
254 check_get_passwd("u1_i1", 190001, TYPE_APP);
255 check_get_passwd("u1_i4545", 194545, TYPE_APP);
256 check_get_passwd("u1_i9999", 199999, TYPE_APP);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800257}
258
Tom Cherry6b116d12019-04-25 10:34:07 -0700259TEST(pwd, getpwnam_app_id_u31_ids) {
260 check_get_passwd("u31_system", 3101000, TYPE_SYSTEM);
261 check_get_passwd("u31_radio", 3101001, TYPE_SYSTEM);
262
263 check_get_passwd("u31_a0", 3110000, TYPE_APP);
264 check_get_passwd("u31_a1234", 3111234, TYPE_APP);
265 check_get_passwd("u31_a9999", 3119999, TYPE_APP);
266
267 check_get_passwd("u31_i1", 3190001, TYPE_APP);
268 check_get_passwd("u31_i4545", 3194545, TYPE_APP);
269 check_get_passwd("u31_i9999", 3199999, TYPE_APP);
Kenny Root2a54e5e2012-09-13 10:52:52 -0700270}
271
Tom Cherry6b116d12019-04-25 10:34:07 -0700272TEST(pwd, getpwnam_app_id_not_allowed_platform) {
273 expect_no_passwd_name("u1_root");
274 expect_no_passwd_name("u1_debuggerd");
275
276 expect_no_passwd_name("u31_root");
277 expect_no_passwd_name("u31_debuggerd");
278}
279
280TEST(pwd, getpwuid_app_id_u1_non_exist) {
281 expect_no_passwd_id(100000); // There is no 'root' for secondary users.
282 expect_no_passwd_id(101999); // End of the system reserved range, unallocated.
283 expect_no_passwd_id(102900); // The OEM ranges were never allocated to secondary users.
284 expect_no_passwd_id(105000); // The OEM ranges were never allocated to secondary users.
285
286 // These ranges are for GIDs only.
287 expect_no_passwd_id(120000);
288 expect_no_passwd_id(130000);
289 expect_no_passwd_id(140000);
290 expect_no_passwd_id(150000);
291}
292
293TEST(pwd, getpwuid_app_id_u31_non_exist) {
294 expect_no_passwd_id(3100000); // There is no 'root' for secondary users.
295 expect_no_passwd_id(3101999); // End of the system reserved range, unallocated.
296 expect_no_passwd_id(3102900); // The OEM ranges were never allocated to secondary users.
297 expect_no_passwd_id(3105000); // The OEM ranges were never allocated to secondary users.
298
299 // These ranges are for GIDs only.
300 expect_no_passwd_id(3120000);
301 expect_no_passwd_id(3130000);
302 expect_no_passwd_id(3140000);
303 expect_no_passwd_id(3150000);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800304}
Tom Cherryc57c5bd2019-05-14 17:02:28 -0700305
306TEST(pwd, getpwnam_r_alignment) {
307#if defined(__BIONIC__)
308 passwd pwd_storage;
309 alignas(16) char buf[512];
310 passwd* pwd;
311 int result = getpwnam_r("root", &pwd_storage, buf + 1, sizeof(buf) - 1, &pwd);
312 ASSERT_EQ(0, result);
313 check_passwd(pwd, "root", 0, TYPE_SYSTEM, true);
314#else
315 GTEST_SKIP() << "bionic-only test";
316#endif
317}
318
319TEST(pwd, getpwuid_r_alignment) {
320#if defined(__BIONIC__)
321 passwd pwd_storage;
322 alignas(16) char buf[512];
323 passwd* pwd;
324 int result = getpwuid_r(0, &pwd_storage, buf + 1, sizeof(buf) - 1, &pwd);
325 ASSERT_EQ(0, result);
326 check_passwd(pwd, "root", 0, TYPE_SYSTEM, true);
327#else
328 GTEST_SKIP() << "bionic-only test";
329#endif
330}
331
332TEST(pwd, getpwnam_r_reentrancy) {
333#if defined(__BIONIC__)
334 passwd pwd_storage[2];
335 char buf[2][512];
336 passwd* pwd[3];
337 int result = getpwnam_r("root", &pwd_storage[0], buf[0], sizeof(buf[0]), &pwd[0]);
338 ASSERT_EQ(0, result);
339 check_passwd(pwd[0], "root", 0, TYPE_SYSTEM, true);
340 pwd[1] = getpwnam("system");
341 ASSERT_NE(nullptr, pwd[1]);
342 check_passwd(pwd[1], "system", 1000, TYPE_SYSTEM, true);
343 result = getpwnam_r("radio", &pwd_storage[1], buf[1], sizeof(buf[1]), &pwd[2]);
344 ASSERT_EQ(0, result);
345 check_passwd(pwd[2], "radio", 1001, TYPE_SYSTEM, true);
346 check_passwd(pwd[0], "root", 0, TYPE_SYSTEM, true);
347 check_passwd(pwd[1], "system", 1000, TYPE_SYSTEM, true);
348#else
349 GTEST_SKIP() << "bionic-only test";
350#endif
351}
352
353TEST(pwd, getpwuid_r_reentrancy) {
354#if defined(__BIONIC__)
355 passwd pwd_storage[2];
356 char buf[2][512];
357 passwd* pwd[3];
358 int result = getpwuid_r(0, &pwd_storage[0], buf[0], sizeof(buf[0]), &pwd[0]);
359 ASSERT_EQ(0, result);
360 check_passwd(pwd[0], "root", 0, TYPE_SYSTEM, true);
361 pwd[1] = getpwuid(1000);
362 ASSERT_NE(nullptr, pwd[1]);
363 check_passwd(pwd[1], "system", 1000, TYPE_SYSTEM, true);
364 result = getpwuid_r(1001, &pwd_storage[1], buf[1], sizeof(buf[1]), &pwd[2]);
365 ASSERT_EQ(0, result);
366 check_passwd(pwd[2], "radio", 1001, TYPE_SYSTEM, true);
367 check_passwd(pwd[0], "root", 0, TYPE_SYSTEM, true);
368 check_passwd(pwd[1], "system", 1000, TYPE_SYSTEM, true);
369#else
370 GTEST_SKIP() << "bionic-only test";
371#endif
372}
373
374TEST(pwd, getpwnam_r_large_enough_suggested_buffer_size) {
375#if defined(__BIONIC__)
376 long size = sysconf(_SC_GETPW_R_SIZE_MAX);
377 ASSERT_GT(size, 0);
378 char buf[size];
379 passwd pwd_storage;
380 passwd* pwd;
381 ASSERT_EQ(0, getpwnam_r("root", &pwd_storage, buf, size, &pwd));
382 check_passwd(pwd, "root", 0, TYPE_SYSTEM, true);
383#else
384 GTEST_SKIP() << "bionic-only test";
385#endif
386}
387
Tom Cherry5c941432018-10-09 11:01:28 -0700388#if defined(__BIONIC__)
Tom Cherry4362f892017-11-14 08:50:43 -0800389template <typename T>
Tom Cherry777b34d2019-02-17 09:38:23 -0800390static void expect_ids(T ids, bool is_group) {
Tom Cherry4362f892017-11-14 08:50:43 -0800391 std::set<typename T::key_type> expected_ids;
392 // Ensure that all android_ids are iterated through.
393 for (size_t n = 0; n < android_id_count; ++n) {
394 EXPECT_EQ(1U, ids.count(android_ids[n].aid)) << "android_ids[n].aid: " << android_ids[n].aid;
395 expected_ids.emplace(android_ids[n].aid);
396 }
397
398 auto expect_range = [&ids, &expected_ids](uid_t start, uid_t end) {
399 for (size_t n = start; n <= end; ++n) {
400 EXPECT_EQ(1U, ids.count(n)) << "n: " << n;
401 expected_ids.emplace(n);
402 }
403 };
404
405 // Ensure that all reserved ranges are iterated through.
406 expect_range(AID_OEM_RESERVED_START, AID_OEM_RESERVED_END);
407 expect_range(AID_OEM_RESERVED_2_START, AID_OEM_RESERVED_2_END);
408 expect_range(AID_APP_START, AID_APP_END);
Tom Cherry6b116d12019-04-25 10:34:07 -0700409 if (is_group) {
410 expect_range(AID_CACHE_GID_START, AID_CACHE_GID_END);
411 expect_range(AID_EXT_GID_START, AID_EXT_GID_END);
412 expect_range(AID_EXT_CACHE_GID_START, AID_EXT_CACHE_GID_END);
413 expect_range(AID_SHARED_GID_START, AID_SHARED_GID_END);
414 }
Tom Cherry4362f892017-11-14 08:50:43 -0800415 expect_range(AID_ISOLATED_START, AID_ISOLATED_END);
416
Tom Cherry6f2e8102020-04-10 10:50:09 -0700417 // Prior to R, we didn't have a mechanism to create vendor AIDs in the system or other non-vendor
418 // partitions, therefore we disabled the rest of these checks for older API levels.
Elliott Hughes95c6cd72019-12-20 13:26:14 -0800419 if (android::base::GetIntProperty("ro.product.first_api_level", 0) <= 29) {
Tom Cherry5c941432018-10-09 11:01:28 -0700420 return;
421 }
422
Tom Cherry777b34d2019-02-17 09:38:23 -0800423 auto allow_range = [&ids](uid_t start, uid_t end) {
424 for (size_t n = start; n <= end; ++n) {
425 ids.erase(n);
426 }
427 };
428
429 allow_range(AID_SYSTEM_RESERVED_START, AID_SYSTEM_EXT_RESERVED_END);
430
Tom Cherry4362f892017-11-14 08:50:43 -0800431 // Ensure that no other ids were returned.
432 auto return_differences = [&ids, &expected_ids] {
433 std::vector<typename T::key_type> missing_from_ids;
434 std::set_difference(expected_ids.begin(), expected_ids.end(), ids.begin(), ids.end(),
435 std::inserter(missing_from_ids, missing_from_ids.begin()));
436 std::vector<typename T::key_type> extra_in_ids;
437 std::set_difference(ids.begin(), ids.end(), expected_ids.begin(), expected_ids.end(),
438 std::inserter(extra_in_ids, extra_in_ids.begin()));
439 std::string result;
440 if (!missing_from_ids.empty()) {
441 result += "Missing ids from results: " + Join(missing_from_ids, " ");
442 }
443 if (!extra_in_ids.empty()) {
444 if (!result.empty()) result += ", ";
445 result += "Extra ids in results: " + Join(extra_in_ids, " ");
446 }
447 return result;
448 };
Orion Hodsonf5fd5ad2022-10-27 10:28:24 +0100449
Elliott Hughes618ce1b2024-09-10 16:01:50 +0000450 // AID_UPROBESTATS (1093) was added in API level 35, but "trunk stable" means
451 // that the 2024Q* builds are tested with the _previous_ release's CTS.
452 if (android::base::GetIntProperty("ro.build.version.sdk", 0) == 34) {
Elliott Hughes140e4d32024-02-10 00:39:07 +0000453#if !defined(AID_UPROBESTATS)
454#define AID_UPROBESTATS 1093
Orion Hodsonf5fd5ad2022-10-27 10:28:24 +0100455#endif
Elliott Hughes140e4d32024-02-10 00:39:07 +0000456 ids.erase(AID_UPROBESTATS);
457 expected_ids.erase(AID_UPROBESTATS);
458 if (getpwuid(AID_UPROBESTATS)) {
459 EXPECT_STREQ(getpwuid(AID_UPROBESTATS)->pw_name, "uprobestats");
460 }
Orion Hodsonf5fd5ad2022-10-27 10:28:24 +0100461 }
Elliott Hughes618ce1b2024-09-10 16:01:50 +0000462 // AID_VIRTUALMACHINE (3013) was added in API level 35, but "trunk stable" means
463 // that the 2024Q* builds are tested with the _previous_ release's CTS.
464 if (android::base::GetIntProperty("ro.build.version.sdk", 0) == 34) {
Elliott Hughes140e4d32024-02-10 00:39:07 +0000465#if !defined(AID_VIRTUALMACHINE)
466#define AID_VIRTUALMACHINE 3013
467#endif
468 ids.erase(AID_VIRTUALMACHINE);
469 expected_ids.erase(AID_VIRTUALMACHINE);
470 if (getpwuid(AID_VIRTUALMACHINE)) {
471 EXPECT_STREQ(getpwuid(AID_VIRTUALMACHINE)->pw_name, "virtualmachine");
472 }
473 }
Elliott Hughes618ce1b2024-09-10 16:01:50 +0000474 // AID_CROS_EC (1094) was added in API level 36, but "trunk stable" means
475 // that the 2024Q* builds are tested with the _previous_ release's CTS.
476 if (android::base::GetIntProperty("ro.build.version.sdk", 0) == 35) {
477#if !defined(AID_CROS_EC)
478#define AID_CROS_EC 1094
479#endif
480 ids.erase(AID_CROS_EC);
481 expected_ids.erase(AID_CROS_EC);
482 if (getpwuid(AID_CROS_EC)) {
483 EXPECT_STREQ(getpwuid(AID_CROS_EC)->pw_name, "cros_ec");
484 }
485 }
Hung Nguyen08fc8bd2024-11-11 11:27:23 -0800486 // AID_MMD (1095) was added in API level 36, but "trunk stable" means
487 // that the 2024Q* builds are tested with the _previous_ release's CTS.
488 if (android::base::GetIntProperty("ro.build.version.sdk", 0) == 35) {
489#if !defined(AID_MMD)
490#define AID_MMD 1095
491#endif
492 ids.erase(AID_MMD);
493 expected_ids.erase(AID_MMD);
494 if (getpwuid(AID_MMD)) {
495 EXPECT_STREQ(getpwuid(AID_MMD)->pw_name, "mmd");
496 }
497 }
HÃ¥kan Kvist88da6022025-01-22 10:25:03 +0100498 // AID_UPDATE_ENGINE_LOG (1096) was added in API level 36, but "trunk stable" means
499 // that the 2024Q* builds are tested with the _previous_ release's CTS.
500 if (android::base::GetIntProperty("ro.build.version.sdk", 0) == 35) {
501#if !defined(AID_UPDATE_ENGINE_LOG)
502#define AID_UPDATE_ENGINE_LOG 1096
503#endif
504 ids.erase(AID_UPDATE_ENGINE_LOG);
505 expected_ids.erase(AID_UPDATE_ENGINE_LOG);
506 if (getpwuid(AID_UPDATE_ENGINE_LOG)) {
507 EXPECT_STREQ(getpwuid(AID_UPDATE_ENGINE_LOG)->pw_name, "update_engine_log");
508 }
509 }
Jakub Czapigad42ed912025-07-25 14:59:59 +0000510 // AID_AP_FIRMWARE (1097) was added in API level 37, but "trunk stable" means
511 // that the 2025Q{1,2} builds are tested with the _previous_ release's CTS.
512 if (android::base::GetIntProperty("ro.build.version.sdk", 0) == 36) {
513#if !defined(AID_AP_FIRMWARE)
514#define AID_AP_FIRMWARE 1097
515#endif
516 ids.erase(AID_AP_FIRMWARE);
517 expected_ids.erase(AID_AP_FIRMWARE);
518 if (getpwuid(AID_AP_FIRMWARE)) {
519 EXPECT_STREQ(getpwuid(AID_AP_FIRMWARE)->pw_name, "ap_firmware");
520 }
521 }
Elliott Hughes140e4d32024-02-10 00:39:07 +0000522
Tom Cherry4362f892017-11-14 08:50:43 -0800523 EXPECT_EQ(expected_ids, ids) << return_differences();
524}
Tom Cherry5c941432018-10-09 11:01:28 -0700525#endif
Tom Cherry4362f892017-11-14 08:50:43 -0800526
Elliott Hughes5367d1b2016-12-12 17:32:14 -0800527TEST(pwd, getpwent_iterate) {
Josh Gao2fe10342018-02-27 14:05:53 -0800528#if defined(__BIONIC__)
Mark Salyzyn722ab052016-04-06 10:35:48 -0700529 passwd* pwd;
Tom Cherry4362f892017-11-14 08:50:43 -0800530 std::set<uid_t> uids;
Mark Salyzyn722ab052016-04-06 10:35:48 -0700531
532 setpwent();
Yi Kong32bc0fc2018-08-02 17:31:13 -0700533 while ((pwd = getpwent()) != nullptr) {
534 ASSERT_TRUE(nullptr != pwd->pw_name);
Tom Cherry4362f892017-11-14 08:50:43 -0800535
Tom Cherry2c05c0f2017-11-10 10:57:21 -0800536 EXPECT_EQ(pwd->pw_gid, pwd->pw_uid) << "pwd->pw_uid: " << pwd->pw_uid;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700537 EXPECT_EQ(nullptr, pwd->pw_passwd) << "pwd->pw_uid: " << pwd->pw_uid;
Mark Salyzyn722ab052016-04-06 10:35:48 -0700538#ifdef __LP64__
Yi Kong32bc0fc2018-08-02 17:31:13 -0700539 EXPECT_TRUE(nullptr == pwd->pw_gecos) << "pwd->pw_uid: " << pwd->pw_uid;
Mark Salyzyn722ab052016-04-06 10:35:48 -0700540#endif
Yi Kong32bc0fc2018-08-02 17:31:13 -0700541 EXPECT_TRUE(nullptr != pwd->pw_shell);
Tom Cherry4362f892017-11-14 08:50:43 -0800542 if (pwd->pw_uid < AID_APP_START || pwd->pw_uid == AID_OVERFLOWUID) {
Tom Cherry2c05c0f2017-11-10 10:57:21 -0800543 EXPECT_STREQ("/", pwd->pw_dir) << "pwd->pw_uid: " << pwd->pw_uid;
Tom Cherry4362f892017-11-14 08:50:43 -0800544 } else {
545 EXPECT_STREQ("/data", pwd->pw_dir) << "pwd->pw_uid: " << pwd->pw_uid;
Mark Salyzyn722ab052016-04-06 10:35:48 -0700546 }
Tom Cherry4362f892017-11-14 08:50:43 -0800547
Tom Cherry0816c902020-04-10 13:00:42 -0700548 EXPECT_EQ(0U, uids.count(pwd->pw_uid)) << "pwd->pw_uid: " << pwd->pw_uid;
Tom Cherry4362f892017-11-14 08:50:43 -0800549 uids.emplace(pwd->pw_uid);
Mark Salyzyn722ab052016-04-06 10:35:48 -0700550 }
551 endpwent();
552
Tom Cherry6b116d12019-04-25 10:34:07 -0700553 expect_ids(uids, false);
Josh Gao2fe10342018-02-27 14:05:53 -0800554#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800555 GTEST_SKIP() << "bionic-only test";
Josh Gao2fe10342018-02-27 14:05:53 -0800556#endif
Mark Salyzyn722ab052016-04-06 10:35:48 -0700557}
558
Tom Cherryb4c25c82018-04-04 15:02:55 -0700559static void check_group(const group* grp, const char* group_name, gid_t gid,
560 bool check_groupname = true) {
Yi Kong32bc0fc2018-08-02 17:31:13 -0700561 ASSERT_TRUE(grp != nullptr);
Tom Cherryb4c25c82018-04-04 15:02:55 -0700562 if (check_groupname) {
563 EXPECT_STREQ(group_name, grp->gr_name);
564 }
Tom Cherry2c05c0f2017-11-10 10:57:21 -0800565 EXPECT_EQ(gid, grp->gr_gid);
Yi Kong32bc0fc2018-08-02 17:31:13 -0700566 ASSERT_TRUE(grp->gr_mem != nullptr);
Tom Cherryb4c25c82018-04-04 15:02:55 -0700567 if (check_groupname) {
568 EXPECT_STREQ(group_name, grp->gr_mem[0]);
569 }
Yi Kong32bc0fc2018-08-02 17:31:13 -0700570 EXPECT_TRUE(grp->gr_mem[1] == nullptr);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800571}
572
Yabin Cuic4786d32015-07-20 19:46:26 -0700573#if defined(__BIONIC__)
574
Tom Cherryb4c25c82018-04-04 15:02:55 -0700575static void check_getgrgid(const char* group_name, gid_t gid, bool check_groupname) {
Yabin Cuia04c79b2014-11-18 16:14:54 -0800576 errno = 0;
577 group* grp = getgrgid(gid);
Elliott Hughes95646e62023-09-21 14:11:19 -0700578 ASSERT_ERRNO(0);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800579 SCOPED_TRACE("getgrgid");
Tom Cherryb4c25c82018-04-04 15:02:55 -0700580 check_group(grp, group_name, gid, check_groupname);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800581}
582
Tom Cherryb4c25c82018-04-04 15:02:55 -0700583static void check_getgrnam(const char* group_name, gid_t gid, bool check_groupname) {
Yabin Cuia04c79b2014-11-18 16:14:54 -0800584 errno = 0;
585 group* grp = getgrnam(group_name);
Elliott Hughes95646e62023-09-21 14:11:19 -0700586 ASSERT_ERRNO(0);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800587 SCOPED_TRACE("getgrnam");
Tom Cherryb4c25c82018-04-04 15:02:55 -0700588 check_group(grp, group_name, gid, check_groupname);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800589}
590
Tom Cherryb4c25c82018-04-04 15:02:55 -0700591static void check_getgrgid_r(const char* group_name, gid_t gid, bool check_groupname) {
Yabin Cuic4786d32015-07-20 19:46:26 -0700592 group grp_storage;
593 char buf[512];
594 group* grp;
595
596 errno = 0;
597 int result = getgrgid_r(gid, &grp_storage, buf, sizeof(buf), &grp);
598 ASSERT_EQ(0, result);
Elliott Hughes95646e62023-09-21 14:11:19 -0700599 ASSERT_ERRNO(0);
Yabin Cuic4786d32015-07-20 19:46:26 -0700600 SCOPED_TRACE("getgrgid_r");
Tom Cherryb4c25c82018-04-04 15:02:55 -0700601 check_group(grp, group_name, gid, check_groupname);
Yabin Cuic4786d32015-07-20 19:46:26 -0700602}
603
Tom Cherryb4c25c82018-04-04 15:02:55 -0700604static void check_getgrnam_r(const char* group_name, gid_t gid, bool check_groupname) {
Yabin Cuic4786d32015-07-20 19:46:26 -0700605 group grp_storage;
606 char buf[512];
607 group* grp;
608
609 errno = 0;
610 int result = getgrnam_r(group_name, &grp_storage, buf, sizeof(buf), &grp);
611 ASSERT_EQ(0, result);
Elliott Hughes95646e62023-09-21 14:11:19 -0700612 ASSERT_ERRNO(0);
Yabin Cuic4786d32015-07-20 19:46:26 -0700613 SCOPED_TRACE("getgrnam_r");
Tom Cherryb4c25c82018-04-04 15:02:55 -0700614 check_group(grp, group_name, gid, check_groupname);
Yabin Cuic4786d32015-07-20 19:46:26 -0700615}
616
Tom Cherryb4c25c82018-04-04 15:02:55 -0700617static void check_get_group(const char* group_name, gid_t gid, bool check_groupname = true) {
Tom Cherry6b116d12019-04-25 10:34:07 -0700618 SCOPED_TRACE("groupname '"s + group_name + "'");
Tom Cherryb4c25c82018-04-04 15:02:55 -0700619 check_getgrgid(group_name, gid, check_groupname);
620 check_getgrnam(group_name, gid, check_groupname);
621 check_getgrgid_r(group_name, gid, check_groupname);
622 check_getgrnam_r(group_name, gid, check_groupname);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800623}
624
Tom Cherry6b116d12019-04-25 10:34:07 -0700625static void expect_no_group_id(gid_t gid) {
626 SCOPED_TRACE("gid '" + std::to_string(gid) + "'");
627 errno = 0;
628 group* group = nullptr;
629 group = getgrgid(gid);
630 EXPECT_EQ(nullptr, group) << "name = '" << group->gr_name << "'";
Elliott Hughes95646e62023-09-21 14:11:19 -0700631 EXPECT_ERRNO(ENOENT);
Tom Cherry6b116d12019-04-25 10:34:07 -0700632
633 struct group group_storage;
634 char buf[512];
635 EXPECT_EQ(ENOENT, getgrgid_r(gid, &group_storage, buf, sizeof(buf), &group));
636 EXPECT_EQ(nullptr, group) << "name = '" << group->gr_name << "'";
637}
638
639static void expect_no_group_name(const char* groupname) {
640 SCOPED_TRACE("groupname '"s + groupname + "'");
641 errno = 0;
642 group* group = nullptr;
643 group = getgrnam(groupname);
644 EXPECT_EQ(nullptr, group) << "name = '" << group->gr_name << "'";
Elliott Hughes95646e62023-09-21 14:11:19 -0700645 EXPECT_ERRNO(ENOENT);
Tom Cherry6b116d12019-04-25 10:34:07 -0700646
647 struct group group_storage;
648 char buf[512];
649 EXPECT_EQ(ENOENT, getgrnam_r(groupname, &group_storage, buf, sizeof(buf), &group));
650 EXPECT_EQ(nullptr, group) << "name = '" << group->gr_name << "'";
651}
652
Yabin Cuia04c79b2014-11-18 16:14:54 -0800653#else // !defined(__BIONIC__)
654
Tom Cherryb4c25c82018-04-04 15:02:55 -0700655static void check_get_group(const char*, gid_t, bool) {
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800656 GTEST_SKIP() << "bionic-only test";
Tom Cherryb4c25c82018-04-04 15:02:55 -0700657}
658
Yabin Cuic4786d32015-07-20 19:46:26 -0700659static void check_get_group(const char*, gid_t) {
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800660 GTEST_SKIP() << "bionic-only test";
Yabin Cuic4786d32015-07-20 19:46:26 -0700661}
662
Tom Cherry6b116d12019-04-25 10:34:07 -0700663static void expect_no_group_id(gid_t /* gid */) {
664 GTEST_SKIP() << "bionic-only test";
665}
666
667static void expect_no_group_name(const char* /* groupname */) {
668 GTEST_SKIP() << "bionic-only test";
669}
670
Yabin Cuia04c79b2014-11-18 16:14:54 -0800671#endif
672
Tom Cherry6b116d12019-04-25 10:34:07 -0700673TEST(grp, getgrnam_platform_ids) {
Yabin Cuia04c79b2014-11-18 16:14:54 -0800674 check_get_group("root", 0);
Tom Cherry6b116d12019-04-25 10:34:07 -0700675 check_get_group("daemon", 1);
676 check_get_group("bin", 2);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800677
Yabin Cuia04c79b2014-11-18 16:14:54 -0800678 check_get_group("system", 1000);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800679 check_get_group("radio", 1001);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800680
Tom Cherry6b116d12019-04-25 10:34:07 -0700681 check_get_group("shell", 2000);
Jorge Lucangeli Obesa39e3012015-09-22 11:46:43 -0700682
Yabin Cuia04c79b2014-11-18 16:14:54 -0800683 check_get_group("nobody", 9999);
684}
685
Tom Cherry6b116d12019-04-25 10:34:07 -0700686TEST(grp, getgrnam_oem_ids) {
687 check_get_group("oem_2900", 2900, false);
688 check_get_group("oem_2945", 2945, false);
689 check_get_group("oem_2999", 2999, false);
690 check_get_group("oem_5000", 5000, false);
691 check_get_group("oem_5454", 5454, false);
692 check_get_group("oem_5999", 5999, false);
693}
694
695TEST(grp, getgrnam_non_exist) {
696 expect_no_passwd_id(999); // End of the system reserved range, unallocated.
697 expect_no_passwd_id(1999); // End of the system reserved range, unallocated.
698 expect_no_passwd_id(2899); // End of the system reserved range, unallocated.
699}
700
701TEST(grp, getgrnam_u0_app_ids) {
Yabin Cuia04c79b2014-11-18 16:14:54 -0800702 check_get_group("u0_a0", 10000);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800703 check_get_group("u0_a1234", 11234);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800704 check_get_group("u0_a9999", 19999);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800705
Jeff Sharkey934bc862016-12-13 14:03:19 -0700706 check_get_group("u0_a0_cache", 20000);
Jeff Sharkey934bc862016-12-13 14:03:19 -0700707 check_get_group("u0_a1234_cache", 21234);
Jeff Sharkey934bc862016-12-13 14:03:19 -0700708 check_get_group("u0_a9999_cache", 29999);
Jeff Sharkey934bc862016-12-13 14:03:19 -0700709
Tom Cherry6b116d12019-04-25 10:34:07 -0700710 check_get_group("u0_a0_ext", 30000);
711 check_get_group("u0_a4545_ext", 34545);
712 check_get_group("u0_a9999_ext", 39999);
Jeff Sharkey934bc862016-12-13 14:03:19 -0700713
Tom Cherry6b116d12019-04-25 10:34:07 -0700714 check_get_group("u0_a0_ext_cache", 40000);
715 check_get_group("u0_a4545_ext_cache", 44545);
716 check_get_group("u0_a9999_ext_cache", 49999);
717
718 check_get_group("all_a0", 50000);
719 check_get_group("all_a4545", 54545);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800720 check_get_group("all_a9999", 59999);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800721
Martijn Coenenf9d22992019-01-16 16:25:40 +0100722 check_get_group("u0_i1", 90001);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800723}
724
Tom Cherry6b116d12019-04-25 10:34:07 -0700725TEST(grp, getgrnam_u1_app_ids) {
726 check_get_group("u1_system", 101000);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800727 check_get_group("u1_radio", 101001);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800728
Yabin Cuia04c79b2014-11-18 16:14:54 -0800729 check_get_group("u1_a0", 110000);
Tom Cherry6b116d12019-04-25 10:34:07 -0700730 check_get_group("u1_a1234", 111234);
731 check_get_group("u1_a9999", 119999);
732
733 check_get_group("u1_a0_cache", 120000);
734 check_get_group("u1_a1234_cache", 121234);
735 check_get_group("u1_a9999_cache", 129999);
736
737 check_get_group("u1_a0_ext", 130000);
738 check_get_group("u1_a4545_ext", 134545);
739 check_get_group("u1_a9999_ext", 139999);
740
741 check_get_group("u1_a0_ext_cache", 140000);
742 check_get_group("u1_a4545_ext_cache", 144545);
743 check_get_group("u1_a9999_ext_cache", 149999);
744
745 check_get_group("u1_i1", 190001);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800746}
747
Tom Cherry6b116d12019-04-25 10:34:07 -0700748TEST(grp, getgrnam_u31_app_ids) {
749 check_get_group("u31_system", 3101000);
750 check_get_group("u31_radio", 3101001);
751
752 check_get_group("u31_a0", 3110000);
753 check_get_group("u31_a1234", 3111234);
754 check_get_group("u31_a9999", 3119999);
755
756 check_get_group("u31_a0_cache", 3120000);
757 check_get_group("u31_a1234_cache", 3121234);
758 check_get_group("u31_a9999_cache", 3129999);
759
760 check_get_group("u31_a0_cache", 3120000);
761 check_get_group("u31_a1234_cache", 3121234);
762 check_get_group("u31_a9999_cache", 3129999);
763
764 check_get_group("u31_a0_ext", 3130000);
765 check_get_group("u31_a4545_ext", 3134545);
766 check_get_group("u31_a9999_ext", 3139999);
767
768 check_get_group("u31_a0_ext_cache", 3140000);
769 check_get_group("u31_a4545_ext_cache", 3144545);
770 check_get_group("u31_a9999_ext_cache", 3149999);
771
772 check_get_group("u31_i1", 3190001);
Yabin Cuia04c79b2014-11-18 16:14:54 -0800773}
774
Tom Cherry6b116d12019-04-25 10:34:07 -0700775TEST(grp, getpgram_app_id_not_allowed_platform) {
776 expect_no_group_name("u1_root");
777 expect_no_group_name("u1_debuggerd");
778
779 expect_no_group_name("u31_root");
780 expect_no_group_name("u31_debuggerd");
781}
782
783TEST(grp, getgrgid_app_id_u1_non_exist) {
784 expect_no_group_id(100000); // There is no 'root' for secondary users.
785 expect_no_group_id(101999); // End of the system reserved range, unallocated.
786 expect_no_group_id(102900); // The OEM ranges were never allocated to secondary users.
787 expect_no_group_id(105000); // The OEM ranges were never allocated to secondary users.
788
789 // The shared range is shared among users, and therefore doesn't exist for secondary users.
790 expect_no_group_id(150000);
791}
792
793TEST(grp, getgrgid_app_id_u31_non_exist) {
794 expect_no_group_id(3100000); // There is no 'root' for secondary users.
795 expect_no_group_id(3101999); // End of the system reserved range, unallocated.
796 expect_no_group_id(3102900); // The OEM ranges were never allocated to secondary users.
797 expect_no_group_id(3105000); // The OEM ranges were never allocated to secondary users.
798
799 // The shared range is shared among users, and therefore doesn't exist for secondary users.
800 expect_no_group_id(3150000);
Kenny Root2a54e5e2012-09-13 10:52:52 -0700801}
Yabin Cuic4786d32015-07-20 19:46:26 -0700802
Tom Cherryc57c5bd2019-05-14 17:02:28 -0700803TEST(grp, getgrnam_r_alignment) {
804#if defined(__BIONIC__)
805 group grp_storage;
806 alignas(16) char buf[512];
807 group* grp;
808 int result = getgrnam_r("root", &grp_storage, buf + 1, sizeof(buf) - 1, &grp);
809 ASSERT_EQ(0, result);
810 check_group(grp, "root", 0);
811#else
812 GTEST_SKIP() << "bionic-only test";
813#endif
814}
815
816TEST(grp, getgrgid_r_alignment) {
817#if defined(__BIONIC__)
818 group grp_storage;
819 alignas(16) char buf[512];
820 group* grp;
821 int result = getgrgid_r(0, &grp_storage, buf + 1, sizeof(buf) - 1, &grp);
822 ASSERT_EQ(0, result);
823 check_group(grp, "root", 0);
824#else
825 GTEST_SKIP() << "bionic-only test";
826#endif
827}
828
Elliott Hughes5367d1b2016-12-12 17:32:14 -0800829TEST(grp, getgrnam_r_reentrancy) {
Yabin Cuic4786d32015-07-20 19:46:26 -0700830#if defined(__BIONIC__)
831 group grp_storage[2];
832 char buf[2][512];
833 group* grp[3];
834 int result = getgrnam_r("root", &grp_storage[0], buf[0], sizeof(buf[0]), &grp[0]);
835 ASSERT_EQ(0, result);
836 check_group(grp[0], "root", 0);
837 grp[1] = getgrnam("system");
838 check_group(grp[1], "system", 1000);
839 result = getgrnam_r("radio", &grp_storage[1], buf[1], sizeof(buf[1]), &grp[2]);
840 ASSERT_EQ(0, result);
841 check_group(grp[2], "radio", 1001);
842 check_group(grp[0], "root", 0);
843 check_group(grp[1], "system", 1000);
844#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800845 GTEST_SKIP() << "bionic-only test";
Yabin Cuic4786d32015-07-20 19:46:26 -0700846#endif
847}
848
Elliott Hughes5367d1b2016-12-12 17:32:14 -0800849TEST(grp, getgrgid_r_reentrancy) {
Yabin Cuic4786d32015-07-20 19:46:26 -0700850#if defined(__BIONIC__)
851 group grp_storage[2];
852 char buf[2][512];
853 group* grp[3];
854 int result = getgrgid_r(0, &grp_storage[0], buf[0], sizeof(buf[0]), &grp[0]);
855 ASSERT_EQ(0, result);
856 check_group(grp[0], "root", 0);
857 grp[1] = getgrgid(1000);
858 check_group(grp[1], "system", 1000);
859 result = getgrgid_r(1001, &grp_storage[1], buf[1], sizeof(buf[1]), &grp[2]);
860 ASSERT_EQ(0, result);
861 check_group(grp[2], "radio", 1001);
862 check_group(grp[0], "root", 0);
863 check_group(grp[1], "system", 1000);
864#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800865 GTEST_SKIP() << "bionic-only test";
Yabin Cuic4786d32015-07-20 19:46:26 -0700866#endif
867}
868
Elliott Hughes5367d1b2016-12-12 17:32:14 -0800869TEST(grp, getgrnam_r_large_enough_suggested_buffer_size) {
Yabin Cuic4786d32015-07-20 19:46:26 -0700870 long size = sysconf(_SC_GETGR_R_SIZE_MAX);
871 ASSERT_GT(size, 0);
872 char buf[size];
873 group grp_storage;
874 group* grp;
875 ASSERT_EQ(0, getgrnam_r("root", &grp_storage, buf, size, &grp));
876 check_group(grp, "root", 0);
877}
Mark Salyzyn722ab052016-04-06 10:35:48 -0700878
Elliott Hughes5367d1b2016-12-12 17:32:14 -0800879TEST(grp, getgrent_iterate) {
Josh Gao2fe10342018-02-27 14:05:53 -0800880#if defined(__BIONIC__)
Mark Salyzyn722ab052016-04-06 10:35:48 -0700881 group* grp;
Tom Cherry4362f892017-11-14 08:50:43 -0800882 std::set<gid_t> gids;
Mark Salyzyn722ab052016-04-06 10:35:48 -0700883
884 setgrent();
Yi Kong32bc0fc2018-08-02 17:31:13 -0700885 while ((grp = getgrent()) != nullptr) {
886 ASSERT_TRUE(grp->gr_name != nullptr) << "grp->gr_gid: " << grp->gr_gid;
887 ASSERT_TRUE(grp->gr_mem != nullptr) << "grp->gr_gid: " << grp->gr_gid;
Tom Cherry2c05c0f2017-11-10 10:57:21 -0800888 EXPECT_STREQ(grp->gr_name, grp->gr_mem[0]) << "grp->gr_gid: " << grp->gr_gid;
Yi Kong32bc0fc2018-08-02 17:31:13 -0700889 EXPECT_TRUE(grp->gr_mem[1] == nullptr) << "grp->gr_gid: " << grp->gr_gid;
Tom Cherry4362f892017-11-14 08:50:43 -0800890
Tom Cherry0816c902020-04-10 13:00:42 -0700891 EXPECT_EQ(0U, gids.count(grp->gr_gid)) << "grp->gr_gid: " << grp->gr_gid;
Tom Cherry4362f892017-11-14 08:50:43 -0800892 gids.emplace(grp->gr_gid);
Mark Salyzyn722ab052016-04-06 10:35:48 -0700893 }
894 endgrent();
895
Tom Cherry6b116d12019-04-25 10:34:07 -0700896 expect_ids(gids, true);
Josh Gao2fe10342018-02-27 14:05:53 -0800897#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800898 GTEST_SKIP() << "bionic-only test";
Josh Gao2fe10342018-02-27 14:05:53 -0800899#endif
Mark Salyzyn722ab052016-04-06 10:35:48 -0700900}
Tom Cherrye88b4082018-05-24 14:44:10 -0700901
Elliott Hughes7cebf832020-08-12 14:25:41 -0700902TEST(grp, getgrouplist) {
903#if defined(__BIONIC__)
904 // Query the number of groups.
905 int ngroups = 0;
906 ASSERT_EQ(-1, getgrouplist("root", 123, nullptr, &ngroups));
907 ASSERT_EQ(1, ngroups);
908
909 // Query the specific groups (just the one you pass in on Android).
910 ngroups = 8;
911 gid_t groups[ngroups];
912 ASSERT_EQ(1, getgrouplist("root", 123, groups, &ngroups));
913 ASSERT_EQ(1, ngroups);
914 ASSERT_EQ(123u, groups[0]);
915#else
916 GTEST_SKIP() << "bionic-only test (groups too unpredictable)";
917#endif
918}
919
Elliott Hughes6a458842024-02-14 17:10:54 -0800920TEST(grp, initgroups) {
921 if (getuid() != 0) GTEST_SKIP() << "test requires root";
922 ASSERT_EQ(0, initgroups("root", 0));
923}
924
Tom Cherrye88b4082018-05-24 14:44:10 -0700925#if defined(__BIONIC__)
926static void TestAidNamePrefix(const std::string& file_path) {
927 std::string file_contents;
928 if (!ReadFileToString(file_path, &file_contents)) {
929 // If we cannot read this file, then there are no vendor defind AID names, in which case this
930 // test passes by default.
931 return;
932 }
933 auto lines = Split(file_contents, "\n");
934 for (const auto& line : lines) {
935 if (line.empty()) continue;
936 auto name = Split(line, ":")[0];
937 EXPECT_TRUE(StartsWith(name, "vendor_"));
938 }
939}
940#endif
941
942TEST(pwd, vendor_prefix_users) {
943#if defined(__BIONIC__)
Chuwei Xu5d9312b2018-10-23 13:50:04 +0800944 if (android::base::GetIntProperty("ro.product.first_api_level", 0) <= 28) {
945 return;
946 }
947
Tom Cherrye88b4082018-05-24 14:44:10 -0700948 TestAidNamePrefix("/vendor/etc/passwd");
949#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800950 GTEST_SKIP() << "bionic-only test";
Tom Cherrye88b4082018-05-24 14:44:10 -0700951#endif
952}
953
954TEST(pwd, vendor_prefix_groups) {
955#if defined(__BIONIC__)
Chuwei Xu5d9312b2018-10-23 13:50:04 +0800956 if (android::base::GetIntProperty("ro.product.first_api_level", 0) <= 28) {
957 return;
958 }
959
Tom Cherrye88b4082018-05-24 14:44:10 -0700960 TestAidNamePrefix("/vendor/etc/group");
961#else
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800962 GTEST_SKIP() << "bionic-only test";
Tom Cherrye88b4082018-05-24 14:44:10 -0700963#endif
964}