• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <dlfcn.h>
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <signal.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #ifdef __MUSL__
23 #include <stropts.h>
24 #endif
25 #include <sys/prctl.h>
26 #include <sys/capability.h>
27 #include <sys/ioctl.h>
28 #include <sys/param.h>
29 #include <sys/resource.h>
30 #include <sys/stat.h>
31 #include <time.h>
32 #include <unistd.h>
33 
34 #include "init.h"
35 #include "init_adapter.h"
36 #include "init_cmds.h"
37 #include "init_cmdexecutor.h"
38 #include "init_log.h"
39 #include "init_cmdexecutor.h"
40 #include "init_jobs_internal.h"
41 #include "init_param.h"
42 #include "init_service.h"
43 #include "init_service_manager.h"
44 #include "init_service_socket.h"
45 #include "init_utils.h"
46 #include "fd_holder_internal.h"
47 #include "loop_event.h"
48 #include "securec.h"
49 #include "service_control.h"
50 #include "init_group_manager.h"
51 #ifndef OHOS_LITE
52 #include "init_hisysevent.h"
53 #endif
54 
55 #if defined(ENABLE_HOOK_MGR)
56 #include "hookmgr.h"
57 #include "bootstage.h"
58 #endif
59 
60 #ifdef WITH_SECCOMP
61 #define APPSPAWN_NAME ("appspawn")
62 #define NWEBSPAWN_NAME ("nwebspawn")
63 #endif
64 
65 #ifdef CODE_SIGNATURE_ENABLE
66 #include "code_sign_attr_utils.h"
67 #endif
68 
69 #ifndef TIOCSCTTY
70 #define TIOCSCTTY 0x540E
71 #endif
72 
73 #define DEF_CRASH_TIME 240000 // default crash time is 240000 ms
74 
SetAllAmbientCapability(void)75 static int SetAllAmbientCapability(void)
76 {
77     for (int i = 0; i <= CAP_LAST_CAP; ++i) {
78         if (SetAmbientCapability(i) != 0) {
79             return SERVICE_FAILURE;
80         }
81     }
82     return SERVICE_SUCCESS;
83 }
84 
SetSystemSeccompPolicy(const Service * service)85 static int SetSystemSeccompPolicy(const Service *service)
86 {
87 #ifdef WITH_SECCOMP
88     if (strncmp(APPSPAWN_NAME, service->name, strlen(APPSPAWN_NAME))
89         && strncmp(NWEBSPAWN_NAME, service->name, strlen(NWEBSPAWN_NAME))) {
90         char cmdContent[MAX_CMD_CONTENT_LEN + 1] = {0};
91 
92         int rc = snprintf_s(cmdContent, MAX_CMD_CONTENT_LEN + 1, strlen(service->name) + 1,
93                             "%s ", service->name);
94         if (rc == -1) {
95             return SERVICE_FAILURE;
96         }
97 
98         rc = strcat_s(cmdContent, MAX_CMD_CONTENT_LEN + 1, service->pathArgs.argv[0]);
99         if (rc != 0) {
100             return SERVICE_FAILURE;
101         }
102 
103         PluginExecCmdByName("SetSeccompPolicy", cmdContent);
104     }
105 #endif
106     return SERVICE_SUCCESS;
107 }
108 
109 #if defined(ENABLE_HOOK_MGR)
110 /**
111  * service Hooking
112  */
ServiceHookWrapper(const HOOK_INFO * hookInfo,void * executionContext)113 static int ServiceHookWrapper(const HOOK_INFO *hookInfo, void *executionContext)
114 {
115     SERVICE_INFO_CTX *serviceContext = (SERVICE_INFO_CTX *)executionContext;
116     ServiceHook realHook = (ServiceHook)hookInfo->hookCookie;
117 
118     realHook(serviceContext);
119     return 0;
120 };
121 
InitAddServiceHook(ServiceHook hook,int hookState)122 int InitAddServiceHook(ServiceHook hook, int hookState)
123 {
124     HOOK_INFO info;
125 
126     info.stage = hookState;
127     info.prio = 0;
128     info.hook = ServiceHookWrapper;
129     info.hookCookie = (void *)hook;
130 
131     return HookMgrAddEx(GetBootStageHookMgr(), &info);
132 }
133 
ServiceRestartHookWrapper(const HOOK_INFO * hookInfo,void * executionContext)134 static int ServiceRestartHookWrapper(const HOOK_INFO *hookInfo, void *executionContext)
135 {
136     SERVICE_RESTART_CTX *serviceContext = (SERVICE_RESTART_CTX *)executionContext;
137     ServiceRestartHook realHook = (ServiceRestartHook)hookInfo->hookCookie;
138 
139     realHook(serviceContext);
140     return 0;
141 }
142 
InitServiceRestartHook(ServiceRestartHook hook,int hookState)143 int InitServiceRestartHook(ServiceRestartHook hook, int hookState)
144 {
145     HOOK_INFO info;
146 
147     info.stage = hookState;
148     info.prio = 0;
149     info.hook = ServiceRestartHookWrapper;
150     info.hookCookie = (void *)hook;
151 
152     return HookMgrAddEx(GetBootStageHookMgr(), &info);
153 }
154 
155 /**
156  * service hooking execute
157  */
ServiceHookExecute(const char * serviceName,const char * info,int stage)158 static void ServiceHookExecute(const char *serviceName, const char *info, int stage)
159 {
160     SERVICE_INFO_CTX context;
161 
162     context.serviceName = serviceName;
163     context.reserved = info;
164 
165     (void)HookMgrExecute(GetBootStageHookMgr(), stage, (void *)(&context), NULL);
166 }
167 #endif
168 
ServiceSetGid(const Service * service)169 static int ServiceSetGid(const Service *service)
170 {
171     if (service->servPerm.gIDCnt == 0) {
172         // use uid as gid
173         INIT_ERROR_CHECK(setgid(service->servPerm.uID) == 0, return SERVICE_FAILURE,
174             "Service error %d %s, failed to set gid.", errno, service->name);
175     }
176     if (service->servPerm.gIDCnt > 0) {
177         INIT_ERROR_CHECK(setgid(service->servPerm.gIDArray[0]) == 0, return SERVICE_FAILURE,
178             "Service error %d %s, failed to set gid.", errno, service->name);
179     }
180     if (service->servPerm.gIDCnt > 1) {
181         INIT_ERROR_CHECK(setgroups(service->servPerm.gIDCnt - 1, (const gid_t *)&service->servPerm.gIDArray[1]) == 0,
182             return SERVICE_FAILURE,
183             "Service error %d %s, failed to set gid.", errno, service->name);
184     }
185 
186     return SERVICE_SUCCESS;
187 }
188 
GetInvalidCaps(const Service * service,unsigned int * caps)189 static void GetInvalidCaps(const Service *service, unsigned int *caps)
190 {
191     int index = 0;
192     bool flags = false;
193     for (unsigned int cap = 0; cap <= CAP_LAST_CAP; cap++) {
194         for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) {
195             if (cap == service->servPerm.caps[i]) {
196                 flags = true;
197                 break;
198             }
199             flags = false;
200         }
201         if (!flags) {
202             caps[index] = cap;
203             index++;
204         }
205     }
206 }
207 
DropCapability(const Service * service)208 static void DropCapability(const Service *service)
209 {
210 #if defined(ENABLE_HOOK_MGR)
211     int invalidCnt = CAP_LAST_CAP - service->servPerm.capsCnt + 1;
212     unsigned int *caps = (unsigned int *)calloc(invalidCnt, sizeof(unsigned int));
213     INIT_ERROR_CHECK(caps != NULL, return, "calloc caps failed! error:%d", errno);
214 
215     GetInvalidCaps(service, caps);
216     for (int i = 0; i < invalidCnt; i++) {
217         if (prctl(PR_CAPBSET_DROP, caps[i])) {
218             INIT_LOGE("prctl PR_SET_SECUREBITS failed: %d", errno);
219             free(caps);
220             return;
221         }
222     }
223     free(caps);
224 #else
225     return;
226 #endif
227 }
228 
SetCapabilities(const Service * service)229 static int SetCapabilities(const Service *service)
230 {
231     struct __user_cap_header_struct capHeader;
232     capHeader.version = _LINUX_CAPABILITY_VERSION_3;
233     capHeader.pid = 0;
234     struct __user_cap_data_struct capData[CAP_NUM] = {};
235     for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) {
236         if (service->servPerm.caps[i] == FULL_CAP) {
237             for (int j = 0; j < CAP_NUM; ++j) {
238                 capData[j].effective = FULL_CAP;
239                 capData[j].permitted = FULL_CAP;
240                 capData[j].inheritable = FULL_CAP;
241             }
242             break;
243         }
244         capData[CAP_TO_INDEX(service->servPerm.caps[i])].effective |= CAP_TO_MASK(service->servPerm.caps[i]);
245         capData[CAP_TO_INDEX(service->servPerm.caps[i])].permitted |= CAP_TO_MASK(service->servPerm.caps[i]);
246         capData[CAP_TO_INDEX(service->servPerm.caps[i])].inheritable |= CAP_TO_MASK(service->servPerm.caps[i]);
247     }
248 
249     INIT_ERROR_CHECK(capset(&capHeader, capData) == 0, return SERVICE_FAILURE,
250         "capset failed for service: %s, error: %d", service->name, errno);
251     for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) {
252         if (service->servPerm.caps[i] == FULL_CAP) {
253             int ret = SetAllAmbientCapability();
254             INIT_ERROR_CHECK(ret == 0, return INIT_ECAP,
255                 "Service error %d %s, failed to set ambient capability.", errno, service->name);
256             return 0;
257         }
258         INIT_ERROR_CHECK(SetAmbientCapability(service->servPerm.caps[i]) == 0, return INIT_ECAP,
259             "Service error %d %s, failed to set ambient capability.", errno, service->name);
260     }
261     return 0;
262 }
SetPerms(const Service * service)263 static int SetPerms(const Service *service)
264 {
265 #if defined(ENABLE_HOOK_MGR)
266     /*
267      * service before setting Perms hooks
268      */
269     ServiceHookExecute(service->name, (const char *)service->pathArgs.argv[0], INIT_SERVICE_SET_PERMS_BEFORE);
270 #endif
271 #ifdef CODE_SIGNATURE_ENABLE
272     if (strcmp(service->name, "nwebspawn") == 0) {
273         INIT_LOGV("Set NWebspawn OwnerId");
274         // set nwebspawn OwnerId
275         (void)SetXpmOwnerId(PROCESS_OWNERID_NWEB, NULL);
276     }
277 #endif
278 
279     INIT_ERROR_CHECK(KeepCapability(service) == 0, return INIT_EKEEPCAP,
280         "Service error %d %s, failed to set keep capability.", errno, service->name);
281 
282     INIT_ERROR_CHECK(ServiceSetGid(service) == SERVICE_SUCCESS, return INIT_EGIDSET,
283         "Service error %d %s, failed to set gid.", errno, service->name);
284 
285     // set seccomp policy before setuid
286     INIT_ERROR_CHECK(SetSystemSeccompPolicy(service) == SERVICE_SUCCESS, return INIT_ESECCOMP,
287         "Service error %d %s, failed to set system seccomp policy.", errno, service->name);
288 
289     if (service->servPerm.uID != 0) {
290         INIT_ERROR_CHECK(setuid(service->servPerm.uID) == 0, return INIT_EUIDSET,
291             "Service error %d %s, failed to set uid.", errno, service->name);
292     } else {
293         if (service->servPerm.capsCnt != 0) {
294             DropCapability(service);
295         }
296     }
297     int ret = SetCapabilities(service);
298     INIT_ERROR_CHECK(ret == 0, return ret,
299         "Service error %d %s, failed to set capabilities.", errno, service->name);
300 
301 #if defined(ENABLE_HOOK_MGR)
302     /*
303      * service set Perms hooks
304      */
305     ServiceHookExecute(service->name, NULL, INIT_SERVICE_SET_PERMS);
306 #endif
307     return SERVICE_SUCCESS;
308 }
309 
WritePid(const Service * service)310 static int WritePid(const Service *service)
311 {
312     pid_t childPid = getpid();
313     for (int i = 0; i < service->writePidArgs.count; i++) {
314         if (service->writePidArgs.argv[i] == NULL) {
315             continue;
316         }
317         FILE *fd = NULL;
318         char *realPath = GetRealPath(service->writePidArgs.argv[i]);
319         if (realPath != NULL) {
320             fd = fopen(realPath, "wb");
321         } else {
322             fd = fopen(service->writePidArgs.argv[i], "wb");
323         }
324         if (fd != NULL) {
325             INIT_CHECK_ONLY_ELOG((int)fprintf(fd, "%d", childPid) > 0,
326                 "Failed to write %s pid:%d", service->writePidArgs.argv[i], childPid);
327             (void)fclose(fd);
328         } else {
329             INIT_LOGE("Failed to open realPath: %s  %s errno:%d.", realPath, service->writePidArgs.argv[i], errno);
330         }
331         if (realPath != NULL) {
332             free(realPath);
333         }
334         INIT_LOGV("ServiceStart writepid filename=%s, childPid=%d, ok", service->writePidArgs.argv[i], childPid);
335     }
336     return SERVICE_SUCCESS;
337 }
338 
CloseServiceFds(Service * service,bool needFree)339 void CloseServiceFds(Service *service, bool needFree)
340 {
341     INIT_ERROR_CHECK(service != NULL, return, "Service null");
342     INIT_LOGI("Closing service \' %s \' fds", service->name);
343     // fdCount > 0, There is no reason fds is NULL
344     if (service->fdCount != 0) {
345         size_t fdCount = service->fdCount;
346         int *fds = service->fds;
347         for (size_t i = 0; i < fdCount; i++) {
348             INIT_LOGV("Closing fd: %d", fds[i]);
349             if (fds[i] != -1) {
350                 close(fds[i]);
351                 fds[i] = -1;
352             }
353         }
354     }
355     service->fdCount = 0;
356     if (needFree && service->fds != NULL) {
357         free(service->fds);
358         service->fds = NULL;
359     }
360 }
361 
PublishHoldFds(Service * service)362 static int PublishHoldFds(Service *service)
363 {
364     INIT_ERROR_CHECK(service != NULL, return INIT_EPARAMETER, "Publish hold fds with invalid service");
365     if (service->fdCount == 0 || service->fds == NULL) {
366         return 0;
367     }
368     char fdBuffer[MAX_FD_HOLDER_BUFFER] = {};
369     char envName[MAX_BUFFER_LEN] = {};
370     int ret = snprintf_s(envName, MAX_BUFFER_LEN, MAX_BUFFER_LEN - 1, ENV_FD_HOLD_PREFIX"%s", service->name);
371     INIT_ERROR_CHECK(ret >= 0, return INIT_EFORMAT,
372         "Service error %d %s, failed to format string for publish", ret, service->name);
373 
374     size_t pos = 0;
375     for (size_t i = 0; i < service->fdCount; i++) {
376         int fd = dup(service->fds[i]);
377         if (fd < 0) {
378             INIT_LOGW("Service warning %d %s, failed to dup fd for publish", errno, service->name);
379             continue;
380         }
381         ret = snprintf_s((char *)fdBuffer + pos, sizeof(fdBuffer) - pos, sizeof(fdBuffer) - 1, "%d ", fd);
382         INIT_ERROR_CHECK(ret >= 0, close(fd); return INIT_EFORMAT,
383             "Service error %d %s, failed to format fd for publish", ret, service->name);
384         pos += (size_t)ret;
385     }
386     fdBuffer[pos - 1] = '\0'; // Remove last ' '
387     INIT_LOGI("Service %s publish fd [%s]", service->name, fdBuffer);
388     return setenv(envName, fdBuffer, 1);
389 }
390 
BindCpuCore(Service * service)391 static int BindCpuCore(Service *service)
392 {
393     if (service == NULL || service->cpuSet == NULL) {
394         return SERVICE_SUCCESS;
395     }
396     if (CPU_COUNT(service->cpuSet) == 0) {
397         return SERVICE_SUCCESS;
398     }
399 #ifndef __LITEOS_A__
400     int pid = getpid();
401     INIT_ERROR_CHECK(sched_setaffinity(pid, sizeof(cpu_set_t), service->cpuSet) == 0,
402         return SERVICE_FAILURE, "%s set affinity between process(pid=%d) with CPU's core failed", service->name, pid);
403     INIT_LOGI("%s set affinity between process(pid=%d) with CPU's core successfully", service->name, pid);
404 #endif
405     return SERVICE_SUCCESS;
406 }
407 
ClearEnvironment(Service * service)408 static void ClearEnvironment(Service *service)
409 {
410     if (strcmp(service->name, "appspawn") != 0 && strcmp(service->name, "nwebspawn") != 0) {
411         sigset_t mask;
412         sigemptyset(&mask);
413         sigaddset(&mask, SIGCHLD);
414         sigaddset(&mask, SIGTERM);
415         sigprocmask(SIG_UNBLOCK, &mask, NULL);
416     }
417     return;
418 }
419 
SetServiceEnv(Service * service)420 static void SetServiceEnv(Service *service)
421 {
422     INIT_CHECK(service->env != NULL, return);
423     for (int i = 0; i < service->envCnt; i++) {
424         if (strlen(service->env[i].name) > 0 && strlen(service->env[i].value) > 0) {
425             int ret = setenv(service->env[i].name, service->env[i].value, 1);
426             INIT_CHECK_ONLY_ELOG(ret != 0, "set service:%s env:%s failed! err=%d",
427                 service->name, service->env[i].name, errno);
428         }
429     }
430 }
431 
InitServiceProperties(Service * service,const ServiceArgs * pathArgs)432 static int InitServiceProperties(Service *service, const ServiceArgs *pathArgs)
433 {
434     INIT_ERROR_CHECK(service != NULL, return -1, "Invalid parameter.");
435     int ret = SetServiceEnterSandbox(service, pathArgs->argv[0]);
436     if (ret != 0) {
437         INIT_LOGW("Service warning %d %s, failed to enter sandbox.", ret, service->name);
438         service->lastErrno = INIT_ESANDBOX;
439     }
440     ret = SetAccessToken(service);
441     if (ret != 0) {
442         INIT_LOGW("Service warning %d %s, failed to set access token.", ret, service->name);
443         service->lastErrno = INIT_EACCESSTOKEN;
444     }
445 
446     SetServiceEnv(service);
447 
448     // deal start job
449     if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
450         DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]);
451         INIT_LOGI("Deal service %s job end", service->name);
452     }
453     ClearEnvironment(service);
454     if (!IsOnDemandService(service)) {
455         INIT_ERROR_CHECK(CreateSocketForService(service) == 0, service->lastErrno = INIT_ESOCKET;
456             return INIT_ESOCKET, "Service error %d %s, failed to create service socket.", errno, service->name);
457     }
458     SetSocketEnvForService(service);
459     INIT_ERROR_CHECK(CreateServiceFile(service) == 0, service->lastErrno = INIT_EFILE;
460         return INIT_EFILE, "Service error %d %s, failed to create service file.", errno, service->name);
461 
462     if ((service->attribute & SERVICE_ATTR_CONSOLE)) {
463         INIT_ERROR_CHECK(OpenConsole() == 0, service->lastErrno = INIT_ECONSOLE;
464             return INIT_ECONSOLE, "Service error %d %s, failed to open console.", errno, service->name);
465     }
466     if ((service->attribute & SERVICE_ATTR_KMSG)) {
467         OpenKmsg();
468     }
469 
470     INIT_ERROR_CHECK(PublishHoldFds(service) == 0, service->lastErrno = INIT_EHOLDER;
471         return INIT_EHOLDER, "Service error %d %s, failed to publish fd", errno, service->name);
472 
473     INIT_CHECK_ONLY_ELOG(BindCpuCore(service) == SERVICE_SUCCESS,
474         "Service warning %d %s, failed to publish fd", errno, service->name);
475 
476     // write pid
477     INIT_ERROR_CHECK(WritePid(service) == SERVICE_SUCCESS, service->lastErrno = INIT_EWRITEPID;
478         return INIT_EWRITEPID, "Service error %d %s, failed to write pid.", errno, service->name);
479 
480     // permissions
481     ret = SetPerms(service);
482     INIT_ERROR_CHECK(ret == SERVICE_SUCCESS, service->lastErrno = ret;
483         return ret, "Service error %d %s, failed to set permissions.", ret, service->name);
484 
485     PluginExecCmdByName("setServiceContent", service->name);
486     return 0;
487 }
488 
EnterServiceSandbox(Service * service)489 void EnterServiceSandbox(Service *service)
490 {
491     INIT_ERROR_CHECK(InitServiceProperties(service, &service->pathArgs) == 0, return, "Failed init service property");
492     if (service->importance != 0) {
493         if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) {
494             INIT_LOGE("setpriority failed for %s, importance = %d, err=%d",
495                 service->name, service->importance, errno);
496                 _exit(0x7f); // 0x7f: user specified
497         }
498     }
499 #ifndef STARTUP_INIT_TEST
500     char *argv[] = { (char *)"/bin/sh", NULL };
501     INIT_CHECK_ONLY_ELOG(execv(argv[0], argv) == 0,
502         "service %s execv sh failed! err %d.", service->name, errno);
503     _exit(PROCESS_EXIT_CODE);
504 #endif
505 }
506 
507 #ifdef IS_DEBUG_VERSION
ServiceNeedDebug(char * name)508 static bool ServiceNeedDebug(char *name)
509 {
510     char nameValue[PARAM_VALUE_LEN_MAX] = {0};
511     unsigned int nameLen = PARAM_VALUE_LEN_MAX;
512     // specify process debugging: param set llvm.debug.service.name "service name"
513     if (SystemReadParam("llvm.debug.service.name", nameValue, &nameLen) == 0) {
514         if (strcmp(nameValue, name) == 0) {
515             return true;
516         }
517     }
518 
519     char debugValue[PARAM_VALUE_LEN_MAX] = {0};
520     unsigned int debugLen = PARAM_VALUE_LEN_MAX;
521     // multi process debugging: param set llvm.debug.service.all 1
522     if (SystemReadParam("llvm.debug.service.all", debugValue, &debugLen) == 0) {
523         if (strcmp(debugValue, "1") == 0) {
524             return true;
525         }
526     }
527     return false;
528 }
529 
IsDebuggableVersion(void)530 static bool IsDebuggableVersion(void)
531 {
532     char secureValue[PARAM_VALUE_LEN_MAX] = {0};
533     unsigned int secureLen = PARAM_VALUE_LEN_MAX;
534     char debugValue[PARAM_VALUE_LEN_MAX] = {0};
535     unsigned int debugLen = PARAM_VALUE_LEN_MAX;
536     // the image is debuggable only when secureValue is 0 and debugValue is 1
537     if (SystemReadParam("const.secure", secureValue, &secureLen) == 0 &&
538         SystemReadParam("const.debuggable", debugValue, &debugLen) == 0) {
539         if (strcmp(secureValue, "0") == 0 &&
540             strcmp(debugValue, "1") == 0) {
541             return true;
542         }
543     }
544     return false;
545 }
546 
CheckTraceStatus(void)547 static int32_t CheckTraceStatus(void)
548 {
549     int fd = open("/proc/self/status", O_RDONLY);
550     if (fd == -1) {
551         INIT_LOGE("lldb: open /proc/self/status error: %{public}d", errno);
552         return (-errno);
553     }
554 
555     char data[1024] = { 0 };  // 1024 data len
556     ssize_t dataNum = read(fd, data, sizeof(data));
557     if (close(fd) < 0) {
558         INIT_LOGE("lldb: close fd error: %{public}d", errno);
559         return (-errno);
560     }
561 
562     if (dataNum <= 0) {
563         INIT_LOGE("lldb: fail to read data");
564         return -1;
565     }
566 
567     const char* tracerPid = "TracerPid:\t";
568     data[1023] = '\0'; // 1023 data last position
569     char *traceStr = strstr(data, tracerPid);
570     if (traceStr == NULL) {
571         INIT_LOGE("lldb: fail to find %{public}s", tracerPid);
572         return -1;
573     }
574     char *separator = strchr(traceStr, '\n');
575     if (separator == NULL) {
576         INIT_LOGE("lldb: fail to find line break");
577         return -1;
578     }
579 
580     int len = separator - traceStr - strlen(tracerPid);
581     char pid = *(traceStr + strlen(tracerPid));
582     if (len > 1 || pid != '0') {
583         return 0;
584     }
585     return -1;
586 }
587 
WaitForDebugger(void)588 static int32_t WaitForDebugger(void)
589 {
590     uint32_t count = 0;
591     while (CheckTraceStatus() != 0) {
592         usleep(1000 * 100); // sleep 1000 * 100 microsecond
593         count++;
594         // remind users to connect to the debugger every 60 * 10 times
595         if (count % (10 * 60) == 0) {
596             INIT_LOGI("lldb: wait for debugger, please attach the process");
597             count = 0;
598         }
599     }
600     return 0;
601 }
602 #endif
603 
CloseOnDemandServiceFdForOtherService(Service * service)604 static void CloseOnDemandServiceFdForOtherService(Service *service)
605 {
606     ServiceSocket *tmpSockNode = GetOnDemandSocketList();
607     while (tmpSockNode != NULL) {
608         if (tmpSockNode->service != service) {
609             ServiceSocket *tmpCloseSocket = tmpSockNode;
610             // If the service is not the OnDemand service itself, will close the OnDemand service socket fd
611             while (tmpCloseSocket != NULL) {
612                 close(tmpCloseSocket->sockFd);
613                 tmpCloseSocket = tmpCloseSocket->next;
614             }
615         }
616         tmpSockNode = tmpSockNode->nextNode;
617     }
618 }
619 
RunChildProcess(Service * service,ServiceArgs * pathArgs)620 static void RunChildProcess(Service *service, ServiceArgs *pathArgs)
621 {
622     // set selinux label by context
623     if (service->context.type != INIT_CONTEXT_MAIN && SetSubInitContext(&service->context, service->name) != 0) {
624         service->lastErrno = INIT_ECONTENT;
625     }
626 
627     CloseOnDemandServiceFdForOtherService(service);
628 
629 #ifdef IS_DEBUG_VERSION
630     // only the image is debuggable and need debug, then wait for debugger
631     if (ServiceNeedDebug(service->name) && IsDebuggableVersion()) {
632         WaitForDebugger();
633     }
634 #endif
635 #ifdef INIT_ASAN
636     CloseStdio();
637 #endif
638     // fail must exit sub process
639     int ret = InitServiceProperties(service, pathArgs);
640     INIT_ERROR_CHECK(ret == 0,
641         _exit(service->lastErrno), "Service error %d %s, failed to set properties", ret, service->name);
642 
643     (void)ServiceExec(service, pathArgs);
644     _exit(service->lastErrno);
645 }
646 
647 #define PATH_MAY_BE_NOT_EXISTS  "/data/"
648 
IsServiceInvalid(Service * service,ServiceArgs * pathArgs)649 static int IsServiceInvalid(Service *service, ServiceArgs *pathArgs)
650 {
651     if (service->attribute & SERVICE_ATTR_INVALID) {
652         INIT_LOGE("ServiceStart invalid:%s", service->name);
653         return SERVICE_FAILURE;
654     }
655     struct stat pathStat = { 0 };
656     service->attribute &= (~(SERVICE_ATTR_NEED_RESTART | SERVICE_ATTR_NEED_STOP));
657     if (stat(pathArgs->argv[0], &pathStat) != 0) {
658         if (strncmp(pathArgs->argv[0], PATH_MAY_BE_NOT_EXISTS, sizeof(PATH_MAY_BE_NOT_EXISTS) - 1) != 0) {
659             service->attribute |= SERVICE_ATTR_INVALID;
660         }
661         service->lastErrno = INIT_EPATH;
662         INIT_LOGE("ServiceStart pathArgs invalid, please check %s,%s", service->name, service->pathArgs.argv[0]);
663         return SERVICE_FAILURE;
664     }
665     return SERVICE_SUCCESS;
666 }
667 
ServiceStart(Service * service,ServiceArgs * pathArgs)668 int ServiceStart(Service *service, ServiceArgs *pathArgs)
669 {
670     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "ServiceStart failed! null ptr.");
671     INIT_INFO_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "ServiceStart already started:%s", service->name);
672     INIT_ERROR_CHECK(pathArgs != NULL && pathArgs->count > 0,
673         return SERVICE_FAILURE, "ServiceStart pathArgs is NULL:%s", service->name);
674     struct timespec startingTime;
675     clock_gettime(CLOCK_REALTIME, &startingTime);
676     INIT_LOGI("ServiceStart starting:%s", service->name);
677     if (IsServiceInvalid(service, pathArgs) != 0) {
678         INIT_LOGE("IsServiceInvalid falied: %s", service->name);
679         return SERVICE_FAILURE;
680     }
681 #if defined(ENABLE_HOOK_MGR)
682     // before service fork hooks
683     ServiceHookExecute(service->name, NULL, INIT_SERVICE_FORK_BEFORE);
684 #endif
685     // pre-start job
686     if (service->serviceJobs.jobsName[JOB_PRE_START] != NULL) {
687         DoJobNow(service->serviceJobs.jobsName[JOB_PRE_START]);
688     }
689     struct timespec preforkTime;
690     clock_gettime(CLOCK_REALTIME, &preforkTime);
691     int pid = fork();
692     if (pid == 0) {
693         RunChildProcess(service, pathArgs);
694     } else if (pid < 0) {
695         INIT_LOGE("ServiceStart error failed to fork %d, %s", errno, service->name);
696         service->lastErrno = INIT_EFORK;
697         return SERVICE_FAILURE;
698     }
699     struct timespec startedTime;
700     clock_gettime(CLOCK_REALTIME, &startedTime);
701 
702     INIT_LOGI("ServiceStart started info %s(pid %d uid %d)", service->name, pid, service->servPerm.uID);
703     INIT_LOGI("starttime:%ld-%ld, prefork:%ld-%ld, startedtime:%ld-%ld",
704         startingTime.tv_sec, startingTime.tv_nsec, preforkTime.tv_sec,
705         preforkTime.tv_nsec, startedTime.tv_sec, startedTime.tv_nsec);
706 #ifndef OHOS_LITE
707     if (!IsOnDemandService(service)) {
708         ReportServiceStart(service->name, pid);
709     }
710 #endif
711     service->pid = pid;
712 #ifndef OHOS_LITE
713     (void)ProcessServiceAdd(service);
714 #endif
715     NotifyServiceChange(service, SERVICE_STARTED);
716 #if defined(ENABLE_HOOK_MGR)
717     // after service fork hooks
718     ServiceHookExecute(service->name, (const char *)&pid, INIT_SERVICE_FORK_AFTER);
719 #endif
720     return SERVICE_SUCCESS;
721 }
722 
ServiceStop(Service * service)723 int ServiceStop(Service *service)
724 {
725     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "stop service failed! null ptr.");
726     NotifyServiceChange(service, SERVICE_STOPPING);
727     if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) {
728         DoJobNow(service->serviceJobs.jobsName[JOB_ON_STOP]);
729     }
730     service->attribute &= ~SERVICE_ATTR_NEED_RESTART;
731     service->attribute |= SERVICE_ATTR_NEED_STOP;
732     if (service->pid <= 0) {
733         return SERVICE_SUCCESS;
734     }
735     CloseServiceSocket(service);
736     CloseServiceFile(service->fileCfg);
737     // Service stop means service is killed by init or command(i.e stop_service) or system is rebooting
738     // There is no reason still to hold fds
739     if (service->fdCount != 0) {
740         CloseServiceFds(service, true);
741     }
742 
743     if (IsServiceWithTimerEnabled(service)) {
744         ServiceStopTimer(service);
745     }
746     INIT_ERROR_CHECK(kill(service->pid, GetKillServiceSig(service->name)) == 0, return SERVICE_FAILURE,
747         "stop service %s pid %d failed! err %d.", service->name, service->pid, errno);
748     INIT_LOGI("stop service %s, pid %d.", service->name, service->pid);
749 #ifndef OHOS_LITE
750     (void)ProcessServiceDied(service);
751 #endif
752     service->pid = -1;
753     NotifyServiceChange(service, SERVICE_STOPPED);
754     return SERVICE_SUCCESS;
755 }
756 
ServiceTerm(Service * service)757 int ServiceTerm(Service *service)
758 {
759     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "stop service failed! null ptr.");
760     NotifyServiceChange(service, SERVICE_STOPPING);
761     if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) {
762         DoJobNow(service->serviceJobs.jobsName[JOB_ON_STOP]);
763     }
764     service->attribute &= ~SERVICE_ATTR_NEED_RESTART;
765     service->attribute |= SERVICE_ATTR_NEED_STOP;
766     if (service->pid <= 0) {
767         return SERVICE_SUCCESS;
768     }
769     CloseServiceSocket(service);
770     CloseServiceFile(service->fileCfg);
771     // Service stop means service is killed by init or command(i.e stop_service) or system is rebooting
772     // There is no reason still to hold fds
773     if (service->fdCount != 0) {
774         CloseServiceFds(service, true);
775     }
776 
777     if (IsServiceWithTimerEnabled(service)) {
778         ServiceStopTimer(service);
779     }
780     INIT_ERROR_CHECK(kill(service->pid, SIGTERM) == 0, return SERVICE_FAILURE,
781         "stop service %s pid %d failed! err %d.", service->name, service->pid, errno);
782     INIT_LOGI("stop service %s, pid %d.", service->name, service->pid);
783 #ifndef OHOS_LITE
784     (void)ProcessServiceDied(service);
785 #endif
786     service->pid = -1;
787     NotifyServiceChange(service, SERVICE_STOPPED);
788     return SERVICE_SUCCESS;
789 }
790 
CalculateCrashTime(Service * service,int crashTimeLimit,int crashCountLimit)791 static bool CalculateCrashTime(Service *service, int crashTimeLimit, int crashCountLimit)
792 {
793     INIT_ERROR_CHECK(service != NULL && crashTimeLimit > 0 && crashCountLimit > 0,
794         return false, "input params error.");
795     struct timespec curTime = {0};
796     (void)clock_gettime(CLOCK_MONOTONIC, &curTime);
797     struct timespec crashTime = {service->firstCrashTime, 0};
798     if (service->crashCnt == 0) {
799         service->firstCrashTime = (uint32_t)curTime.tv_sec;
800         ++service->crashCnt;
801         if (service->crashCnt == crashCountLimit) {
802             return false;
803         }
804     } else if (IntervalTime(&crashTime, &curTime) > (uint32_t)crashTimeLimit) {
805         service->firstCrashTime = (uint32_t)curTime.tv_sec;
806         service->crashCnt = 1;
807     } else {
808         ++service->crashCnt;
809         if (service->crashCnt >= crashCountLimit) {
810             return false;
811         }
812     }
813     return true;
814 }
815 
ExecRestartCmd(Service * service)816 static int ExecRestartCmd(Service *service)
817 {
818     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Exec service failed! null ptr.");
819     if (service->restartArg == NULL) {
820         return SERVICE_SUCCESS;
821     }
822     for (int i = 0; i < service->restartArg->cmdNum; i++) {
823         INIT_LOGI("ExecRestartCmd cmdLine->cmdContent %s ", service->restartArg->cmds[i].cmdContent);
824         DoCmdByIndex(service->restartArg->cmds[i].cmdIndex, service->restartArg->cmds[i].cmdContent, NULL);
825     }
826     free(service->restartArg);
827     service->restartArg = NULL;
828     return SERVICE_SUCCESS;
829 }
830 
CheckServiceSocket(Service * service)831 static void CheckServiceSocket(Service *service)
832 {
833     if (service->socketCfg == NULL) {
834         return;
835     }
836     ServiceSocket *tmpSock = service->socketCfg;
837     while (tmpSock != NULL) {
838         if (tmpSock->sockFd <= 0) {
839             INIT_LOGE("Invalid socket %s for service", service->name);
840             tmpSock = tmpSock->next;
841         }
842         AddSocketWatcher(&tmpSock->watcher, service, tmpSock->sockFd);
843         tmpSock = tmpSock->next;
844     }
845     return;
846 }
847 
IsDebugMode(void)848 static bool IsDebugMode(void)
849 {
850     char secureValue[PARAM_VALUE_LEN_MAX] = {0};
851     unsigned int secureLen = PARAM_VALUE_LEN_MAX;
852     char debugValue[PARAM_VALUE_LEN_MAX] = {0};
853     unsigned int debugLen = PARAM_VALUE_LEN_MAX;
854     // the image is debuggable only when secureValue is 0 and debugValue is 1
855     if (SystemReadParam("const.secure", secureValue, &secureLen) == 0 &&
856         SystemReadParam("const.debuggable", debugValue, &debugLen) == 0) {
857         if (strcmp(secureValue, "0") == 0 &&
858             strcmp(debugValue, "1") == 0) {
859             return true;
860         }
861     }
862     return false;
863 }
864 
CheckOndemandService(Service * service)865 static void CheckOndemandService(Service *service)
866 {
867     CheckServiceSocket(service);
868     if (strcmp(service->name, "console") == 0 && IsDebugMode()) {
869         INIT_LOGI("Watch console service in debug mode");
870         if (WatchConsoleDevice(service) < 0) {
871             INIT_LOGE("Failed to watch console service after it exit, mark console service invalid");
872             service->attribute |= SERVICE_ATTR_INVALID;
873         }
874     }
875 }
876 
ServiceReapHookExecute(Service * service)877 static void ServiceReapHookExecute(Service *service)
878 {
879 #if defined(ENABLE_HOOK_MGR)
880     HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_REAP, (void*)service, NULL);
881 #endif
882 }
883 
ServiceReap(Service * service)884 void ServiceReap(Service *service)
885 {
886     INIT_CHECK(service != NULL, return);
887     INIT_LOGI("ServiceReap info %s pid %d.", service->name, service->pid);
888     NotifyServiceChange(service, SERVICE_STOPPED);
889     int tmp = service->pid;
890     service->pid = -1;
891 
892     if (service->attribute & SERVICE_ATTR_INVALID) {
893         INIT_LOGE("ServiceReap error invalid service %s", service->name);
894         return;
895     }
896 
897     // If the service set timer
898     // which means the timer handler will start the service
899     // Init should not start it automatically.
900     INIT_CHECK(IsServiceWithTimerEnabled(service) == 0, return);
901     if (!IsOnDemandService(service)) {
902         CloseServiceSocket(service);
903     }
904     CloseServiceFile(service->fileCfg);
905     // stopped by system-init itself, no need to restart even if it is not one-shot service
906     if (service->attribute & SERVICE_ATTR_NEED_STOP) {
907         service->attribute &= (~SERVICE_ATTR_NEED_STOP);
908         service->crashCnt = 0;
909         return;
910     }
911 
912     // for one-shot service
913     if (service->attribute & SERVICE_ATTR_ONCE) {
914         // no need to restart
915         if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
916             service->attribute &= (~SERVICE_ATTR_NEED_STOP);
917             return;
918         }
919         // the service could be restart even if it is one-shot service
920     }
921 
922     if (service->attribute & SERVICE_ATTR_PERIOD) { //period
923         ServiceStartTimer(service, service->period);
924         return;
925     }
926 
927     // service no need to restart if it is an ondemand service.
928     if (IsOnDemandService(service)) {
929         CheckOndemandService(service);
930         return;
931     }
932 
933     if (service->attribute & SERVICE_ATTR_CRITICAL) { // critical
934         if (!CalculateCrashTime(service, service->crashTime, service->crashCount)) {
935             INIT_LOGE("ServiceReap error critical service crashed %s %d", service->name, service->crashCount);
936             service->pid = tmp;
937             ServiceReapHookExecute(service);
938             service->pid = -1;
939             ExecReboot("panic");
940         }
941     } else if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
942         if (!CalculateCrashTime(service, service->crashTime, service->crashCount)) {
943             INIT_LOGI("ServiceReap start failed! %s will reStart %d second later", service->name, service->crashTime);
944             service->crashCnt = 0;
945             ServiceReStartTimer(service, DEF_CRASH_TIME);
946             return;
947         }
948     }
949 
950     int ret = ExecRestartCmd(service);
951     INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "ServiceReap Failed to exec restartArg for %s", service->name);
952 
953     if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
954         DoJobNow(service->serviceJobs.jobsName[JOB_ON_RESTART]);
955     }
956     ret = ServiceStart(service, &service->pathArgs);
957     INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "ServiceReap ServiceStart failed %s", service->name);
958     service->attribute &= (~SERVICE_ATTR_NEED_RESTART);
959 }
960 
UpdaterServiceFds(Service * service,int * fds,size_t fdCount)961 int UpdaterServiceFds(Service *service, int *fds, size_t fdCount)
962 {
963     if (service == NULL || fds == NULL) {
964         INIT_LOGE("Invalid service info or fds");
965         return -1;
966     }
967 
968     if (fdCount == 0) {
969         INIT_LOGE("Update service fds with fdCount is 0, ignore.");
970         return 0;
971     }
972 
973     // if service->fds is NULL, allocate new memory to hold the fds
974     // else if service->fds is not NULL, we will try to override it.
975     // There are two cases:
976     // 1) service->fdCount != fdCount:
977     //  It is not easy to re-use the memory of service->fds, so we have to free the memory first
978     //  then re-allocate memory to store new fds
979     // 2) service->fdCount == fdCount
980     //  A situation we happy to meet, just override it.
981 
982     int ret = 0;
983     if (service->fdCount == fdCount) {
984         // case 2
985         CloseServiceFds(service, false);
986         if (memcpy_s(service->fds, sizeof(int) * (fdCount + 1), fds, sizeof(int) * fdCount) != 0) {
987             INIT_LOGE("Failed to copy fds to service");
988             // Something wrong happened, maybe service->fds is broken, clear it.
989             free(service->fds);
990             service->fds = NULL;
991             service->fdCount = 0;
992             ret = -1;
993         } else {
994             service->fdCount = fdCount;
995         }
996     } else {
997         if (service->fdCount > 0) {
998             // case 1
999             CloseServiceFds(service, true);
1000         }
1001         INIT_ERROR_CHECK(fdCount <= MAX_HOLD_FDS, return -1, "Invalid fdCount %d", fdCount);
1002         service->fds = calloc(fdCount + 1, sizeof(int));
1003         if (service->fds == NULL) {
1004             INIT_LOGE("Service \' %s \' failed to allocate memory for fds", service->name);
1005             ret = -1;
1006         } else {
1007             if (memcpy_s(service->fds, sizeof(int) * (fdCount + 1), fds, sizeof(int) * fdCount) != 0) {
1008                 INIT_LOGE("Failed to copy fds to service");
1009                 // Something wrong happened, maybe service->fds is broken, clear it.
1010                 free(service->fds);
1011                 service->fds = NULL;
1012                 service->fdCount = 0;
1013                 return -1;
1014             } else {
1015                 service->fdCount = fdCount;
1016             }
1017         }
1018     }
1019     INIT_LOGI("Hold fd for service \' %s \' done", service->name);
1020     return ret;
1021 }
1022 
ServiceStopTimer(Service * service)1023 void ServiceStopTimer(Service *service)
1024 {
1025     INIT_ERROR_CHECK(service != NULL, return, "Stop timer with invalid service");
1026     if (IsServiceWithTimerEnabled(service)) {
1027         // Stop timer first
1028         if (service->timer) {
1029             LE_StopTimer(LE_GetDefaultLoop(), service->timer);
1030         }
1031         service->timer = NULL;
1032         DisableServiceTimer(service);
1033     }
1034 }
1035 
ServiceTimerStartProcess(const TimerHandle handler,void * context)1036 static void ServiceTimerStartProcess(const TimerHandle handler, void *context)
1037 {
1038     UNUSED(handler);
1039     Service *service = (Service *)context;
1040 
1041     if (service == NULL) {
1042         INIT_LOGE("Service timer process with invalid service");
1043         return;
1044     }
1045 
1046     // OK, service is ready to start.
1047     // Before start the service, stop service timer.
1048     // make sure it will not enter timer handler next time.
1049     ServiceStopTimer(service);
1050     int ret = ServiceStart(service, &service->pathArgs);
1051     if (ret != SERVICE_SUCCESS) {
1052         INIT_LOGE("Start service \' %s \' in timer failed", service->name);
1053     }
1054 }
1055 
ServiceTimerReStartProcess(const TimerHandle handler,void * context)1056 static void ServiceTimerReStartProcess(const TimerHandle handler, void *context)
1057 {
1058     UNUSED(handler);
1059     Service *service = (Service *)context;
1060 
1061     if (service == NULL) {
1062         INIT_LOGE("Service timer process with invalid service");
1063         return;
1064     }
1065 
1066     // OK, service is ready to start.
1067     // Before start the service, stop service timer.
1068     // make sure it will not enter timer handler next time.
1069     ServiceStopTimer(service);
1070 
1071     if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
1072         DoJobNow(service->serviceJobs.jobsName[JOB_ON_RESTART]);
1073     }
1074     int ret = ServiceStart(service, &service->pathArgs);
1075     if (ret != SERVICE_SUCCESS) {
1076         INIT_LOGE("Start service \' %s \' in timer failed", service->name);
1077     }
1078 }
1079 
ServiceStartTimer(Service * service,uint64_t timeout)1080 void ServiceStartTimer(Service *service, uint64_t timeout)
1081 {
1082     bool oldTimerClean = false;
1083     INIT_ERROR_CHECK(service != NULL, return, "Start timer with invalid service");
1084     // If the service already set a timer.
1085     // And a new request coming. close it and create a new one.
1086     if (IsServiceWithTimerEnabled(service)) {
1087         ServiceStopTimer(service);
1088         oldTimerClean = true;
1089     }
1090     LE_STATUS status = LE_CreateTimer(LE_GetDefaultLoop(), &service->timer, ServiceTimerStartProcess,
1091         (void *)service);
1092     if (status != LE_SUCCESS) {
1093         INIT_LOGE("Create service timer for service \' %s \' failed, status = %d", service->name, status);
1094         if (oldTimerClean) {
1095             INIT_LOGE("previous timer is cleared");
1096         }
1097         return;
1098     }
1099     status = LE_StartTimer(LE_GetDefaultLoop(), service->timer, timeout, 1);
1100     INIT_ERROR_CHECK(status == LE_SUCCESS, return,
1101         "Start service timer for service \' %s \' failed, status = %d", service->name, status);
1102     EnableServiceTimer(service);
1103 }
1104 
ServiceReStartTimer(Service * service,uint64_t timeout)1105 void ServiceReStartTimer(Service *service, uint64_t timeout)
1106 {
1107     bool oldTimerClean = false;
1108     INIT_ERROR_CHECK(service != NULL, return, "Start timer with invalid service");
1109     // If the service already set a timer.
1110     // And a new request coming. close it and create a new one.
1111     if (IsServiceWithTimerEnabled(service)) {
1112         ServiceStopTimer(service);
1113         oldTimerClean = true;
1114     }
1115     LE_STATUS status = LE_CreateTimer(LE_GetDefaultLoop(), &service->timer, ServiceTimerReStartProcess,
1116         (void *)service);
1117     if (status != LE_SUCCESS) {
1118         INIT_LOGE("Create service timer for service \' %s \' failed, status = %d", service->name, status);
1119         if (oldTimerClean) {
1120             INIT_LOGE("previous timer is cleared");
1121         }
1122         return;
1123     }
1124     status = LE_StartTimer(LE_GetDefaultLoop(), service->timer, timeout, 1);
1125     INIT_ERROR_CHECK(status == LE_SUCCESS, return,
1126         "Start service timer for service \' %s \' failed, status = %d", service->name, status);
1127     EnableServiceTimer(service);
1128 }
1129