Merge "Require vendor users and groups to start with vendor_"
This commit is contained in:
commit
903e5702f4
5 changed files with 81 additions and 16 deletions
|
@ -46,8 +46,8 @@
|
|||
#include "generated_android_ids.h"
|
||||
#include "grp_pwd_file.h"
|
||||
|
||||
static PasswdFile vendor_passwd("/vendor/etc/passwd");
|
||||
static GroupFile vendor_group("/vendor/etc/group");
|
||||
static PasswdFile vendor_passwd("/vendor/etc/passwd", "vendor_");
|
||||
static GroupFile vendor_group("/vendor/etc/group", "vendor_");
|
||||
|
||||
// POSIX seems to envisage an implementation where the <pwd.h> functions are
|
||||
// implemented by brute-force searching with getpwent(3), and the <grp.h>
|
||||
|
|
|
@ -30,9 +30,12 @@
|
|||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <async_safe/log.h>
|
||||
|
||||
#include "private/ErrnoRestorer.h"
|
||||
|
||||
// This file mmap's /*/etc/passwd and /*/etc/group in order to return their contents without any
|
||||
|
@ -189,7 +192,8 @@ struct GroupLine {
|
|||
|
||||
} // namespace
|
||||
|
||||
MmapFile::MmapFile(const char* filename) : filename_(filename) {
|
||||
MmapFile::MmapFile(const char* filename, const char* required_prefix)
|
||||
: filename_(filename), required_prefix_(required_prefix) {
|
||||
lock_.init(false);
|
||||
}
|
||||
|
||||
|
@ -266,6 +270,18 @@ 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_.
|
||||
if (required_prefix_ != nullptr) {
|
||||
if (strncmp(line->fields[0], required_prefix_, strlen(required_prefix_)) != 0) {
|
||||
char name[kGrpPwdBufferSize];
|
||||
CopyFieldToString(name, line->fields[0], sizeof(name));
|
||||
async_safe_format_log(ANDROID_LOG_ERROR, "libc",
|
||||
"Found user/group name '%s' in '%s' without required prefix '%s'",
|
||||
name, filename_, required_prefix_);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (predicate(line)) return true;
|
||||
}
|
||||
|
||||
|
@ -303,7 +319,8 @@ bool MmapFile::FindByName(const char* name, Line* line) {
|
|||
});
|
||||
}
|
||||
|
||||
PasswdFile::PasswdFile(const char* filename) : mmap_file_(filename) {
|
||||
PasswdFile::PasswdFile(const char* filename, const char* required_prefix)
|
||||
: mmap_file_(filename, required_prefix) {
|
||||
}
|
||||
|
||||
bool PasswdFile::FindById(uid_t id, passwd_state_t* passwd_state) {
|
||||
|
@ -318,7 +335,8 @@ bool PasswdFile::FindByName(const char* name, passwd_state_t* passwd_state) {
|
|||
return mmap_file_.FindByName(name, &passwd_line) && passwd_line.ToPasswdState(passwd_state);
|
||||
}
|
||||
|
||||
GroupFile::GroupFile(const char* filename) : mmap_file_(filename) {
|
||||
GroupFile::GroupFile(const char* filename, const char* required_prefix)
|
||||
: mmap_file_(filename, required_prefix) {
|
||||
}
|
||||
|
||||
bool GroupFile::FindById(gid_t id, group_state_t* group_state) {
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
class MmapFile {
|
||||
public:
|
||||
MmapFile(const char* filename);
|
||||
MmapFile(const char* filename, const char* required_prefix);
|
||||
|
||||
template <typename Line>
|
||||
bool FindById(uid_t uid, Line* line);
|
||||
|
@ -65,11 +65,12 @@ class MmapFile {
|
|||
const char* filename_ = nullptr;
|
||||
const char* start_ = nullptr;
|
||||
const char* end_ = nullptr;
|
||||
const char* required_prefix_;
|
||||
};
|
||||
|
||||
class PasswdFile {
|
||||
public:
|
||||
PasswdFile(const char* filename);
|
||||
PasswdFile(const char* filename, const char* required_prefix);
|
||||
|
||||
bool FindById(uid_t id, passwd_state_t* passwd_state);
|
||||
bool FindByName(const char* name, passwd_state_t* passwd_state);
|
||||
|
@ -85,7 +86,7 @@ class PasswdFile {
|
|||
|
||||
class GroupFile {
|
||||
public:
|
||||
GroupFile(const char* filename);
|
||||
GroupFile(const char* filename, const char* required_prefix);
|
||||
|
||||
bool FindById(gid_t id, group_state_t* group_state);
|
||||
bool FindByName(const char* name, group_state_t* group_state);
|
||||
|
|
|
@ -31,18 +31,20 @@
|
|||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
|
||||
static constexpr size_t kGrpPwdBufferSize = 32;
|
||||
|
||||
struct group_state_t {
|
||||
group group_;
|
||||
char* group_members_[2];
|
||||
char group_name_buffer_[32];
|
||||
char group_name_buffer_[kGrpPwdBufferSize];
|
||||
// Must be last so init_group_state can run a simple memset for the above
|
||||
ssize_t getgrent_idx;
|
||||
};
|
||||
|
||||
struct passwd_state_t {
|
||||
passwd passwd_;
|
||||
char name_buffer_[32];
|
||||
char dir_buffer_[32];
|
||||
char sh_buffer_[32];
|
||||
char name_buffer_[kGrpPwdBufferSize];
|
||||
char dir_buffer_[kGrpPwdBufferSize];
|
||||
char sh_buffer_[kGrpPwdBufferSize];
|
||||
ssize_t getpwent_idx;
|
||||
};
|
||||
|
|
|
@ -94,7 +94,7 @@ TEST(grp_pwd_file, passwd_file_one_entry) {
|
|||
static const char test_string[] = "name:password:1:2:user_info:dir:shell\n";
|
||||
write(file.fd, test_string, sizeof(test_string) - 1);
|
||||
|
||||
PasswdFile passwd_file(file.filename);
|
||||
PasswdFile passwd_file(file.filename, nullptr);
|
||||
FileUnmapper unmapper(passwd_file);
|
||||
|
||||
FindAndCheckPasswdEntry(&passwd_file, "name", 1, 2, "dir", "shell");
|
||||
|
@ -114,7 +114,7 @@ TEST(grp_pwd_file, group_file_one_entry) {
|
|||
static const char test_string[] = "name:password:1:one,two,three\n";
|
||||
write(file.fd, test_string, sizeof(test_string) - 1);
|
||||
|
||||
GroupFile group_file(file.filename);
|
||||
GroupFile group_file(file.filename, nullptr);
|
||||
FileUnmapper unmapper(group_file);
|
||||
|
||||
FindAndCheckGroupEntry(&group_file, "name", 1);
|
||||
|
@ -150,7 +150,7 @@ TEST(grp_pwd_file, passwd_file_many_entries) {
|
|||
|
||||
write(file.fd, test_string, sizeof(test_string) - 1);
|
||||
|
||||
PasswdFile passwd_file(file.filename);
|
||||
PasswdFile passwd_file(file.filename, nullptr);
|
||||
FileUnmapper unmapper(passwd_file);
|
||||
|
||||
FindAndCheckPasswdEntry(&passwd_file, "first", 1, 2, "dir", "shell");
|
||||
|
@ -186,7 +186,7 @@ TEST(grp_pwd_file, group_file_many_entries) {
|
|||
|
||||
write(file.fd, test_string, sizeof(test_string) - 1);
|
||||
|
||||
GroupFile group_file(file.filename);
|
||||
GroupFile group_file(file.filename, nullptr);
|
||||
FileUnmapper unmapper(group_file);
|
||||
|
||||
FindAndCheckGroupEntry(&group_file, "first", 1);
|
||||
|
@ -200,3 +200,47 @@ TEST(grp_pwd_file, group_file_many_entries) {
|
|||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
#endif // __BIONIC__
|
||||
}
|
||||
|
||||
TEST(grp_pwd_file, passwd_file_required_prefix) {
|
||||
#if defined(__BIONIC__)
|
||||
TemporaryFile file;
|
||||
ASSERT_NE(-1, file.fd);
|
||||
static const char test_string[] =
|
||||
"name:password:1:2:user_info:dir:shell\n"
|
||||
"vendor_name:password:3:4:user_info:dir:shell\n";
|
||||
write(file.fd, test_string, sizeof(test_string) - 1);
|
||||
|
||||
PasswdFile passwd_file(file.filename, "vendor_");
|
||||
FileUnmapper unmapper(passwd_file);
|
||||
|
||||
EXPECT_FALSE(passwd_file.FindByName("name", nullptr));
|
||||
EXPECT_FALSE(passwd_file.FindById(1, nullptr));
|
||||
|
||||
FindAndCheckPasswdEntry(&passwd_file, "vendor_name", 3, 4, "dir", "shell");
|
||||
|
||||
#else // __BIONIC__
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
#endif // __BIONIC__
|
||||
}
|
||||
|
||||
TEST(grp_pwd_file, group_file_required_prefix) {
|
||||
#if defined(__BIONIC__)
|
||||
TemporaryFile file;
|
||||
ASSERT_NE(-1, file.fd);
|
||||
static const char test_string[] =
|
||||
"name:password:1:one,two,three\n"
|
||||
"vendor_name:password:2:one,two,three\n";
|
||||
write(file.fd, test_string, sizeof(test_string) - 1);
|
||||
|
||||
GroupFile group_file(file.filename, "vendor_");
|
||||
FileUnmapper unmapper(group_file);
|
||||
|
||||
EXPECT_FALSE(group_file.FindByName("name", nullptr));
|
||||
EXPECT_FALSE(group_file.FindById(1, nullptr));
|
||||
|
||||
FindAndCheckGroupEntry(&group_file, "vendor_name", 2);
|
||||
|
||||
#else // __BIONIC__
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
#endif // __BIONIC__
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue