1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci 16d9f0492fSopenharmony_ci#include <cerrno> 17d9f0492fSopenharmony_ci#include <cstdlib> 18d9f0492fSopenharmony_ci#include <cstdio> 19d9f0492fSopenharmony_ci#include <cstdint> 20d9f0492fSopenharmony_ci#include <getopt.h> 21d9f0492fSopenharmony_ci#include <iostream> 22d9f0492fSopenharmony_ci#include <map> 23d9f0492fSopenharmony_ci#include <securec.h> 24d9f0492fSopenharmony_ci#include <string> 25d9f0492fSopenharmony_ci#include <unistd.h> 26d9f0492fSopenharmony_ci#include <vector> 27d9f0492fSopenharmony_ci 28d9f0492fSopenharmony_ci#ifdef ENABLE_ENTER_APPSPAWN_SANDBOX 29d9f0492fSopenharmony_ci#include "appspawn.h" 30d9f0492fSopenharmony_ci#endif 31d9f0492fSopenharmony_ci#include "begetctl.h" 32d9f0492fSopenharmony_ci#include "control_fd.h" 33d9f0492fSopenharmony_ci#include "init_utils.h" 34d9f0492fSopenharmony_ci#include "sandbox.h" 35d9f0492fSopenharmony_ci#include "sandbox_namespace.h" 36d9f0492fSopenharmony_ci#include "string_ex.h" 37d9f0492fSopenharmony_ci 38d9f0492fSopenharmony_ciusing namespace OHOS; 39d9f0492fSopenharmony_cistruct option g_options[] = { 40d9f0492fSopenharmony_ci { "service_name", required_argument, nullptr, 's' }, 41d9f0492fSopenharmony_ci { "namespace_name", required_argument, nullptr, 'n' }, 42d9f0492fSopenharmony_ci { "process_name", required_argument, nullptr, 'p' }, 43d9f0492fSopenharmony_ci { "process_pid", required_argument, nullptr, 'b' }, 44d9f0492fSopenharmony_ci { "help", no_argument, nullptr, 'h' }, 45d9f0492fSopenharmony_ci { nullptr, 0, nullptr, 0 }, 46d9f0492fSopenharmony_ci}; 47d9f0492fSopenharmony_ci 48d9f0492fSopenharmony_cistatic void Usage() 49d9f0492fSopenharmony_ci{ 50d9f0492fSopenharmony_ci std::cout << "sandbox -s | -n [-p] | -p | -b | -h" << std::endl; 51d9f0492fSopenharmony_ci std::cout << "sandbox -s, --service_name=sandbox service \"enter service sandbox\"" << std::endl; 52d9f0492fSopenharmony_ci std::cout << "sandbox -n, --namespace_name=namespace name \"namespace name, system, chipset etc.\"" << std::endl; 53d9f0492fSopenharmony_ci std::cout << "sandbox -p, --process=process name \"sh, hdcd, hdf_devhost, etc.\"" << std::endl; 54d9f0492fSopenharmony_ci std::cout << "sandbox -b, --process_pid=process pid \"sh, enter native app sandbox, etc.\"" << std::endl; 55d9f0492fSopenharmony_ci std::cout << "sandbox -h, --help \"Show help\"" << std::endl; 56d9f0492fSopenharmony_ci#ifndef STARTUP_INIT_TEST 57d9f0492fSopenharmony_ci exit(0); 58d9f0492fSopenharmony_ci#endif 59d9f0492fSopenharmony_ci} 60d9f0492fSopenharmony_ci 61d9f0492fSopenharmony_cistatic void RunSandbox(const std::string &sandboxName) 62d9f0492fSopenharmony_ci{ 63d9f0492fSopenharmony_ci InitDefaultNamespace(); 64d9f0492fSopenharmony_ci if (!InitSandboxWithName(sandboxName.c_str())) { 65d9f0492fSopenharmony_ci std::cout << "Init sandbox failed." << std::endl; 66d9f0492fSopenharmony_ci return; 67d9f0492fSopenharmony_ci } 68d9f0492fSopenharmony_ci 69d9f0492fSopenharmony_ci DumpSandboxByName(sandboxName.c_str()); 70d9f0492fSopenharmony_ci if (PrepareSandbox(sandboxName.c_str()) != 0) { 71d9f0492fSopenharmony_ci std::cout << "Prepare sandbox failed." << std::endl; 72d9f0492fSopenharmony_ci return; 73d9f0492fSopenharmony_ci } 74d9f0492fSopenharmony_ci EnterDefaultNamespace(); 75d9f0492fSopenharmony_ci CloseDefaultNamespace(); 76d9f0492fSopenharmony_ci EnterSandbox(sandboxName.c_str()); 77d9f0492fSopenharmony_ci return; 78d9f0492fSopenharmony_ci} 79d9f0492fSopenharmony_ci 80d9f0492fSopenharmony_cistatic void EnterShell() 81d9f0492fSopenharmony_ci{ 82d9f0492fSopenharmony_ci char *argv[] = { const_cast<char *>("sh"), nullptr }; 83d9f0492fSopenharmony_ci char *envp[] = { nullptr }; 84d9f0492fSopenharmony_ci if (execve("/system/bin/sh", argv, envp) != 0) { 85d9f0492fSopenharmony_ci std::cout << "execve sh failed! err = "<< errno << std::endl; 86d9f0492fSopenharmony_ci } 87d9f0492fSopenharmony_ci return; 88d9f0492fSopenharmony_ci} 89d9f0492fSopenharmony_ci 90d9f0492fSopenharmony_cistatic const int MAX_PROCESS_ARGC = 8; 91d9f0492fSopenharmony_cistatic void EnterExec(const std::string &processName) 92d9f0492fSopenharmony_ci{ 93d9f0492fSopenharmony_ci std::string tmpName = processName; 94d9f0492fSopenharmony_ci std::vector<std::string> vtr; 95d9f0492fSopenharmony_ci const std::string sep = " "; 96d9f0492fSopenharmony_ci OHOS::SplitStr(tmpName, sep, vtr, true, false); 97d9f0492fSopenharmony_ci 98d9f0492fSopenharmony_ci if ((vtr.size() > MAX_PROCESS_ARGC) || (vtr.size() == 0)) { 99d9f0492fSopenharmony_ci std::cout << "Service parameters is error." << std::endl; 100d9f0492fSopenharmony_ci return; 101d9f0492fSopenharmony_ci } 102d9f0492fSopenharmony_ci char *argv[MAX_PROCESS_ARGC] = {}; 103d9f0492fSopenharmony_ci std::vector<std::string>::iterator it; 104d9f0492fSopenharmony_ci int i = 0; 105d9f0492fSopenharmony_ci for (it = vtr.begin(); it != vtr.end(); ++it) { 106d9f0492fSopenharmony_ci argv[i] = (char *)(*it).c_str(); 107d9f0492fSopenharmony_ci std::cout << std::string(argv[i]) << std::endl; 108d9f0492fSopenharmony_ci i++; 109d9f0492fSopenharmony_ci } 110d9f0492fSopenharmony_ci argv[i] = NULL; 111d9f0492fSopenharmony_ci char *envp[] = { NULL }; 112d9f0492fSopenharmony_ci if (execve(argv[0], argv, envp) != 0) { 113d9f0492fSopenharmony_ci std::cout << "execve:" << argv[0] << "failed! err = "<< errno << std::endl; 114d9f0492fSopenharmony_ci } 115d9f0492fSopenharmony_ci return; 116d9f0492fSopenharmony_ci} 117d9f0492fSopenharmony_ci 118d9f0492fSopenharmony_cistatic int SendAppspawnCmdMessage(const CmdAgent *agent, uint16_t type, const char *cmd, const char *ptyName) 119d9f0492fSopenharmony_ci{ 120d9f0492fSopenharmony_ci#ifdef ENABLE_ENTER_APPSPAWN_SANDBOX 121d9f0492fSopenharmony_ci if ((agent == NULL) || (cmd == NULL) || (ptyName == NULL)) { 122d9f0492fSopenharmony_ci BEGET_LOGE("Invalid parameter"); 123d9f0492fSopenharmony_ci return -1; 124d9f0492fSopenharmony_ci } 125d9f0492fSopenharmony_ci 126d9f0492fSopenharmony_ci AppSpawnClientHandle clientHandle; 127d9f0492fSopenharmony_ci int ret = AppSpawnClientInit("AppSpawn", &clientHandle); 128d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, return -1, "AppSpawnClientInit error, errno = %d", errno); 129d9f0492fSopenharmony_ci AppSpawnReqMsgHandle reqHandle; 130d9f0492fSopenharmony_ci ret = AppSpawnReqMsgCreate(AppSpawnMsgType::MSG_BEGET_CMD, cmd, &reqHandle); 131d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, AppSpawnClientDestroy(clientHandle); return -1, "AppSpawnReqMsgCreate error"); 132d9f0492fSopenharmony_ci ret = AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BEGETCTL_BOOT); 133d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, AppSpawnClientDestroy(clientHandle); return -1, "AppSpawnReqMsgSetAppFlag error"); 134d9f0492fSopenharmony_ci ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_BEGET_PID, cmd); 135d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, AppSpawnClientDestroy(clientHandle); return -1, "add %s request message error", cmd); 136d9f0492fSopenharmony_ci ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_BEGET_PTY_NAME, ptyName); 137d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, AppSpawnClientDestroy(clientHandle); 138d9f0492fSopenharmony_ci return -1, "add %s request message error", ptyName); 139d9f0492fSopenharmony_ci AppSpawnResult result = {}; 140d9f0492fSopenharmony_ci ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result); 141d9f0492fSopenharmony_ci if (ret != 0 || result.result != 0) { 142d9f0492fSopenharmony_ci AppSpawnClientDestroy(clientHandle); 143d9f0492fSopenharmony_ci return -1; 144d9f0492fSopenharmony_ci } 145d9f0492fSopenharmony_ci AppSpawnClientDestroy(clientHandle); 146d9f0492fSopenharmony_ci return 0; 147d9f0492fSopenharmony_ci#endif 148d9f0492fSopenharmony_ci return -1; 149d9f0492fSopenharmony_ci} 150d9f0492fSopenharmony_ci 151d9f0492fSopenharmony_cistatic void CmdAppspawnClientInit(const char *cmd, CallbackSendMsgProcess sendMsg) 152d9f0492fSopenharmony_ci{ 153d9f0492fSopenharmony_ci if (cmd == nullptr) { 154d9f0492fSopenharmony_ci BEGET_LOGE("[control_fd] Invalid parameter"); 155d9f0492fSopenharmony_ci return; 156d9f0492fSopenharmony_ci } 157d9f0492fSopenharmony_ci 158d9f0492fSopenharmony_ci CmdAgent agent; 159d9f0492fSopenharmony_ci int ret = InitPtyInterface(&agent, ACTION_APP_SANDBOX, cmd, sendMsg); 160d9f0492fSopenharmony_ci if (ret != 0) { 161d9f0492fSopenharmony_ci BEGET_LOGE("App with pid=%s does not support entering sandbox environment", cmd); 162d9f0492fSopenharmony_ci return; 163d9f0492fSopenharmony_ci } 164d9f0492fSopenharmony_ci LE_RunLoop(LE_GetDefaultLoop()); 165d9f0492fSopenharmony_ci LE_CloseLoop(LE_GetDefaultLoop()); 166d9f0492fSopenharmony_ci BEGET_LOGI("Cmd Client exit "); 167d9f0492fSopenharmony_ci} 168d9f0492fSopenharmony_ci 169d9f0492fSopenharmony_cistatic void RunCmd(const std::string &serviceName, const std::string &namespaceName, const std::string &processName, 170d9f0492fSopenharmony_ci const std::string &pid) 171d9f0492fSopenharmony_ci{ 172d9f0492fSopenharmony_ci bool isNamespaceOnly = !namespaceName.empty() && processName.empty() && serviceName.empty() && pid.empty(); 173d9f0492fSopenharmony_ci bool isNamespaceAndProcess = !namespaceName.empty() && !processName.empty() && serviceName.empty() && pid.empty(); 174d9f0492fSopenharmony_ci bool isProcessOnly = namespaceName.empty() && !processName.empty() && serviceName.empty() && pid.empty(); 175d9f0492fSopenharmony_ci bool isServiceOnly = namespaceName.empty() && processName.empty() && !serviceName.empty() && pid.empty(); 176d9f0492fSopenharmony_ci bool isPidOnly = namespaceName.empty() && processName.empty() && serviceName.empty() && !pid.empty(); 177d9f0492fSopenharmony_ci if (isNamespaceOnly) { 178d9f0492fSopenharmony_ci RunSandbox(namespaceName); 179d9f0492fSopenharmony_ci EnterShell(); 180d9f0492fSopenharmony_ci } else if (isNamespaceAndProcess) { 181d9f0492fSopenharmony_ci RunSandbox(namespaceName); 182d9f0492fSopenharmony_ci EnterExec(processName); 183d9f0492fSopenharmony_ci } else if (isProcessOnly) { 184d9f0492fSopenharmony_ci std::cout << "process name:" << processName << std::endl; 185d9f0492fSopenharmony_ci RunSandbox(std::string("system")); 186d9f0492fSopenharmony_ci EnterExec(processName); 187d9f0492fSopenharmony_ci } else if (isServiceOnly) { 188d9f0492fSopenharmony_ci std::cout << "enter sandbox service name " << serviceName << std::endl; 189d9f0492fSopenharmony_ci CmdClientInit(INIT_CONTROL_FD_SOCKET_PATH, ACTION_SANDBOX, serviceName.c_str(), nullptr); 190d9f0492fSopenharmony_ci } else if (isPidOnly) { 191d9f0492fSopenharmony_ci CmdAppspawnClientInit(pid.c_str(), SendAppspawnCmdMessage); 192d9f0492fSopenharmony_ci } else { 193d9f0492fSopenharmony_ci Usage(); 194d9f0492fSopenharmony_ci } 195d9f0492fSopenharmony_ci} 196d9f0492fSopenharmony_ci 197d9f0492fSopenharmony_cistatic int main_cmd(BShellHandle shell, int argc, char **argv) 198d9f0492fSopenharmony_ci{ 199d9f0492fSopenharmony_ci int rc = -1; 200d9f0492fSopenharmony_ci int optIndex = -1; 201d9f0492fSopenharmony_ci std::string serviceName {}; 202d9f0492fSopenharmony_ci std::string namespaceName {}; 203d9f0492fSopenharmony_ci std::string processName {}; 204d9f0492fSopenharmony_ci std::string pid {}; 205d9f0492fSopenharmony_ci while ((rc = getopt_long(argc, argv, "s:n:p:h:b:", g_options, &optIndex)) != -1) { 206d9f0492fSopenharmony_ci switch (rc) { 207d9f0492fSopenharmony_ci case 0: { 208d9f0492fSopenharmony_ci std::string optionName = g_options[optIndex].name; 209d9f0492fSopenharmony_ci if (optionName == "service_name") { 210d9f0492fSopenharmony_ci serviceName = optarg; 211d9f0492fSopenharmony_ci } else if (optionName == "help") { 212d9f0492fSopenharmony_ci Usage(); 213d9f0492fSopenharmony_ci } else if (optionName == "namespace_name") { 214d9f0492fSopenharmony_ci namespaceName = optarg; 215d9f0492fSopenharmony_ci } else if (optionName == "process_name") { 216d9f0492fSopenharmony_ci processName = optarg; 217d9f0492fSopenharmony_ci } else if (optionName == "process_pid") { 218d9f0492fSopenharmony_ci pid = optarg; 219d9f0492fSopenharmony_ci } 220d9f0492fSopenharmony_ci break; 221d9f0492fSopenharmony_ci } 222d9f0492fSopenharmony_ci case 's': 223d9f0492fSopenharmony_ci serviceName = optarg; 224d9f0492fSopenharmony_ci break; 225d9f0492fSopenharmony_ci case 'h': 226d9f0492fSopenharmony_ci Usage(); 227d9f0492fSopenharmony_ci break; 228d9f0492fSopenharmony_ci case 'n': 229d9f0492fSopenharmony_ci namespaceName = optarg; 230d9f0492fSopenharmony_ci break; 231d9f0492fSopenharmony_ci case 'p': 232d9f0492fSopenharmony_ci processName = optarg; 233d9f0492fSopenharmony_ci break; 234d9f0492fSopenharmony_ci case 'b': 235d9f0492fSopenharmony_ci pid = optarg; 236d9f0492fSopenharmony_ci break; 237d9f0492fSopenharmony_ci case '?': 238d9f0492fSopenharmony_ci std::cout << "Invalid argument\n"; 239d9f0492fSopenharmony_ci break; 240d9f0492fSopenharmony_ci default: 241d9f0492fSopenharmony_ci std::cout << "Invalid argument\n"; 242d9f0492fSopenharmony_ci break; 243d9f0492fSopenharmony_ci } 244d9f0492fSopenharmony_ci } 245d9f0492fSopenharmony_ci RunCmd(serviceName, namespaceName, processName, pid); 246d9f0492fSopenharmony_ci return 0; 247d9f0492fSopenharmony_ci} 248d9f0492fSopenharmony_ci 249d9f0492fSopenharmony_ciMODULE_CONSTRUCTOR(void) 250d9f0492fSopenharmony_ci{ 251d9f0492fSopenharmony_ci const CmdInfo infos[] = { 252d9f0492fSopenharmony_ci { 253d9f0492fSopenharmony_ci const_cast<char *>("sandbox"), main_cmd, const_cast<char *>("enter service sandbox"), 254d9f0492fSopenharmony_ci const_cast<char *>("sandbox -s service_name"), 255d9f0492fSopenharmony_ci NULL 256d9f0492fSopenharmony_ci }, 257d9f0492fSopenharmony_ci { 258d9f0492fSopenharmony_ci const_cast<char *>("sandbox"), main_cmd, const_cast<char *>("enter namespace, system, chipset etc."), 259d9f0492fSopenharmony_ci const_cast<char *>("sandbox -n namespace_name [-p]"), 260d9f0492fSopenharmony_ci NULL 261d9f0492fSopenharmony_ci }, 262d9f0492fSopenharmony_ci { 263d9f0492fSopenharmony_ci const_cast<char *>("sandbox"), main_cmd, const_cast<char *>("enter namespace and exec process"), 264d9f0492fSopenharmony_ci const_cast<char *>("sandbox -p process_name"), 265d9f0492fSopenharmony_ci NULL 266d9f0492fSopenharmony_ci }, 267d9f0492fSopenharmony_ci { 268d9f0492fSopenharmony_ci const_cast<char *>("sandbox"), main_cmd, const_cast<char *>("enter native app sandbox namespace"), 269d9f0492fSopenharmony_ci const_cast<char *>("sandbox -b pid"), 270d9f0492fSopenharmony_ci NULL 271d9f0492fSopenharmony_ci } 272d9f0492fSopenharmony_ci }; 273d9f0492fSopenharmony_ci for (size_t i = 0; i < ARRAY_LENGTH(infos); i++) { 274d9f0492fSopenharmony_ci BShellEnvRegisterCmd(GetShellHandle(), &infos[i]); 275d9f0492fSopenharmony_ci } 276d9f0492fSopenharmony_ci} 277