169570cc8Sopenharmony_ci/*
269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License.
569570cc8Sopenharmony_ci * You may obtain a copy of the License at
669570cc8Sopenharmony_ci *
769570cc8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
869570cc8Sopenharmony_ci *
969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and
1369570cc8Sopenharmony_ci * limitations under the License.
1469570cc8Sopenharmony_ci */
1569570cc8Sopenharmony_ci
1669570cc8Sopenharmony_ci#include "appspawn_adapter.h"
1769570cc8Sopenharmony_ci
1869570cc8Sopenharmony_ci#include <sys/signalfd.h>
1969570cc8Sopenharmony_ci#include <sys/wait.h>
2069570cc8Sopenharmony_ci#include "securec.h"
2169570cc8Sopenharmony_ci
2269570cc8Sopenharmony_ci#include "appspawn_hook.h"
2369570cc8Sopenharmony_ci#include "appspawn_utils.h"
2469570cc8Sopenharmony_ci#include "init_utils.h"
2569570cc8Sopenharmony_ci
2669570cc8Sopenharmony_ciAPPSPAWN_STATIC void SetSystemEnv(void)
2769570cc8Sopenharmony_ci{
2869570cc8Sopenharmony_ci    int32_t ret;
2969570cc8Sopenharmony_ci    char envValue[MAX_ENV_VALUE_LEN];
3069570cc8Sopenharmony_ci    ret = ConvertEnvValue("/bin:/system/bin:${PATH}", envValue, MAX_ENV_VALUE_LEN);
3169570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return, "Convert env value failed");
3269570cc8Sopenharmony_ci    ret = setenv("PATH", envValue, true);
3369570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return, "Set env fail value=%{public}s", envValue);
3469570cc8Sopenharmony_ci}
3569570cc8Sopenharmony_ci
3669570cc8Sopenharmony_ciAPPSPAWN_STATIC void RunAppSandbox(const char *ptyName)
3769570cc8Sopenharmony_ci{
3869570cc8Sopenharmony_ci    if (ptyName == NULL) {
3969570cc8Sopenharmony_ci        return;
4069570cc8Sopenharmony_ci    }
4169570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST
4269570cc8Sopenharmony_ci    SetSystemEnv();
4369570cc8Sopenharmony_ci    OpenConsole();
4469570cc8Sopenharmony_ci    char *realPath = realpath(ptyName, NULL);
4569570cc8Sopenharmony_ci    if (realPath == NULL) {
4669570cc8Sopenharmony_ci        APPSPAWN_CHECK(errno == ENOENT, return,
4769570cc8Sopenharmony_ci            "Failed to resolve %{public}s real path err=%{public}d", ptyName, errno);
4869570cc8Sopenharmony_ci    }
4969570cc8Sopenharmony_ci    APPSPAWN_CHECK(realPath != NULL, _exit(1), "Failed get realpath, err=%{public}d", errno);
5069570cc8Sopenharmony_ci    int n = strncmp(realPath, "/dev/pts/", strlen("/dev/pts/"));
5169570cc8Sopenharmony_ci    APPSPAWN_CHECK(n == 0, free(realPath); _exit(1), "pts path %{public}s is invaild", realPath);
5269570cc8Sopenharmony_ci    int fd = open(realPath, O_RDWR);
5369570cc8Sopenharmony_ci    free(realPath);
5469570cc8Sopenharmony_ci    APPSPAWN_CHECK(fd >= 0, _exit(1), "Failed open %{public}s, err=%{public}d", ptyName, errno);
5569570cc8Sopenharmony_ci    (void)dup2(fd, STDIN_FILENO);
5669570cc8Sopenharmony_ci    (void)dup2(fd, STDOUT_FILENO);
5769570cc8Sopenharmony_ci    (void)dup2(fd, STDERR_FILENO); // Redirect fd to 0, 1, 2
5869570cc8Sopenharmony_ci    (void)close(fd);
5969570cc8Sopenharmony_ci
6069570cc8Sopenharmony_ci    char *argv[] = { (char *)"/bin/sh", NULL };
6169570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_LOG(execv(argv[0], argv) == 0,
6269570cc8Sopenharmony_ci        "app %{public}s execv sh failed! err %{public}d.", ptyName, errno);
6369570cc8Sopenharmony_ci    _exit(0x7f); // 0x7f: user specified
6469570cc8Sopenharmony_ci#endif
6569570cc8Sopenharmony_ci    APPSPAWN_LOGE("Exit RunAppSandbox %{public}s exit", ptyName);
6669570cc8Sopenharmony_ci}
6769570cc8Sopenharmony_ci
6869570cc8Sopenharmony_ciAPPSPAWN_STATIC int RunBegetctlBootApp(AppSpawnMgr *content, AppSpawningCtx *property)
6969570cc8Sopenharmony_ci{
7069570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1);
7169570cc8Sopenharmony_ci    UNUSED(content);
7269570cc8Sopenharmony_ci    if ((property->client.flags & APP_BEGETCTL_BOOT) != APP_BEGETCTL_BOOT) {
7369570cc8Sopenharmony_ci        APPSPAWN_LOGW("Enter begetctl boot without BEGETCTL_BOOT flag set");
7469570cc8Sopenharmony_ci        return 0;
7569570cc8Sopenharmony_ci    }
7669570cc8Sopenharmony_ci    uint32_t len = 0;
7769570cc8Sopenharmony_ci    const char *cmdMsg = (const char *)GetAppSpawnMsgExtInfo(property->message, MSG_EXT_NAME_BEGET_PTY_NAME, &len);
7869570cc8Sopenharmony_ci    APPSPAWN_CHECK(cmdMsg != NULL, return -1, "Failed to get extInfo");
7969570cc8Sopenharmony_ci    RunAppSandbox(cmdMsg);
8069570cc8Sopenharmony_ci    return 0;
8169570cc8Sopenharmony_ci}
8269570cc8Sopenharmony_ci
8369570cc8Sopenharmony_ciMODULE_CONSTRUCTOR(void)
8469570cc8Sopenharmony_ci{
8569570cc8Sopenharmony_ci    AddAppSpawnHook(STAGE_CHILD_PRE_RUN, HOOK_PRIO_LOWEST, RunBegetctlBootApp);
8669570cc8Sopenharmony_ci}
8769570cc8Sopenharmony_ci
88