1/* 2 * Copyright (c) 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 16#include "appspawn_adapter.h" 17 18#include <sys/signalfd.h> 19#include <sys/wait.h> 20#include "securec.h" 21 22#include "appspawn_hook.h" 23#include "appspawn_utils.h" 24#include "init_utils.h" 25 26APPSPAWN_STATIC void SetSystemEnv(void) 27{ 28 int32_t ret; 29 char envValue[MAX_ENV_VALUE_LEN]; 30 ret = ConvertEnvValue("/bin:/system/bin:${PATH}", envValue, MAX_ENV_VALUE_LEN); 31 APPSPAWN_CHECK(ret == 0, return, "Convert env value failed"); 32 ret = setenv("PATH", envValue, true); 33 APPSPAWN_CHECK(ret == 0, return, "Set env fail value=%{public}s", envValue); 34} 35 36APPSPAWN_STATIC void RunAppSandbox(const char *ptyName) 37{ 38 if (ptyName == NULL) { 39 return; 40 } 41#ifndef APPSPAWN_TEST 42 SetSystemEnv(); 43 OpenConsole(); 44 char *realPath = realpath(ptyName, NULL); 45 if (realPath == NULL) { 46 APPSPAWN_CHECK(errno == ENOENT, return, 47 "Failed to resolve %{public}s real path err=%{public}d", ptyName, errno); 48 } 49 APPSPAWN_CHECK(realPath != NULL, _exit(1), "Failed get realpath, err=%{public}d", errno); 50 int n = strncmp(realPath, "/dev/pts/", strlen("/dev/pts/")); 51 APPSPAWN_CHECK(n == 0, free(realPath); _exit(1), "pts path %{public}s is invaild", realPath); 52 int fd = open(realPath, O_RDWR); 53 free(realPath); 54 APPSPAWN_CHECK(fd >= 0, _exit(1), "Failed open %{public}s, err=%{public}d", ptyName, errno); 55 (void)dup2(fd, STDIN_FILENO); 56 (void)dup2(fd, STDOUT_FILENO); 57 (void)dup2(fd, STDERR_FILENO); // Redirect fd to 0, 1, 2 58 (void)close(fd); 59 60 char *argv[] = { (char *)"/bin/sh", NULL }; 61 APPSPAWN_CHECK_ONLY_LOG(execv(argv[0], argv) == 0, 62 "app %{public}s execv sh failed! err %{public}d.", ptyName, errno); 63 _exit(0x7f); // 0x7f: user specified 64#endif 65 APPSPAWN_LOGE("Exit RunAppSandbox %{public}s exit", ptyName); 66} 67 68APPSPAWN_STATIC int RunBegetctlBootApp(AppSpawnMgr *content, AppSpawningCtx *property) 69{ 70 APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1); 71 UNUSED(content); 72 if ((property->client.flags & APP_BEGETCTL_BOOT) != APP_BEGETCTL_BOOT) { 73 APPSPAWN_LOGW("Enter begetctl boot without BEGETCTL_BOOT flag set"); 74 return 0; 75 } 76 uint32_t len = 0; 77 const char *cmdMsg = (const char *)GetAppSpawnMsgExtInfo(property->message, MSG_EXT_NAME_BEGET_PTY_NAME, &len); 78 APPSPAWN_CHECK(cmdMsg != NULL, return -1, "Failed to get extInfo"); 79 RunAppSandbox(cmdMsg); 80 return 0; 81} 82 83MODULE_CONSTRUCTOR(void) 84{ 85 AddAppSpawnHook(STAGE_CHILD_PRE_RUN, HOOK_PRIO_LOWEST, RunBegetctlBootApp); 86} 87 88