sandbox.cpp 6.5 KB
Newer Older
X
xionglei6 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cerrno>
#include <cstdlib>
#include <cstdio>
#include <cstdint>
#include <getopt.h>
#include <iostream>
#include <map>
#include <string>
#include <unistd.h>
#include <vector>

#include "begetctl.h"
M
Mupceet 已提交
28
#include "control_fd.h"
X
xionglei6 已提交
29 30 31 32 33 34 35
#include "init_utils.h"
#include "sandbox.h"
#include "sandbox_namespace.h"
#include "string_ex.h"

using namespace OHOS;
struct option g_options[] = {
M
Mupceet 已提交
36 37
    { "service_name", required_argument, nullptr, 's' },
    { "namespace_name", required_argument, nullptr, 'n' },
X
xionglei6 已提交
38 39 40 41 42 43 44
    { "process_name", required_argument, nullptr, 'p' },
    { "help", no_argument, nullptr, 'h' },
    { nullptr, 0, nullptr, 0 },
};

static void Usage()
{
M
Mupceet 已提交
45 46 47
    std::cout << "sandbox -s | -n [-p] | -p | -h" << std::endl;
    std::cout << "sandbox -s, --service_name=sandbox service \"enter service sandbox\"" << std::endl;
    std::cout << "sandbox -n, --namespace_name=namespace name \"namespace name, system, chipset etc.\"" << std::endl;
X
xionglei6 已提交
48 49 50 51 52
    std::cout << "sandbox -p, --process=process name \"sh, hdcd, hdf_devhost, etc.\"" << std::endl;
    std::cout << "sandbox -h, --help \"Show help\"" << std::endl;
    exit(0);
}

M
Mupceet 已提交
53
static void RunSandbox(const std::string &sandboxName)
X
xionglei6 已提交
54
{
M
Mupceet 已提交
55
    if (sandboxName.empty()) {
X
xionglei6 已提交
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
        return;
    }
    InitDefaultNamespace();
    if (!InitSandboxWithName(sandboxName.c_str())) {
        std::cout << "Init sandbox failed." << std::endl;
        return;
    }

    DumpSandboxByName(sandboxName.c_str());
    if (PrepareSandbox(sandboxName.c_str()) != 0) {
        std::cout << "Prepare sandbox failed." << std::endl;
        return;
    }
    EnterDefaultNamespace();
    CloseDefaultNamespace();
    EnterSandbox(sandboxName.c_str());
    return;
}

static void EnterShell()
{
    char *argv[] = { (char *)"sh", NULL };
    char *envp[] = { nullptr };
    if (execve("/system/bin/sh", argv, envp) != 0) {
        std::cout << "execve sh failed! err = "<< errno << std::endl;
    }
    return;
}

static const int MAX_PROCESS_ARGC = 8;
static void EnterExec(const std::string &processName)
{
    if (processName.empty()) {
        std::cout << "process name is nullptr." << std::endl;
        return;
    }
    std::string tmpName = processName;
    std::vector<std::string> vtr;
    const std::string sep = " ";
    OHOS::SplitStr(tmpName, sep, vtr, true, false);

    if ((vtr.size() > MAX_PROCESS_ARGC) || (vtr.size() <= 0)) {
        std::cout << "Service parameters is error." << std::endl;
        return;
    }
    char *argv[MAX_PROCESS_ARGC] = {};
    std::vector<std::string>::iterator it;
    int i = 0;
    for (it = vtr.begin(); it != vtr.end(); it++) {
        argv[i] = (char *)(*it).c_str();
        std::cout << std::string(argv[i]) << std::endl;
        i++;
    }
    argv[i] = NULL;
    char *envp[] = { NULL };
    if (execve(argv[0], argv, envp) != 0) {
        std::cout << "execve:" << argv[0] << "failed! err = "<< errno << std::endl;
    }
    return;
}

M
Mupceet 已提交
117
static void RunCmd(const std::string &serviceName, const std::string &namespaceName, const std::string &processName)
X
xionglei6 已提交
118
{
M
Mupceet 已提交
119 120
    if (!namespaceName.empty() && processName.empty() && serviceName.empty()) {
        RunSandbox(namespaceName);
X
xionglei6 已提交
121
        EnterShell();
M
Mupceet 已提交
122 123
    } else if (!namespaceName.empty() && !processName.empty() && serviceName.empty()) {
        RunSandbox(namespaceName);
X
xionglei6 已提交
124
        EnterExec(processName);
M
Mupceet 已提交
125
    } else if (namespaceName.empty() && !processName.empty() && serviceName.empty()) {
X
xionglei6 已提交
126
        std::cout << "process name:" << processName << std::endl;
M
Mupceet 已提交
127
        RunSandbox(std::string("system"));
X
xionglei6 已提交
128
        EnterExec(processName);
M
Mupceet 已提交
129 130
    } else if (namespaceName.empty() && processName.empty() && !serviceName.empty()) {
        std::cout << "enter sandbox service name " << serviceName << std::endl;
M
Mupceet 已提交
131
        CmdClientInit(INIT_CONTROL_FD_SOCKET_PATH, ACTION_SANDBOX, serviceName.c_str());
X
xionglei6 已提交
132 133 134 135 136 137 138 139 140
    } else {
        Usage();
    }
}

static int main_cmd(BShellHandle shell, int argc, char **argv)
{
    int rc = -1;
    int optIndex = -1;
M
Mupceet 已提交
141 142
    std::string serviceName {};
    std::string namespaceName {};
X
xionglei6 已提交
143
    std::string processName {};
M
Mupceet 已提交
144
    while ((rc = getopt_long(argc, argv, "s:n:p:h",  g_options, &optIndex)) != -1) {
X
xionglei6 已提交
145 146 147
        switch (rc) {
            case 0: {
                std::string optionName = g_options[optIndex].name;
M
Mupceet 已提交
148 149
                if (optionName == "service_name") {
                    serviceName = optarg;
X
xionglei6 已提交
150 151
                } else if (optionName == "help") {
                    Usage();
M
Mupceet 已提交
152 153
                } else if (optionName == "namespace_name") {
                    namespaceName = optarg;
X
xionglei6 已提交
154 155 156 157 158
                } else if (optionName == "process_name") {
                    processName = optarg;
                }
                break;
            }
M
Mupceet 已提交
159 160
            case 's':
                serviceName = optarg;
X
xionglei6 已提交
161 162 163 164
                break;
            case 'h':
                Usage();
                break;
M
Mupceet 已提交
165 166
            case 'n':
                namespaceName = optarg;
X
xionglei6 已提交
167 168
                break;
            case 'p':
M
Mupceet 已提交
169
                std::cout << "process name:" << optarg << std::endl;
X
xionglei6 已提交
170 171 172
                processName = optarg;
                break;
            case '?':
173
                std::cout << "Invalid argument\n";
X
xionglei6 已提交
174 175
                break;
            default:
176
                std::cout << "Invalid argument\n";
X
xionglei6 已提交
177 178 179
                break;
        }
    }
M
Mupceet 已提交
180
    RunCmd(serviceName, namespaceName, processName);
X
xionglei6 已提交
181 182 183 184 185
    return 0;
}

MODULE_CONSTRUCTOR(void)
{
M
Mupceet 已提交
186
    const CmdInfo infos[] = {
X
xionglei6 已提交
187
        {
M
Mupceet 已提交
188 189 190 191 192 193 194 195 196 197 198 199
            (char *)"sandbox", main_cmd, (char *)"enter service sandbox",
            (char *)"sandbox -s service_name",
            NULL
        },
        {
            (char *)"sandbox", main_cmd, (char *)"enter namespace, system, chipset etc.",
            (char *)"sandbox -n namespace_name [-p]",
            NULL
        },
        {
            (char *)"sandbox", main_cmd, (char *)"enter namespace and exec process",
            (char *)"sandbox -p process_name",
X
xionglei6 已提交
200 201 202 203 204 205 206
            NULL
        }
    };
    for (size_t i = 0; i < ARRAY_LENGTH(infos); i++) {
        BShellEnvRegitsterCmd(GetShellHandle(), &infos[i]);
    }
}