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