• 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 #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 #if defined(ENABLE_HOOK_MGR)
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 #if defined(ENABLE_HOOK_MGR)
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 #if defined(ENABLE_HOOK_MGR)
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 #if defined(ENABLE_HOOK_MGR)
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! err=%d",
409                 service->name, service->env[i].name, errno);
410         }
411     }
412 }
413 
InitServiceProperties(Service * service,const ServiceArgs * pathArgs)414 static int InitServiceProperties(Service *service, const ServiceArgs *pathArgs)
415 {
416     INIT_ERROR_CHECK(service != NULL, return -1, "Invalid parameter.");
417     int ret = SetServiceEnterSandbox(service, pathArgs->argv[0]);
418     if (ret != 0) {
419         INIT_LOGW("Service warning %d %s, failed to enter sandbox.", ret, service->name);
420         service->lastErrno = INIT_ESANDBOX;
421     }
422     ret = SetAccessToken(service);
423     if (ret != 0) {
424         INIT_LOGW("Service warning %d %s, failed to set access token.", ret, service->name);
425         service->lastErrno = INIT_EACCESSTOKEN;
426     }
427 
428     SetServiceEnv(service);
429 
430     // deal start job
431     if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
432         DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]);
433         INIT_LOGI("Deal service %s job end", service->name);
434     }
435     ClearEnvironment(service);
436     if (!IsOnDemandService(service)) {
437         INIT_ERROR_CHECK(CreateSocketForService(service) == 0, service->lastErrno = INIT_ESOCKET;
438             return INIT_ESOCKET, "Service error %d %s, failed to create service socket.", errno, service->name);
439     }
440     SetSocketEnvForService(service);
441     INIT_ERROR_CHECK(CreateServiceFile(service) == 0, service->lastErrno = INIT_EFILE;
442         return INIT_EFILE, "Service error %d %s, failed to create service file.", errno, service->name);
443 
444     if ((service->attribute & SERVICE_ATTR_CONSOLE)) {
445         INIT_ERROR_CHECK(OpenConsole() == 0, service->lastErrno = INIT_ECONSOLE;
446             return INIT_ECONSOLE, "Service error %d %s, failed to open console.", errno, service->name);
447     }
448     if ((service->attribute & SERVICE_ATTR_KMSG)) {
449         OpenKmsg();
450     }
451 
452     INIT_ERROR_CHECK(PublishHoldFds(service) == 0, service->lastErrno = INIT_EHOLDER;
453         return INIT_EHOLDER, "Service error %d %s, failed to publish fd", errno, service->name);
454 
455     INIT_CHECK_ONLY_ELOG(BindCpuCore(service) == SERVICE_SUCCESS,
456         "Service warning %d %s, failed to publish fd", errno, service->name);
457 
458     // write pid
459     INIT_ERROR_CHECK(WritePid(service) == SERVICE_SUCCESS, service->lastErrno = INIT_EWRITEPID;
460         return INIT_EWRITEPID, "Service error %d %s, failed to write pid.", errno, service->name);
461 
462     // permissions
463     ret = SetPerms(service);
464     INIT_ERROR_CHECK(ret == SERVICE_SUCCESS, service->lastErrno = ret;
465         return ret, "Service error %d %s, failed to set permissions.", ret, service->name);
466 
467     PluginExecCmdByName("setServiceContent", service->name);
468     return 0;
469 }
470 
EnterServiceSandbox(Service * service)471 void EnterServiceSandbox(Service *service)
472 {
473     INIT_ERROR_CHECK(InitServiceProperties(service, &service->pathArgs) == 0, return, "Failed init service property");
474     if (service->importance != 0) {
475         if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) {
476             INIT_LOGE("setpriority failed for %s, importance = %d, err=%d",
477                 service->name, service->importance, errno);
478                 _exit(0x7f); // 0x7f: user specified
479         }
480     }
481 #ifndef STARTUP_INIT_TEST
482     char *argv[] = { (char *)"/bin/sh", NULL };
483     INIT_CHECK_ONLY_ELOG(execv(argv[0], argv) == 0,
484         "service %s execv sh failed! err %d.", service->name, errno);
485     _exit(PROCESS_EXIT_CODE);
486 #endif
487 }
488 
489 #ifdef IS_DEBUG_VERSION
ServiceNeedDebug(char * name)490 static bool ServiceNeedDebug(char *name)
491 {
492     char nameValue[PARAM_VALUE_LEN_MAX] = {0};
493     unsigned int nameLen = PARAM_VALUE_LEN_MAX;
494     // specify process debugging: param set llvm.debug.service.name "service name"
495     if (SystemReadParam("llvm.debug.service.name", nameValue, &nameLen) == 0) {
496         if (strcmp(nameValue, name) == 0) {
497             return true;
498         }
499     }
500 
501     char debugValue[PARAM_VALUE_LEN_MAX] = {0};
502     unsigned int debugLen = PARAM_VALUE_LEN_MAX;
503     // multi process debugging: param set llvm.debug.service.all 1
504     if (SystemReadParam("llvm.debug.service.all", debugValue, &debugLen) == 0) {
505         if (strcmp(debugValue, "1") == 0) {
506             return true;
507         }
508     }
509     return false;
510 }
511 
IsDebuggableVersion(void)512 static bool IsDebuggableVersion(void)
513 {
514     char secureValue[PARAM_VALUE_LEN_MAX] = {0};
515     unsigned int secureLen = PARAM_VALUE_LEN_MAX;
516     char debugValue[PARAM_VALUE_LEN_MAX] = {0};
517     unsigned int debugLen = PARAM_VALUE_LEN_MAX;
518     // the image is debuggable only when secureValue is 0 and debugValue is 1
519     if (SystemReadParam("const.secure", secureValue, &secureLen) == 0 &&
520         SystemReadParam("const.debuggable", debugValue, &debugLen) == 0) {
521         if (strcmp(secureValue, "0") == 0 &&
522             strcmp(debugValue, "1") == 0) {
523             return true;
524         }
525     }
526     return false;
527 }
528 
CheckTraceStatus(void)529 static int32_t CheckTraceStatus(void)
530 {
531     int fd = open("/proc/self/status", O_RDONLY);
532     if (fd == -1) {
533         INIT_LOGE("lldb: open /proc/self/status error: %{public}d", errno);
534         return (-errno);
535     }
536 
537     char data[1024] = { 0 };  // 1024 data len
538     ssize_t dataNum = read(fd, data, sizeof(data));
539     if (close(fd) < 0) {
540         INIT_LOGE("lldb: close fd error: %{public}d", errno);
541         return (-errno);
542     }
543 
544     if (dataNum <= 0) {
545         INIT_LOGE("lldb: fail to read data");
546         return -1;
547     }
548 
549     const char* tracerPid = "TracerPid:\t";
550     data[1023] = '\0'; // 1023 data last position
551     char *traceStr = strstr(data, tracerPid);
552     if (traceStr == NULL) {
553         INIT_LOGE("lldb: fail to find %{public}s", tracerPid);
554         return -1;
555     }
556     char *separator = strchr(traceStr, '\n');
557     if (separator == NULL) {
558         INIT_LOGE("lldb: fail to find line break");
559         return -1;
560     }
561 
562     int len = separator - traceStr - strlen(tracerPid);
563     char pid = *(traceStr + strlen(tracerPid));
564     if (len > 1 || pid != '0') {
565         return 0;
566     }
567     return -1;
568 }
569 
WaitForDebugger(void)570 static int32_t WaitForDebugger(void)
571 {
572     uint32_t count = 0;
573     while (CheckTraceStatus() != 0) {
574         usleep(1000 * 100); // sleep 1000 * 100 microsecond
575         count++;
576         // remind users to connect to the debugger every 60 * 10 times
577         if (count % (10 * 60) == 0) {
578             INIT_LOGI("lldb: wait for debugger, please attach the process");
579             count = 0;
580         }
581     }
582     return 0;
583 }
584 #endif
585 
CloseOnDemandServiceFdForOtherService(Service * service)586 static void CloseOnDemandServiceFdForOtherService(Service *service)
587 {
588     ServiceSocket *tmpSockNode = GetOnDemandSocketList();
589     while (tmpSockNode != NULL) {
590         if (tmpSockNode->service != service) {
591             ServiceSocket *tmpCloseSocket = tmpSockNode;
592             // If the service is not the OnDemand service itself, will close the OnDemand service socket fd
593             while (tmpCloseSocket != NULL) {
594                 close(tmpCloseSocket->sockFd);
595                 tmpCloseSocket = tmpCloseSocket->next;
596             }
597         }
598         tmpSockNode = tmpSockNode->nextNode;
599     }
600 }
601 
RunChildProcess(Service * service,ServiceArgs * pathArgs)602 static void RunChildProcess(Service *service, ServiceArgs *pathArgs)
603 {
604     // set selinux label by context
605     if (service->context.type != INIT_CONTEXT_MAIN && SetSubInitContext(&service->context, service->name) != 0) {
606         service->lastErrno = INIT_ECONTENT;
607     }
608 
609     CloseOnDemandServiceFdForOtherService(service);
610 
611 #ifdef IS_DEBUG_VERSION
612     // only the image is debuggable and need debug, then wait for debugger
613     if (ServiceNeedDebug(service->name) && IsDebuggableVersion()) {
614         WaitForDebugger();
615     }
616 #endif
617 #ifdef INIT_ASAN
618     CloseStdio();
619 #endif
620     // fail must exit sub process
621     int ret = InitServiceProperties(service, pathArgs);
622     INIT_ERROR_CHECK(ret == 0,
623         _exit(service->lastErrno), "Service error %d %s, failed to set properties", ret, service->name);
624 
625     (void)ServiceExec(service, pathArgs);
626     _exit(service->lastErrno);
627 }
628 
IsServiceInvalid(Service * service,ServiceArgs * pathArgs)629 static int IsServiceInvalid(Service *service, ServiceArgs *pathArgs)
630 {
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     return SERVICE_SUCCESS;
644 }
645 
ServiceStart(Service * service,ServiceArgs * pathArgs)646 int ServiceStart(Service *service, ServiceArgs *pathArgs)
647 {
648     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "ServiceStart failed! null ptr.");
649     INIT_INFO_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "ServiceStart already started:%s", service->name);
650     INIT_ERROR_CHECK(pathArgs != NULL && pathArgs->count > 0,
651         return SERVICE_FAILURE, "ServiceStart pathArgs is NULL:%s", service->name);
652     struct timespec startingTime;
653     clock_gettime(CLOCK_REALTIME, &startingTime);
654     INIT_LOGI("ServiceStart starting:%s", service->name);
655     if (IsServiceInvalid(service, pathArgs) != 0) {
656         INIT_LOGE("IsServiceInvalid falied: %s", service->name);
657         return SERVICE_FAILURE;
658     }
659 #if defined(ENABLE_HOOK_MGR)
660     // before service fork hooks
661     ServiceHookExecute(service->name, NULL, INIT_SERVICE_FORK_BEFORE);
662 #endif
663     // pre-start job
664     if (service->serviceJobs.jobsName[JOB_PRE_START] != NULL) {
665         DoJobNow(service->serviceJobs.jobsName[JOB_PRE_START]);
666     }
667     struct timespec prefork;
668     clock_gettime(CLOCK_REALTIME, &prefork);
669     int pid = fork();
670     if (pid == 0) {
671         RunChildProcess(service, pathArgs);
672     } else if (pid < 0) {
673         INIT_LOGE("ServiceStart error failed to fork %d, %s", errno, service->name);
674         service->lastErrno = INIT_EFORK;
675         return SERVICE_FAILURE;
676     }
677     struct timespec startedTime;
678     clock_gettime(CLOCK_REALTIME, &startedTime);
679     INIT_LOGI("ServiceStart started info %s(pid %d uid %d)", service->name, pid, service->servPerm.uID);
680     INIT_LOGI("starttime:%ld-%ld,preforktime:%ld-%ld,startedtime:%ld-%ld",
681               startingTime.tv_sec, startingTime.tv_nsec, prefork.tv_sec,
682               prefork.tv_nsec, startedTime.tv_sec, startedTime.tv_nsec);
683 #ifndef OHOS_LITE
684     if (!IsOnDemandService(service)) {
685         ReportServiceStart(service->name, pid);
686     }
687 #endif
688     service->pid = pid;
689 #ifndef OHOS_LITE
690     (void)ProcessServiceAdd(service);
691 #endif
692     NotifyServiceChange(service, SERVICE_STARTED);
693 #if defined(ENABLE_HOOK_MGR)
694     // after service fork hooks
695     ServiceHookExecute(service->name, (const char *)&pid, INIT_SERVICE_FORK_AFTER);
696 #endif
697     return SERVICE_SUCCESS;
698 }
699 
ServiceStop(Service * service)700 int ServiceStop(Service *service)
701 {
702     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "stop service failed! null ptr.");
703     NotifyServiceChange(service, SERVICE_STOPPING);
704     if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) {
705         DoJobNow(service->serviceJobs.jobsName[JOB_ON_STOP]);
706     }
707     service->attribute &= ~SERVICE_ATTR_NEED_RESTART;
708     service->attribute |= SERVICE_ATTR_NEED_STOP;
709     if (service->pid <= 0) {
710         return SERVICE_SUCCESS;
711     }
712     CloseServiceSocket(service);
713     CloseServiceFile(service->fileCfg);
714     // Service stop means service is killed by init or command(i.e stop_service) or system is rebooting
715     // There is no reason still to hold fds
716     if (service->fdCount != 0) {
717         CloseServiceFds(service, true);
718     }
719 
720     if (IsServiceWithTimerEnabled(service)) {
721         ServiceStopTimer(service);
722     }
723     INIT_ERROR_CHECK(kill(service->pid, GetKillServiceSig(service->name)) == 0, return SERVICE_FAILURE,
724         "stop service %s pid %d failed! err %d.", service->name, service->pid, errno);
725     INIT_LOGI("stop service %s, pid %d.", service->name, service->pid);
726     service->pid = -1;
727     NotifyServiceChange(service, SERVICE_STOPPED);
728     return SERVICE_SUCCESS;
729 }
730 
CalculateCrashTime(Service * service,int crashTimeLimit,int crashCountLimit)731 static bool CalculateCrashTime(Service *service, int crashTimeLimit, int crashCountLimit)
732 {
733     INIT_ERROR_CHECK(service != NULL && crashTimeLimit > 0 && crashCountLimit > 0,
734         return false, "input params error.");
735     struct timespec curTime = {0};
736     (void)clock_gettime(CLOCK_MONOTONIC, &curTime);
737     struct timespec crashTime = {service->firstCrashTime, 0};
738     if (service->crashCnt == 0) {
739         service->firstCrashTime = (uint32_t)curTime.tv_sec;
740         ++service->crashCnt;
741         if (service->crashCnt == crashCountLimit) {
742             return false;
743         }
744     } else if (IntervalTime(&crashTime, &curTime) > (uint32_t)crashTimeLimit) {
745         service->firstCrashTime = (uint32_t)curTime.tv_sec;
746         service->crashCnt = 1;
747     } else {
748         ++service->crashCnt;
749         if (service->crashCnt >= crashCountLimit) {
750             return false;
751         }
752     }
753     return true;
754 }
755 
ExecRestartCmd(Service * service)756 static int ExecRestartCmd(Service *service)
757 {
758     INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Exec service failed! null ptr.");
759     if (service->restartArg == NULL) {
760         return SERVICE_SUCCESS;
761     }
762     for (int i = 0; i < service->restartArg->cmdNum; i++) {
763         INIT_LOGI("ExecRestartCmd cmdLine->cmdContent %s ", service->restartArg->cmds[i].cmdContent);
764         DoCmdByIndex(service->restartArg->cmds[i].cmdIndex, service->restartArg->cmds[i].cmdContent, NULL);
765     }
766     free(service->restartArg);
767     service->restartArg = NULL;
768     return SERVICE_SUCCESS;
769 }
770 
CheckServiceSocket(Service * service)771 static void CheckServiceSocket(Service *service)
772 {
773     if (service->socketCfg == NULL) {
774         return;
775     }
776     ServiceSocket *tmpSock = service->socketCfg;
777     while (tmpSock != NULL) {
778         if (tmpSock->sockFd <= 0) {
779             INIT_LOGE("Invalid socket %s for service", service->name);
780             tmpSock = tmpSock->next;
781         }
782         AddSocketWatcher(&tmpSock->watcher, service, tmpSock->sockFd);
783         tmpSock = tmpSock->next;
784     }
785     return;
786 }
787 
IsDebugMode()788 static bool IsDebugMode()
789 {
790     char secureValue[PARAM_VALUE_LEN_MAX] = {0};
791     unsigned int secureLen = PARAM_VALUE_LEN_MAX;
792     char debugValue[PARAM_VALUE_LEN_MAX] = {0};
793     unsigned int debugLen = PARAM_VALUE_LEN_MAX;
794     // the image is debuggable only when secureValue is 0 and debugValue is 1
795     if (SystemReadParam("const.secure", secureValue, &secureLen) == 0 &&
796         SystemReadParam("const.debuggable", debugValue, &debugLen) == 0) {
797         if (strcmp(secureValue, "0") == 0 &&
798             strcmp(debugValue, "1") == 0) {
799             return true;
800         }
801     }
802     return false;
803 }
804 
CheckOndemandService(Service * service)805 static void CheckOndemandService(Service *service)
806 {
807     CheckServiceSocket(service);
808     if (strcmp(service->name, "console") == 0 && IsDebugMode()) {
809         INIT_LOGI("Watch console service in debug mode");
810         if (WatchConsoleDevice(service) < 0) {
811             INIT_LOGE("Failed to watch console service after it exit, mark console service invalid");
812             service->attribute |= SERVICE_ATTR_INVALID;
813         }
814     }
815 }
816 
ServiceReapHookExecute(Service * service)817 static void ServiceReapHookExecute(Service *service)
818 {
819 #if defined(ENABLE_HOOK_MGR)
820     HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_REAP, (void*)service, NULL);
821 #endif
822 }
823 
ServiceReap(Service * service)824 void ServiceReap(Service *service)
825 {
826     INIT_CHECK(service != NULL, return);
827     INIT_LOGI("ServiceReap info %s pid %d.", service->name, service->pid);
828     NotifyServiceChange(service, SERVICE_STOPPED);
829     int tmp = service->pid;
830     service->pid = -1;
831 
832     if (service->attribute & SERVICE_ATTR_INVALID) {
833         INIT_LOGE("ServiceReap error invalid service %s", service->name);
834         return;
835     }
836 
837     // If the service set timer
838     // which means the timer handler will start the service
839     // Init should not start it automatically.
840     INIT_CHECK(IsServiceWithTimerEnabled(service) == 0, return);
841     if (!IsOnDemandService(service)) {
842         CloseServiceSocket(service);
843     }
844     CloseServiceFile(service->fileCfg);
845     // stopped by system-init itself, no need to restart even if it is not one-shot service
846     if (service->attribute & SERVICE_ATTR_NEED_STOP) {
847         service->attribute &= (~SERVICE_ATTR_NEED_STOP);
848         service->crashCnt = 0;
849         return;
850     }
851 
852     // for one-shot service
853     if (service->attribute & SERVICE_ATTR_ONCE) {
854         // no need to restart
855         if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
856             service->attribute &= (~SERVICE_ATTR_NEED_STOP);
857             return;
858         }
859         // the service could be restart even if it is one-shot service
860     }
861 
862     if (service->attribute & SERVICE_ATTR_PERIOD) { //period
863         ServiceStartTimer(service, service->period);
864         return;
865     }
866 
867     // service no need to restart if it is an ondemand service.
868     if (IsOnDemandService(service)) {
869         CheckOndemandService(service);
870         return;
871     }
872 
873     if (service->attribute & SERVICE_ATTR_CRITICAL) { // critical
874         if (!CalculateCrashTime(service, service->crashTime, service->crashCount)) {
875             INIT_LOGE("ServiceReap error critical service crashed %s %d", service->name, service->crashCount);
876             service->pid = tmp;
877             ServiceReapHookExecute(service);
878             service->pid = -1;
879             ExecReboot("panic");
880         }
881     } else if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
882         if (!CalculateCrashTime(service, service->crashTime, service->crashCount)) {
883             INIT_LOGI("ServiceReap start failed! %s will reStart %d second later", service->name, service->crashTime);
884             service->crashCnt = 0;
885             ServiceReStartTimer(service, DEF_CRASH_TIME);
886             return;
887         }
888     }
889 
890     int ret = ExecRestartCmd(service);
891     INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "ServiceReap Failed to exec restartArg for %s", service->name);
892 
893     if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
894         DoJobNow(service->serviceJobs.jobsName[JOB_ON_RESTART]);
895     }
896     ret = ServiceStart(service, &service->pathArgs);
897     INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "ServiceReap ServiceStart failed %s", service->name);
898     service->attribute &= (~SERVICE_ATTR_NEED_RESTART);
899 }
900 
UpdaterServiceFds(Service * service,int * fds,size_t fdCount)901 int UpdaterServiceFds(Service *service, int *fds, size_t fdCount)
902 {
903     if (service == NULL || fds == NULL) {
904         INIT_LOGE("Invalid service info or fds");
905         return -1;
906     }
907 
908     if (fdCount == 0) {
909         INIT_LOGE("Update service fds with fdCount is 0, ignore.");
910         return 0;
911     }
912 
913     // if service->fds is NULL, allocate new memory to hold the fds
914     // else if service->fds is not NULL, we will try to override it.
915     // There are two cases:
916     // 1) service->fdCount != fdCount:
917     //  It is not easy to re-use the memory of service->fds, so we have to free the memory first
918     //  then re-allocate memory to store new fds
919     // 2) service->fdCount == fdCount
920     //  A situation we happy to meet, just override it.
921 
922     int ret = 0;
923     if (service->fdCount == fdCount) {
924         // case 2
925         CloseServiceFds(service, false);
926         if (memcpy_s(service->fds, sizeof(int) * (fdCount + 1), fds, sizeof(int) * fdCount) != 0) {
927             INIT_LOGE("Failed to copy fds to service");
928             // Something wrong happened, maybe service->fds is broken, clear it.
929             free(service->fds);
930             service->fds = NULL;
931             service->fdCount = 0;
932             ret = -1;
933         } else {
934             service->fdCount = fdCount;
935         }
936     } else {
937         if (service->fdCount > 0) {
938             // case 1
939             CloseServiceFds(service, true);
940         }
941         INIT_ERROR_CHECK(fdCount <= MAX_HOLD_FDS, return -1, "Invalid fdCount %d", fdCount);
942         service->fds = calloc(fdCount + 1, sizeof(int));
943         if (service->fds == NULL) {
944             INIT_LOGE("Service \' %s \' failed to allocate memory for fds", service->name);
945             ret = -1;
946         } else {
947             if (memcpy_s(service->fds, sizeof(int) * (fdCount + 1), fds, sizeof(int) * fdCount) != 0) {
948                 INIT_LOGE("Failed to copy fds to service");
949                 // Something wrong happened, maybe service->fds is broken, clear it.
950                 free(service->fds);
951                 service->fds = NULL;
952                 service->fdCount = 0;
953                 return -1;
954             } else {
955                 service->fdCount = fdCount;
956             }
957         }
958     }
959     INIT_LOGI("Hold fd for service \' %s \' done", service->name);
960     return ret;
961 }
962 
ServiceStopTimer(Service * service)963 void ServiceStopTimer(Service *service)
964 {
965     INIT_ERROR_CHECK(service != NULL, return, "Stop timer with invalid service");
966     if (IsServiceWithTimerEnabled(service)) {
967         // Stop timer first
968         if (service->timer) {
969             LE_StopTimer(LE_GetDefaultLoop(), service->timer);
970         }
971         service->timer = NULL;
972         DisableServiceTimer(service);
973     }
974 }
975 
ServiceTimerStartProcess(const TimerHandle handler,void * context)976 static void ServiceTimerStartProcess(const TimerHandle handler, void *context)
977 {
978     UNUSED(handler);
979     Service *service = (Service *)context;
980 
981     if (service == NULL) {
982         INIT_LOGE("Service timer process with invalid service");
983         return;
984     }
985 
986     // OK, service is ready to start.
987     // Before start the service, stop service timer.
988     // make sure it will not enter timer handler next time.
989     ServiceStopTimer(service);
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 
ServiceTimerReStartProcess(const TimerHandle handler,void * context)996 static void ServiceTimerReStartProcess(const TimerHandle handler, void *context)
997 {
998     UNUSED(handler);
999     Service *service = (Service *)context;
1000 
1001     if (service == NULL) {
1002         INIT_LOGE("Service timer process with invalid service");
1003         return;
1004     }
1005 
1006     // OK, service is ready to start.
1007     // Before start the service, stop service timer.
1008     // make sure it will not enter timer handler next time.
1009     ServiceStopTimer(service);
1010 
1011     if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
1012         DoJobNow(service->serviceJobs.jobsName[JOB_ON_RESTART]);
1013     }
1014     int ret = ServiceStart(service, &service->pathArgs);
1015     if (ret != SERVICE_SUCCESS) {
1016         INIT_LOGE("Start service \' %s \' in timer failed", service->name);
1017     }
1018 }
1019 
ServiceStartTimer(Service * service,uint64_t timeout)1020 void ServiceStartTimer(Service *service, uint64_t timeout)
1021 {
1022     bool oldTimerClean = false;
1023     INIT_ERROR_CHECK(service != NULL, return, "Start timer with invalid service");
1024     // If the service already set a timer.
1025     // And a new request coming. close it and create a new one.
1026     if (IsServiceWithTimerEnabled(service)) {
1027         ServiceStopTimer(service);
1028         oldTimerClean = true;
1029     }
1030     LE_STATUS status = LE_CreateTimer(LE_GetDefaultLoop(), &service->timer, ServiceTimerStartProcess,
1031         (void *)service);
1032     if (status != LE_SUCCESS) {
1033         INIT_LOGE("Create service timer for service \' %s \' failed, status = %d", service->name, status);
1034         if (oldTimerClean) {
1035             INIT_LOGE("previous timer is cleared");
1036         }
1037         return;
1038     }
1039     status = LE_StartTimer(LE_GetDefaultLoop(), service->timer, timeout, 1);
1040     INIT_ERROR_CHECK(status == LE_SUCCESS, return,
1041         "Start service timer for service \' %s \' failed, status = %d", service->name, status);
1042     EnableServiceTimer(service);
1043 }
1044 
ServiceReStartTimer(Service * service,uint64_t timeout)1045 void ServiceReStartTimer(Service *service, uint64_t timeout)
1046 {
1047     bool oldTimerClean = false;
1048     INIT_ERROR_CHECK(service != NULL, return, "Start timer with invalid service");
1049     // If the service already set a timer.
1050     // And a new request coming. close it and create a new one.
1051     if (IsServiceWithTimerEnabled(service)) {
1052         ServiceStopTimer(service);
1053         oldTimerClean = true;
1054     }
1055     LE_STATUS status = LE_CreateTimer(LE_GetDefaultLoop(), &service->timer, ServiceTimerReStartProcess,
1056         (void *)service);
1057     if (status != LE_SUCCESS) {
1058         INIT_LOGE("Create service timer for service \' %s \' failed, status = %d", service->name, status);
1059         if (oldTimerClean) {
1060             INIT_LOGE("previous timer is cleared");
1061         }
1062         return;
1063     }
1064     status = LE_StartTimer(LE_GetDefaultLoop(), service->timer, timeout, 1);
1065     INIT_ERROR_CHECK(status == LE_SUCCESS, return,
1066         "Start service timer for service \' %s \' failed, status = %d", service->name, status);
1067     EnableServiceTimer(service);
1068 }
1069