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