diff options
author | Tom Cherry <tomcherry@google.com> | 2018-05-16 21:03:53 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-05-16 21:03:53 +0000 |
commit | 7b405f8b983fe43401fa9f6c75671b73203b71b0 (patch) | |
tree | 5ae868a248df36213ce8a0490bf2632c1861aafd | |
parent | 3962060761667f6aa59e73d09870be091d5d0db7 (diff) | |
parent | f64d31c875dc27054b25023a2b5069ddfeff8da7 (diff) | |
download | bionic-7b405f8b983fe43401fa9f6c75671b73203b71b0.tar.gz |
Merge "Require vendor users and groups to start with vendor_" into pi-dev
-rw-r--r-- | libc/bionic/grp_pwd.cpp | 4 | ||||
-rw-r--r-- | libc/bionic/grp_pwd_file.cpp | 24 | ||||
-rw-r--r-- | libc/bionic/grp_pwd_file.h | 7 | ||||
-rw-r--r-- | libc/private/grp_pwd.h | 10 | ||||
-rw-r--r-- | tests/grp_pwd_file_test.cpp | 52 |
5 files changed, 81 insertions, 16 deletions
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp index 952058fef..1de8fc5ea 100644 --- a/libc/bionic/grp_pwd.cpp +++ b/libc/bionic/grp_pwd.cpp @@ -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> diff --git a/libc/bionic/grp_pwd_file.cpp b/libc/bionic/grp_pwd_file.cpp index 37493a7a7..d19b41eae 100644 --- a/libc/bionic/grp_pwd_file.cpp +++ b/libc/bionic/grp_pwd_file.cpp @@ -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) { diff --git a/libc/bionic/grp_pwd_file.h b/libc/bionic/grp_pwd_file.h index 048cd82d0..29d75f4d8 100644 --- a/libc/bionic/grp_pwd_file.h +++ b/libc/bionic/grp_pwd_file.h @@ -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); diff --git a/libc/private/grp_pwd.h b/libc/private/grp_pwd.h index e1aff4f9e..ab7958683 100644 --- a/libc/private/grp_pwd.h +++ b/libc/private/grp_pwd.h @@ -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; }; diff --git a/tests/grp_pwd_file_test.cpp b/tests/grp_pwd_file_test.cpp index d6f3c9f3f..872180565 100644 --- a/tests/grp_pwd_file_test.cpp +++ b/tests/grp_pwd_file_test.cpp @@ -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__ +} |