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