1*00c7fec1SAndroid Build Coastguard Worker /* 2*00c7fec1SAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project 3*00c7fec1SAndroid Build Coastguard Worker * 4*00c7fec1SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*00c7fec1SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*00c7fec1SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*00c7fec1SAndroid Build Coastguard Worker * 8*00c7fec1SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*00c7fec1SAndroid Build Coastguard Worker * 10*00c7fec1SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*00c7fec1SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*00c7fec1SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*00c7fec1SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*00c7fec1SAndroid Build Coastguard Worker * limitations under the License. 15*00c7fec1SAndroid Build Coastguard Worker */ 16*00c7fec1SAndroid Build Coastguard Worker 17*00c7fec1SAndroid Build Coastguard Worker #pragma once 18*00c7fec1SAndroid Build Coastguard Worker 19*00c7fec1SAndroid Build Coastguard Worker #include <signal.h> 20*00c7fec1SAndroid Build Coastguard Worker #include <sys/types.h> 21*00c7fec1SAndroid Build Coastguard Worker 22*00c7fec1SAndroid Build Coastguard Worker #include <algorithm> 23*00c7fec1SAndroid Build Coastguard Worker #include <chrono> 24*00c7fec1SAndroid Build Coastguard Worker #include <memory> 25*00c7fec1SAndroid Build Coastguard Worker #include <optional> 26*00c7fec1SAndroid Build Coastguard Worker #include <set> 27*00c7fec1SAndroid Build Coastguard Worker #include <string> 28*00c7fec1SAndroid Build Coastguard Worker #include <vector> 29*00c7fec1SAndroid Build Coastguard Worker 30*00c7fec1SAndroid Build Coastguard Worker #include <android-base/chrono_utils.h> 31*00c7fec1SAndroid Build Coastguard Worker #include <cutils/iosched_policy.h> 32*00c7fec1SAndroid Build Coastguard Worker 33*00c7fec1SAndroid Build Coastguard Worker #include "action.h" 34*00c7fec1SAndroid Build Coastguard Worker #include "capabilities.h" 35*00c7fec1SAndroid Build Coastguard Worker #include "interprocess_fifo.h" 36*00c7fec1SAndroid Build Coastguard Worker #include "keyword_map.h" 37*00c7fec1SAndroid Build Coastguard Worker #include "mount_namespace.h" 38*00c7fec1SAndroid Build Coastguard Worker #include "parser.h" 39*00c7fec1SAndroid Build Coastguard Worker #include "service_utils.h" 40*00c7fec1SAndroid Build Coastguard Worker #include "subcontext.h" 41*00c7fec1SAndroid Build Coastguard Worker 42*00c7fec1SAndroid Build Coastguard Worker #define SVC_DISABLED 0x001 // do not autostart with class 43*00c7fec1SAndroid Build Coastguard Worker #define SVC_ONESHOT 0x002 // do not restart on exit 44*00c7fec1SAndroid Build Coastguard Worker #define SVC_RUNNING 0x004 // currently active 45*00c7fec1SAndroid Build Coastguard Worker #define SVC_RESTARTING 0x008 // waiting to restart 46*00c7fec1SAndroid Build Coastguard Worker #define SVC_CONSOLE 0x010 // requires console 47*00c7fec1SAndroid Build Coastguard Worker #define SVC_CRITICAL 0x020 // will reboot into bootloader if keeps crashing 48*00c7fec1SAndroid Build Coastguard Worker #define SVC_RESET 0x040 // Use when stopping a process, 49*00c7fec1SAndroid Build Coastguard Worker // but not disabling so it can be restarted with its class. 50*00c7fec1SAndroid Build Coastguard Worker #define SVC_RC_DISABLED 0x080 // Remember if the disabled flag was set in the rc script. 51*00c7fec1SAndroid Build Coastguard Worker #define SVC_RESTART 0x100 // Use to safely restart (stop, wait, start) a service. 52*00c7fec1SAndroid Build Coastguard Worker #define SVC_DISABLED_START 0x200 // A start was requested but it was disabled at the time. 53*00c7fec1SAndroid Build Coastguard Worker #define SVC_EXEC 0x400 // This service was started by either 'exec' or 'exec_start' and stops 54*00c7fec1SAndroid Build Coastguard Worker // init from processing more commands until it completes 55*00c7fec1SAndroid Build Coastguard Worker 56*00c7fec1SAndroid Build Coastguard Worker #define SVC_SHUTDOWN_CRITICAL 0x800 // This service is critical for shutdown and 57*00c7fec1SAndroid Build Coastguard Worker // should not be killed during shutdown 58*00c7fec1SAndroid Build Coastguard Worker #define SVC_TEMPORARY 0x1000 // This service was started by 'exec' and should be removed from the 59*00c7fec1SAndroid Build Coastguard Worker // service list once it is reaped. 60*00c7fec1SAndroid Build Coastguard Worker #define SVC_GENTLE_KILL 0x2000 // This service should be stopped with SIGTERM instead of SIGKILL 61*00c7fec1SAndroid Build Coastguard Worker // Will still be SIGKILLed after timeout period of 200 ms 62*00c7fec1SAndroid Build Coastguard Worker 63*00c7fec1SAndroid Build Coastguard Worker #define NR_SVC_SUPP_GIDS 32 // thirty two supplementary groups 64*00c7fec1SAndroid Build Coastguard Worker 65*00c7fec1SAndroid Build Coastguard Worker namespace android { 66*00c7fec1SAndroid Build Coastguard Worker namespace init { 67*00c7fec1SAndroid Build Coastguard Worker 68*00c7fec1SAndroid Build Coastguard Worker class Service { 69*00c7fec1SAndroid Build Coastguard Worker friend class ServiceParser; 70*00c7fec1SAndroid Build Coastguard Worker 71*00c7fec1SAndroid Build Coastguard Worker public: 72*00c7fec1SAndroid Build Coastguard Worker Service(const std::string& name, Subcontext* subcontext_for_restart_commands, 73*00c7fec1SAndroid Build Coastguard Worker const std::string& filename, const std::vector<std::string>& args); 74*00c7fec1SAndroid Build Coastguard Worker 75*00c7fec1SAndroid Build Coastguard Worker Service(const std::string& name, unsigned flags, std::optional<uid_t> uid, gid_t gid, 76*00c7fec1SAndroid Build Coastguard Worker const std::vector<gid_t>& supp_gids, int namespace_flags, const std::string& seclabel, 77*00c7fec1SAndroid Build Coastguard Worker Subcontext* subcontext_for_restart_commands, const std::string& filename, 78*00c7fec1SAndroid Build Coastguard Worker const std::vector<std::string>& args); 79*00c7fec1SAndroid Build Coastguard Worker Service(const Service&) = delete; 80*00c7fec1SAndroid Build Coastguard Worker void operator=(const Service&) = delete; 81*00c7fec1SAndroid Build Coastguard Worker 82*00c7fec1SAndroid Build Coastguard Worker static Result<std::unique_ptr<Service>> MakeTemporaryOneshotService( 83*00c7fec1SAndroid Build Coastguard Worker const std::vector<std::string>& args); 84*00c7fec1SAndroid Build Coastguard Worker IsRunning()85*00c7fec1SAndroid Build Coastguard Worker bool IsRunning() { return (flags_ & SVC_RUNNING) != 0; } IsEnabled()86*00c7fec1SAndroid Build Coastguard Worker bool IsEnabled() { return (flags_ & SVC_DISABLED) == 0; } 87*00c7fec1SAndroid Build Coastguard Worker Result<void> ExecStart(); 88*00c7fec1SAndroid Build Coastguard Worker Result<void> Start(); 89*00c7fec1SAndroid Build Coastguard Worker Result<void> StartIfNotDisabled(); 90*00c7fec1SAndroid Build Coastguard Worker Result<void> Enable(); 91*00c7fec1SAndroid Build Coastguard Worker void Reset(); 92*00c7fec1SAndroid Build Coastguard Worker void Stop(); 93*00c7fec1SAndroid Build Coastguard Worker void Terminate(); 94*00c7fec1SAndroid Build Coastguard Worker void Timeout(); 95*00c7fec1SAndroid Build Coastguard Worker void Restart(); 96*00c7fec1SAndroid Build Coastguard Worker void Reap(const siginfo_t& siginfo); 97*00c7fec1SAndroid Build Coastguard Worker void DumpState() const; SetShutdownCritical()98*00c7fec1SAndroid Build Coastguard Worker void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; } IsShutdownCritical()99*00c7fec1SAndroid Build Coastguard Worker bool IsShutdownCritical() const { return (flags_ & SVC_SHUTDOWN_CRITICAL) != 0; } UnSetExec()100*00c7fec1SAndroid Build Coastguard Worker void UnSetExec() { 101*00c7fec1SAndroid Build Coastguard Worker is_exec_service_running_ = false; 102*00c7fec1SAndroid Build Coastguard Worker flags_ &= ~SVC_EXEC; 103*00c7fec1SAndroid Build Coastguard Worker } AddReapCallback(std::function<void (const siginfo_t & siginfo)> callback)104*00c7fec1SAndroid Build Coastguard Worker void AddReapCallback(std::function<void(const siginfo_t& siginfo)> callback) { 105*00c7fec1SAndroid Build Coastguard Worker reap_callbacks_.emplace_back(std::move(callback)); 106*00c7fec1SAndroid Build Coastguard Worker } 107*00c7fec1SAndroid Build Coastguard Worker void SetStartedInFirstStage(pid_t pid); 108*00c7fec1SAndroid Build Coastguard Worker bool MarkSocketPersistent(const std::string& socket_name); CheckAllCommands()109*00c7fec1SAndroid Build Coastguard Worker size_t CheckAllCommands() const { return onrestart_.CheckAllCommands(); } 110*00c7fec1SAndroid Build Coastguard Worker is_exec_service_running()111*00c7fec1SAndroid Build Coastguard Worker static bool is_exec_service_running() { return is_exec_service_running_; } 112*00c7fec1SAndroid Build Coastguard Worker name()113*00c7fec1SAndroid Build Coastguard Worker const std::string& name() const { return name_; } classnames()114*00c7fec1SAndroid Build Coastguard Worker const std::set<std::string>& classnames() const { return classnames_; } flags()115*00c7fec1SAndroid Build Coastguard Worker unsigned flags() const { return flags_; } pid()116*00c7fec1SAndroid Build Coastguard Worker pid_t pid() const { return pid_; } time_started()117*00c7fec1SAndroid Build Coastguard Worker android::base::boot_clock::time_point time_started() const { return time_started_; } crash_count()118*00c7fec1SAndroid Build Coastguard Worker int crash_count() const { return crash_count_; } was_last_exit_ok()119*00c7fec1SAndroid Build Coastguard Worker int was_last_exit_ok() const { return was_last_exit_ok_; } uid()120*00c7fec1SAndroid Build Coastguard Worker uid_t uid() const { return proc_attr_.uid(); } gid()121*00c7fec1SAndroid Build Coastguard Worker gid_t gid() const { return proc_attr_.gid; } namespace_flags()122*00c7fec1SAndroid Build Coastguard Worker int namespace_flags() const { return namespaces_.flags; } supp_gids()123*00c7fec1SAndroid Build Coastguard Worker const std::vector<gid_t>& supp_gids() const { return proc_attr_.supp_gids; } seclabel()124*00c7fec1SAndroid Build Coastguard Worker const std::string& seclabel() const { return seclabel_; } keycodes()125*00c7fec1SAndroid Build Coastguard Worker const std::vector<int>& keycodes() const { return keycodes_; } ioprio_class()126*00c7fec1SAndroid Build Coastguard Worker IoSchedClass ioprio_class() const { return proc_attr_.ioprio_class; } ioprio_pri()127*00c7fec1SAndroid Build Coastguard Worker int ioprio_pri() const { return proc_attr_.ioprio_pri; } interfaces()128*00c7fec1SAndroid Build Coastguard Worker const std::set<std::string>& interfaces() const { return interfaces_; } priority()129*00c7fec1SAndroid Build Coastguard Worker int priority() const { return proc_attr_.priority; } oom_score_adjust()130*00c7fec1SAndroid Build Coastguard Worker int oom_score_adjust() const { return oom_score_adjust_; } is_override()131*00c7fec1SAndroid Build Coastguard Worker bool is_override() const { return override_; } process_cgroup_empty()132*00c7fec1SAndroid Build Coastguard Worker bool process_cgroup_empty() const { return process_cgroup_empty_; } start_order()133*00c7fec1SAndroid Build Coastguard Worker unsigned long start_order() const { return start_order_; } set_sigstop(bool value)134*00c7fec1SAndroid Build Coastguard Worker void set_sigstop(bool value) { sigstop_ = value; } restart_period()135*00c7fec1SAndroid Build Coastguard Worker std::chrono::seconds restart_period() const { 136*00c7fec1SAndroid Build Coastguard Worker // If the service exited abnormally or due to timeout, late limit the restart even if 137*00c7fec1SAndroid Build Coastguard Worker // restart_period is set to a very short value. 138*00c7fec1SAndroid Build Coastguard Worker // If not, i.e. restart after a deliberate and successful exit, respect the period. 139*00c7fec1SAndroid Build Coastguard Worker if (!was_last_exit_ok_) { 140*00c7fec1SAndroid Build Coastguard Worker return std::max(restart_period_, default_restart_period_); 141*00c7fec1SAndroid Build Coastguard Worker } 142*00c7fec1SAndroid Build Coastguard Worker return restart_period_; 143*00c7fec1SAndroid Build Coastguard Worker } timeout_period()144*00c7fec1SAndroid Build Coastguard Worker std::optional<std::chrono::seconds> timeout_period() const { return timeout_period_; } args()145*00c7fec1SAndroid Build Coastguard Worker const std::vector<std::string>& args() const { return args_; } is_updatable()146*00c7fec1SAndroid Build Coastguard Worker bool is_updatable() const { return updatable_; } set_oneshot(bool value)147*00c7fec1SAndroid Build Coastguard Worker void set_oneshot(bool value) { 148*00c7fec1SAndroid Build Coastguard Worker if (value) { 149*00c7fec1SAndroid Build Coastguard Worker flags_ |= SVC_ONESHOT; 150*00c7fec1SAndroid Build Coastguard Worker } else { 151*00c7fec1SAndroid Build Coastguard Worker flags_ &= ~SVC_ONESHOT; 152*00c7fec1SAndroid Build Coastguard Worker } 153*00c7fec1SAndroid Build Coastguard Worker } subcontext()154*00c7fec1SAndroid Build Coastguard Worker const Subcontext* subcontext() const { return subcontext_; } filename()155*00c7fec1SAndroid Build Coastguard Worker const std::string& filename() const { return filename_; } set_filename(const std::string & name)156*00c7fec1SAndroid Build Coastguard Worker void set_filename(const std::string& name) { filename_ = name; } GetSigchldFd()157*00c7fec1SAndroid Build Coastguard Worker static int GetSigchldFd() { 158*00c7fec1SAndroid Build Coastguard Worker static int sigchld_fd = CreateSigchldFd().release(); 159*00c7fec1SAndroid Build Coastguard Worker return sigchld_fd; 160*00c7fec1SAndroid Build Coastguard Worker } 161*00c7fec1SAndroid Build Coastguard Worker 162*00c7fec1SAndroid Build Coastguard Worker private: 163*00c7fec1SAndroid Build Coastguard Worker void NotifyStateChange(const std::string& new_state) const; 164*00c7fec1SAndroid Build Coastguard Worker void StopOrReset(int how); 165*00c7fec1SAndroid Build Coastguard Worker void KillProcessGroup(int signal); 166*00c7fec1SAndroid Build Coastguard Worker void SetProcessAttributesAndCaps(InterprocessFifo setsid_finished); 167*00c7fec1SAndroid Build Coastguard Worker void ResetFlagsForStart(); 168*00c7fec1SAndroid Build Coastguard Worker Result<void> CheckConsole(); 169*00c7fec1SAndroid Build Coastguard Worker void ConfigureMemcg(); 170*00c7fec1SAndroid Build Coastguard Worker void RunService(const std::vector<Descriptor>& descriptors, InterprocessFifo cgroups_activated, 171*00c7fec1SAndroid Build Coastguard Worker InterprocessFifo setsid_finished); 172*00c7fec1SAndroid Build Coastguard Worker void SetMountNamespace(); 173*00c7fec1SAndroid Build Coastguard Worker static ::android::base::unique_fd CreateSigchldFd(); 174*00c7fec1SAndroid Build Coastguard Worker 175*00c7fec1SAndroid Build Coastguard Worker static unsigned long next_start_order_; 176*00c7fec1SAndroid Build Coastguard Worker static bool is_exec_service_running_; 177*00c7fec1SAndroid Build Coastguard Worker 178*00c7fec1SAndroid Build Coastguard Worker const std::string name_; 179*00c7fec1SAndroid Build Coastguard Worker std::set<std::string> classnames_; 180*00c7fec1SAndroid Build Coastguard Worker 181*00c7fec1SAndroid Build Coastguard Worker unsigned flags_; 182*00c7fec1SAndroid Build Coastguard Worker pid_t pid_; 183*00c7fec1SAndroid Build Coastguard Worker android::base::boot_clock::time_point time_started_; // time of last start 184*00c7fec1SAndroid Build Coastguard Worker android::base::boot_clock::time_point time_crashed_; // first crash within inspection window 185*00c7fec1SAndroid Build Coastguard Worker int crash_count_; // number of times crashed within window 186*00c7fec1SAndroid Build Coastguard Worker bool upgraded_mte_ = false; // whether we upgraded async MTE -> sync MTE before 187*00c7fec1SAndroid Build Coastguard Worker std::chrono::minutes fatal_crash_window_ = 4min; // fatal() when more than 4 crashes in it 188*00c7fec1SAndroid Build Coastguard Worker std::optional<std::string> fatal_reboot_target_; // reboot target of fatal handler 189*00c7fec1SAndroid Build Coastguard Worker bool was_last_exit_ok_ = 190*00c7fec1SAndroid Build Coastguard Worker true; // true if the service never exited, or exited with status code 0 191*00c7fec1SAndroid Build Coastguard Worker 192*00c7fec1SAndroid Build Coastguard Worker std::optional<CapSet> capabilities_; 193*00c7fec1SAndroid Build Coastguard Worker ProcessAttributes proc_attr_; 194*00c7fec1SAndroid Build Coastguard Worker NamespaceInfo namespaces_; 195*00c7fec1SAndroid Build Coastguard Worker 196*00c7fec1SAndroid Build Coastguard Worker std::string seclabel_; 197*00c7fec1SAndroid Build Coastguard Worker 198*00c7fec1SAndroid Build Coastguard Worker std::vector<SocketDescriptor> sockets_; 199*00c7fec1SAndroid Build Coastguard Worker std::vector<FileDescriptor> files_; 200*00c7fec1SAndroid Build Coastguard Worker std::vector<std::pair<std::string, std::string>> environment_vars_; 201*00c7fec1SAndroid Build Coastguard Worker // Environment variables that only get applied to the next run. 202*00c7fec1SAndroid Build Coastguard Worker std::vector<std::pair<std::string, std::string>> once_environment_vars_; 203*00c7fec1SAndroid Build Coastguard Worker 204*00c7fec1SAndroid Build Coastguard Worker const Subcontext* const subcontext_; 205*00c7fec1SAndroid Build Coastguard Worker Action onrestart_; // Commands to execute on restart. 206*00c7fec1SAndroid Build Coastguard Worker 207*00c7fec1SAndroid Build Coastguard Worker std::vector<std::string> writepid_files_; 208*00c7fec1SAndroid Build Coastguard Worker 209*00c7fec1SAndroid Build Coastguard Worker std::vector<std::string> task_profiles_; 210*00c7fec1SAndroid Build Coastguard Worker 211*00c7fec1SAndroid Build Coastguard Worker std::set<std::string> interfaces_; // e.g. [email protected]::IBaz/instance-name 212*00c7fec1SAndroid Build Coastguard Worker 213*00c7fec1SAndroid Build Coastguard Worker // keycodes for triggering this service via /dev/input/input* 214*00c7fec1SAndroid Build Coastguard Worker std::vector<int> keycodes_; 215*00c7fec1SAndroid Build Coastguard Worker 216*00c7fec1SAndroid Build Coastguard Worker int oom_score_adjust_; 217*00c7fec1SAndroid Build Coastguard Worker 218*00c7fec1SAndroid Build Coastguard Worker int swappiness_ = -1; 219*00c7fec1SAndroid Build Coastguard Worker int soft_limit_in_bytes_ = -1; 220*00c7fec1SAndroid Build Coastguard Worker 221*00c7fec1SAndroid Build Coastguard Worker int limit_in_bytes_ = -1; 222*00c7fec1SAndroid Build Coastguard Worker int limit_percent_ = -1; 223*00c7fec1SAndroid Build Coastguard Worker std::string limit_property_; 224*00c7fec1SAndroid Build Coastguard Worker 225*00c7fec1SAndroid Build Coastguard Worker bool process_cgroup_empty_ = false; 226*00c7fec1SAndroid Build Coastguard Worker 227*00c7fec1SAndroid Build Coastguard Worker bool override_ = false; 228*00c7fec1SAndroid Build Coastguard Worker 229*00c7fec1SAndroid Build Coastguard Worker unsigned long start_order_; 230*00c7fec1SAndroid Build Coastguard Worker 231*00c7fec1SAndroid Build Coastguard Worker bool sigstop_ = false; 232*00c7fec1SAndroid Build Coastguard Worker 233*00c7fec1SAndroid Build Coastguard Worker const std::chrono::seconds default_restart_period_ = 5s; 234*00c7fec1SAndroid Build Coastguard Worker std::chrono::seconds restart_period_ = default_restart_period_; 235*00c7fec1SAndroid Build Coastguard Worker std::optional<std::chrono::seconds> timeout_period_; 236*00c7fec1SAndroid Build Coastguard Worker 237*00c7fec1SAndroid Build Coastguard Worker bool updatable_ = false; 238*00c7fec1SAndroid Build Coastguard Worker 239*00c7fec1SAndroid Build Coastguard Worker const std::vector<std::string> args_; 240*00c7fec1SAndroid Build Coastguard Worker 241*00c7fec1SAndroid Build Coastguard Worker std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_; 242*00c7fec1SAndroid Build Coastguard Worker 243*00c7fec1SAndroid Build Coastguard Worker std::optional<MountNamespace> mount_namespace_; 244*00c7fec1SAndroid Build Coastguard Worker 245*00c7fec1SAndroid Build Coastguard Worker std::optional<std::string> on_failure_reboot_target_; 246*00c7fec1SAndroid Build Coastguard Worker 247*00c7fec1SAndroid Build Coastguard Worker std::string filename_; 248*00c7fec1SAndroid Build Coastguard Worker }; 249*00c7fec1SAndroid Build Coastguard Worker 250*00c7fec1SAndroid Build Coastguard Worker } // namespace init 251*00c7fec1SAndroid Build Coastguard Worker } // namespace android 252