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/mount.h>
24 #include <sys/prctl.h>
25 #include <sys/resource.h>
26 #include <sys/stat.h>
27 #include <sys/time.h>
28 #include <sys/wait.h>
29 #include <termios.h>
30 #include <unistd.h>
31 
32 #include <android-base/file.h>
33 #include <android-base/logging.h>
34 #include <android-base/parseint.h>
35 #include <android-base/stringprintf.h>
36 #include <android-base/strings.h>
37 #include <android-base/unique_fd.h>
38 #include <hidl-util/FQName.h>
39 #include <processgroup/processgroup.h>
40 #include <selinux/selinux.h>
41 #include <system/thread_defs.h>
42 
43 #include "rlimit_parser.h"
44 #include "util.h"
45 
46 #if defined(__ANDROID__)
47 #include <sys/system_properties.h>
48 
49 #include <android-base/properties.h>
50 
51 #include "init.h"
52 #include "property_service.h"
53 #else
54 #include "host_init_stubs.h"
55 #endif
56 
57 using android::base::boot_clock;
58 using android::base::GetProperty;
59 using android::base::Join;
60 using android::base::ParseInt;
61 using android::base::StartsWith;
62 using android::base::StringPrintf;
63 using android::base::unique_fd;
64 using android::base::WriteStringToFile;
65 
66 namespace android {
67 namespace init {
68 
ComputeContextFromExecutable(const std::string & service_path)69 static Result<std::string> ComputeContextFromExecutable(const std::string& service_path) {
70     std::string computed_context;
71 
72     char* raw_con = nullptr;
73     char* raw_filecon = nullptr;
74 
75     if (getcon(&raw_con) == -1) {
76         return Error() << "Could not get security context";
77     }
78     std::unique_ptr<char> mycon(raw_con);
79 
80     if (getfilecon(service_path.c_str(), &raw_filecon) == -1) {
81         return Error() << "Could not get file context";
82     }
83     std::unique_ptr<char> filecon(raw_filecon);
84 
85     char* new_con = nullptr;
86     int rc = security_compute_create(mycon.get(), filecon.get(),
87                                      string_to_security_class("process"), &new_con);
88     if (rc == 0) {
89         computed_context = new_con;
90         free(new_con);
91     }
92     if (rc == 0 && computed_context == mycon.get()) {
93         return Error() << "File " << service_path << "(labeled \"" << filecon.get()
94                        << "\") has incorrect label or no domain transition from " << mycon.get()
95                        << " to another SELinux domain defined. Have you configured your "
96                           "service correctly? https://source.android.com/security/selinux/"
97                           "device-policy#label_new_services_and_address_denials";
98     }
99     if (rc < 0) {
100         return Error() << "Could not get process context";
101     }
102     return computed_context;
103 }
104 
SetUpMountNamespace() const105 Result<Success> Service::SetUpMountNamespace() const {
106     constexpr unsigned int kSafeFlags = MS_NODEV | MS_NOEXEC | MS_NOSUID;
107 
108     // Recursively remount / as slave like zygote does so unmounting and mounting /proc
109     // doesn't interfere with the parent namespace's /proc mount. This will also
110     // prevent any other mounts/unmounts initiated by the service from interfering
111     // with the parent namespace but will still allow mount events from the parent
112     // namespace to propagate to the child.
113     if (mount("rootfs", "/", nullptr, (MS_SLAVE | MS_REC), nullptr) == -1) {
114         return ErrnoError() << "Could not remount(/) recursively as slave";
115     }
116 
117     // umount() then mount() /proc and/or /sys
118     // Note that it is not sufficient to mount with MS_REMOUNT.
119     if (namespace_flags_ & CLONE_NEWPID) {
120         if (umount("/proc") == -1) {
121             return ErrnoError() << "Could not umount(/proc)";
122         }
123         if (mount("", "/proc", "proc", kSafeFlags, "") == -1) {
124             return ErrnoError() << "Could not mount(/proc)";
125         }
126     }
127     bool remount_sys = std::any_of(namespaces_to_enter_.begin(), namespaces_to_enter_.end(),
128                                    [](const auto& entry) { return entry.first == CLONE_NEWNET; });
129     if (remount_sys) {
130         if (umount2("/sys", MNT_DETACH) == -1) {
131             return ErrnoError() << "Could not umount(/sys)";
132         }
133         if (mount("", "/sys", "sys", kSafeFlags, "") == -1) {
134             return ErrnoError() << "Could not mount(/sys)";
135         }
136     }
137     return Success();
138 }
139 
SetUpPidNamespace() const140 Result<Success> Service::SetUpPidNamespace() const {
141     if (prctl(PR_SET_NAME, name_.c_str()) == -1) {
142         return ErrnoError() << "Could not set name";
143     }
144 
145     pid_t child_pid = fork();
146     if (child_pid == -1) {
147         return ErrnoError() << "Could not fork init inside the PID namespace";
148     }
149 
150     if (child_pid > 0) {
151         // So that we exit with the right status.
152         static int init_exitstatus = 0;
153         signal(SIGTERM, [](int) { _exit(init_exitstatus); });
154 
155         pid_t waited_pid;
156         int status;
157         while ((waited_pid = wait(&status)) > 0) {
158              // This loop will end when there are no processes left inside the
159              // PID namespace or when the init process inside the PID namespace
160              // gets a signal.
161             if (waited_pid == child_pid) {
162                 init_exitstatus = status;
163             }
164         }
165         if (!WIFEXITED(init_exitstatus)) {
166             _exit(EXIT_FAILURE);
167         }
168         _exit(WEXITSTATUS(init_exitstatus));
169     }
170     return Success();
171 }
172 
EnterNamespaces() const173 Result<Success> Service::EnterNamespaces() const {
174     for (const auto& [nstype, path] : namespaces_to_enter_) {
175         auto fd = unique_fd{open(path.c_str(), O_RDONLY | O_CLOEXEC)};
176         if (!fd) {
177             return ErrnoError() << "Could not open namespace at " << path;
178         }
179         if (setns(fd, nstype) == -1) {
180             return ErrnoError() << "Could not setns() namespace at " << path;
181         }
182     }
183     return Success();
184 }
185 
ExpandArgsAndExecv(const std::vector<std::string> & args)186 static bool ExpandArgsAndExecv(const std::vector<std::string>& args) {
187     std::vector<std::string> expanded_args;
188     std::vector<char*> c_strings;
189 
190     expanded_args.resize(args.size());
191     c_strings.push_back(const_cast<char*>(args[0].data()));
192     for (std::size_t i = 1; i < args.size(); ++i) {
193         if (!expand_props(args[i], &expanded_args[i])) {
194             LOG(FATAL) << args[0] << ": cannot expand '" << args[i] << "'";
195         }
196         c_strings.push_back(expanded_args[i].data());
197     }
198     c_strings.push_back(nullptr);
199 
200     return execv(c_strings[0], c_strings.data()) == 0;
201 }
202 
203 unsigned long Service::next_start_order_ = 1;
204 bool Service::is_exec_service_running_ = false;
205 
Service(const std::string & name,Subcontext * subcontext_for_restart_commands,const std::vector<std::string> & args)206 Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
207                  const std::vector<std::string>& args)
208     : Service(name, 0, 0, 0, {}, 0, 0, "", subcontext_for_restart_commands, args) {}
209 
Service(const std::string & name,unsigned flags,uid_t uid,gid_t gid,const std::vector<gid_t> & supp_gids,const CapSet & capabilities,unsigned namespace_flags,const std::string & seclabel,Subcontext * subcontext_for_restart_commands,const std::vector<std::string> & args)210 Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
211                  const std::vector<gid_t>& supp_gids, const CapSet& capabilities,
212                  unsigned namespace_flags, const std::string& seclabel,
213                  Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args)
214     : name_(name),
215       classnames_({"default"}),
216       flags_(flags),
217       pid_(0),
218       crash_count_(0),
219       uid_(uid),
220       gid_(gid),
221       supp_gids_(supp_gids),
222       capabilities_(capabilities),
223       namespace_flags_(namespace_flags),
224       seclabel_(seclabel),
225       onrestart_(false, subcontext_for_restart_commands, "<Service '" + name + "' onrestart>", 0,
226                  "onrestart", {}),
227       keychord_id_(0),
228       ioprio_class_(IoSchedClass_NONE),
229       ioprio_pri_(0),
230       priority_(0),
231       oom_score_adjust_(-1000),
232       swappiness_(-1),
233       soft_limit_in_bytes_(-1),
234       limit_in_bytes_(-1),
235       start_order_(0),
236       args_(args) {}
237 
NotifyStateChange(const std::string & new_state) const238 void Service::NotifyStateChange(const std::string& new_state) const {
239     if ((flags_ & SVC_TEMPORARY) != 0) {
240         // Services created by 'exec' are temporary and don't have properties tracking their state.
241         return;
242     }
243 
244     std::string prop_name = "init.svc." + name_;
245     property_set(prop_name, new_state);
246 
247     if (new_state == "running") {
248         uint64_t start_ns = time_started_.time_since_epoch().count();
249         std::string boottime_property = "ro.boottime." + name_;
250         if (GetProperty(boottime_property, "").empty()) {
251             property_set(boottime_property, std::to_string(start_ns));
252         }
253     }
254 }
255 
KillProcessGroup(int signal)256 void Service::KillProcessGroup(int signal) {
257     // If we've already seen a successful result from killProcessGroup*(), then we have removed
258     // the cgroup already and calling these functions a second time will simply result in an error.
259     // This is true regardless of which signal was sent.
260     // These functions handle their own logging, so no additional logging is needed.
261     if (!process_cgroup_empty_) {
262         LOG(INFO) << "Sending signal " << signal << " to service '" << name_ << "' (pid " << pid_
263                   << ") process group...";
264         int r;
265         if (signal == SIGTERM) {
266             r = killProcessGroupOnce(uid_, pid_, signal);
267         } else {
268             r = killProcessGroup(uid_, pid_, signal);
269         }
270 
271         if (r == 0) process_cgroup_empty_ = true;
272     }
273 }
274 
SetProcessAttributes()275 void Service::SetProcessAttributes() {
276     for (const auto& rlimit : rlimits_) {
277         if (setrlimit(rlimit.first, &rlimit.second) == -1) {
278             LOG(FATAL) << StringPrintf("setrlimit(%d, {rlim_cur=%ld, rlim_max=%ld}) failed",
279                                        rlimit.first, rlimit.second.rlim_cur, rlimit.second.rlim_max);
280         }
281     }
282     // Keep capabilites on uid change.
283     if (capabilities_.any() && uid_) {
284         // If Android is running in a container, some securebits might already
285         // be locked, so don't change those.
286         unsigned long securebits = prctl(PR_GET_SECUREBITS);
287         if (securebits == -1UL) {
288             PLOG(FATAL) << "prctl(PR_GET_SECUREBITS) failed for " << name_;
289         }
290         securebits |= SECBIT_KEEP_CAPS | SECBIT_KEEP_CAPS_LOCKED;
291         if (prctl(PR_SET_SECUREBITS, securebits) != 0) {
292             PLOG(FATAL) << "prctl(PR_SET_SECUREBITS) failed for " << name_;
293         }
294     }
295 
296     // TODO: work out why this fails for `console` then upgrade to FATAL.
297     if (setpgid(0, getpid()) == -1) PLOG(ERROR) << "setpgid failed for " << name_;
298 
299     if (gid_) {
300         if (setgid(gid_) != 0) {
301             PLOG(FATAL) << "setgid failed for " << name_;
302         }
303     }
304     if (setgroups(supp_gids_.size(), &supp_gids_[0]) != 0) {
305         PLOG(FATAL) << "setgroups failed for " << name_;
306     }
307     if (uid_) {
308         if (setuid(uid_) != 0) {
309             PLOG(FATAL) << "setuid failed for " << name_;
310         }
311     }
312     if (!seclabel_.empty()) {
313         if (setexeccon(seclabel_.c_str()) < 0) {
314             PLOG(FATAL) << "cannot setexeccon('" << seclabel_ << "') for " << name_;
315         }
316     }
317     if (priority_ != 0) {
318         if (setpriority(PRIO_PROCESS, 0, priority_) != 0) {
319             PLOG(FATAL) << "setpriority failed for " << name_;
320         }
321     }
322     if (capabilities_.any()) {
323         if (!SetCapsForExec(capabilities_)) {
324             LOG(FATAL) << "cannot set capabilities for " << name_;
325         }
326     } else if (uid_) {
327         // Inheritable caps can be non-zero when running in a container.
328         if (!DropInheritableCaps()) {
329             LOG(FATAL) << "cannot drop inheritable caps for " << name_;
330         }
331     }
332 }
333 
Reap(const siginfo_t & siginfo)334 void Service::Reap(const siginfo_t& siginfo) {
335     if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) {
336         KillProcessGroup(SIGKILL);
337     }
338 
339     // Remove any descriptor resources we may have created.
340     std::for_each(descriptors_.begin(), descriptors_.end(),
341                   std::bind(&DescriptorInfo::Clean, std::placeholders::_1));
342 
343     for (const auto& f : reap_callbacks_) {
344         f(siginfo);
345     }
346 
347     if (flags_ & SVC_EXEC) UnSetExec();
348 
349     if (flags_ & SVC_TEMPORARY) return;
350 
351     pid_ = 0;
352     flags_ &= (~SVC_RUNNING);
353     start_order_ = 0;
354 
355     // Oneshot processes go into the disabled state on exit,
356     // except when manually restarted.
357     if ((flags_ & SVC_ONESHOT) && !(flags_ & SVC_RESTART)) {
358         flags_ |= SVC_DISABLED;
359     }
360 
361     // Disabled and reset processes do not get restarted automatically.
362     if (flags_ & (SVC_DISABLED | SVC_RESET))  {
363         NotifyStateChange("stopped");
364         return;
365     }
366 
367     // If we crash > 4 times in 4 minutes, reboot into recovery.
368     boot_clock::time_point now = boot_clock::now();
369     if ((flags_ & SVC_CRITICAL) && !(flags_ & SVC_RESTART)) {
370         if (now < time_crashed_ + 4min) {
371             if (++crash_count_ > 4) {
372                 LOG(FATAL) << "critical process '" << name_ << "' exited 4 times in 4 minutes";
373             }
374         } else {
375             time_crashed_ = now;
376             crash_count_ = 1;
377         }
378     }
379 
380     flags_ &= (~SVC_RESTART);
381     flags_ |= SVC_RESTARTING;
382 
383     // Execute all onrestart commands for this service.
384     onrestart_.ExecuteAllCommands();
385 
386     NotifyStateChange("restarting");
387     return;
388 }
389 
DumpState() const390 void Service::DumpState() const {
391     LOG(INFO) << "service " << name_;
392     LOG(INFO) << "  class '" << Join(classnames_, " ") << "'";
393     LOG(INFO) << "  exec " << Join(args_, " ");
394     std::for_each(descriptors_.begin(), descriptors_.end(),
395                   [] (const auto& info) { LOG(INFO) << *info; });
396 }
397 
ParseCapabilities(const std::vector<std::string> & args)398 Result<Success> Service::ParseCapabilities(const std::vector<std::string>& args) {
399     capabilities_ = 0;
400 
401     if (!CapAmbientSupported()) {
402         return Error()
403                << "capabilities requested but the kernel does not support ambient capabilities";
404     }
405 
406     unsigned int last_valid_cap = GetLastValidCap();
407     if (last_valid_cap >= capabilities_.size()) {
408         LOG(WARNING) << "last valid run-time capability is larger than CAP_LAST_CAP";
409     }
410 
411     for (size_t i = 1; i < args.size(); i++) {
412         const std::string& arg = args[i];
413         int res = LookupCap(arg);
414         if (res < 0) {
415             return Error() << StringPrintf("invalid capability '%s'", arg.c_str());
416         }
417         unsigned int cap = static_cast<unsigned int>(res);  // |res| is >= 0.
418         if (cap > last_valid_cap) {
419             return Error() << StringPrintf("capability '%s' not supported by the kernel",
420                                            arg.c_str());
421         }
422         capabilities_[cap] = true;
423     }
424     return Success();
425 }
426 
ParseClass(const std::vector<std::string> & args)427 Result<Success> Service::ParseClass(const std::vector<std::string>& args) {
428     classnames_ = std::set<std::string>(args.begin() + 1, args.end());
429     return Success();
430 }
431 
ParseConsole(const std::vector<std::string> & args)432 Result<Success> Service::ParseConsole(const std::vector<std::string>& args) {
433     flags_ |= SVC_CONSOLE;
434     console_ = args.size() > 1 ? "/dev/" + args[1] : "";
435     return Success();
436 }
437 
ParseCritical(const std::vector<std::string> & args)438 Result<Success> Service::ParseCritical(const std::vector<std::string>& args) {
439     flags_ |= SVC_CRITICAL;
440     return Success();
441 }
442 
ParseDisabled(const std::vector<std::string> & args)443 Result<Success> Service::ParseDisabled(const std::vector<std::string>& args) {
444     flags_ |= SVC_DISABLED;
445     flags_ |= SVC_RC_DISABLED;
446     return Success();
447 }
448 
ParseEnterNamespace(const std::vector<std::string> & args)449 Result<Success> Service::ParseEnterNamespace(const std::vector<std::string>& args) {
450     if (args[1] != "net") {
451         return Error() << "Init only supports entering network namespaces";
452     }
453     if (!namespaces_to_enter_.empty()) {
454         return Error() << "Only one network namespace may be entered";
455     }
456     // Network namespaces require that /sys is remounted, otherwise the old adapters will still be
457     // present. Therefore, they also require mount namespaces.
458     namespace_flags_ |= CLONE_NEWNS;
459     namespaces_to_enter_.emplace_back(CLONE_NEWNET, args[2]);
460     return Success();
461 }
462 
ParseGroup(const std::vector<std::string> & args)463 Result<Success> Service::ParseGroup(const std::vector<std::string>& args) {
464     auto gid = DecodeUid(args[1]);
465     if (!gid) {
466         return Error() << "Unable to decode GID for '" << args[1] << "': " << gid.error();
467     }
468     gid_ = *gid;
469 
470     for (std::size_t n = 2; n < args.size(); n++) {
471         gid = DecodeUid(args[n]);
472         if (!gid) {
473             return Error() << "Unable to decode GID for '" << args[n] << "': " << gid.error();
474         }
475         supp_gids_.emplace_back(*gid);
476     }
477     return Success();
478 }
479 
ParsePriority(const std::vector<std::string> & args)480 Result<Success> Service::ParsePriority(const std::vector<std::string>& args) {
481     priority_ = 0;
482     if (!ParseInt(args[1], &priority_,
483                   static_cast<int>(ANDROID_PRIORITY_HIGHEST), // highest is negative
484                   static_cast<int>(ANDROID_PRIORITY_LOWEST))) {
485         return Error() << StringPrintf("process priority value must be range %d - %d",
486                                        ANDROID_PRIORITY_HIGHEST, ANDROID_PRIORITY_LOWEST);
487     }
488     return Success();
489 }
490 
ParseInterface(const std::vector<std::string> & args)491 Result<Success> Service::ParseInterface(const std::vector<std::string>& args) {
492     const std::string& interface_name = args[1];
493     const std::string& instance_name = args[2];
494 
495     const FQName fq_name = FQName(interface_name);
496     if (!fq_name.isValid()) {
497         return Error() << "Invalid fully-qualified name for interface '" << interface_name << "'";
498     }
499 
500     if (!fq_name.isFullyQualified()) {
501         return Error() << "Interface name not fully-qualified '" << interface_name << "'";
502     }
503 
504     if (fq_name.isValidValueName()) {
505         return Error() << "Interface name must not be a value name '" << interface_name << "'";
506     }
507 
508     const std::string fullname = interface_name + "/" + instance_name;
509 
510     for (const auto& svc : ServiceList::GetInstance()) {
511         if (svc->interfaces().count(fullname) > 0) {
512             return Error() << "Interface '" << fullname << "' redefined in " << name()
513                            << " but is already defined by " << svc->name();
514         }
515     }
516 
517     interfaces_.insert(fullname);
518 
519     return Success();
520 }
521 
ParseIoprio(const std::vector<std::string> & args)522 Result<Success> Service::ParseIoprio(const std::vector<std::string>& args) {
523     if (!ParseInt(args[2], &ioprio_pri_, 0, 7)) {
524         return Error() << "priority value must be range 0 - 7";
525     }
526 
527     if (args[1] == "rt") {
528         ioprio_class_ = IoSchedClass_RT;
529     } else if (args[1] == "be") {
530         ioprio_class_ = IoSchedClass_BE;
531     } else if (args[1] == "idle") {
532         ioprio_class_ = IoSchedClass_IDLE;
533     } else {
534         return Error() << "ioprio option usage: ioprio <rt|be|idle> <0-7>";
535     }
536 
537     return Success();
538 }
539 
ParseKeycodes(const std::vector<std::string> & args)540 Result<Success> Service::ParseKeycodes(const std::vector<std::string>& args) {
541     for (std::size_t i = 1; i < args.size(); i++) {
542         int code;
543         if (ParseInt(args[i], &code)) {
544             keycodes_.emplace_back(code);
545         } else {
546             LOG(WARNING) << "ignoring invalid keycode: " << args[i];
547         }
548     }
549     return Success();
550 }
551 
ParseOneshot(const std::vector<std::string> & args)552 Result<Success> Service::ParseOneshot(const std::vector<std::string>& args) {
553     flags_ |= SVC_ONESHOT;
554     return Success();
555 }
556 
ParseOnrestart(const std::vector<std::string> & args)557 Result<Success> Service::ParseOnrestart(const std::vector<std::string>& args) {
558     std::vector<std::string> str_args(args.begin() + 1, args.end());
559     int line = onrestart_.NumCommands() + 1;
560     if (auto result = onrestart_.AddCommand(str_args, line); !result) {
561         return Error() << "cannot add Onrestart command: " << result.error();
562     }
563     return Success();
564 }
565 
ParseNamespace(const std::vector<std::string> & args)566 Result<Success> Service::ParseNamespace(const std::vector<std::string>& args) {
567     for (size_t i = 1; i < args.size(); i++) {
568         if (args[i] == "pid") {
569             namespace_flags_ |= CLONE_NEWPID;
570             // PID namespaces require mount namespaces.
571             namespace_flags_ |= CLONE_NEWNS;
572         } else if (args[i] == "mnt") {
573             namespace_flags_ |= CLONE_NEWNS;
574         } else {
575             return Error() << "namespace must be 'pid' or 'mnt'";
576         }
577     }
578     return Success();
579 }
580 
ParseOomScoreAdjust(const std::vector<std::string> & args)581 Result<Success> Service::ParseOomScoreAdjust(const std::vector<std::string>& args) {
582     if (!ParseInt(args[1], &oom_score_adjust_, -1000, 1000)) {
583         return Error() << "oom_score_adjust value must be in range -1000 - +1000";
584     }
585     return Success();
586 }
587 
ParseOverride(const std::vector<std::string> & args)588 Result<Success> Service::ParseOverride(const std::vector<std::string>& args) {
589     override_ = true;
590     return Success();
591 }
592 
ParseMemcgSwappiness(const std::vector<std::string> & args)593 Result<Success> Service::ParseMemcgSwappiness(const std::vector<std::string>& args) {
594     if (!ParseInt(args[1], &swappiness_, 0)) {
595         return Error() << "swappiness value must be equal or greater than 0";
596     }
597     return Success();
598 }
599 
ParseMemcgLimitInBytes(const std::vector<std::string> & args)600 Result<Success> Service::ParseMemcgLimitInBytes(const std::vector<std::string>& args) {
601     if (!ParseInt(args[1], &limit_in_bytes_, 0)) {
602         return Error() << "limit_in_bytes value must be equal or greater than 0";
603     }
604     return Success();
605 }
606 
ParseMemcgSoftLimitInBytes(const std::vector<std::string> & args)607 Result<Success> Service::ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args) {
608     if (!ParseInt(args[1], &soft_limit_in_bytes_, 0)) {
609         return Error() << "soft_limit_in_bytes value must be equal or greater than 0";
610     }
611     return Success();
612 }
613 
ParseProcessRlimit(const std::vector<std::string> & args)614 Result<Success> Service::ParseProcessRlimit(const std::vector<std::string>& args) {
615     auto rlimit = ParseRlimit(args);
616     if (!rlimit) return rlimit.error();
617 
618     rlimits_.emplace_back(*rlimit);
619     return Success();
620 }
621 
ParseSeclabel(const std::vector<std::string> & args)622 Result<Success> Service::ParseSeclabel(const std::vector<std::string>& args) {
623     seclabel_ = args[1];
624     return Success();
625 }
626 
ParseSetenv(const std::vector<std::string> & args)627 Result<Success> Service::ParseSetenv(const std::vector<std::string>& args) {
628     environment_vars_.emplace_back(args[1], args[2]);
629     return Success();
630 }
631 
ParseShutdown(const std::vector<std::string> & args)632 Result<Success> Service::ParseShutdown(const std::vector<std::string>& args) {
633     if (args[1] == "critical") {
634         flags_ |= SVC_SHUTDOWN_CRITICAL;
635         return Success();
636     }
637     return Error() << "Invalid shutdown option";
638 }
639 
640 template <typename T>
AddDescriptor(const std::vector<std::string> & args)641 Result<Success> Service::AddDescriptor(const std::vector<std::string>& args) {
642     int perm = args.size() > 3 ? std::strtoul(args[3].c_str(), 0, 8) : -1;
643     Result<uid_t> uid = 0;
644     Result<gid_t> gid = 0;
645     std::string context = args.size() > 6 ? args[6] : "";
646 
647     if (args.size() > 4) {
648         uid = DecodeUid(args[4]);
649         if (!uid) {
650             return Error() << "Unable to find UID for '" << args[4] << "': " << uid.error();
651         }
652     }
653 
654     if (args.size() > 5) {
655         gid = DecodeUid(args[5]);
656         if (!gid) {
657             return Error() << "Unable to find GID for '" << args[5] << "': " << gid.error();
658         }
659     }
660 
661     auto descriptor = std::make_unique<T>(args[1], args[2], *uid, *gid, perm, context);
662 
663     auto old =
664         std::find_if(descriptors_.begin(), descriptors_.end(),
665                      [&descriptor] (const auto& other) { return descriptor.get() == other.get(); });
666 
667     if (old != descriptors_.end()) {
668         return Error() << "duplicate descriptor " << args[1] << " " << args[2];
669     }
670 
671     descriptors_.emplace_back(std::move(descriptor));
672     return Success();
673 }
674 
675 // name type perm [ uid gid context ]
ParseSocket(const std::vector<std::string> & args)676 Result<Success> Service::ParseSocket(const std::vector<std::string>& args) {
677     if (!StartsWith(args[2], "dgram") && !StartsWith(args[2], "stream") &&
678         !StartsWith(args[2], "seqpacket")) {
679         return Error() << "socket type must be 'dgram', 'stream' or 'seqpacket'";
680     }
681     return AddDescriptor<SocketInfo>(args);
682 }
683 
684 // name type perm [ uid gid context ]
ParseFile(const std::vector<std::string> & args)685 Result<Success> Service::ParseFile(const std::vector<std::string>& args) {
686     if (args[2] != "r" && args[2] != "w" && args[2] != "rw") {
687         return Error() << "file type must be 'r', 'w' or 'rw'";
688     }
689     if ((args[1][0] != '/') || (args[1].find("../") != std::string::npos)) {
690         return Error() << "file name must not be relative";
691     }
692     return AddDescriptor<FileInfo>(args);
693 }
694 
ParseUser(const std::vector<std::string> & args)695 Result<Success> Service::ParseUser(const std::vector<std::string>& args) {
696     auto uid = DecodeUid(args[1]);
697     if (!uid) {
698         return Error() << "Unable to find UID for '" << args[1] << "': " << uid.error();
699     }
700     uid_ = *uid;
701     return Success();
702 }
703 
ParseWritepid(const std::vector<std::string> & args)704 Result<Success> Service::ParseWritepid(const std::vector<std::string>& args) {
705     writepid_files_.assign(args.begin() + 1, args.end());
706     return Success();
707 }
708 
709 class Service::OptionParserMap : public KeywordMap<OptionParser> {
710   public:
OptionParserMap()711     OptionParserMap() {}
712 
713   private:
714     const Map& map() const override;
715 };
716 
map() const717 const Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
718     constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
719     // clang-format off
720     static const Map option_parsers = {
721         {"capabilities",
722                         {1,     kMax, &Service::ParseCapabilities}},
723         {"class",       {1,     kMax, &Service::ParseClass}},
724         {"console",     {0,     1,    &Service::ParseConsole}},
725         {"critical",    {0,     0,    &Service::ParseCritical}},
726         {"disabled",    {0,     0,    &Service::ParseDisabled}},
727         {"enter_namespace",
728                         {2,     2,    &Service::ParseEnterNamespace}},
729         {"group",       {1,     NR_SVC_SUPP_GIDS + 1, &Service::ParseGroup}},
730         {"interface",   {2,     2,    &Service::ParseInterface}},
731         {"ioprio",      {2,     2,    &Service::ParseIoprio}},
732         {"priority",    {1,     1,    &Service::ParsePriority}},
733         {"keycodes",    {1,     kMax, &Service::ParseKeycodes}},
734         {"oneshot",     {0,     0,    &Service::ParseOneshot}},
735         {"onrestart",   {1,     kMax, &Service::ParseOnrestart}},
736         {"override",    {0,     0,    &Service::ParseOverride}},
737         {"oom_score_adjust",
738                         {1,     1,    &Service::ParseOomScoreAdjust}},
739         {"memcg.swappiness",
740                         {1,     1,    &Service::ParseMemcgSwappiness}},
741         {"memcg.soft_limit_in_bytes",
742                         {1,     1,    &Service::ParseMemcgSoftLimitInBytes}},
743         {"memcg.limit_in_bytes",
744                         {1,     1,    &Service::ParseMemcgLimitInBytes}},
745         {"namespace",   {1,     2,    &Service::ParseNamespace}},
746         {"rlimit",      {3,     3,    &Service::ParseProcessRlimit}},
747         {"seclabel",    {1,     1,    &Service::ParseSeclabel}},
748         {"setenv",      {2,     2,    &Service::ParseSetenv}},
749         {"shutdown",    {1,     1,    &Service::ParseShutdown}},
750         {"socket",      {3,     6,    &Service::ParseSocket}},
751         {"file",        {2,     2,    &Service::ParseFile}},
752         {"user",        {1,     1,    &Service::ParseUser}},
753         {"writepid",    {1,     kMax, &Service::ParseWritepid}},
754     };
755     // clang-format on
756     return option_parsers;
757 }
758 
ParseLine(const std::vector<std::string> & args)759 Result<Success> Service::ParseLine(const std::vector<std::string>& args) {
760     static const OptionParserMap parser_map;
761     auto parser = parser_map.FindFunction(args);
762 
763     if (!parser) return parser.error();
764 
765     return std::invoke(*parser, this, args);
766 }
767 
ExecStart()768 Result<Success> Service::ExecStart() {
769     flags_ |= SVC_ONESHOT;
770 
771     if (auto result = Start(); !result) {
772         return result;
773     }
774 
775     flags_ |= SVC_EXEC;
776     is_exec_service_running_ = true;
777 
778     LOG(INFO) << "SVC_EXEC pid " << pid_ << " (uid " << uid_ << " gid " << gid_ << "+"
779               << supp_gids_.size() << " context " << (!seclabel_.empty() ? seclabel_ : "default")
780               << ") started; waiting...";
781 
782     return Success();
783 }
784 
Start()785 Result<Success> Service::Start() {
786     bool disabled = (flags_ & (SVC_DISABLED | SVC_RESET));
787     // Starting a service removes it from the disabled or reset state and
788     // immediately takes it out of the restarting state if it was in there.
789     flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
790 
791     // Running processes require no additional work --- if they're in the
792     // process of exiting, we've ensured that they will immediately restart
793     // on exit, unless they are ONESHOT. For ONESHOT service, if it's in
794     // stopping status, we just set SVC_RESTART flag so it will get restarted
795     // in Reap().
796     if (flags_ & SVC_RUNNING) {
797         if ((flags_ & SVC_ONESHOT) && disabled) {
798             flags_ |= SVC_RESTART;
799         }
800         // It is not an error to try to start a service that is already running.
801         return Success();
802     }
803 
804     bool needs_console = (flags_ & SVC_CONSOLE);
805     if (needs_console) {
806         if (console_.empty()) {
807             console_ = default_console;
808         }
809 
810         // Make sure that open call succeeds to ensure a console driver is
811         // properly registered for the device node
812         int console_fd = open(console_.c_str(), O_RDWR | O_CLOEXEC);
813         if (console_fd < 0) {
814             flags_ |= SVC_DISABLED;
815             return ErrnoError() << "Couldn't open console '" << console_ << "'";
816         }
817         close(console_fd);
818     }
819 
820     struct stat sb;
821     if (stat(args_[0].c_str(), &sb) == -1) {
822         flags_ |= SVC_DISABLED;
823         return ErrnoError() << "Cannot find '" << args_[0] << "'";
824     }
825 
826     std::string scon;
827     if (!seclabel_.empty()) {
828         scon = seclabel_;
829     } else {
830         auto result = ComputeContextFromExecutable(args_[0]);
831         if (!result) {
832             return result.error();
833         }
834         scon = *result;
835     }
836 
837     LOG(INFO) << "starting service '" << name_ << "'...";
838 
839     pid_t pid = -1;
840     if (namespace_flags_) {
841         pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
842     } else {
843         pid = fork();
844     }
845 
846     if (pid == 0) {
847         umask(077);
848 
849         if (auto result = EnterNamespaces(); !result) {
850             LOG(FATAL) << "Service '" << name_ << "' could not enter namespaces: " << result.error();
851         }
852 
853         if (namespace_flags_ & CLONE_NEWNS) {
854             if (auto result = SetUpMountNamespace(); !result) {
855                 LOG(FATAL) << "Service '" << name_
856                            << "' could not set up mount namespace: " << result.error();
857             }
858         }
859 
860         if (namespace_flags_ & CLONE_NEWPID) {
861             // This will fork again to run an init process inside the PID
862             // namespace.
863             if (auto result = SetUpPidNamespace(); !result) {
864                 LOG(FATAL) << "Service '" << name_
865                            << "' could not set up PID namespace: " << result.error();
866             }
867         }
868 
869         for (const auto& [key, value] : environment_vars_) {
870             setenv(key.c_str(), value.c_str(), 1);
871         }
872 
873         std::for_each(descriptors_.begin(), descriptors_.end(),
874                       std::bind(&DescriptorInfo::CreateAndPublish, std::placeholders::_1, scon));
875 
876         // See if there were "writepid" instructions to write to files under /dev/cpuset/.
877         auto cpuset_predicate = [](const std::string& path) {
878             return StartsWith(path, "/dev/cpuset/");
879         };
880         auto iter = std::find_if(writepid_files_.begin(), writepid_files_.end(), cpuset_predicate);
881         if (iter == writepid_files_.end()) {
882             // There were no "writepid" instructions for cpusets, check if the system default
883             // cpuset is specified to be used for the process.
884             std::string default_cpuset = GetProperty("ro.cpuset.default", "");
885             if (!default_cpuset.empty()) {
886                 // Make sure the cpuset name starts and ends with '/'.
887                 // A single '/' means the 'root' cpuset.
888                 if (default_cpuset.front() != '/') {
889                     default_cpuset.insert(0, 1, '/');
890                 }
891                 if (default_cpuset.back() != '/') {
892                     default_cpuset.push_back('/');
893                 }
894                 writepid_files_.push_back(
895                     StringPrintf("/dev/cpuset%stasks", default_cpuset.c_str()));
896             }
897         }
898         std::string pid_str = std::to_string(getpid());
899         for (const auto& file : writepid_files_) {
900             if (!WriteStringToFile(pid_str, file)) {
901                 PLOG(ERROR) << "couldn't write " << pid_str << " to " << file;
902             }
903         }
904 
905         if (ioprio_class_ != IoSchedClass_NONE) {
906             if (android_set_ioprio(getpid(), ioprio_class_, ioprio_pri_)) {
907                 PLOG(ERROR) << "failed to set pid " << getpid()
908                             << " ioprio=" << ioprio_class_ << "," << ioprio_pri_;
909             }
910         }
911 
912         if (needs_console) {
913             setsid();
914             OpenConsole();
915         } else {
916             ZapStdio();
917         }
918 
919         // As requested, set our gid, supplemental gids, uid, context, and
920         // priority. Aborts on failure.
921         SetProcessAttributes();
922 
923         if (!ExpandArgsAndExecv(args_)) {
924             PLOG(ERROR) << "cannot execve('" << args_[0] << "')";
925         }
926 
927         _exit(127);
928     }
929 
930     if (pid < 0) {
931         pid_ = 0;
932         return ErrnoError() << "Failed to fork";
933     }
934 
935     if (oom_score_adjust_ != -1000) {
936         std::string oom_str = std::to_string(oom_score_adjust_);
937         std::string oom_file = StringPrintf("/proc/%d/oom_score_adj", pid);
938         if (!WriteStringToFile(oom_str, oom_file)) {
939             PLOG(ERROR) << "couldn't write oom_score_adj: " << strerror(errno);
940         }
941     }
942 
943     time_started_ = boot_clock::now();
944     pid_ = pid;
945     flags_ |= SVC_RUNNING;
946     start_order_ = next_start_order_++;
947     process_cgroup_empty_ = false;
948 
949     errno = -createProcessGroup(uid_, pid_);
950     if (errno != 0) {
951         PLOG(ERROR) << "createProcessGroup(" << uid_ << ", " << pid_ << ") failed for service '"
952                     << name_ << "'";
953     } else {
954         if (swappiness_ != -1) {
955             if (!setProcessGroupSwappiness(uid_, pid_, swappiness_)) {
956                 PLOG(ERROR) << "setProcessGroupSwappiness failed";
957             }
958         }
959 
960         if (soft_limit_in_bytes_ != -1) {
961             if (!setProcessGroupSoftLimit(uid_, pid_, soft_limit_in_bytes_)) {
962                 PLOG(ERROR) << "setProcessGroupSoftLimit failed";
963             }
964         }
965 
966         if (limit_in_bytes_ != -1) {
967             if (!setProcessGroupLimit(uid_, pid_, limit_in_bytes_)) {
968                 PLOG(ERROR) << "setProcessGroupLimit failed";
969             }
970         }
971     }
972 
973     NotifyStateChange("running");
974     return Success();
975 }
976 
StartIfNotDisabled()977 Result<Success> Service::StartIfNotDisabled() {
978     if (!(flags_ & SVC_DISABLED)) {
979         return Start();
980     } else {
981         flags_ |= SVC_DISABLED_START;
982     }
983     return Success();
984 }
985 
Enable()986 Result<Success> Service::Enable() {
987     flags_ &= ~(SVC_DISABLED | SVC_RC_DISABLED);
988     if (flags_ & SVC_DISABLED_START) {
989         return Start();
990     }
991     return Success();
992 }
993 
Reset()994 void Service::Reset() {
995     StopOrReset(SVC_RESET);
996 }
997 
Stop()998 void Service::Stop() {
999     StopOrReset(SVC_DISABLED);
1000 }
1001 
Terminate()1002 void Service::Terminate() {
1003     flags_ &= ~(SVC_RESTARTING | SVC_DISABLED_START);
1004     flags_ |= SVC_DISABLED;
1005     if (pid_) {
1006         KillProcessGroup(SIGTERM);
1007         NotifyStateChange("stopping");
1008     }
1009 }
1010 
Restart()1011 void Service::Restart() {
1012     if (flags_ & SVC_RUNNING) {
1013         /* Stop, wait, then start the service. */
1014         StopOrReset(SVC_RESTART);
1015     } else if (!(flags_ & SVC_RESTARTING)) {
1016         /* Just start the service since it's not running. */
1017         if (auto result = Start(); !result) {
1018             LOG(ERROR) << "Could not restart '" << name_ << "': " << result.error();
1019         }
1020     } /* else: Service is restarting anyways. */
1021 }
1022 
1023 // The how field should be either SVC_DISABLED, SVC_RESET, or SVC_RESTART.
StopOrReset(int how)1024 void Service::StopOrReset(int how) {
1025     // The service is still SVC_RUNNING until its process exits, but if it has
1026     // already exited it shoudn't attempt a restart yet.
1027     flags_ &= ~(SVC_RESTARTING | SVC_DISABLED_START);
1028 
1029     if ((how != SVC_DISABLED) && (how != SVC_RESET) && (how != SVC_RESTART)) {
1030         // An illegal flag: default to SVC_DISABLED.
1031         how = SVC_DISABLED;
1032     }
1033 
1034     // If the service has not yet started, prevent it from auto-starting with its class.
1035     if (how == SVC_RESET) {
1036         flags_ |= (flags_ & SVC_RC_DISABLED) ? SVC_DISABLED : SVC_RESET;
1037     } else {
1038         flags_ |= how;
1039     }
1040     // Make sure it's in right status when a restart immediately follow a
1041     // stop/reset or vice versa.
1042     if (how == SVC_RESTART) {
1043         flags_ &= (~(SVC_DISABLED | SVC_RESET));
1044     } else {
1045         flags_ &= (~SVC_RESTART);
1046     }
1047 
1048     if (pid_) {
1049         KillProcessGroup(SIGKILL);
1050         NotifyStateChange("stopping");
1051     } else {
1052         NotifyStateChange("stopped");
1053     }
1054 }
1055 
ZapStdio() const1056 void Service::ZapStdio() const {
1057     int fd;
1058     fd = open("/dev/null", O_RDWR);
1059     dup2(fd, 0);
1060     dup2(fd, 1);
1061     dup2(fd, 2);
1062     close(fd);
1063 }
1064 
OpenConsole() const1065 void Service::OpenConsole() const {
1066     int fd = open(console_.c_str(), O_RDWR);
1067     if (fd == -1) fd = open("/dev/null", O_RDWR);
1068     ioctl(fd, TIOCSCTTY, 0);
1069     dup2(fd, 0);
1070     dup2(fd, 1);
1071     dup2(fd, 2);
1072     close(fd);
1073 }
1074 
ServiceList()1075 ServiceList::ServiceList() {}
1076 
GetInstance()1077 ServiceList& ServiceList::GetInstance() {
1078     static ServiceList instance;
1079     return instance;
1080 }
1081 
AddService(std::unique_ptr<Service> service)1082 void ServiceList::AddService(std::unique_ptr<Service> service) {
1083     services_.emplace_back(std::move(service));
1084 }
1085 
MakeTemporaryOneshotService(const std::vector<std::string> & args)1086 std::unique_ptr<Service> Service::MakeTemporaryOneshotService(const std::vector<std::string>& args) {
1087     // Parse the arguments: exec [SECLABEL [UID [GID]*] --] COMMAND ARGS...
1088     // SECLABEL can be a - to denote default
1089     std::size_t command_arg = 1;
1090     for (std::size_t i = 1; i < args.size(); ++i) {
1091         if (args[i] == "--") {
1092             command_arg = i + 1;
1093             break;
1094         }
1095     }
1096     if (command_arg > 4 + NR_SVC_SUPP_GIDS) {
1097         LOG(ERROR) << "exec called with too many supplementary group ids";
1098         return nullptr;
1099     }
1100 
1101     if (command_arg >= args.size()) {
1102         LOG(ERROR) << "exec called without command";
1103         return nullptr;
1104     }
1105     std::vector<std::string> str_args(args.begin() + command_arg, args.end());
1106 
1107     static size_t exec_count = 0;
1108     exec_count++;
1109     std::string name = "exec " + std::to_string(exec_count) + " (" + Join(str_args, " ") + ")";
1110 
1111     unsigned flags = SVC_ONESHOT | SVC_TEMPORARY;
1112     CapSet no_capabilities;
1113     unsigned namespace_flags = 0;
1114 
1115     std::string seclabel = "";
1116     if (command_arg > 2 && args[1] != "-") {
1117         seclabel = args[1];
1118     }
1119     Result<uid_t> uid = 0;
1120     if (command_arg > 3) {
1121         uid = DecodeUid(args[2]);
1122         if (!uid) {
1123             LOG(ERROR) << "Unable to decode UID for '" << args[2] << "': " << uid.error();
1124             return nullptr;
1125         }
1126     }
1127     Result<gid_t> gid = 0;
1128     std::vector<gid_t> supp_gids;
1129     if (command_arg > 4) {
1130         gid = DecodeUid(args[3]);
1131         if (!gid) {
1132             LOG(ERROR) << "Unable to decode GID for '" << args[3] << "': " << gid.error();
1133             return nullptr;
1134         }
1135         std::size_t nr_supp_gids = command_arg - 1 /* -- */ - 4 /* exec SECLABEL UID GID */;
1136         for (size_t i = 0; i < nr_supp_gids; ++i) {
1137             auto supp_gid = DecodeUid(args[4 + i]);
1138             if (!supp_gid) {
1139                 LOG(ERROR) << "Unable to decode GID for '" << args[4 + i]
1140                            << "': " << supp_gid.error();
1141                 return nullptr;
1142             }
1143             supp_gids.push_back(*supp_gid);
1144         }
1145     }
1146 
1147     return std::make_unique<Service>(name, flags, *uid, *gid, supp_gids, no_capabilities,
1148                                      namespace_flags, seclabel, nullptr, str_args);
1149 }
1150 
1151 // Shutdown services in the opposite order that they were started.
services_in_shutdown_order() const1152 const std::vector<Service*> ServiceList::services_in_shutdown_order() const {
1153     std::vector<Service*> shutdown_services;
1154     for (const auto& service : services_) {
1155         if (service->start_order() > 0) shutdown_services.emplace_back(service.get());
1156     }
1157     std::sort(shutdown_services.begin(), shutdown_services.end(),
1158               [](const auto& a, const auto& b) { return a->start_order() > b->start_order(); });
1159     return shutdown_services;
1160 }
1161 
RemoveService(const Service & svc)1162 void ServiceList::RemoveService(const Service& svc) {
1163     auto svc_it = std::find_if(services_.begin(), services_.end(),
1164                                [&svc] (const std::unique_ptr<Service>& s) {
1165                                    return svc.name() == s->name();
1166                                });
1167     if (svc_it == services_.end()) {
1168         return;
1169     }
1170 
1171     services_.erase(svc_it);
1172 }
1173 
DumpState() const1174 void ServiceList::DumpState() const {
1175     for (const auto& s : services_) {
1176         s->DumpState();
1177     }
1178 }
1179 
ParseSection(std::vector<std::string> && args,const std::string & filename,int line)1180 Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,
1181                                             const std::string& filename, int line) {
1182     if (args.size() < 3) {
1183         return Error() << "services must have a name and a program";
1184     }
1185 
1186     const std::string& name = args[1];
1187     if (!IsValidName(name)) {
1188         return Error() << "invalid service name '" << name << "'";
1189     }
1190 
1191     Subcontext* restart_action_subcontext = nullptr;
1192     if (subcontexts_) {
1193         for (auto& subcontext : *subcontexts_) {
1194             if (StartsWith(filename, subcontext.path_prefix())) {
1195                 restart_action_subcontext = &subcontext;
1196                 break;
1197             }
1198         }
1199     }
1200 
1201     std::vector<std::string> str_args(args.begin() + 2, args.end());
1202     service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);
1203     return Success();
1204 }
1205 
ParseLineSection(std::vector<std::string> && args,int line)1206 Result<Success> ServiceParser::ParseLineSection(std::vector<std::string>&& args, int line) {
1207     return service_ ? service_->ParseLine(std::move(args)) : Success();
1208 }
1209 
EndSection()1210 Result<Success> ServiceParser::EndSection() {
1211     if (service_) {
1212         Service* old_service = service_list_->FindService(service_->name());
1213         if (old_service) {
1214             if (!service_->is_override()) {
1215                 return Error() << "ignored duplicate definition of service '" << service_->name()
1216                                << "'";
1217             }
1218 
1219             service_list_->RemoveService(*old_service);
1220             old_service = nullptr;
1221         }
1222 
1223         service_list_->AddService(std::move(service_));
1224     }
1225 
1226     return Success();
1227 }
1228 
IsValidName(const std::string & name) const1229 bool ServiceParser::IsValidName(const std::string& name) const {
1230     // Property names can be any length, but may only contain certain characters.
1231     // Property values can contain any characters, but may only be a certain length.
1232     // (The latter restriction is needed because `start` and `stop` work by writing
1233     // the service name to the "ctl.start" and "ctl.stop" properties.)
1234     return IsLegalPropertyName("init.svc." + name) && name.size() <= PROP_VALUE_MAX;
1235 }
1236 
1237 }  // namespace init
1238 }  // namespace android
1239