Merge "Load /etc/{passwd,group} from all partitions"
This commit is contained in:
commit
5a8482ef8f
4 changed files with 78 additions and 27 deletions
|
@ -50,8 +50,21 @@
|
|||
#include "generated_android_ids.h"
|
||||
#include "grp_pwd_file.h"
|
||||
|
||||
static PasswdFile vendor_passwd("/vendor/etc/passwd", "vendor_");
|
||||
static GroupFile vendor_group("/vendor/etc/group", "vendor_");
|
||||
static PasswdFile passwd_files[] = {
|
||||
{ "/system/etc/passwd", "system_" },
|
||||
{ "/vendor/etc/passwd", "vendor_" },
|
||||
{ "/odm/etc/passwd", "odm_" },
|
||||
{ "/product/etc/passwd", "product_" },
|
||||
{ "/system_ext/etc/passwd", "system_ext_" },
|
||||
};
|
||||
|
||||
static GroupFile group_files[] = {
|
||||
{ "/system/etc/group", "system_" },
|
||||
{ "/vendor/etc/group", "vendor_" },
|
||||
{ "/odm/etc/group", "odm_" },
|
||||
{ "/product/etc/group", "product_" },
|
||||
{ "/system_ext/etc/group", "system_ext_" },
|
||||
};
|
||||
|
||||
// POSIX seems to envisage an implementation where the <pwd.h> functions are
|
||||
// implemented by brute-force searching with getpwent(3), and the <grp.h>
|
||||
|
@ -91,7 +104,7 @@ static passwd* android_iinfo_to_passwd(passwd_state_t* state,
|
|||
const android_id_info* iinfo) {
|
||||
snprintf(state->name_buffer_, sizeof(state->name_buffer_), "%s", iinfo->name);
|
||||
snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
|
||||
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
|
||||
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/bin/sh");
|
||||
|
||||
passwd* pw = &state->passwd_;
|
||||
pw->pw_uid = iinfo->aid;
|
||||
|
@ -421,17 +434,19 @@ static id_t oem_id_from_name(const char* name) {
|
|||
}
|
||||
|
||||
static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) {
|
||||
for (auto& passwd_file : passwd_files) {
|
||||
if (passwd_file.FindById(uid, state)) {
|
||||
return &state->passwd_;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_oem_id(uid)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (vendor_passwd.FindById(uid, state)) {
|
||||
return &state->passwd_;
|
||||
}
|
||||
|
||||
snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u", uid);
|
||||
snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
|
||||
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/vendor/bin/sh");
|
||||
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/bin/sh");
|
||||
|
||||
passwd* pw = &state->passwd_;
|
||||
pw->pw_uid = uid;
|
||||
|
@ -440,12 +455,14 @@ static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) {
|
|||
}
|
||||
|
||||
static group* oem_id_to_group(gid_t gid, group_state_t* state) {
|
||||
if (!is_oem_id(gid)) {
|
||||
return nullptr;
|
||||
for (auto& group_file : group_files) {
|
||||
if (group_file.FindById(gid, state)) {
|
||||
return &state->group_;
|
||||
}
|
||||
}
|
||||
|
||||
if (vendor_group.FindById(gid, state)) {
|
||||
return &state->group_;
|
||||
if (!is_oem_id(gid)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
snprintf(state->group_name_buffer_, sizeof(state->group_name_buffer_),
|
||||
|
@ -477,7 +494,7 @@ static passwd* app_id_to_passwd(uid_t uid, passwd_state_t* state) {
|
|||
snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/data");
|
||||
}
|
||||
|
||||
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
|
||||
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/bin/sh");
|
||||
|
||||
passwd* pw = &state->passwd_;
|
||||
pw->pw_uid = uid;
|
||||
|
@ -523,8 +540,8 @@ passwd* getpwnam_internal(const char* login, passwd_state_t* state) {
|
|||
return android_iinfo_to_passwd(state, android_id_info);
|
||||
}
|
||||
|
||||
if (vendor_passwd.FindByName(login, state)) {
|
||||
if (is_oem_id(state->passwd_.pw_uid)) {
|
||||
for (auto& passwd_file : passwd_files) {
|
||||
if (passwd_file.FindByName(login, state)) {
|
||||
return &state->passwd_;
|
||||
}
|
||||
}
|
||||
|
@ -633,6 +650,22 @@ passwd* getpwent() {
|
|||
state->getpwent_idx++ - start + AID_OEM_RESERVED_2_START, state);
|
||||
}
|
||||
|
||||
start = end;
|
||||
end += AID_SYSTEM_EXT_RESERVED_END - AID_SYSTEM_RESERVED_START + 1;
|
||||
|
||||
if (state->getpwent_idx < end) {
|
||||
// No one calls this enough to worry about how inefficient the below is.
|
||||
auto* oem_passwd =
|
||||
oem_id_to_passwd(state->getpwent_idx++ - start + AID_SYSTEM_RESERVED_START, state);
|
||||
while (oem_passwd == nullptr && state->getpwent_idx < end) {
|
||||
oem_passwd =
|
||||
oem_id_to_passwd(state->getpwent_idx++ - start + AID_SYSTEM_RESERVED_START, state);
|
||||
}
|
||||
if (oem_passwd != nullptr) {
|
||||
return oem_passwd;
|
||||
}
|
||||
}
|
||||
|
||||
state->getpwent_idx = get_next_app_id(state->getpwent_idx, false);
|
||||
|
||||
if (state->getpwent_idx != -1) {
|
||||
|
@ -666,8 +699,8 @@ static group* getgrnam_internal(const char* name, group_state_t* state) {
|
|||
return android_iinfo_to_group(state, android_id_info);
|
||||
}
|
||||
|
||||
if (vendor_group.FindByName(name, state)) {
|
||||
if (is_oem_id(state->group_.gr_gid)) {
|
||||
for (auto& group_file : group_files) {
|
||||
if (group_file.FindByName(name, state)) {
|
||||
return &state->group_;
|
||||
}
|
||||
}
|
||||
|
@ -753,6 +786,22 @@ group* getgrent() {
|
|||
state->getgrent_idx++ - start + AID_OEM_RESERVED_2_START, state);
|
||||
}
|
||||
|
||||
start = end;
|
||||
end += AID_SYSTEM_EXT_RESERVED_END - AID_SYSTEM_RESERVED_START + 1;
|
||||
|
||||
if (state->getgrent_idx < end) {
|
||||
// No one calls this enough to worry about how inefficient the below is.
|
||||
init_group_state(state);
|
||||
auto* oem_group =
|
||||
oem_id_to_group(state->getgrent_idx++ - start + AID_SYSTEM_RESERVED_START, state);
|
||||
while (oem_group == nullptr && state->getgrent_idx < end) {
|
||||
oem_group = oem_id_to_group(state->getgrent_idx++ - start + AID_SYSTEM_RESERVED_START, state);
|
||||
}
|
||||
if (oem_group != nullptr) {
|
||||
return oem_group;
|
||||
}
|
||||
}
|
||||
|
||||
start = end;
|
||||
end += AID_USER_OFFSET - AID_APP_START; // Do not expose higher groups
|
||||
|
||||
|
|
|
@ -270,8 +270,8 @@ bool MmapFile::Find(Line* line, Predicate predicate) {
|
|||
|
||||
while (line_beginning < end) {
|
||||
line_beginning = ParseLine(line_beginning, end, line->fields, line->kNumFields);
|
||||
// To comply with Treble, users/groups from the vendor partition need to be prefixed with
|
||||
// vendor_.
|
||||
// To comply with Treble, users/groups from each partition need to be prefixed with
|
||||
// the partition name.
|
||||
if (required_prefix_ != nullptr) {
|
||||
if (strncmp(line->fields[0], required_prefix_, strlen(required_prefix_)) != 0) {
|
||||
char name[kGrpPwdBufferSize];
|
||||
|
|
|
@ -176,8 +176,6 @@ __p_type.typebuf
|
|||
__sym_ntop.unname
|
||||
__sym_ntos.unname
|
||||
_ZL10gFunctions
|
||||
_ZL12vendor_group
|
||||
_ZL13vendor_passwd
|
||||
freelist
|
||||
__p_option.nbuf
|
||||
__p_time.nbuf
|
||||
|
|
|
@ -75,11 +75,7 @@ static void check_passwd(const passwd* pwd, const char* username, uid_t uid, uid
|
|||
EXPECT_STREQ("/", pwd->pw_dir);
|
||||
}
|
||||
|
||||
if (uid_type == TYPE_VENDOR) {
|
||||
EXPECT_STREQ("/vendor/bin/sh", pwd->pw_shell);
|
||||
} else {
|
||||
EXPECT_STREQ("/system/bin/sh", pwd->pw_shell);
|
||||
}
|
||||
EXPECT_STREQ("/bin/sh", pwd->pw_shell);
|
||||
}
|
||||
|
||||
static void check_getpwuid(const char* username, uid_t uid, uid_type_t uid_type,
|
||||
|
@ -382,7 +378,7 @@ TEST(pwd, getpwnam_r_large_enough_suggested_buffer_size) {
|
|||
|
||||
#if defined(__BIONIC__)
|
||||
template <typename T>
|
||||
static void expect_ids(const T& ids, bool is_group) {
|
||||
static void expect_ids(T ids, bool is_group) {
|
||||
std::set<typename T::key_type> expected_ids;
|
||||
// Ensure that all android_ids are iterated through.
|
||||
for (size_t n = 0; n < android_id_count; ++n) {
|
||||
|
@ -415,6 +411,14 @@ static void expect_ids(const T& ids, bool is_group) {
|
|||
return;
|
||||
}
|
||||
|
||||
auto allow_range = [&ids](uid_t start, uid_t end) {
|
||||
for (size_t n = start; n <= end; ++n) {
|
||||
ids.erase(n);
|
||||
}
|
||||
};
|
||||
|
||||
allow_range(AID_SYSTEM_RESERVED_START, AID_SYSTEM_EXT_RESERVED_END);
|
||||
|
||||
// Ensure that no other ids were returned.
|
||||
auto return_differences = [&ids, &expected_ids] {
|
||||
std::vector<typename T::key_type> missing_from_ids;
|
||||
|
|
Loading…
Reference in a new issue