From 31525f5cb659a51194a7e4710528e54ff91444d8 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Wed, 9 May 2018 18:33:31 -0700 Subject: [PATCH] init: implement getpwnam for host init verifier Bug: 36970783 Test: test bullhead successfully at TOT Test: create errors and check that they're caught Test: create uid in passwd and check that it's successful Change-Id: I237fb8df16a294757fe898bdbbd42e850bcb8301 --- init/Android.bp | 5 ++- init/host_init_verifier.cpp | 80 ++++++++++++++++++++++++++++++++----- 2 files changed, 74 insertions(+), 11 deletions(-) diff --git a/init/Android.bp b/init/Android.bp index f579647a8..25877c083 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -250,7 +250,10 @@ cc_binary { proto: { type: "lite", }, - generated_headers: ["generated_stub_builtin_function_map"], + generated_headers: [ + "generated_stub_builtin_function_map", + "generated_android_ids" + ], target: { android: { enabled: false, diff --git a/init/host_init_verifier.cpp b/init/host_init_verifier.cpp index c6ec078df..d6884af91 100644 --- a/init/host_init_verifier.cpp +++ b/init/host_init_verifier.cpp @@ -14,12 +14,17 @@ // limitations under the License. // +#include #include +#include #include #include +#include +#include #include +#include #include #include "action.h" @@ -31,21 +36,74 @@ #include "result.h" #include "service.h" +#define EXCLUDE_FS_CONFIG_STRUCTURES +#include "generated_android_ids.h" + using namespace std::literals; +using android::base::ParseInt; +using android::base::ReadFileToString; using android::base::Split; -// The host passwd file won't have the Android entries, so we fake success here. +static std::string out_dir; + +static std::vector> GetVendorPasswd() { + std::string passwd; + if (!ReadFileToString(out_dir + "/vendor/etc/passwd", &passwd)) { + return {}; + } + + std::vector> result; + auto passwd_lines = Split(passwd, "\n"); + for (const auto& line : passwd_lines) { + auto split_line = Split(line, ":"); + if (split_line.size() < 3) { + continue; + } + int uid = 0; + if (!ParseInt(split_line[2], &uid)) { + continue; + } + result.emplace_back(split_line[0], uid); + } + return result; +} + passwd* getpwnam(const char* login) { // NOLINT: implementing bad function. - char dummy_buf[] = "dummy"; - static passwd dummy_passwd = { - .pw_name = dummy_buf, - .pw_dir = dummy_buf, - .pw_shell = dummy_buf, - .pw_uid = 123, - .pw_gid = 123, + // This isn't thread safe, but that's okay for our purposes. + static char static_name[32] = ""; + static char static_dir[32] = "/"; + static char static_shell[32] = "/system/bin/sh"; + static passwd static_passwd = { + .pw_name = static_name, + .pw_dir = static_dir, + .pw_shell = static_shell, + .pw_uid = 0, + .pw_gid = 0, }; - return &dummy_passwd; + + for (size_t n = 0; n < android_id_count; ++n) { + if (!strcmp(android_ids[n].name, login)) { + snprintf(static_name, sizeof(static_name), "%s", android_ids[n].name); + static_passwd.pw_uid = android_ids[n].aid; + static_passwd.pw_gid = android_ids[n].aid; + return &static_passwd; + } + } + + static const auto vendor_passwd = GetVendorPasswd(); + + for (const auto& [name, uid] : vendor_passwd) { + if (name == login) { + snprintf(static_name, sizeof(static_name), "%s", name.c_str()); + static_passwd.pw_uid = uid; + static_passwd.pw_gid = uid; + return &static_passwd; + } + } + + errno = ENOENT; + return nullptr; } namespace android { @@ -65,6 +123,8 @@ int main(int argc, char** argv) { return -1; } + out_dir = argv[1]; + auto properties = Split(argv[2], ","); for (const auto& property : properties) { auto split_property = Split(property, "="); @@ -81,7 +141,7 @@ int main(int argc, char** argv) { Parser parser; parser.AddSectionParser("service", std::make_unique(&sl, nullptr)); parser.AddSectionParser("on", std::make_unique(&am, nullptr)); - parser.AddSectionParser("import", std::make_unique(argv[1], &parser)); + parser.AddSectionParser("import", std::make_unique(out_dir, &parser)); if (!parser.ParseConfig(argv[1] + "/root/init.rc"s)) { LOG(ERROR) << "Failed to find root init.rc script";