1 /*
2  * Copyright (c) 2021-2024 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 #include "init_cmds.h"
16 
17 #include <dlfcn.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <net/if.h>
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/ioctl.h>
25 #include <sys/mount.h>
26 #include <sys/resource.h>
27 #include <sys/stat.h>
28 #include <sys/syscall.h>
29 #include <sys/sysmacros.h>
30 #include <sys/wait.h>
31 #include <unistd.h>
32 #include <linux/module.h>
33 
34 #include "bootstage.h"
35 #include "fs_manager/fs_manager.h"
36 #include "init_cmdexecutor.h"
37 #include "init_jobs_internal.h"
38 #include "init_log.h"
39 #include "init_param.h"
40 #include "init_service_manager.h"
41 #include "init_utils.h"
42 #include "sandbox.h"
43 #include "sandbox_namespace.h"
44 #include "securec.h"
45 #include "fscrypt_utils.h"
46 
47 #ifdef SUPPORT_PROFILER_HIDEBUG
48 #include <hidebug_base.h>
49 #endif
50 
51 #define FSCRYPT_POLICY_BUF_SIZE (60)
52 #define DECIMAL 10
53 #define OCTAL 8
54 
GetParamValue(const char * symValue,unsigned int symLen,char * paramValue,unsigned int paramLen)55 int GetParamValue(const char *symValue, unsigned int symLen, char *paramValue, unsigned int paramLen)
56 {
57     INIT_CHECK_RETURN_VALUE((symValue != NULL) && (paramValue != NULL) && (paramLen != 0), -1);
58     char tmpName[PARAM_NAME_LEN_MAX] = { 0 };
59     int ret;
60     uint32_t curr = 0;
61     char *start = (char *)symValue;
62     if (symLen > strlen(symValue)) {
63         return -1;
64     }
65     char *end = (char *)symValue + symLen;
66     do {
67         char *begin = strchr(start, '$');
68         if (begin == NULL || begin >= end) { // not has '$' copy the original string
69             ret = strncpy_s(paramValue + curr, paramLen - curr, start, symLen);
70             INIT_ERROR_CHECK(ret == EOK, return -1, "Failed to copy start %s", start);
71             break;
72         } else {
73             ret = memcpy_s(paramValue + curr, paramLen - curr, start, begin - start);
74             INIT_ERROR_CHECK(ret == 0, return -1, "Failed to copy first value %s", symValue);
75             curr += begin - start;
76         }
77         while (*begin != '{') {
78             INIT_CHECK_RETURN_VALUE(*begin != '\0', -1);
79             begin++;
80         }
81         begin++;
82         char *left = strchr(begin, '}');
83         INIT_CHECK_RETURN_VALUE(left != NULL, -1);
84 
85         // copy param name
86         ret = strncpy_s(tmpName, PARAM_NAME_LEN_MAX, begin, left - begin);
87         INIT_ERROR_CHECK(ret == EOK, return -1, "Invalid param name %s", symValue);
88         if (paramLen < curr) {
89             INIT_LOGE("Failed to get param value over max length");
90             return -1;
91         }
92         uint32_t valueLen = paramLen - curr;
93         ret = SystemReadParam(tmpName, paramValue + curr, &valueLen);
94         INIT_ERROR_CHECK(ret == 0, return -1, "Failed to get param %s", tmpName);
95         curr += valueLen;
96         left++;
97         if ((unsigned int)(left - symValue) >= symLen) {
98             break;
99         }
100         start = left;
101     } while (1);
102     return 0;
103 }
104 
SyncExecCommand(int argc,char * const * argv)105 static int SyncExecCommand(int argc, char * const *argv)
106 {
107     INIT_LOGI("Sync exec: %s", argv[0]);
108     pid_t pid = fork();
109     INIT_ERROR_CHECK(!(pid < 0), return -1, "Fork new process to format failed: %d", errno);
110     if (pid == 0) {
111         INIT_CHECK_ONLY_ELOG(execv(argv[0], argv) == 0, "execv %s failed! err %d.", argv[0], errno);
112         exit(-1);
113     }
114     int status;
115     pid_t ret = waitpid(pid, &status, 0);
116     if (ret != pid) {
117         INIT_LOGE("Failed to wait pid %d, errno %d", pid, errno);
118         return -1;
119     }
120     INIT_LOGI("Sync exec: %s result %d %d", argv[0], WEXITSTATUS(status), WIFEXITED(status));
121     return WEXITSTATUS(status);
122 }
123 
DoIfup(const struct CmdArgs * ctx)124 static void DoIfup(const struct CmdArgs *ctx)
125 {
126     struct ifreq interface;
127     INIT_ERROR_CHECK(strncpy_s(interface.ifr_name, IFNAMSIZ - 1, ctx->argv[0], strlen(ctx->argv[0])) == EOK,
128         return, "DoIfup failed to copy interface name");
129     INIT_LOGV("interface name: %s", interface.ifr_name);
130 
131     int fd = socket(AF_INET, SOCK_DGRAM, 0);
132     INIT_ERROR_CHECK(fd >= 0, return, "DoIfup failed to create socket, err = %d", errno);
133 
134     if (ioctl(fd, SIOCGIFFLAGS, &interface) >= 0) {
135         interface.ifr_flags |= IFF_UP;
136         INIT_CHECK_ONLY_ELOG(ioctl(fd, SIOCSIFFLAGS, &interface) >= 0,
137             "DoIfup failed to do ioctl with command \"SIOCSIFFLAGS\", err = %d", errno);
138     }
139     close(fd);
140 }
141 
142 // format insmod <ko name> [-f] [options]
DoInsmod(const struct CmdArgs * ctx)143 static void DoInsmod(const struct CmdArgs *ctx)
144 {
145     int index = 0;
146     int flags = 0;
147     char *fileName = NULL;
148     if (ctx->argc > index) {
149         fileName = ctx->argv[index];
150         index++;
151     }
152     INIT_ERROR_CHECK(fileName != NULL, return, "Can not find file name from param %s", ctx->argv[0]);
153     INIT_LOGV("Install mode %s ", fileName);
154     char *realPath = GetRealPath(fileName);
155     INIT_ERROR_CHECK(realPath != NULL, return, "Can not get real file name from param %s", ctx->argv[0]);
156     if (ctx->argc > 1 && ctx->argv[1] != NULL && strcmp(ctx->argv[1], "-f") == 0) { // [-f]
157         flags = MODULE_INIT_IGNORE_VERMAGIC | MODULE_INIT_IGNORE_MODVERSIONS;
158         index++;
159     }
160     char *options = BuildStringFromCmdArg(ctx, index); // [options]
161     int fd = open(realPath, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
162     if (fd >= 0) {
163         int rc = syscall(__NR_finit_module, fd, options, flags);
164         if (rc == -1) {
165             INIT_LOGE("Failed to install kernel module for %s failed options %s err: %d", realPath, options, errno);
166         }
167     }
168     if (options != NULL) {
169         free(options);
170     }
171     if (fd >= 0) {
172         close(fd);
173     }
174     free(realPath);
175     return;
176 }
177 
DoSetParam(const struct CmdArgs * ctx)178 static void DoSetParam(const struct CmdArgs *ctx)
179 {
180     INIT_LOGV("set param name: %s, value %s ", ctx->argv[0], ctx->argv[1]);
181     SystemWriteParam(ctx->argv[0], ctx->argv[1]);
182 }
183 
DoLoadPersistParams(const struct CmdArgs * ctx)184 static void DoLoadPersistParams(const struct CmdArgs *ctx)
185 {
186     INIT_LOGV("LoadPersistParams");
187     LoadPersistParams();
188 }
189 
DoLoadPrivatePersistParams(const struct CmdArgs * ctx)190 static void DoLoadPrivatePersistParams(const struct CmdArgs *ctx)
191 {
192     INIT_LOGV("LoadPersistParams");
193     LoadPrivatePersistParams();
194     HookMgrExecute(GetBootStageHookMgr(), INIT_POST_PERSIST_PARAM_LOAD, NULL, NULL);
195 }
196 
DoTriggerCmd(const struct CmdArgs * ctx)197 static void DoTriggerCmd(const struct CmdArgs *ctx)
198 {
199     INIT_LOGV("DoTrigger :%s", ctx->argv[0]);
200     DoTriggerExec(ctx->argv[0]);
201 }
202 
DoLoadDefaultParams(const struct CmdArgs * ctx)203 static void DoLoadDefaultParams(const struct CmdArgs *ctx)
204 {
205     int mode = 0;
206     if (ctx->argc > 1 && strcmp(ctx->argv[1], "onlyadd") == 0) {
207         mode = LOAD_PARAM_ONLY_ADD;
208     }
209     INIT_LOGV("DoLoadDefaultParams args : %s %d", ctx->argv[0], mode);
210     LoadDefaultParams(ctx->argv[0], mode);
211 }
212 
DoSyncExec(const struct CmdArgs * ctx)213 static void DoSyncExec(const struct CmdArgs *ctx)
214 {
215     // format: syncexec /xxx/xxx/xxx xxx
216     INIT_ERROR_CHECK(ctx != NULL && ctx->argv[0] != NULL, return, "DoSyncExec: invalid arguments");
217     SyncExecCommand(ctx->argc, ctx->argv);
218     return;
219 }
220 
DoExec(const struct CmdArgs * ctx)221 static void DoExec(const struct CmdArgs *ctx)
222 {
223     // format: exec /xxx/xxx/xxx xxx
224     INIT_ERROR_CHECK(ctx != NULL && ctx->argv[0] != NULL, return, "DoExec: invalid arguments");
225     pid_t pid = fork();
226     INIT_ERROR_CHECK(pid >= 0, return, "DoExec: failed to fork child process to exec \"%s\"", ctx->argv[0]);
227 
228     if (pid == 0) {
229         OpenHidebug(ctx->argv[0]);
230         int ret = execv(ctx->argv[0], ctx->argv);
231         INIT_CHECK_ONLY_ELOG(ret != -1, "DoExec: execute \"%s\" failed: %d.", ctx->argv[0], errno);
232         _exit(0x7f);
233     }
234     return;
235 }
236 
DoSymlink(const struct CmdArgs * ctx)237 static void DoSymlink(const struct CmdArgs *ctx)
238 {
239     // format: symlink /xxx/xxx/xxx /xxx/xxx/xxx
240     int ret = symlink(ctx->argv[0], ctx->argv[1]);
241     if (ret != 0 && errno != EEXIST) {
242         INIT_LOGE("DoSymlink: link %s to %s failed: %d", ctx->argv[0], ctx->argv[1], errno);
243     }
244 }
245 
GetDeviceMode(const char * deviceStr)246 static mode_t GetDeviceMode(const char *deviceStr)
247 {
248     switch (*deviceStr) {
249         case 'b':
250         case 'B':
251             return S_IFBLK;
252         case 'c':
253         case 'C':
254             return S_IFCHR;
255         case 'f':
256         case 'F':
257             return S_IFIFO;
258         default:
259             return -1;
260     }
261 }
262 
DoMakeNode(const struct CmdArgs * ctx)263 static void DoMakeNode(const struct CmdArgs *ctx)
264 {
265     // format: mknod path b 0644 1 9
266     const int deviceTypePos = 1;
267     const int authorityPos = 2;
268     const int majorDevicePos = 3;
269     const int minorDevicePos = 4;
270     INIT_ERROR_CHECK(access(ctx->argv[1], F_OK), return, "DoMakeNode failed, path has sexisted");
271     mode_t deviceMode = GetDeviceMode(ctx->argv[deviceTypePos]);
272     errno = 0;
273     unsigned int major = strtoul(ctx->argv[majorDevicePos], NULL, DECIMAL);
274     INIT_CHECK_ONLY_ELOG(errno != ERANGE, "Failed to strtoul %s", ctx->argv[majorDevicePos]);
275     unsigned int minor = strtoul(ctx->argv[minorDevicePos], NULL, DECIMAL);
276     INIT_CHECK_ONLY_ELOG(errno != ERANGE, "Failed to strtoul %s", ctx->argv[minorDevicePos]);
277     mode_t authority = strtoul(ctx->argv[authorityPos], NULL, OCTAL);
278     INIT_CHECK_ONLY_ELOG(errno != ERANGE, "Failed to strtoul %s", ctx->argv[authorityPos]);
279     int ret = mknod(ctx->argv[0], deviceMode | authority, makedev(major, minor));
280     if (ret != 0) {
281         INIT_LOGE("DoMakeNode: path: %s failed: %d", ctx->argv[0], errno);
282     }
283 }
284 
DoMakeDevice(const struct CmdArgs * ctx)285 static void DoMakeDevice(const struct CmdArgs *ctx)
286 {
287     // format: makedev major minor
288     errno = 0;
289     unsigned int major = strtoul(ctx->argv[0], NULL, DECIMAL);
290     INIT_CHECK_ONLY_ELOG(errno != ERANGE, "Failed to strtoul %s", ctx->argv[0]);
291     unsigned int minor = strtoul(ctx->argv[1], NULL, DECIMAL);
292     INIT_CHECK_ONLY_ELOG(errno != ERANGE, "Failed to strtoul %s", ctx->argv[1]);
293     dev_t deviceId = makedev(major, minor);
294     INIT_CHECK_ONLY_ELOG(deviceId >= 0, "DoMakedevice \" major:%s, minor:%s \" failed :%d ", ctx->argv[0],
295         ctx->argv[1], errno);
296     return;
297 }
298 
DoMountFstabFile(const struct CmdArgs * ctx)299 static void DoMountFstabFile(const struct CmdArgs *ctx)
300 {
301     INIT_LOGI("Mount partitions from fstab file \" %s \"", ctx->argv[0]);
302     int ret = MountAllWithFstabFile(ctx->argv[0], 0);
303     INIT_LOGI("Mount partitions from fstab file \" %s \" finish ret %d", ctx->argv[0], ret);
304     HookMgrExecute(GetBootStageHookMgr(), INIT_MOUNT_STAGE, NULL, NULL);
305 }
306 
DoUmountFstabFile(const struct CmdArgs * ctx)307 static void DoUmountFstabFile(const struct CmdArgs *ctx)
308 {
309     INIT_LOGI("Umount partitions from fstab file \" %s \"", ctx->argv[0]);
310     int rc = UmountAllWithFstabFile(ctx->argv[0]);
311     if (rc < 0) {
312         INIT_LOGE("Run command umount_fstab failed");
313     } else {
314         INIT_LOGI("Umount partitions from fstab done");
315     }
316 }
317 
DoRestorecon(const struct CmdArgs * ctx)318 static void DoRestorecon(const struct CmdArgs *ctx)
319 {
320     int ret;
321     INIT_CMD_INFO cmdInfo;
322     cmdInfo.cmdName = "restorecon";
323     cmdInfo.cmdContent = ctx->argv[0];
324     cmdInfo.reserved = NULL;
325     if (ctx->argc > 1) {
326         if (strcmp(ctx->argv[0], "-F") == 0) {
327             cmdInfo.cmdContent = ctx->argv[1];
328         }
329         if (strcmp(ctx->argv[ctx->argc - 1], "--skip-ELX") == 0) {
330             cmdInfo.reserved = ctx->argv[ctx->argc - 1];
331         }
332     }
333 
334     HOOK_EXEC_OPTIONS options;
335     options.flags = TRAVERSE_STOP_WHEN_ERROR;
336     options.preHook = NULL;
337     options.postHook = NULL;
338     ret = HookMgrExecute(GetBootStageHookMgr(), INIT_RESTORECON, (void*)(&cmdInfo), (void*)(&options));
339     if (ret == 0) {
340         return;
341     }
342     if (ctx->argc > 1) {
343         if (strcmp(ctx->argv[0], "-F") == 0) {
344             PluginExecCmdByName("restoreContentRecurseForce", ctx->argv[1]);
345         } else if (strcmp(ctx->argv[ctx->argc - 1], "--skip-ELX") == 0) {
346             PluginExecCmdByName("restoreContentRecurseSkipElx", ctx->argv[0]);
347         }
348     } else {
349         PluginExecCmdByName("restoreContentRecurse", ctx->argv[0]);
350     }
351     return;
352 }
353 
DoLoadAccessTokenId(const struct CmdArgs * ctx)354 static void DoLoadAccessTokenId(const struct CmdArgs *ctx)
355 {
356     LoadAccessTokenId();
357 }
358 
FilterService(const Service * service,const char ** exclude,int size)359 static int FilterService(const Service *service, const char **exclude, int size)
360 {
361     for (int i = 0; i < size; i++) {
362         if (exclude[i] != NULL && strcmp(service->name, exclude[i]) == 0) {
363             return 1;
364         }
365     }
366     return 0;
367 }
368 
DoStopAllServices(const struct CmdArgs * ctx)369 static void DoStopAllServices(const struct CmdArgs *ctx)
370 {
371     int flags = SERVICE_ATTR_INVALID;
372     if (ctx->argc >= 1 && strcmp(ctx->argv[0], "true") == 0) {
373         flags |= SERVICE_ATTR_NEEDWAIT;
374         StopAllServices(flags, (const char **)(&ctx->argv[1]), ctx->argc - 1, FilterService);
375     } else {
376         StopAllServices(flags, (const char **)ctx->argv, ctx->argc, FilterService);
377     }
378     return;
379 }
380 
DoUmount(const struct CmdArgs * ctx)381 static void DoUmount(const struct CmdArgs *ctx)
382 {
383     INIT_LOGI("DoUmount %s",  ctx->argv[0]);
384     MountStatus status = GetMountStatusForMountPoint(ctx->argv[0]);
385     if (status == MOUNT_MOUNTED) {
386         int ret = umount(ctx->argv[0]);
387         if ((ret != 0) && (ctx->argc > 1) && (strcmp(ctx->argv[1], "MNT_FORCE") == 0)) {
388             ret = umount2(ctx->argv[0], MNT_FORCE);
389         }
390         INIT_CHECK_ONLY_ELOG(ret == 0, "Failed to umount %s, errno %d", ctx->argv[0], errno);
391     } else if (status == MOUNT_UMOUNTED) {
392         INIT_LOGI("%s is already umounted", ctx->argv[0]);
393     } else {
394         INIT_LOGE("Failed to get %s mount status", ctx->argv[0]);
395     }
396 }
397 
DoRemoveDmDevice(const struct CmdArgs * ctx)398 static void DoRemoveDmDevice(const struct CmdArgs *ctx)
399 {
400     INIT_LOGI("DoRemoveDmDevice %s",  ctx->argv[0]);
401     int ret = FsManagerDmRemoveDevice(ctx->argv[0]);
402     if (ret < 0) {
403         INIT_LOGE("Failed to remove dm device %s", ctx->argv[0]);
404     } else {
405         INIT_LOGI("Successed to remove dm device %s", ctx->argv[0]);
406     }
407 }
408 
DoMountOneFstabFile(const struct CmdArgs * ctx)409 static void DoMountOneFstabFile(const struct CmdArgs *ctx)
410 {
411     INIT_LOGI("Mount %s from fstab file \" %s \"",  ctx->argv[1], ctx->argv[0]);
412     int ret = MountOneWithFstabFile(ctx->argv[0], ctx->argv[1], 1);
413     if (ret < 0) {
414         INIT_LOGE("Failed to mount dm device %d", ret);
415     } else {
416         INIT_LOGI("Successed to mount dm device %d", ret);
417     }
418 }
419 
DoSync(const struct CmdArgs * ctx)420 static void DoSync(const struct CmdArgs *ctx)
421 {
422     sync();
423 }
424 
DoTimerStart(const struct CmdArgs * ctx)425 static void DoTimerStart(const struct CmdArgs *ctx)
426 {
427     INIT_LOGI("Timer start service with arg = %s", ctx->argv[0]);
428     char *arg = ctx->argv[0];
429     int count = 0;
430     int expectedCount = 2;
431     char **splitArgs = SplitStringExt(ctx->argv[0], "|", &count, expectedCount);
432     if (splitArgs == NULL) {
433         INIT_LOGE("Call timer_start with invalid arguments");
434         return;
435     }
436 
437     if (count != expectedCount) {
438         INIT_LOGE("Call timer_start with unexpected arguments %s", arg);
439         FreeStringVector(splitArgs, count);
440         return;
441     }
442 
443     Service *service = GetServiceByName(splitArgs[0]);
444     if (service == NULL) {
445         INIT_LOGE("Cannot find service in timer_start command");
446         FreeStringVector(splitArgs, count);
447         return;
448     }
449 
450     errno = 0;
451     uint64_t timeout = strtoull(splitArgs[1], NULL, DECIMAL_BASE);
452     if (errno != 0) {
453         INIT_LOGE("call timer_start with invalid timer");
454         FreeStringVector(splitArgs, count);
455         return;
456     }
457     // not need this anymore , release memory.
458     FreeStringVector(splitArgs, count);
459     ServiceStartTimer(service, timeout);
460 }
461 
DoTimerStop(const struct CmdArgs * ctx)462 static void DoTimerStop(const struct CmdArgs *ctx)
463 {
464     INIT_LOGI("Stop service timer with arg = %s", ctx->argv[0]);
465     const char *serviceName = ctx->argv[0];
466     Service *service = GetServiceByName(serviceName);
467     if (service == NULL) {
468         INIT_LOGE("Cannot find service in timer_stop command");
469         return;
470     }
471     ServiceStopTimer(service);
472 }
473 
InitFscryptPolicy(void)474 static bool InitFscryptPolicy(void)
475 {
476     char policy[FSCRYPT_POLICY_BUF_SIZE];
477     if (LoadFscryptPolicy(policy, FSCRYPT_POLICY_BUF_SIZE) == 0) {
478         if (SetFscryptSysparam(policy) == 0) {
479             return true;
480         }
481     }
482     return false;
483 }
484 
DoInitGlobalKey(const struct CmdArgs * ctx)485 static void DoInitGlobalKey(const struct CmdArgs *ctx)
486 {
487     INIT_LOGV("Do init global key start");
488     const char *dataDir = "/data";
489     if (strncmp(ctx->argv[0], dataDir, strlen(dataDir)) != 0) {
490         INIT_LOGE("Not data partitation");
491         return;
492     }
493     if (!InitFscryptPolicy()) {
494         INIT_LOGW("Init fscrypt failed, not enable fscrypt");
495         return;
496     }
497 
498     char * const argv[] = {
499         "/system/bin/sdc",
500         "filecrypt",
501         "init_global_key",
502         NULL
503     };
504     int argc = ARRAY_LENGTH(argv);
505     int ret = SyncExecCommand(argc, argv);
506     if (ret != 0) {
507         INIT_LOGE("[startup_failed]Init global key failed %d", INIT_GOLBALY_KEY_FAILED);
508     }
509     INIT_CMD_INFO cmdInfo;
510     cmdInfo.cmdName = "init_global_key";
511     cmdInfo.cmdContent = (const char *)&ret;
512     cmdInfo.reserved = NULL;
513     HookMgrExecute(GetBootStageHookMgr(), INIT_POST_DATA_UNENCRYPT, (void*)(&cmdInfo), NULL);
514 }
515 
DoInitMainUser(const struct CmdArgs * ctx)516 static void DoInitMainUser(const struct CmdArgs *ctx)
517 {
518     char * const argv[] = {
519         "/system/bin/sdc",
520         "filecrypt",
521         "init_main_user",
522         NULL
523     };
524     int argc = ARRAY_LENGTH(argv);
525     int ret = SyncExecCommand(argc, argv);
526     INIT_CMD_INFO cmdInfo;
527     cmdInfo.cmdName = "init_main_user";
528     cmdInfo.cmdContent = (const char *)&ret;
529     cmdInfo.reserved = NULL;
530     HookMgrExecute(GetBootStageHookMgr(), INIT_POST_DATA_UNENCRYPT, (void*)(&cmdInfo), NULL);
531 }
532 
DoMkswap(const struct CmdArgs * ctx)533 static void DoMkswap(const struct CmdArgs *ctx)
534 {
535     char *const argv[] = {
536         "/system/bin/mkswap",
537         ctx->argv[0],
538         NULL
539     };
540     int argc = ARRAY_LENGTH(argv);
541     SyncExecCommand(argc, argv);
542 }
543 
DoSwapon(const struct CmdArgs * ctx)544 static void DoSwapon(const struct CmdArgs *ctx)
545 {
546     char *const argv[] = {
547         "/system/bin/swapon",
548         ctx->argv[0],
549         NULL
550     };
551     int argc = ARRAY_LENGTH(argv);
552     SyncExecCommand(argc, argv);
553 }
554 
DoMkSandbox(const struct CmdArgs * ctx)555 static void DoMkSandbox(const struct CmdArgs *ctx)
556 {
557     INIT_LOGV("Do make sandbox start");
558     const char *sandbox = ctx->argv[0];
559     InitDefaultNamespace();
560     if (!InitSandboxWithName(sandbox)) {
561         INIT_LOGE("Failed to init sandbox with name %s.", sandbox);
562     }
563 
564     if (PrepareSandbox(sandbox) != 0) {
565         INIT_LOGE("Failed to prepare sandbox %s.", sandbox);
566         DestroySandbox(sandbox);
567     }
568     if (EnterDefaultNamespace() < 0) {
569         INIT_LOGE("Failed to set default namespace.");
570     }
571     CloseDefaultNamespace();
572 }
573 
574 static const struct CmdTable g_cmdTable[] = {
575     { "syncexec ", 1, 10, 0, DoSyncExec },
576     { "exec ", 1, 10, 0, DoExec },
577     { "mknode ", 5, 5, 0, DoMakeNode },
578     { "makedev ", 2, 2, 0, DoMakeDevice },
579     { "symlink ", 2, 2, 1, DoSymlink },
580     { "trigger ", 0, 1, 0, DoTriggerCmd },
581     { "insmod ", 1, 10, 1, DoInsmod },
582     { "setparam ", 2, 2, 0, DoSetParam },
583     { "load_persist_params ", 0, 1, 0, DoLoadPersistParams },
584     { "load_private_persist_params ", 0, 1, 0, DoLoadPrivatePersistParams },
585     { "load_param ", 1, 2, 0, DoLoadDefaultParams },
586     { "load_access_token_id ", 0, 1, 0, DoLoadAccessTokenId },
587     { "ifup ", 1, 1, 1, DoIfup },
588     { "mount_fstab ", 1, 1, 0, DoMountFstabFile },
589     { "umount_fstab ", 1, 1, 0, DoUmountFstabFile },
590     { "remove_dm_device", 1, 1, 0, DoRemoveDmDevice },
591     { "mount_one_fstab", 2, 2, 0, DoMountOneFstabFile },
592     { "restorecon ", 1, 2, 1, DoRestorecon },
593     { "stopAllServices ", 0, 10, 0, DoStopAllServices },
594     { "umount ", 1, 1, 0, DoUmount },
595     { "sync ", 0, 1, 0, DoSync },
596     { "timer_start", 1, 1, 0, DoTimerStart },
597     { "timer_stop", 1, 1, 0, DoTimerStop },
598     { "init_global_key ", 1, 1, 0, DoInitGlobalKey },
599     { "init_main_user ", 0, 1, 0, DoInitMainUser },
600     { "mkswap", 1, 1, 0, DoMkswap},
601     { "swapon", 1, 1, 0, DoSwapon},
602     { "mksandbox", 1, 1, 0, DoMkSandbox},
603 };
604 
GetCmdTable(int * number)605 const struct CmdTable *GetCmdTable(int *number)
606 {
607     *number = (int)ARRAY_LENGTH(g_cmdTable);
608     return g_cmdTable;
609 }
610 
OpenHidebug(const char * name)611 void OpenHidebug(const char *name)
612 {
613 #ifdef SUPPORT_PROFILER_HIDEBUG
614     InitEnvironmentParam(name);
615 #endif
616 }
617 
SetFileCryptPolicy(const char * dir)618 int SetFileCryptPolicy(const char *dir)
619 {
620     if (dir == NULL) {
621         INIT_LOGE("SetFileCryptPolicy:dir is null");
622         return -EINVAL;
623     }
624     return FscryptPolicyEnable(dir);
625 }
626