• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "service.h"
18 
19 #include <fcntl.h>
20 #include <inttypes.h>
21 #include <linux/securebits.h>
22 #include <sched.h>
23 #include <sys/prctl.h>
24 #include <sys/stat.h>
25 #include <sys/time.h>
26 #include <termios.h>
27 #include <unistd.h>
28 
29 #include <android-base/file.h>
30 #include <android-base/logging.h>
31 #include <android-base/properties.h>
32 #include <android-base/scopeguard.h>
33 #include <android-base/stringprintf.h>
34 #include <android-base/strings.h>
35 #include <cutils/sockets.h>
36 #include <processgroup/processgroup.h>
37 #include <selinux/selinux.h>
38 
39 #include "lmkd_service.h"
40 #include "service_list.h"
41 #include "util.h"
42 
43 #ifdef INIT_FULL_SOURCES
44 #include <ApexProperties.sysprop.h>
45 #include <android/api-level.h>
46 
47 #include "mount_namespace.h"
48 #include "selinux.h"
49 #else
50 #include "host_init_stubs.h"
51 #endif
52 
53 using android::base::boot_clock;
54 using android::base::GetProperty;
55 using android::base::Join;
56 using android::base::make_scope_guard;
57 using android::base::SetProperty;
58 using android::base::StartsWith;
59 using android::base::StringPrintf;
60 using android::base::WriteStringToFile;
61 
62 namespace android {
63 namespace init {
64 
ComputeContextFromExecutable(const std::string & service_path)65 static Result<std::string> ComputeContextFromExecutable(const std::string& service_path) {
66     std::string computed_context;
67 
68     char* raw_con = nullptr;
69     char* raw_filecon = nullptr;
70 
71     if (getcon(&raw_con) == -1) {
72         return Error() << "Could not get security context";
73     }
74     std::unique_ptr<char> mycon(raw_con);
75 
76     if (getfilecon(service_path.c_str(), &raw_filecon) == -1) {
77         return Error() << "Could not get file context";
78     }
79     std::unique_ptr<char> filecon(raw_filecon);
80 
81     char* new_con = nullptr;
82     int rc = security_compute_create(mycon.get(), filecon.get(),
83                                      string_to_security_class("process"), &new_con);
84     if (rc == 0) {
85         computed_context = new_con;
86         free(new_con);
87     }
88     if (rc == 0 && computed_context == mycon.get()) {
89         return Error() << "File " << service_path << "(labeled \"" << filecon.get()
90                        << "\") has incorrect label or no domain transition from " << mycon.get()
91                        << " to another SELinux domain defined. Have you configured your "
92                           "service correctly? https://source.android.com/security/selinux/"
93                           "device-policy#label_new_services_and_address_denials";
94     }
95     if (rc < 0) {
96         return Error() << "Could not get process context";
97     }
98     return computed_context;
99 }
100 
ExpandArgsAndExecv(const std::vector<std::string> & args,bool sigstop)101 static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop) {
102     std::vector<std::string> expanded_args;
103     std::vector<char*> c_strings;
104 
105     expanded_args.resize(args.size());
106     c_strings.push_back(const_cast<char*>(args[0].data()));
107     for (std::size_t i = 1; i < args.size(); ++i) {
108         auto expanded_arg = ExpandProps(args[i]);
109         if (!expanded_arg.ok()) {
110             LOG(FATAL) << args[0] << ": cannot expand arguments': " << expanded_arg.error();
111         }
112         expanded_args[i] = *expanded_arg;
113         c_strings.push_back(expanded_args[i].data());
114     }
115     c_strings.push_back(nullptr);
116 
117     if (sigstop) {
118         kill(getpid(), SIGSTOP);
119     }
120 
121     return execv(c_strings[0], c_strings.data()) == 0;
122 }
123 
AreRuntimeApexesReady()124 static bool AreRuntimeApexesReady() {
125     struct stat buf;
126     return stat("/apex/com.android.art/", &buf) == 0 &&
127            stat("/apex/com.android.runtime/", &buf) == 0;
128 }
129 
130 unsigned long Service::next_start_order_ = 1;
131 bool Service::is_exec_service_running_ = false;
132 
Service(const std::string & name,Subcontext * subcontext_for_restart_commands,const std::vector<std::string> & args,bool from_apex)133 Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
134                  const std::vector<std::string>& args, bool from_apex)
135     : Service(name, 0, 0, 0, {}, 0, "", subcontext_for_restart_commands, args, from_apex) {}
136 
Service(const std::string & name,unsigned flags,uid_t uid,gid_t gid,const std::vector<gid_t> & supp_gids,int namespace_flags,const std::string & seclabel,Subcontext * subcontext_for_restart_commands,const std::vector<std::string> & args,bool from_apex)137 Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
138                  const std::vector<gid_t>& supp_gids, int namespace_flags,
139                  const std::string& seclabel, Subcontext* subcontext_for_restart_commands,
140                  const std::vector<std::string>& args, bool from_apex)
141     : name_(name),
142       classnames_({"default"}),
143       flags_(flags),
144       pid_(0),
145       crash_count_(0),
146       proc_attr_{.ioprio_class = IoSchedClass_NONE,
147                  .ioprio_pri = 0,
148                  .uid = uid,
149                  .gid = gid,
150                  .supp_gids = supp_gids,
151                  .priority = 0},
152       namespaces_{.flags = namespace_flags},
153       seclabel_(seclabel),
154       onrestart_(false, subcontext_for_restart_commands, "<Service '" + name + "' onrestart>", 0,
155                  "onrestart", {}),
156       oom_score_adjust_(DEFAULT_OOM_SCORE_ADJUST),
157       start_order_(0),
158       args_(args),
159       from_apex_(from_apex) {}
160 
NotifyStateChange(const std::string & new_state) const161 void Service::NotifyStateChange(const std::string& new_state) const {
162     if ((flags_ & SVC_TEMPORARY) != 0) {
163         // Services created by 'exec' are temporary and don't have properties tracking their state.
164         return;
165     }
166 
167     std::string prop_name = "init.svc." + name_;
168     SetProperty(prop_name, new_state);
169 
170     if (new_state == "running") {
171         uint64_t start_ns = time_started_.time_since_epoch().count();
172         std::string boottime_property = "ro.boottime." + name_;
173         if (GetProperty(boottime_property, "").empty()) {
174             SetProperty(boottime_property, std::to_string(start_ns));
175         }
176     }
177 
178     // init.svc_debug_pid.* properties are only for tests, and should not be used
179     // on device for security checks.
180     std::string pid_property = "init.svc_debug_pid." + name_;
181     if (new_state == "running") {
182         SetProperty(pid_property, std::to_string(pid_));
183     } else if (new_state == "stopped") {
184         SetProperty(pid_property, "");
185     }
186 }
187 
KillProcessGroup(int signal,bool report_oneshot)188 void Service::KillProcessGroup(int signal, bool report_oneshot) {
189     // If we've already seen a successful result from killProcessGroup*(), then we have removed
190     // the cgroup already and calling these functions a second time will simply result in an error.
191     // This is true regardless of which signal was sent.
192     // These functions handle their own logging, so no additional logging is needed.
193     if (!process_cgroup_empty_) {
194         LOG(INFO) << "Sending signal " << signal << " to service '" << name_ << "' (pid " << pid_
195                   << ") process group...";
196         int max_processes = 0;
197         int r;
198         if (signal == SIGTERM) {
199             r = killProcessGroupOnce(proc_attr_.uid, pid_, signal, &max_processes);
200         } else {
201             r = killProcessGroup(proc_attr_.uid, pid_, signal, &max_processes);
202         }
203 
204         if (report_oneshot && max_processes > 0) {
205             LOG(WARNING)
206                     << "Killed " << max_processes
207                     << " additional processes from a oneshot process group for service '" << name_
208                     << "'. This is new behavior, previously child processes would not be killed in "
209                        "this case.";
210         }
211 
212         if (r == 0) process_cgroup_empty_ = true;
213     }
214 
215     if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) {
216         LmkdUnregister(name_, pid_);
217     }
218 }
219 
SetProcessAttributesAndCaps()220 void Service::SetProcessAttributesAndCaps() {
221     // Keep capabilites on uid change.
222     if (capabilities_ && proc_attr_.uid) {
223         // If Android is running in a container, some securebits might already
224         // be locked, so don't change those.
225         unsigned long securebits = prctl(PR_GET_SECUREBITS);
226         if (securebits == -1UL) {
227             PLOG(FATAL) << "prctl(PR_GET_SECUREBITS) failed for " << name_;
228         }
229         securebits |= SECBIT_KEEP_CAPS | SECBIT_KEEP_CAPS_LOCKED;
230         if (prctl(PR_SET_SECUREBITS, securebits) != 0) {
231             PLOG(FATAL) << "prctl(PR_SET_SECUREBITS) failed for " << name_;
232         }
233     }
234 
235     if (auto result = SetProcessAttributes(proc_attr_); !result.ok()) {
236         LOG(FATAL) << "cannot set attribute for " << name_ << ": " << result.error();
237     }
238 
239     if (!seclabel_.empty()) {
240         if (setexeccon(seclabel_.c_str()) < 0) {
241             PLOG(FATAL) << "cannot setexeccon('" << seclabel_ << "') for " << name_;
242         }
243     }
244 
245     if (capabilities_) {
246         if (!SetCapsForExec(*capabilities_)) {
247             LOG(FATAL) << "cannot set capabilities for " << name_;
248         }
249     } else if (proc_attr_.uid) {
250         // Inheritable caps can be non-zero when running in a container.
251         if (!DropInheritableCaps()) {
252             LOG(FATAL) << "cannot drop inheritable caps for " << name_;
253         }
254     }
255 }
256 
Reap(const siginfo_t & siginfo)257 void Service::Reap(const siginfo_t& siginfo) {
258     if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) {
259         KillProcessGroup(SIGKILL, false);
260     } else {
261         // Legacy behavior from ~2007 until Android R: this else branch did not exist and we did not
262         // kill the process group in this case.
263         if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_R__) {
264             // The new behavior in Android R is to kill these process groups in all cases.  The
265             // 'true' parameter instructions KillProcessGroup() to report a warning message where it
266             // detects a difference in behavior has occurred.
267             KillProcessGroup(SIGKILL, true);
268         }
269     }
270 
271     // Remove any socket resources we may have created.
272     for (const auto& socket : sockets_) {
273         auto path = ANDROID_SOCKET_DIR "/" + socket.name;
274         unlink(path.c_str());
275     }
276 
277     for (const auto& f : reap_callbacks_) {
278         f(siginfo);
279     }
280 
281     if ((siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) && on_failure_reboot_target_) {
282         LOG(ERROR) << "Service with 'reboot_on_failure' option failed, shutting down system.";
283         trigger_shutdown(*on_failure_reboot_target_);
284     }
285 
286     if (flags_ & SVC_EXEC) UnSetExec();
287 
288     if (flags_ & SVC_TEMPORARY) return;
289 
290     pid_ = 0;
291     flags_ &= (~SVC_RUNNING);
292     start_order_ = 0;
293 
294     // Oneshot processes go into the disabled state on exit,
295     // except when manually restarted.
296     if ((flags_ & SVC_ONESHOT) && !(flags_ & SVC_RESTART) && !(flags_ & SVC_RESET)) {
297         flags_ |= SVC_DISABLED;
298     }
299 
300     // Disabled and reset processes do not get restarted automatically.
301     if (flags_ & (SVC_DISABLED | SVC_RESET))  {
302         NotifyStateChange("stopped");
303         return;
304     }
305 
306 #if INIT_FULL_SOURCES
307     static bool is_apex_updatable = android::sysprop::ApexProperties::updatable().value_or(false);
308 #else
309     static bool is_apex_updatable = false;
310 #endif
311     const bool is_process_updatable = !pre_apexd_ && is_apex_updatable;
312 
313     // If we crash > 4 times in 4 minutes or before boot_completed,
314     // reboot into bootloader or set crashing property
315     boot_clock::time_point now = boot_clock::now();
316     if (((flags_ & SVC_CRITICAL) || is_process_updatable) && !(flags_ & SVC_RESTART)) {
317         bool boot_completed = android::base::GetBoolProperty("sys.boot_completed", false);
318         if (now < time_crashed_ + 4min || !boot_completed) {
319             if (++crash_count_ > 4) {
320                 if (flags_ & SVC_CRITICAL) {
321                     // Aborts into bootloader
322                     LOG(FATAL) << "critical process '" << name_ << "' exited 4 times "
323                                << (boot_completed ? "in 4 minutes" : "before boot completed");
324                 } else {
325                     LOG(ERROR) << "updatable process '" << name_ << "' exited 4 times "
326                                << (boot_completed ? "in 4 minutes" : "before boot completed");
327                     // Notifies update_verifier and apexd
328                     SetProperty("sys.init.updatable_crashing_process_name", name_);
329                     SetProperty("sys.init.updatable_crashing", "1");
330                 }
331             }
332         } else {
333             time_crashed_ = now;
334             crash_count_ = 1;
335         }
336     }
337 
338     flags_ &= (~SVC_RESTART);
339     flags_ |= SVC_RESTARTING;
340 
341     // Execute all onrestart commands for this service.
342     onrestart_.ExecuteAllCommands();
343 
344     NotifyStateChange("restarting");
345     return;
346 }
347 
DumpState() const348 void Service::DumpState() const {
349     LOG(INFO) << "service " << name_;
350     LOG(INFO) << "  class '" << Join(classnames_, " ") << "'";
351     LOG(INFO) << "  exec " << Join(args_, " ");
352     for (const auto& socket : sockets_) {
353         LOG(INFO) << "  socket " << socket.name;
354     }
355     for (const auto& file : files_) {
356         LOG(INFO) << "  file " << file.name;
357     }
358 }
359 
360 
ExecStart()361 Result<void> Service::ExecStart() {
362     auto reboot_on_failure = make_scope_guard([this] {
363         if (on_failure_reboot_target_) {
364             trigger_shutdown(*on_failure_reboot_target_);
365         }
366     });
367 
368     if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
369         // Don't delay the service for ExecStart() as the semantic is that
370         // the caller might depend on the side effect of the execution.
371         return Error() << "Cannot start an updatable service '" << name_
372                        << "' before configs from APEXes are all loaded";
373     }
374 
375     flags_ |= SVC_ONESHOT;
376 
377     if (auto result = Start(); !result.ok()) {
378         return result;
379     }
380 
381     flags_ |= SVC_EXEC;
382     is_exec_service_running_ = true;
383 
384     LOG(INFO) << "SVC_EXEC service '" << name_ << "' pid " << pid_ << " (uid " << proc_attr_.uid
385               << " gid " << proc_attr_.gid << "+" << proc_attr_.supp_gids.size() << " context "
386               << (!seclabel_.empty() ? seclabel_ : "default") << ") started; waiting...";
387 
388     reboot_on_failure.Disable();
389     return {};
390 }
391 
Start()392 Result<void> Service::Start() {
393     auto reboot_on_failure = make_scope_guard([this] {
394         if (on_failure_reboot_target_) {
395             trigger_shutdown(*on_failure_reboot_target_);
396         }
397     });
398 
399     if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
400         ServiceList::GetInstance().DelayService(*this);
401         return Error() << "Cannot start an updatable service '" << name_
402                        << "' before configs from APEXes are all loaded. "
403                        << "Queued for execution.";
404     }
405 
406     bool disabled = (flags_ & (SVC_DISABLED | SVC_RESET));
407     // Starting a service removes it from the disabled or reset state and
408     // immediately takes it out of the restarting state if it was in there.
409     flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
410 
411     // Running processes require no additional work --- if they're in the
412     // process of exiting, we've ensured that they will immediately restart
413     // on exit, unless they are ONESHOT. For ONESHOT service, if it's in
414     // stopping status, we just set SVC_RESTART flag so it will get restarted
415     // in Reap().
416     if (flags_ & SVC_RUNNING) {
417         if ((flags_ & SVC_ONESHOT) && disabled) {
418             flags_ |= SVC_RESTART;
419         }
420         // It is not an error to try to start a service that is already running.
421         reboot_on_failure.Disable();
422         return {};
423     }
424 
425     bool needs_console = (flags_ & SVC_CONSOLE);
426     if (needs_console) {
427         if (proc_attr_.console.empty()) {
428             proc_attr_.console = "/dev/" + GetProperty("ro.boot.console", "console");
429         }
430 
431         // Make sure that open call succeeds to ensure a console driver is
432         // properly registered for the device node
433         int console_fd = open(proc_attr_.console.c_str(), O_RDWR | O_CLOEXEC);
434         if (console_fd < 0) {
435             flags_ |= SVC_DISABLED;
436             return ErrnoError() << "Couldn't open console '" << proc_attr_.console << "'";
437         }
438         close(console_fd);
439     }
440 
441     struct stat sb;
442     if (stat(args_[0].c_str(), &sb) == -1) {
443         flags_ |= SVC_DISABLED;
444         return ErrnoError() << "Cannot find '" << args_[0] << "'";
445     }
446 
447     std::string scon;
448     if (!seclabel_.empty()) {
449         scon = seclabel_;
450     } else {
451         auto result = ComputeContextFromExecutable(args_[0]);
452         if (!result.ok()) {
453             return result.error();
454         }
455         scon = *result;
456     }
457 
458     if (!AreRuntimeApexesReady() && !pre_apexd_) {
459         // If this service is started before the Runtime and ART APEXes get
460         // available, mark it as pre-apexd one. Note that this marking is
461         // permanent. So for example, if the service is re-launched (e.g., due
462         // to crash), it is still recognized as pre-apexd... for consistency.
463         pre_apexd_ = true;
464     }
465 
466     post_data_ = ServiceList::GetInstance().IsPostData();
467 
468     LOG(INFO) << "starting service '" << name_ << "'...";
469 
470     std::vector<Descriptor> descriptors;
471     for (const auto& socket : sockets_) {
472         if (auto result = socket.Create(scon); result.ok()) {
473             descriptors.emplace_back(std::move(*result));
474         } else {
475             LOG(INFO) << "Could not create socket '" << socket.name << "': " << result.error();
476         }
477     }
478 
479     for (const auto& file : files_) {
480         if (auto result = file.Create(); result.ok()) {
481             descriptors.emplace_back(std::move(*result));
482         } else {
483             LOG(INFO) << "Could not open file '" << file.name << "': " << result.error();
484         }
485     }
486 
487     pid_t pid = -1;
488     if (namespaces_.flags) {
489         pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr);
490     } else {
491         pid = fork();
492     }
493 
494     if (pid == 0) {
495         umask(077);
496 
497         if (auto result = EnterNamespaces(namespaces_, name_, pre_apexd_); !result.ok()) {
498             LOG(FATAL) << "Service '" << name_
499                        << "' failed to set up namespaces: " << result.error();
500         }
501 
502         for (const auto& [key, value] : environment_vars_) {
503             setenv(key.c_str(), value.c_str(), 1);
504         }
505 
506         for (const auto& descriptor : descriptors) {
507             descriptor.Publish();
508         }
509 
510         if (auto result = WritePidToFiles(&writepid_files_); !result.ok()) {
511             LOG(ERROR) << "failed to write pid to files: " << result.error();
512         }
513 
514         if (task_profiles_.size() > 0 && !SetTaskProfiles(getpid(), task_profiles_)) {
515             LOG(ERROR) << "failed to set task profiles";
516         }
517 
518         // As requested, set our gid, supplemental gids, uid, context, and
519         // priority. Aborts on failure.
520         SetProcessAttributesAndCaps();
521 
522         if (!ExpandArgsAndExecv(args_, sigstop_)) {
523             PLOG(ERROR) << "cannot execv('" << args_[0]
524                         << "'). See the 'Debugging init' section of init's README.md for tips";
525         }
526 
527         _exit(127);
528     }
529 
530     if (pid < 0) {
531         pid_ = 0;
532         return ErrnoError() << "Failed to fork";
533     }
534 
535     if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) {
536         std::string oom_str = std::to_string(oom_score_adjust_);
537         std::string oom_file = StringPrintf("/proc/%d/oom_score_adj", pid);
538         if (!WriteStringToFile(oom_str, oom_file)) {
539             PLOG(ERROR) << "couldn't write oom_score_adj";
540         }
541     }
542 
543     time_started_ = boot_clock::now();
544     pid_ = pid;
545     flags_ |= SVC_RUNNING;
546     start_order_ = next_start_order_++;
547     process_cgroup_empty_ = false;
548 
549     bool use_memcg = swappiness_ != -1 || soft_limit_in_bytes_ != -1 || limit_in_bytes_ != -1 ||
550                       limit_percent_ != -1 || !limit_property_.empty();
551     errno = -createProcessGroup(proc_attr_.uid, pid_, use_memcg);
552     if (errno != 0) {
553         PLOG(ERROR) << "createProcessGroup(" << proc_attr_.uid << ", " << pid_
554                     << ") failed for service '" << name_ << "'";
555     } else if (use_memcg) {
556         if (swappiness_ != -1) {
557             if (!setProcessGroupSwappiness(proc_attr_.uid, pid_, swappiness_)) {
558                 PLOG(ERROR) << "setProcessGroupSwappiness failed";
559             }
560         }
561 
562         if (soft_limit_in_bytes_ != -1) {
563             if (!setProcessGroupSoftLimit(proc_attr_.uid, pid_, soft_limit_in_bytes_)) {
564                 PLOG(ERROR) << "setProcessGroupSoftLimit failed";
565             }
566         }
567 
568         size_t computed_limit_in_bytes = limit_in_bytes_;
569         if (limit_percent_ != -1) {
570             long page_size = sysconf(_SC_PAGESIZE);
571             long num_pages = sysconf(_SC_PHYS_PAGES);
572             if (page_size > 0 && num_pages > 0) {
573                 size_t max_mem = SIZE_MAX;
574                 if (size_t(num_pages) < SIZE_MAX / size_t(page_size)) {
575                     max_mem = size_t(num_pages) * size_t(page_size);
576                 }
577                 computed_limit_in_bytes =
578                         std::min(computed_limit_in_bytes, max_mem / 100 * limit_percent_);
579             }
580         }
581 
582         if (!limit_property_.empty()) {
583             // This ends up overwriting computed_limit_in_bytes but only if the
584             // property is defined.
585             computed_limit_in_bytes = android::base::GetUintProperty(
586                     limit_property_, computed_limit_in_bytes, SIZE_MAX);
587         }
588 
589         if (computed_limit_in_bytes != size_t(-1)) {
590             if (!setProcessGroupLimit(proc_attr_.uid, pid_, computed_limit_in_bytes)) {
591                 PLOG(ERROR) << "setProcessGroupLimit failed";
592             }
593         }
594     }
595 
596     if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) {
597         LmkdRegister(name_, proc_attr_.uid, pid_, oom_score_adjust_);
598     }
599 
600     NotifyStateChange("running");
601     reboot_on_failure.Disable();
602     return {};
603 }
604 
StartIfNotDisabled()605 Result<void> Service::StartIfNotDisabled() {
606     if (!(flags_ & SVC_DISABLED)) {
607         return Start();
608     } else {
609         flags_ |= SVC_DISABLED_START;
610     }
611     return {};
612 }
613 
Enable()614 Result<void> Service::Enable() {
615     flags_ &= ~(SVC_DISABLED | SVC_RC_DISABLED);
616     if (flags_ & SVC_DISABLED_START) {
617         return Start();
618     }
619     return {};
620 }
621 
Reset()622 void Service::Reset() {
623     StopOrReset(SVC_RESET);
624 }
625 
ResetIfPostData()626 void Service::ResetIfPostData() {
627     if (post_data_) {
628         if (flags_ & SVC_RUNNING) {
629             running_at_post_data_reset_ = true;
630         }
631         StopOrReset(SVC_RESET);
632     }
633 }
634 
StartIfPostData()635 Result<void> Service::StartIfPostData() {
636     // Start the service, but only if it was started after /data was mounted,
637     // and it was still running when we reset the post-data services.
638     if (running_at_post_data_reset_) {
639         return Start();
640     }
641 
642     return {};
643 }
644 
Stop()645 void Service::Stop() {
646     StopOrReset(SVC_DISABLED);
647 }
648 
Terminate()649 void Service::Terminate() {
650     flags_ &= ~(SVC_RESTARTING | SVC_DISABLED_START);
651     flags_ |= SVC_DISABLED;
652     if (pid_) {
653         KillProcessGroup(SIGTERM);
654         NotifyStateChange("stopping");
655     }
656 }
657 
Timeout()658 void Service::Timeout() {
659     // All process state flags will be taken care of in Reap(), we really just want to kill the
660     // process here when it times out.  Oneshot processes will transition to be disabled, and
661     // all other processes will transition to be restarting.
662     LOG(INFO) << "Service '" << name_ << "' expired its timeout of " << timeout_period_->count()
663               << " seconds and will now be killed";
664     if (pid_) {
665         KillProcessGroup(SIGKILL);
666         NotifyStateChange("stopping");
667     }
668 }
669 
Restart()670 void Service::Restart() {
671     if (flags_ & SVC_RUNNING) {
672         /* Stop, wait, then start the service. */
673         StopOrReset(SVC_RESTART);
674     } else if (!(flags_ & SVC_RESTARTING)) {
675         /* Just start the service since it's not running. */
676         if (auto result = Start(); !result.ok()) {
677             LOG(ERROR) << "Could not restart '" << name_ << "': " << result.error();
678         }
679     } /* else: Service is restarting anyways. */
680 }
681 
682 // The how field should be either SVC_DISABLED, SVC_RESET, or SVC_RESTART.
StopOrReset(int how)683 void Service::StopOrReset(int how) {
684     // The service is still SVC_RUNNING until its process exits, but if it has
685     // already exited it shoudn't attempt a restart yet.
686     flags_ &= ~(SVC_RESTARTING | SVC_DISABLED_START);
687 
688     if ((how != SVC_DISABLED) && (how != SVC_RESET) && (how != SVC_RESTART)) {
689         // An illegal flag: default to SVC_DISABLED.
690         how = SVC_DISABLED;
691     }
692 
693     // If the service has not yet started, prevent it from auto-starting with its class.
694     if (how == SVC_RESET) {
695         flags_ |= (flags_ & SVC_RC_DISABLED) ? SVC_DISABLED : SVC_RESET;
696     } else {
697         flags_ |= how;
698     }
699     // Make sure it's in right status when a restart immediately follow a
700     // stop/reset or vice versa.
701     if (how == SVC_RESTART) {
702         flags_ &= (~(SVC_DISABLED | SVC_RESET));
703     } else {
704         flags_ &= (~SVC_RESTART);
705     }
706 
707     if (pid_) {
708         KillProcessGroup(SIGKILL);
709         NotifyStateChange("stopping");
710     } else {
711         NotifyStateChange("stopped");
712     }
713 }
714 
MakeTemporaryOneshotService(const std::vector<std::string> & args)715 Result<std::unique_ptr<Service>> Service::MakeTemporaryOneshotService(
716         const std::vector<std::string>& args) {
717     // Parse the arguments: exec [SECLABEL [UID [GID]*] --] COMMAND ARGS...
718     // SECLABEL can be a - to denote default
719     std::size_t command_arg = 1;
720     for (std::size_t i = 1; i < args.size(); ++i) {
721         if (args[i] == "--") {
722             command_arg = i + 1;
723             break;
724         }
725     }
726     if (command_arg > 4 + NR_SVC_SUPP_GIDS) {
727         return Error() << "exec called with too many supplementary group ids";
728     }
729 
730     if (command_arg >= args.size()) {
731         return Error() << "exec called without command";
732     }
733     std::vector<std::string> str_args(args.begin() + command_arg, args.end());
734 
735     static size_t exec_count = 0;
736     exec_count++;
737     std::string name = "exec " + std::to_string(exec_count) + " (" + Join(str_args, " ") + ")";
738 
739     unsigned flags = SVC_ONESHOT | SVC_TEMPORARY;
740     unsigned namespace_flags = 0;
741 
742     std::string seclabel = "";
743     if (command_arg > 2 && args[1] != "-") {
744         seclabel = args[1];
745     }
746     Result<uid_t> uid = 0;
747     if (command_arg > 3) {
748         uid = DecodeUid(args[2]);
749         if (!uid.ok()) {
750             return Error() << "Unable to decode UID for '" << args[2] << "': " << uid.error();
751         }
752     }
753     Result<gid_t> gid = 0;
754     std::vector<gid_t> supp_gids;
755     if (command_arg > 4) {
756         gid = DecodeUid(args[3]);
757         if (!gid.ok()) {
758             return Error() << "Unable to decode GID for '" << args[3] << "': " << gid.error();
759         }
760         std::size_t nr_supp_gids = command_arg - 1 /* -- */ - 4 /* exec SECLABEL UID GID */;
761         for (size_t i = 0; i < nr_supp_gids; ++i) {
762             auto supp_gid = DecodeUid(args[4 + i]);
763             if (!supp_gid.ok()) {
764                 return Error() << "Unable to decode GID for '" << args[4 + i]
765                                << "': " << supp_gid.error();
766             }
767             supp_gids.push_back(*supp_gid);
768         }
769     }
770 
771     return std::make_unique<Service>(name, flags, *uid, *gid, supp_gids, namespace_flags, seclabel,
772                                      nullptr, str_args, false);
773 }
774 
775 }  // namespace init
776 }  // namespace android
777