From 40acb379cdac2e71b888bfa22bdcb409aa2753b1 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Wed, 1 Aug 2018 13:41:12 -0700 Subject: [PATCH] Move watchdogd out of init We're moving past a world where static executables are needed, including watchdogd, so treat this like any other executable and place it in /system/bin. Bug: 73660730 Test: watchdogd still runs Change-Id: I1f7508fd55dce6e9ee72a6ab7a085011a76c0053 --- init/Android.bp | 2 -- init/Android.mk | 1 - init/devices.cpp | 2 +- init/host_init_stubs.cpp | 5 ++--- init/host_init_stubs.h | 5 ++++- init/init.cpp | 5 ----- init/init.h | 4 ++-- init/property_service.cpp | 3 ++- init/selinux.cpp | 21 ++++++++++----------- init/selinux.h | 2 +- init/service.cpp | 9 +++++++++ init/subcontext.cpp | 3 ++- init/util.cpp | 2 +- init/watchdogd.h | 28 ---------------------------- watchdogd/Android.bp | 14 ++++++++++++++ {init => watchdogd}/watchdogd.cpp | 19 ++++--------------- 16 files changed, 52 insertions(+), 73 deletions(-) delete mode 100644 init/watchdogd.h create mode 100644 watchdogd/Android.bp rename {init => watchdogd}/watchdogd.cpp (80%) diff --git a/init/Android.bp b/init/Android.bp index 660d58676..a93bb66af 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -127,7 +127,6 @@ cc_library_static { "ueventd.cpp", "ueventd_parser.cpp", "util.cpp", - "watchdogd.cpp", ], whole_static_libs: ["libcap"], header_libs: ["bootimg_headers"], @@ -157,7 +156,6 @@ cc_binary { srcs: ["main.cpp"], symlinks: [ "sbin/ueventd", - "sbin/watchdogd", ], } */ diff --git a/init/Android.mk b/init/Android.mk index d0cb820b5..9d9d368b7 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -98,7 +98,6 @@ LOCAL_REQUIRED_MODULES := \ # Create symlinks. LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \ ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \ - ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd LOCAL_SANITIZE := signed-integer-overflow include $(BUILD_EXECUTABLE) diff --git a/init/devices.cpp b/init/devices.cpp index ed4a7398a..108a67fc5 100644 --- a/init/devices.cpp +++ b/init/devices.cpp @@ -34,7 +34,7 @@ #include "util.h" #ifdef _INIT_INIT_H -#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals" +#error "Do not include init.h in files used by ueventd; it will expose init's globals" #endif using android::base::Basename; diff --git a/init/host_init_stubs.cpp b/init/host_init_stubs.cpp index 2352fc733..8866bdcd6 100644 --- a/init/host_init_stubs.cpp +++ b/init/host_init_stubs.cpp @@ -41,10 +41,9 @@ uint32_t HandlePropertySet(const std::string&, const std::string&, const std::st } // selinux.h -bool SelinuxHasVendorInit() { - return true; +int SelinuxGetVendorAndroidVersion() { + return 10000; } - void SelabelInitialize() {} bool SelabelLookupFileContext(const std::string& key, int type, std::string* result) { diff --git a/init/host_init_stubs.h b/init/host_init_stubs.h index f0e1f0729..0af11f667 100644 --- a/init/host_init_stubs.h +++ b/init/host_init_stubs.h @@ -23,6 +23,9 @@ #include +// android/api-level.h +#define __ANDROID_API_P__ 28 + // sys/system_properties.h #define PROP_VALUE_MAX 92 @@ -41,7 +44,7 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value, const std::string& source_context, const ucred& cr, std::string* error); // selinux.h -bool SelinuxHasVendorInit(); +int SelinuxGetVendorAndroidVersion(); void SelabelInitialize(); bool SelabelLookupFileContext(const std::string& key, int type, std::string* result); diff --git a/init/init.cpp b/init/init.cpp index 73194bdd9..a93d31665 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -58,7 +58,6 @@ #include "sigchld_handler.h" #include "ueventd.h" #include "util.h" -#include "watchdogd.h" using namespace std::chrono_literals; using namespace std::string_literals; @@ -617,10 +616,6 @@ int main(int argc, char** argv) { return ueventd_main(argc, argv); } - if (!strcmp(basename(argv[0]), "watchdogd")) { - return watchdogd_main(argc, argv); - } - if (argc > 1 && !strcmp(argv[1], "subcontext")) { android::base::InitLogging(argv, &android::base::KernelLogger); const BuiltinFunctionMap function_map; diff --git a/init/init.h b/init/init.h index 6c82fa12c..f244ad7fe 100644 --- a/init/init.h +++ b/init/init.h @@ -31,8 +31,8 @@ namespace android { namespace init { -// Note: These globals are *only* valid in init, so they should not be used in ueventd, -// watchdogd, or any files that may be included in those, such as devices.cpp and util.cpp. +// Note: These globals are *only* valid in init, so they should not be used in ueventd +// or any files that may be included in ueventd, such as devices.cpp and util.cpp. // TODO: Have an Init class and remove all globals. extern std::string default_console; extern std::vector late_import_paths; diff --git a/init/property_service.cpp b/init/property_service.cpp index c0d811fc6..cd2f630ca 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -16,6 +16,7 @@ #include "property_service.h" +#include #include #include #include @@ -576,7 +577,7 @@ static void LoadProperties(char* data, const char* filter, const char* filename) size_t flen = 0; const char* context = kInitContext.c_str(); - if (SelinuxHasVendorInit()) { + if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_P__) { for (const auto& [path_prefix, secontext] : paths_and_secontexts) { if (StartsWith(filename, path_prefix)) { context = secontext; diff --git a/init/selinux.cpp b/init/selinux.cpp index 94f206ede..1adf523b3 100644 --- a/init/selinux.cpp +++ b/init/selinux.cpp @@ -47,6 +47,7 @@ #include "selinux.h" +#include #include #include #include @@ -470,29 +471,27 @@ void SelinuxSetupKernelLogging() { selinux_set_callback(SELINUX_CB_LOG, cb); } -// This function checks whether the sepolicy supports vendor init. -bool SelinuxHasVendorInit() { +// This function returns the Android version with which the vendor SEPolicy was compiled. +// It is used for version checks such as whether or not vendor_init should be used +int SelinuxGetVendorAndroidVersion() { if (!IsSplitPolicyDevice()) { - // If this device does not split sepolicy files, vendor_init will be available in the latest - // monolithic sepolicy file. - return true; + // If this device does not split sepolicy files, it's not a Treble device and therefore, + // we assume it's always on the latest platform. + return __ANDROID_API_FUTURE__; } std::string version; if (!GetVendorMappingVersion(&version)) { - // Return true as the default if we failed to load the vendor sepolicy version. - return true; + LOG(FATAL) << "Could not read vendor SELinux version"; } int major_version; std::string major_version_str(version, 0, version.find('.')); if (!ParseInt(major_version_str, &major_version)) { - PLOG(ERROR) << "Failed to parse the vendor sepolicy major version " << major_version_str; - // Return true as the default if we failed to parse the major version. - return true; + PLOG(FATAL) << "Failed to parse the vendor sepolicy major version " << major_version_str; } - return major_version >= 28; + return major_version; } // selinux_android_file_context_handle() takes on the order of 10+ms to run, so we want to cache diff --git a/init/selinux.h b/init/selinux.h index 30069b53d..c41d7f0d9 100644 --- a/init/selinux.h +++ b/init/selinux.h @@ -27,7 +27,7 @@ void SelinuxInitialize(); void SelinuxRestoreContext(); void SelinuxSetupKernelLogging(); -bool SelinuxHasVendorInit(); +int SelinuxGetVendorAndroidVersion(); void SelabelInitialize(); bool SelabelLookupFileContext(const std::string& key, int type, std::string* result); diff --git a/init/service.cpp b/init/service.cpp index 4c2747e64..d20e90a70 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -46,10 +46,12 @@ #include "util.h" #if defined(__ANDROID__) +#include #include #include "init.h" #include "property_service.h" +#include "selinux.h" #else #include "host_init_stubs.h" #endif @@ -1211,6 +1213,13 @@ Result ServiceParser::ParseSection(std::vector&& args, } std::vector str_args(args.begin() + 2, args.end()); + + if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_P__) { + if (str_args[0] == "/sbin/watchdogd") { + str_args[0] = "/system/bin/watchdogd"; + } + } + service_ = std::make_unique(name, restart_action_subcontext, str_args); return Success(); } diff --git a/init/subcontext.cpp b/init/subcontext.cpp index ee7251328..c2a21d45c 100644 --- a/init/subcontext.cpp +++ b/init/subcontext.cpp @@ -30,6 +30,7 @@ #include "util.h" #if defined(__ANDROID__) +#include #include "property_service.h" #include "selinux.h" #else @@ -355,7 +356,7 @@ static std::vector subcontexts; static bool shutting_down; std::vector* InitializeSubcontexts() { - if (SelinuxHasVendorInit()) { + if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_P__) { for (const auto& [path_prefix, secontext] : paths_and_secontexts) { subcontexts.emplace_back(path_prefix, secontext); } diff --git a/init/util.cpp b/init/util.cpp index 7735717fc..105ac87fc 100644 --- a/init/util.cpp +++ b/init/util.cpp @@ -47,7 +47,7 @@ #endif #ifdef _INIT_INIT_H -#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals" +#error "Do not include init.h in files used by ueventd; it will expose init's globals" #endif using android::base::boot_clock; diff --git a/init/watchdogd.h b/init/watchdogd.h deleted file mode 100644 index 73f77d594..000000000 --- a/init/watchdogd.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _INIT_WATCHDOGD_H_ -#define _INIT_WATCHDOGD_H_ - -namespace android { -namespace init { - -int watchdogd_main(int argc, char **argv); - -} // namespace init -} // namespace android - -#endif diff --git a/watchdogd/Android.bp b/watchdogd/Android.bp new file mode 100644 index 000000000..0fbc33cd2 --- /dev/null +++ b/watchdogd/Android.bp @@ -0,0 +1,14 @@ +cc_binary { + name: "watchdogd", + recovery_available: true, + srcs: ["watchdogd.cpp"], + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + ], + shared_libs: ["libbase"], + sanitize: { + misc_undefined: ["signed-integer-overflow"], + }, +} diff --git a/init/watchdogd.cpp b/watchdogd/watchdogd.cpp similarity index 80% rename from init/watchdogd.cpp rename to watchdogd/watchdogd.cpp index e03a2c31d..5dc41e6b8 100644 --- a/init/watchdogd.cpp +++ b/watchdogd/watchdogd.cpp @@ -23,16 +23,9 @@ #include -#ifdef _INIT_INIT_H -#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals" -#endif - #define DEV_NAME "/dev/watchdog" -namespace android { -namespace init { - -int watchdogd_main(int argc, char **argv) { +int main(int argc, char** argv) { android::base::InitLogging(argv, &android::base::KernelLogger); int interval = 10; @@ -43,7 +36,7 @@ int watchdogd_main(int argc, char **argv) { LOG(INFO) << "watchdogd started (interval " << interval << ", margin " << margin << ")!"; - int fd = open(DEV_NAME, O_RDWR|O_CLOEXEC); + int fd = open(DEV_NAME, O_RDWR | O_CLOEXEC); if (fd == -1) { PLOG(ERROR) << "Failed to open " << DEV_NAME; return 1; @@ -63,9 +56,8 @@ int watchdogd_main(int argc, char **argv) { interval = 1; } LOG(WARNING) << "Adjusted interval to timeout returned by driver: " - << "timeout " << timeout - << ", interval " << interval - << ", margin " << margin; + << "timeout " << timeout << ", interval " << interval << ", margin " + << margin; } } @@ -74,6 +66,3 @@ int watchdogd_main(int argc, char **argv) { sleep(interval); } } - -} // namespace init -} // namespace android