aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Cherry <tomcherry@google.com>2018-05-16 21:03:53 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2018-05-16 21:03:53 +0000
commit7b405f8b983fe43401fa9f6c75671b73203b71b0 (patch)
tree5ae868a248df36213ce8a0490bf2632c1861aafd
parent3962060761667f6aa59e73d09870be091d5d0db7 (diff)
parentf64d31c875dc27054b25023a2b5069ddfeff8da7 (diff)
downloadbionic-7b405f8b983fe43401fa9f6c75671b73203b71b0.tar.gz
Merge "Require vendor users and groups to start with vendor_" into pi-dev
-rw-r--r--libc/bionic/grp_pwd.cpp4
-rw-r--r--libc/bionic/grp_pwd_file.cpp24
-rw-r--r--libc/bionic/grp_pwd_file.h7
-rw-r--r--libc/private/grp_pwd.h10
-rw-r--r--tests/grp_pwd_file_test.cpp52
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__
+}