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