diff --git a/bundle.json b/bundle.json index a880b0eb8b2d0c3bff9efc9865c613b02b3c7c4e..fc32053c74d3046cf67df5bedf82aac22c85dc83 100755 --- a/bundle.json +++ b/bundle.json @@ -51,7 +51,8 @@ "//base/startup/init_lite/services/init/module_engine:libinit_stub_empty", "//base/startup/init_lite/device_info:device_info_group", "//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox", - "//base/startup/init_lite/test/exec_test:exectest" + "//base/startup/init_lite/test/exec_test:exectest", + "//base/startup/init_lite/interfaces/innerkits/control_fd:libcontrolfd" ], "inner_kits": [ { diff --git a/interfaces/innerkits/control_fd/BUILD.gn b/interfaces/innerkits/control_fd/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..e8c008854f0bf92f32f604f447d979fd86b21be1 --- /dev/null +++ b/interfaces/innerkits/control_fd/BUILD.gn @@ -0,0 +1,59 @@ +# 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. + +import("//base/startup/init_lite/begetd.gni") +import("//build/ohos.gni") + +ohos_shared_library("libcontrolfd") { + sources = [ + "control_fd_client.c", + "control_fd_service.c", + ] + include_dirs = [ + ".", + "//third_party/bounds_checking_function/include", + "//base/startup/init_lite/services/include", + "//base/startup/init_lite/interfaces/innerkits/include", + "//base/startup/init_lite/services/loopevent/include", + ] + deps = [ + "//base/startup/init_lite/services/loopevent:loopevent", + "//base/startup/init_lite/services/utils:libinit_tools", + "//base/startup/init_lite/services/utils:libinit_utils", + "//third_party/bounds_checking_function:libsec_shared", + ] + deps += [ "//base/startup/init_lite/services/log:agent_log" ] + part_name = "init" + install_images = [ "system" ] +} + +# For init only +ohos_static_library("libcontrolfd_static") { + sources = [ + "control_fd_client.c", + "control_fd_service.c", + ] + include_dirs = [ + ".", + "//third_party/bounds_checking_function/include", + "//base/startup/init_lite/services/include", + "//base/startup/init_lite/interfaces/innerkits/include", + "//base/startup/init_lite/services/loopevent/include", + ] + deps = [ + "//base/startup/init_lite/services/loopevent:loopevent", + "//base/startup/init_lite/services/utils:libinit_tools", + "//base/startup/init_lite/services/utils:libinit_utils", + ] + part_name = "init" +} diff --git a/interfaces/innerkits/control_fd/control_fd.h b/interfaces/innerkits/control_fd/control_fd.h new file mode 100644 index 0000000000000000000000000000000000000000..e0dbe2ecc7d4fad49d5096ea357b49b6ea841b8e --- /dev/null +++ b/interfaces/innerkits/control_fd/control_fd.h @@ -0,0 +1,70 @@ +/* + * 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. + */ + +#ifndef CONTROL_FD_ +#define CONTROL_FD_ + +#include +#include "loop_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define INIT_CONTROL_FD_SOCKET_PATH "/dev/unix/socket/init_control_fd" + +#define CONTROL_FD_FIFO_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) +#define FIFO_BUF_SIZE 4096 +#define FIFO_PATH_SIZE 128 + +typedef struct CmdService_ { + TaskHandle serverTask; +} CmdService; + +typedef struct CmdAgent_ { + TaskHandle task; + WatcherHandle input; // watch stdin + WatcherHandle reader; // watch read pipe +} CmdAgent; + +typedef void (* CallbackControlFdProcess)(uint16_t type, const char *serviceCmd, const void *context); + +typedef enum { + ACTION_SANDBOX = 0, + ACTION_DUMP, + ACTION_PARAM_SHELL, + ACTION_MAX +} ActionType; + +typedef struct { + uint16_t msgSize; + uint16_t type; + uint32_t pid; + char fifoName[FIFO_PATH_SIZE]; + char cmd[0]; +} CmdMessage; + +void CmdServiceInit(const char *socketPath, CallbackControlFdProcess func); +void CmdClientInit(const char *socketPath, uint16_t type, const char *cmd, const char *fifoName); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif \ No newline at end of file diff --git a/interfaces/innerkits/control_fd/control_fd_client.c b/interfaces/innerkits/control_fd/control_fd_client.c new file mode 100644 index 0000000000000000000000000000000000000000..a8ec22969a53143f04e36e586b19ce9c228342f6 --- /dev/null +++ b/interfaces/innerkits/control_fd/control_fd_client.c @@ -0,0 +1,265 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "beget_ext.h" +#include "control_fd.h" +#include "init_utils.h" +#include "securec.h" + +static char g_FifoReadPath[FIFO_PATH_SIZE] = {0}; +static int g_FifoReadFd = -1; + +static char g_FifoWritePath[FIFO_PATH_SIZE] = {0}; +static int g_FifoWriteFd = -1; + +static void ProcessFifoWrite(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context) +{ + if ((fd < 0) || (events == NULL) || (context == NULL)) { + BEGET_LOGE("[control_fd] Invaild fifo write parameter"); + return; + } + int fifow = *((int *)context); + if (fifow < 0) { + BEGET_LOGE("[control_fd] invaild fifo write fd"); + return; + } + char rbuf[FIFO_BUF_SIZE] = {0}; + int rlen = read(fd, rbuf, FIFO_BUF_SIZE - 1); + int ret = fflush(stdin); + BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed fflush err=%d", errno); + if (rlen > 0) { + int wlen = write(fifow, rbuf, rlen); + BEGET_ERROR_CHECK(wlen == rlen, return, "[control_fd] Failed write fifo err=%d", errno); + } + printf("#"); + ret = fflush(stdout); + BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed fflush err=%d", errno); + *events = Event_Read; +} + +static void ProcessFifoRead(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context) +{ + if ((fd < 0) || (events == NULL)) { + BEGET_LOGE("[control_fd] Invaild fifo read parameter"); + return; + } + char buf[FIFO_BUF_SIZE] = {0}; + int readlen = read(fd, buf, FIFO_BUF_SIZE - 1); + if (readlen > 0) { + fprintf(stdout, "%s", buf); + } + int ret = fflush(stdout); + BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed fflush err=%d", errno); + printf("#"); + ret = fflush(stdout); + BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed fflush err=%d", errno); + *events = Event_Read; +} + +static void DestroyCmdFifo(void) +{ + if (g_FifoReadFd >= 0) { + (void)close(g_FifoReadFd); + } + if (g_FifoWriteFd >= 0) { + (void)close(g_FifoWriteFd); + } + g_FifoReadFd = -1; + g_FifoWriteFd = -1; + int ret = unlink(g_FifoReadPath); + BEGET_CHECK_ONLY_ELOG(ret == 0, "Failed unlink fifo %s", g_FifoReadPath); + ret = unlink(g_FifoWritePath); + BEGET_CHECK_ONLY_ELOG(ret == 0, "Failed unlink fifo %s", g_FifoReadPath); +} + +static void CmdOnRecvMessage(const TaskHandle task, const uint8_t *buffer, uint32_t buffLen) +{ + BEGET_LOGI("[control_fd] CmdOnRecvMessage %s len %d.", (char *)buffer, buffLen); +} + +static void CmdOnConntectComplete(const TaskHandle client) +{ + BEGET_LOGI("[control_fd] CmdOnConntectComplete"); +} + +static void CmdOnClose(const TaskHandle task) +{ + BEGET_LOGI("[control_fd] CmdOnClose"); + DestroyCmdFifo(); +} + +static void CmdDisConnectComplete(const TaskHandle client) +{ + BEGET_LOGI("[control_fd] CmdDisConnectComplete"); +} + +static void CmdAgentInit(WatcherHandle handle, const char *path, bool read, ProcessWatchEvent func) +{ + BEGET_LOGI("[control_fd] client open %s", (read ? "read" : "write")); + if (read == true) { + g_FifoReadFd = open(path, O_RDONLY | O_TRUNC | O_NONBLOCK); + BEGET_ERROR_CHECK(g_FifoReadFd >= 0, return, "[control_fd] Failed to open fifo read"); + BEGET_LOGI("[control_fd] g_FifoReadFd is %d", g_FifoReadFd); + } else { + g_FifoWriteFd = open(path, O_WRONLY | O_TRUNC); + BEGET_ERROR_CHECK(g_FifoWriteFd >= 0, return, "[control_fd] Failed to open fifo write"); + BEGET_LOGI("[control_fd] g_FifoWriteFd is %d", g_FifoWriteFd); + } + + // start watcher for stdin + LE_WatchInfo info = {}; + info.flags = 0; + info.events = Event_Read; + info.processEvent = func; + if (read == true) { + info.fd = g_FifoReadFd; // read fifo0 + BEGET_ERROR_CHECK(LE_StartWatcher(LE_GetDefaultLoop(), &handle, &info, NULL) == LE_SUCCESS, + return, "[control_fd] Failed le_loop start watcher fifo read"); + } else { + info.fd = STDIN_FILENO; // read stdin and write fifo1 + BEGET_ERROR_CHECK(LE_StartWatcher(LE_GetDefaultLoop(), &handle, &info, &g_FifoWriteFd) == LE_SUCCESS, + return, "[control_fd] Failed le_loop start watcher stdin"); + } + return; +} + +static void CmdOnSendMessageComplete(const TaskHandle task, const BufferHandle handle) +{ + BEGET_LOGI("[control_fd] CmdOnSendMessageComplete"); + CmdAgent *agent = (CmdAgent *)LE_GetUserData(task); + BEGET_ERROR_CHECK(agent != NULL, return, "[control_fd] Invalid agent"); + CmdAgentInit(agent->input, g_FifoWritePath, false, ProcessFifoWrite); + printf("#"); + int ret = fflush(stdout); + BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed fflush err=%d", errno); +} + +static CmdAgent *CmdAgentCreate(const char *server) +{ + if (server == NULL) { + BEGET_LOGE("[control_fd] Invaild parameter"); + return NULL; + } + TaskHandle task = NULL; + LE_StreamInfo info = {}; + info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT; + info.server = (char *)server; + info.baseInfo.userDataSize = sizeof(CmdAgent); + info.baseInfo.close = CmdOnClose; + info.disConntectComplete = CmdDisConnectComplete; + info.connectComplete = CmdOnConntectComplete; + info.sendMessageComplete = CmdOnSendMessageComplete; + info.recvMessage = CmdOnRecvMessage; + LE_STATUS status = LE_CreateStreamClient(LE_GetDefaultLoop(), &task, &info); + BEGET_ERROR_CHECK(status == 0, return NULL, "[control_fd] Failed create client"); + CmdAgent *agent = (CmdAgent *)LE_GetUserData(task); + BEGET_ERROR_CHECK(agent != NULL, return NULL, "[control_fd] Invalid agent"); + agent->task = task; + return agent; +} + +static int CreateFifo(const char *pipeName) +{ + if (pipeName == NULL) { + BEGET_LOGE("[control_fd] Invaild parameter"); + return -1; + } + // create fifo for cmd + CheckAndCreateDir(pipeName); + int ret = mkfifo(pipeName, CONTROL_FD_FIFO_MODE); + if (ret != 0) { + if (errno != EEXIST) { + return -1; + } + } + return 0; +} + +static int SendCmdMessage(const CmdAgent *agent, uint16_t type, const char *cmd, const char *fifoName) +{ + if ((agent == NULL) || (cmd == NULL) || (fifoName == NULL)) { + BEGET_LOGE("[control_fd] Invaild parameter"); + return -1; + } + int ret = 0; + BufferHandle handle = NULL; + uint32_t bufferSize = sizeof(CmdMessage) + strlen(cmd) + FIFO_PATH_SIZE + 1; + handle = LE_CreateBuffer(LE_GetDefaultLoop(), bufferSize); + char *buff = (char *)LE_GetBufferInfo(handle, NULL, NULL); + BEGET_ERROR_CHECK(buff != NULL, return -1, "[control_fd] Failed get buffer info"); + CmdMessage *message = (CmdMessage *)buff; + message->msgSize = bufferSize; + message->type = type; + message->pid = getpid(); + ret = strcpy_s(message->fifoName, FIFO_PATH_SIZE - 1, fifoName); + BEGET_ERROR_CHECK(ret == 0, LE_FreeBuffer(LE_GetDefaultLoop(), agent->task, handle); + return -1, "[control_fd] Failed to copy fifo name %s", fifoName); + ret = strcpy_s(message->cmd, bufferSize - sizeof(CmdMessage) - FIFO_PATH_SIZE, cmd); + BEGET_ERROR_CHECK(ret == 0, LE_FreeBuffer(LE_GetDefaultLoop(), agent->task, handle); + return -1, "[control_fd] Failed to copy cmd %s", cmd); + ret = LE_Send(LE_GetDefaultLoop(), agent->task, handle, bufferSize); + BEGET_ERROR_CHECK(ret == 0, return -1, "[control_fd] Failed LE_Send msg type %d, pid %d, cmd %s", + message->type, message->pid, message->cmd); + return 0; +} + +static int CmdMakeFifoInit(const char *fifoPath) +{ + if (fifoPath == NULL) { + BEGET_LOGE("[control_fd] Invaild parameter"); + return -1; + } + int ret = sprintf_s(g_FifoReadPath, sizeof(g_FifoReadPath) - 1, "/dev/fifo/%s0.%d", fifoPath, getpid()); + BEGET_ERROR_CHECK(ret > 0, return -1, "[control_fd] Failed sprintf_s err=%d", errno); + ret = CreateFifo(g_FifoReadPath); + BEGET_ERROR_CHECK(ret == 0, return -1, "[control_fd] Failed create fifo err=%d", errno); + + ret = sprintf_s(g_FifoWritePath, sizeof(g_FifoWritePath) - 1, "/dev/fifo/%s1.%d", fifoPath, getpid()); + BEGET_ERROR_CHECK(ret > 0, return -1, "[control_fd] Failed sprintf_s err=%d", errno); + ret = CreateFifo(g_FifoWritePath); + BEGET_ERROR_CHECK(ret == 0, return -1, "[control_fd] Failed create fifo err=%d", errno); + return 0; +} + +void CmdClientInit(const char *socketPath, uint16_t type, const char *cmd, const char *fifoName) +{ + if ((socketPath == NULL) || (cmd == NULL)) { + BEGET_LOGE("[control_fd] Invaild parameter"); + } + BEGET_LOGI("[control_fd] CmdAgentInit"); + int ret = CmdMakeFifoInit(fifoName); + BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed init fifo"); + CmdAgent *agent = CmdAgentCreate(socketPath); + BEGET_ERROR_CHECK(agent != NULL, return, "[control_fd] Failed to create agent"); + CmdAgentInit(agent->reader, g_FifoReadPath, true, ProcessFifoRead); + ret = SendCmdMessage(agent, type, cmd, fifoName); + BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed send message"); + LE_RunLoop(LE_GetDefaultLoop()); + BEGET_LOGI("Cmd Client exit "); + LE_CloseStreamTask(LE_GetDefaultLoop(), agent->task); + free(agent); + DestroyCmdFifo(); +} diff --git a/interfaces/innerkits/control_fd/control_fd_service.c b/interfaces/innerkits/control_fd/control_fd_service.c new file mode 100644 index 0000000000000000000000000000000000000000..c3892849a1aadba4b2bf30380dc25c4f5acd8d14 --- /dev/null +++ b/interfaces/innerkits/control_fd/control_fd_service.c @@ -0,0 +1,154 @@ +/* + * 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 +#include +#include +#include +#include + +#include "beget_ext.h" +#include "control_fd.h" +#include "init_utils.h" +#include "securec.h" + +static CmdService g_cmdService; + +CallbackControlFdProcess g_controlFdFunc = NULL; + +static void CmdOnClose(const TaskHandle task) +{ + BEGET_LOGI("[control_fd] CmdOnClose"); +} + +static void CmdDisConnectComplete(const TaskHandle client) +{ + BEGET_LOGI("[control_fd] CmdDisConnectComplete"); +} + +static void CmdOnSendMessageComplete(const TaskHandle task, const BufferHandle handle) +{ + BEGET_LOGI("[control_fd] CmdOnSendMessageComplete "); +} + +static int OpenFifo(int pid, bool read, const char *pipeName) +{ + // create pipe for cmd + if (pipeName == NULL) { + return -1; + } + char buffer[FIFO_PATH_SIZE] = {0}; + int ret = 0; + if (read == true) { + ret = sprintf_s(buffer, sizeof(buffer) - 1, "/dev/fifo/%s1.%d", pipeName, pid); + BEGET_ERROR_CHECK(ret > 0, return -1, "[control_fd] Failed sprintf_s err=%d", errno); + } else { + ret = sprintf_s(buffer, sizeof(buffer) - 1, "/dev/fifo/%s0.%d", pipeName, pid); + BEGET_ERROR_CHECK(ret > 0, return -1, "[control_fd] Failed sprintf_s err=%d", errno); + } + + int flags = read ? (O_RDONLY | O_TRUNC | O_NONBLOCK) : (O_WRONLY | O_TRUNC); + return open(buffer, flags); +} + +static void CmdOnRecvMessage(const TaskHandle task, const uint8_t *buffer, uint32_t buffLen) +{ + BEGET_LOGI("[control_fd] CmdOnRecvMessage"); + if (buffer == NULL) { + return; + } + // parse msg to exec + CmdMessage *msg = (CmdMessage *)buffer; + if ((msg->type < 0) || (msg->type >= ACTION_MAX) || (msg->cmd[0] == '\0') || (msg->fifoName[0] == '\0')) { + BEGET_LOGE("[control_fd] Failed msg "); + return; + } + + int reader = OpenFifo(msg->pid, true, msg->fifoName); // read + BEGET_ERROR_CHECK(reader > 0, return, "[control_fd] Failed to open filo"); + + int writer = OpenFifo(msg->pid, false, msg->fifoName); // write + BEGET_ERROR_CHECK(writer > 0, return, "[control_fd] Failed to open filo"); + + pid_t pid = fork(); + if (pid == 0) { + (void)dup2(reader, STDIN_FILENO); + (void)dup2(writer, STDOUT_FILENO); + (void)dup2(writer, STDERR_FILENO); // Redirect fd to 0, 1, 2 + g_controlFdFunc(msg->type, msg->cmd, NULL); + exit(0); + } else if (pid < 0) { + BEGET_LOGE("[control_fd] Failed fork service"); + } + return; +} + +static int SendMessage(LoopHandle loop, TaskHandle task, const char *message) +{ + if (message == NULL) { + BEGET_LOGE("[control_fd] Invaild parameter"); + return -1; + } + BufferHandle handle = NULL; + uint32_t bufferSize = strlen(message) + 1; + handle = LE_CreateBuffer(loop, bufferSize); + char *buff = (char *)LE_GetBufferInfo(handle, NULL, &bufferSize); + BEGET_ERROR_CHECK(buff != NULL, return -1, "[control_fd] Failed get buffer info"); + int ret = memcpy_s(buff, bufferSize, message, strlen(message) + 1); + BEGET_ERROR_CHECK(ret == 0, LE_FreeBuffer(LE_GetDefaultLoop(), task, handle); + return -1, "[control_fd] Failed memcpy_s err=%d", errno); + LE_STATUS status = LE_Send(loop, task, handle, strlen(message) + 1); + BEGET_ERROR_CHECK(status == LE_SUCCESS, return -1, "[control_fd] Failed le send msg"); + return 0; +} + +static int CmdOnIncommingConntect(const LoopHandle loop, const TaskHandle server) +{ + BEGET_LOGI("[control_fd] CmdOnIncommingConntect"); + TaskHandle client = NULL; + LE_StreamInfo info = {}; + info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT; + info.baseInfo.close = CmdOnClose; + info.baseInfo.userDataSize = sizeof(CmdAgent); + info.disConntectComplete = CmdDisConnectComplete; + info.sendMessageComplete = CmdOnSendMessageComplete; + info.recvMessage = CmdOnRecvMessage; + int ret = LE_AcceptStreamClient(LE_GetDefaultLoop(), server, &client, &info); + BEGET_ERROR_CHECK(ret == 0, return -1, "[control_fd] Failed accept stream") + CmdAgent *agent = (CmdAgent *)LE_GetUserData(client); + BEGET_ERROR_CHECK(agent != NULL, return -1, "[control_fd] Invalid agent"); + agent->task = client; + ret = SendMessage(LE_GetDefaultLoop(), agent->task, "connect success."); + BEGET_ERROR_CHECK(ret == 0, return -1, "[control_fd] Failed send msg"); + return 0; +} + +void CmdServiceInit(const char *socketPath, CallbackControlFdProcess func) +{ + if ((socketPath == NULL) || (func == NULL)) { + BEGET_LOGE("[control_fd] Invaild parameter"); + return; + } + LE_StreamServerInfo info = {}; + info.baseInfo.flags = TASK_STREAM | TASK_SERVER | TASK_PIPE; + info.server = (char *)socketPath; + info.socketId = -1; + info.baseInfo.close = NULL; + info.disConntectComplete = NULL; + info.incommingConntect = CmdOnIncommingConntect; + info.sendMessageComplete = NULL; + info.recvMessage = NULL; + g_controlFdFunc = func; + (void)LE_CreateStreamServer(LE_GetDefaultLoop(), &g_cmdService.serverTask, &info); +} diff --git a/interfaces/innerkits/sandbox/include/sandbox.h b/interfaces/innerkits/sandbox/include/sandbox.h index 4fa96f2b9afe143fed4f358f527a465f15cd159e..b1267b276c0599be47dcc820b71527b58d11ec35 100644 --- a/interfaces/innerkits/sandbox/include/sandbox.h +++ b/interfaces/innerkits/sandbox/include/sandbox.h @@ -56,7 +56,6 @@ bool InitSandboxWithName(const char *name); int PrepareSandbox(const char *name); int EnterSandbox(const char *name); void DestroySandbox(const char *name); -int CheckSupportSandbox(void); void DumpSandboxByName(const char *name); #ifdef __cplusplus } diff --git a/interfaces/innerkits/sandbox/include/sandbox_namespace.h b/interfaces/innerkits/sandbox/include/sandbox_namespace.h index 4e398a5979fd81a9de447dddc57d5746634fe44c..1462e776d7be352899c553b1e2770fd409b46c07 100644 --- a/interfaces/innerkits/sandbox/include/sandbox_namespace.h +++ b/interfaces/innerkits/sandbox/include/sandbox_namespace.h @@ -23,7 +23,7 @@ extern "C" { int GetNamespaceFd(const char *nsPath); int UnshareNamespace(int nsType); -int SetNamespce(int nsFd, int nsType); +int SetNamespace(int nsFd, int nsType); void InitDefaultNamespace(void); int EnterDefaultNamespace(void); void CloseDefaultNamespace(void); diff --git a/interfaces/innerkits/sandbox/sandbox.c b/interfaces/innerkits/sandbox/sandbox.c old mode 100755 new mode 100644 index 548041226c174d4bbe5c0ff8389e861932554035..aa74692873f5002cadd2b87a5101f7e24bf98f5b --- a/interfaces/innerkits/sandbox/sandbox.c +++ b/interfaces/innerkits/sandbox/sandbox.c @@ -220,7 +220,7 @@ static int GetSandboxInfo(sandbox_t *sandbox, cJSON *root, const char *itemName) } else if (strcmp(itemName, SANDBOX_SYMLINK_TAG) == 0) { func = AddSymbolLinksToSandbox; } else { - BEGET_LOGE("Failed %s item name is not support.", itemName); + BEGET_LOGE("%s item name is not support.", itemName); return -1; } for (int i = 0; i < counts; i++) { @@ -279,7 +279,7 @@ static int ParseSandboxConfig(sandbox_t *sandbox, const char *sandboxConfig) static const struct SandboxMap *GetSandboxMapByName(const char *name) { if (name == NULL) { - BEGET_LOGE("Failed get sandbox map name is NULL."); + BEGET_LOGE("Sandbox map name is NULL."); return NULL; } int len = ARRAY_LENGTH(g_map); @@ -306,7 +306,7 @@ static void InitSandbox(sandbox_t *sandbox, const char *sandboxConfig, const cha } sandbox->ns = GetNamespaceFd("/proc/self/ns/mnt"); if (sandbox->ns < 0) { - BEGET_LOGE("Failed get sandbox namespace fd."); + BEGET_LOGE("Get sandbox namespace fd is failed"); return; } @@ -446,7 +446,7 @@ int PrepareSandbox(const char *name) BEGET_ERROR_CHECK(name != NULL, return -1, "Prepare sandbox name is NULL."); BEGET_ERROR_CHECK(getuid() == 0, return -1, "Current process uid is not root, exit."); const struct SandboxMap *map = GetSandboxMapByName(name); - BEGET_ERROR_CHECK(map != NULL, return -1, "Failed get sandbox map by name %s.", name); + BEGET_ERROR_CHECK(map != NULL, return -1, "Cannot get sandbox map by name %s.", name); sandbox_t *sandbox = map->sandbox; BEGET_CHECK(IsValidSandbox(sandbox) == true, return -1); BEGET_INFO_CHECK(sandbox->isCreated == false, return 0, "Sandbox %s already created", sandbox->name); @@ -569,7 +569,7 @@ void DestroySandbox(const char *name) } const struct SandboxMap *map = GetSandboxMapByName(name); if (map == NULL) { - BEGET_LOGE("Failed get sandbox map by name %s.", name); + BEGET_LOGE("Cannot get sandbox map by name %s.", name); return; } sandbox_t *sandbox = map->sandbox; @@ -599,7 +599,7 @@ int EnterSandbox(const char *name) } const struct SandboxMap *map = GetSandboxMapByName(name); if (map == NULL) { - BEGET_LOGE("Failed to get sandbox map by name %s.", name); + BEGET_LOGE("Cannot get sandbox map by name %s.", name); return -1; } sandbox_t *sandbox = map->sandbox; @@ -612,8 +612,8 @@ int EnterSandbox(const char *name) return -1; } if (sandbox->ns > 0) { - if (SetNamespce(sandbox->ns, CLONE_NEWNS) < 0) { - BEGET_LOGE("Failed to enter mount namespace for sandbox \' %s \', err=%d.", name, errno); + if (SetNamespace(sandbox->ns, CLONE_NEWNS) < 0) { + BEGET_LOGE("Cannot enter mount namespace for sandbox \' %s \', err=%d.", name, errno); return -1; } } else { diff --git a/interfaces/innerkits/sandbox/sandbox_namespace.c b/interfaces/innerkits/sandbox/sandbox_namespace.c index 071f129811565f6be6ba54976c4473fd9e7d76b5..e38e6b2fc857f140b5001cb94a856801731db558 100644 --- a/interfaces/innerkits/sandbox/sandbox_namespace.c +++ b/interfaces/innerkits/sandbox/sandbox_namespace.c @@ -30,7 +30,7 @@ int GetNamespaceFd(const char *nsPath) } int ns = open(nsPath, O_RDONLY | O_CLOEXEC); if (ns < 0) { - BEGET_LOGE("Failed unshare namespace, err=%d", errno); + BEGET_LOGE("Open default namespace failed, err=%d", errno); return -1; } return ns; @@ -40,25 +40,25 @@ int UnshareNamespace(int nsType) { if (nsType == CLONE_NEWNS) { if (unshare(nsType) < 0) { - BEGET_LOGE("Failed unshare namespace, err=%d", errno); + BEGET_LOGE("Unshare namespace failed, err=%d", errno); return -1; } else { return 0; } } else { - BEGET_LOGE("Failed unshare, type is not support"); + BEGET_LOGE("Namespace type is not support"); return -1; } } -int SetNamespce(int nsFd, int nsType) +int SetNamespace(int nsFd, int nsType) { if (nsFd < 0) { - BEGET_LOGE("Failed get namespace fd"); + BEGET_LOGE("Namespace fd is invaild"); return -1; } if (nsType != CLONE_NEWNS) { - BEGET_LOGE("Failed get namespace type"); + BEGET_LOGE("Namespace type is not support"); return -1; } return setns(nsFd, nsType); @@ -78,7 +78,7 @@ int EnterDefaultNamespace(void) if (g_defaultNs < 0) { return -1; } - return SetNamespce(g_defaultNs, CLONE_NEWNS); + return SetNamespace(g_defaultNs, CLONE_NEWNS); } void CloseDefaultNamespace(void) diff --git a/services/BUILD.gn b/services/BUILD.gn index a312dc09ab2f1b5b2170d64b5812e96f350f8197..c3edd66a8e0a6a41f993e71ed762769db8b511ae 100755 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -124,6 +124,7 @@ if (defined(ohos_lite)) { "init/standard/init.c", "init/standard/init_cmdexecutor.c", "init/standard/init_cmds.c", + "init/standard/init_control_fd_service.c", "init/standard/init_jobs.c", "init/standard/init_mount.c", "init/standard/init_reboot.c", @@ -158,12 +159,14 @@ if (defined(ohos_lite)) { "//base/startup/init_lite/ueventd/include", "//third_party/cJSON", "//third_party/bounds_checking_function/include", + "//base/startup/init_lite/interfaces/innerkits/control_fd", ] deps = [ "//base/customization/config_policy/frameworks/config_policy:configpolicy_util_for_init_static", "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", "//base/startup/init_lite/interfaces/innerkits:libfsmanager_static", + "//base/startup/init_lite/interfaces/innerkits/control_fd:libcontrolfd_static", "//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox_static", "//base/startup/init_lite/services/log:init_log", "//base/startup/init_lite/services/loopevent:loopevent", diff --git a/services/begetctl/BUILD.gn b/services/begetctl/BUILD.gn index a7f57cd260a844a2ed9ef4bf56ccd2034e9a3ef4..b9cba1f8fb0a247c23e4d46dded6b2af2a4e382b 100755 --- a/services/begetctl/BUILD.gn +++ b/services/begetctl/BUILD.gn @@ -87,9 +87,11 @@ if (defined(ohos_lite)) { "//base/startup/init_lite/services/loopevent/include", "//third_party/bounds_checking_function/include", "//base/startup/init_lite/interfaces/innerkits/sandbox/include", + "//base/startup/init_lite/interfaces/innerkits/control_fd", ] deps = [ "//base/startup/init_lite/interfaces/innerkits:libbegetutil", + "//base/startup/init_lite/interfaces/innerkits/control_fd:libcontrolfd", "//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox", "//third_party/bounds_checking_function:libsec_shared", ] diff --git a/services/begetctl/param_cmd.c b/services/begetctl/param_cmd.c old mode 100755 new mode 100644 diff --git a/services/begetctl/sandbox.cpp b/services/begetctl/sandbox.cpp index 74d4c2bd6ccdc0d53cb0dfaa215c64b21b3b9272..40afb37db82b5382818d11b6a4c2bfb66100ae4d 100644 --- a/services/begetctl/sandbox.cpp +++ b/services/begetctl/sandbox.cpp @@ -25,6 +25,7 @@ #include #include "begetctl.h" +#include "control_fd.h" #include "init_utils.h" #include "sandbox.h" #include "sandbox_namespace.h" @@ -32,8 +33,8 @@ using namespace OHOS; struct option g_options[] = { - { "config_file", required_argument, nullptr, 'c' }, - { "sandbox_name", required_argument, nullptr, 's' }, + { "service_name", required_argument, nullptr, 's' }, + { "namespace_name", required_argument, nullptr, 'n' }, { "process_name", required_argument, nullptr, 'p' }, { "help", no_argument, nullptr, 'h' }, { nullptr, 0, nullptr, 0 }, @@ -41,43 +42,17 @@ struct option g_options[] = { static void Usage() { - std::cout << "sandbox -c, --config_file=sandbox config file \"config file with json format\"" << std::endl; - std::cout << "sandbox -s, --sandbox_name=sandbox name \"Sandbox name, system, chipset etc.\"" << std::endl; + 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; 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); } -static std::string SearchConfigBySandboxName(const std::string &sandboxName) +static void RunSandbox(const std::string &sandboxName) { - std::map sandboxConfigMap = { - {"system", "/system/etc/system-sandbox.json"}, - {"chipset", "/system/etc/chipset-sandbox.json"}, - {"priv-app", "/system/etc/priv-app-sandbox.json"}, - {"app", "/system/etc/app-sandbox.json"}, - }; - auto it = sandboxConfigMap.find(sandboxName); - if (it == sandboxConfigMap.end()) { - return ""; - } else { - return it->second; - } -} - -static void RunSandbox(const std::string &configFile, const std::string &name) -{ - std::string config {}; - std::string sandboxName {}; - if (!name.empty()) { - config = SearchConfigBySandboxName(name); - sandboxName = name; - } else { - // Without sandbox name, give one. - sandboxName = "sandbox_test"; - } - - if (config.empty()) { - std::cout << "No sandbox name " << sandboxName << "or config file specified!" << std::endl; + if (sandboxName.empty()) { return; } InitDefaultNamespace(); @@ -139,18 +114,21 @@ static void EnterExec(const std::string &processName) return; } -static void RunCmd(const std::string &configFile, const std::string &sandboxName, const std::string &processName) +static void RunCmd(const std::string &serviceName, const std::string &namespaceName, const std::string &processName) { - if (!sandboxName.empty() && processName.empty()) { - RunSandbox(configFile, sandboxName); + if (!namespaceName.empty() && processName.empty() && serviceName.empty()) { + RunSandbox(namespaceName); EnterShell(); - } else if (!sandboxName.empty() && !processName.empty()) { - RunSandbox(configFile, sandboxName); + } else if (!namespaceName.empty() && !processName.empty() && serviceName.empty()) { + RunSandbox(namespaceName); EnterExec(processName); - } else if (sandboxName.empty() && !processName.empty()) { + } else if (namespaceName.empty() && !processName.empty() && serviceName.empty()) { std::cout << "process name:" << processName << std::endl; - RunSandbox(configFile, std::string("system")); + RunSandbox(std::string("system")); EnterExec(processName); + } else if (namespaceName.empty() && processName.empty() && !serviceName.empty()) { + std::cout << "enter sandbox service name " << serviceName << std::endl; + CmdClientInit(INIT_CONTROL_FD_SOCKET_PATH, ACTION_SANDBOX, serviceName.c_str(), "FIFO"); } else { Usage(); } @@ -160,35 +138,35 @@ static int main_cmd(BShellHandle shell, int argc, char **argv) { int rc = -1; int optIndex = -1; - std::string configFile {}; - std::string sandboxName {}; + std::string serviceName {}; + std::string namespaceName {}; std::string processName {}; - while ((rc = getopt_long(argc, argv, "c:s:p:h", g_options, &optIndex)) != -1) { + while ((rc = getopt_long(argc, argv, "s:n:p:h", g_options, &optIndex)) != -1) { switch (rc) { case 0: { std::string optionName = g_options[optIndex].name; - if (optionName == "config_file") { - configFile = optarg; + if (optionName == "service_name") { + serviceName = optarg; } else if (optionName == "help") { Usage(); - } else if (optionName == "sandbox_name") { - sandboxName = optarg; + } else if (optionName == "namespace_name") { + namespaceName = optarg; } else if (optionName == "process_name") { processName = optarg; } break; } - case 'c': - configFile = optarg; + case 's': + serviceName = optarg; break; case 'h': Usage(); break; - case 's': - sandboxName = optarg; + case 'n': + namespaceName = optarg; break; case 'p': - std::cout << "1111 process name:" << optarg << std::endl; + std::cout << "process name:" << optarg << std::endl; processName = optarg; break; case '?': @@ -199,7 +177,7 @@ static int main_cmd(BShellHandle shell, int argc, char **argv) break; } } - RunCmd(configFile, sandboxName, processName); + RunCmd(serviceName, namespaceName, processName); return 0; } @@ -207,8 +185,18 @@ MODULE_CONSTRUCTOR(void) { CmdInfo infos[] = { { - (char *)"sandbox", main_cmd, (char *)"sandbox debug tool", - (char *)"sandbox -s, --sandbox=system, chipset, priv-app, or app", + (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", NULL } }; diff --git a/services/include/init_hashmap.h b/services/include/init_hashmap.h old mode 100755 new mode 100644 diff --git a/services/include/init_utils.h b/services/include/init_utils.h index a98bbeb6583926b22615f387db1b24f3af598f0c..5ad8d5fa002d0ee162157a7fff48acb996dac13d 100644 --- a/services/include/init_utils.h +++ b/services/include/init_utils.h @@ -59,6 +59,7 @@ size_t WriteAll(int fd, const char *buffer, size_t size); char *GetRealPath(const char *source); int StringToInt(const char *str, int defaultValue); int MakeDirRecursive(const char *dir, mode_t mode); +void CheckAndCreateDir(const char *fileName); int MakeDir(const char *dir, mode_t mode); int ReadFileInDir(const char *dirPath, const char *includeExt, int (*processFile)(const char *fileName, void *context), void *context); diff --git a/services/include/list.h b/services/include/list.h old mode 100755 new mode 100644 diff --git a/services/init/include/init_control_fd_service.h b/services/init/include/init_control_fd_service.h new file mode 100644 index 0000000000000000000000000000000000000000..a383e747f4f9005370aeff597768754255e0978e --- /dev/null +++ b/services/init/include/init_control_fd_service.h @@ -0,0 +1,21 @@ +/* + * 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. + */ + +#ifndef CONTROL_FD_SERVICE_H +#define CONTROL_FD_SERVICE_H + +void InitControlFd(void); + +#endif \ No newline at end of file diff --git a/services/init/include/init_group_manager.h b/services/init/include/init_group_manager.h old mode 100755 new mode 100644 diff --git a/services/init/include/init_service.h b/services/init/include/init_service.h index cdcf6af21c756a320eaf6ab324b5c4a64d9352be..4a552e358b05cfc1febfbf24438bef9bca4a8677 100644 --- a/services/init/include/init_service.h +++ b/services/init/include/init_service.h @@ -173,7 +173,7 @@ int SetAccessToken(const Service *service); void GetAccessToken(void); void ServiceStopTimer(Service *service); void ServiceStartTimer(Service *service, uint64_t timeout); - +void EnterServiceSandbox(Service *service); #ifdef __cplusplus #if __cplusplus } diff --git a/services/init/include/init_service_manager.h b/services/init/include/init_service_manager.h index 35080b1d64f40dc188babc2318411ce006fc6956..39d06834c96f9a8d001f165acd218bf817b2e5ca 100644 --- a/services/init/include/init_service_manager.h +++ b/services/init/include/init_service_manager.h @@ -66,6 +66,7 @@ Service *AddService(const char *name); #ifdef OHOS_SERVICE_DUMP void DumpAllServices(); +void DumpOneService(const Service *service); #endif #ifdef __cplusplus #if __cplusplus diff --git a/services/init/init_common_cmds.c b/services/init/init_common_cmds.c old mode 100755 new mode 100644 diff --git a/services/init/init_common_service.c b/services/init/init_common_service.c index e82fa33aca615b5c114277a7d3c64375e821941b..dafd6ee08f4b80d2ad06fc9b1b1951c338fe9d98 100644 --- a/services/init/init_common_service.c +++ b/services/init/init_common_service.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -278,6 +279,57 @@ static void ClearEnvironment(Service *service) return; } +static int InitServicePropertys(Service *service) +{ + INIT_ERROR_CHECK(service != NULL, return -1, "Invaild parameter."); + SetServiceEnterSandbox(service->pathArgs.argv[0], service->attribute); + INIT_CHECK_ONLY_ELOG(SetAccessToken(service) == SERVICE_SUCCESS, "access token failed %s", service->name); + // deal start job + if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) { + DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]); + } + ClearEnvironment(service); + + if (!IsOnDemandService(service)) { + INIT_ERROR_CHECK(CreateServiceSocket(service) >= 0, return -1, + "service %s exit! create socket failed!", service->name); + } + + CreateServiceFile(service->fileCfg); + if (service->attribute & SERVICE_ATTR_CONSOLE) { + OpenConsole(); + } + + PublishHoldFds(service); + INIT_CHECK_ONLY_ELOG(BindCpuCore(service) == SERVICE_SUCCESS, + "binding core number failed for service %s", service->name); + // permissions + INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, _exit(PROCESS_EXIT_CODE), + "service %s exit! set perms failed! err %d.", service->name, errno); + // write pid + INIT_ERROR_CHECK(WritePid(service) == SERVICE_SUCCESS, _exit(PROCESS_EXIT_CODE), + "service %s exit! write pid failed!", service->name); + SetSecon(service); + return 0; +} + +void EnterServiceSandbox(Service *service) +{ + INIT_ERROR_CHECK(InitServicePropertys(service) == 0, return, "Failed init service property"); + if (service->importance != 0) { + if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) { + INIT_LOGE("setpriority failed for %s, importance = %d, err=%d", + service->name, service->importance, errno); + _exit(0x7f); // 0x7f: user specified + } + } + INIT_CHECK_ONLY_ELOG(unsetenv("UV_THREADPOOL_SIZE") == 0, "set UV_THREADPOOL_SIZE error : %d.", errno); + char *argv[] = { (char *)"/bin/sh", NULL }; + INIT_CHECK_ONLY_ELOG(execv(argv[0], argv) == 0, + "service %s execv sh failed! err %d.", service->name, errno); + _exit(PROCESS_EXIT_CODE); +} + int ServiceStart(Service *service) { INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr."); @@ -298,35 +350,7 @@ int ServiceStart(Service *service) } int pid = fork(); if (pid == 0) { - SetServiceEnterSandbox(service->pathArgs.argv[0], service->attribute); - - INIT_CHECK_ONLY_ELOG(SetAccessToken(service) == SERVICE_SUCCESS, "access token failed %s", service->name); - // deal start job - if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) { - DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]); - } - - ClearEnvironment(service); - - if (!IsOnDemandService(service)) { - INIT_ERROR_CHECK(CreateServiceSocket(service) >= 0, return SERVICE_FAILURE, - "service %s exit! create socket failed!", service->name); - } - - CreateServiceFile(service->fileCfg); - if (service->attribute & SERVICE_ATTR_CONSOLE) { - OpenConsole(); - } - PublishHoldFds(service); - INIT_CHECK_ONLY_ELOG(BindCpuCore(service) == SERVICE_SUCCESS, - "binding core number failed for service %s", service->name); - // permissions - INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, _exit(PROCESS_EXIT_CODE), - "service %s exit! set perms failed! err %d.", service->name, errno); - // write pid - INIT_ERROR_CHECK(WritePid(service) == SERVICE_SUCCESS, _exit(PROCESS_EXIT_CODE), - "service %s exit! write pid failed!", service->name); - SetSecon(service); + INIT_ERROR_CHECK(InitServicePropertys(service) == 0, return SERVICE_FAILURE, "Failed init service property"); ServiceExec(service); _exit(PROCESS_EXIT_CODE); } else if (pid < 0) { diff --git a/services/init/init_service_manager.c b/services/init/init_service_manager.c index 0e25758c0a790af07e9a7e74daa7a4792e4b757d..128b92e24b71b24d4a4ad765fffc596f2065deba 100644 --- a/services/init/init_service_manager.c +++ b/services/init/init_service_manager.c @@ -46,45 +46,45 @@ static const int CRITICAL_CONFIG_ARRAY_LEN = 3; #ifdef OHOS_SERVICE_DUMP static void DumpServiceArgs(const char *info, const ServiceArgs *args) { - INIT_LOGI("\tservice %s count %d", info, args->count); + printf("\tservice %s count %d", info, args->count); for (int j = 0; j < args->count; j++) { if (args->argv[j] != NULL) { - INIT_LOGI("\t\tinfo [%d] %s", j, args->argv[j]); + printf("\t\tinfo [%d] %s", j, args->argv[j]); } } } static void DumpServiceJobs(const Service *service) { - INIT_LOGI("\tservice job info"); + printf("\tservice job info"); if (service->serviceJobs.jobsName[JOB_ON_BOOT] != NULL) { - INIT_LOGI("\t\tservice boot job %s", service->serviceJobs.jobsName[JOB_ON_BOOT]); + printf("\t\tservice boot job %s", service->serviceJobs.jobsName[JOB_ON_BOOT]); } if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) { - INIT_LOGI("\t\tservice start job %s", service->serviceJobs.jobsName[JOB_ON_START]); + printf("\t\tservice start job %s", service->serviceJobs.jobsName[JOB_ON_START]); } if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) { - INIT_LOGI("\t\tservice stop job %s", service->serviceJobs.jobsName[JOB_ON_STOP]); + printf("\t\tservice stop job %s", service->serviceJobs.jobsName[JOB_ON_STOP]); } if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) { - INIT_LOGI("\t\tservice restart job %s", service->serviceJobs.jobsName[JOB_ON_RESTART]); + printf("\t\tservice restart job %s", service->serviceJobs.jobsName[JOB_ON_RESTART]); } } static void DumpServiceSocket(const Service *service) { - INIT_LOGI("\tservice socket info"); + printf("\tservice socket info"); ServiceSocket *sockopt = service->socketCfg; while (sockopt != NULL) { - INIT_LOGI("\t\tsocket name: %s", sockopt->name); - INIT_LOGI("\t\tsocket type: %d", sockopt->type); - INIT_LOGI("\t\tsocket uid: %d", sockopt->uid); - INIT_LOGI("\t\tsocket gid: %d", sockopt->gid); + printf("\t\tsocket name: %s", sockopt->name); + printf("\t\tsocket type: %d", sockopt->type); + printf("\t\tsocket uid: %d", sockopt->uid); + printf("\t\tsocket gid: %d", sockopt->gid); sockopt = sockopt->next; } } -void DumpAllServices() +void DumpOneService(const Service *service) { const InitArgInfo startModeMap[] = { {"condition", START_MODE_CONDITION}, @@ -93,8 +93,33 @@ void DumpAllServices() }; int size = 0; const InitArgInfo *statusMap = GetServieStatusMap(&size); - INIT_LOGI("Ready to dump all services:"); - INIT_LOGI("total service number: %d", g_serviceSpace.serviceCount); + printf("\tservice name: [%s]", service->name); + printf("\tservice pid: [%d]", service->pid); + printf("\tservice crashCnt: [%d]", service->crashCnt); + printf("\tservice attribute: [%d]", service->attribute); + printf("\tservice importance: [%d]", service->importance); + printf("\tservice startMode: [%s]", startModeMap[service->status].name); + printf("\tservice status: [%s]", statusMap[service->status].name); + printf("\tservice perms uID [%d]", service->servPerm.uID); + DumpServiceArgs("path arg", &service->pathArgs); + DumpServiceArgs("writepid file", &service->writePidArgs); + DumpServiceJobs(service); + DumpServiceSocket(service); + + printf("\tservice perms groupId %d", service->servPerm.gIDCnt); + for (int i = 0; i < service->servPerm.gIDCnt; i++) { + printf("\t\tservice perms groupId %d", service->servPerm.gIDArray[i]); + } + printf("\tservice perms capability %d", service->servPerm.capsCnt); + for (int i = 0; i < (int)service->servPerm.capsCnt; i++) { + printf("\t\tservice perms capability %d", service->servPerm.caps[i]); + } +} + +void DumpAllServices() +{ + printf("Ready to dump all services:"); + printf("total service number: %d", g_serviceSpace.serviceCount); InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL); while (node != NULL) { if (node->data.service == NULL) { @@ -102,30 +127,10 @@ void DumpAllServices() continue; } Service *service = node->data.service; - INIT_LOGI("\tservice name: [%s]", service->name); - INIT_LOGI("\tservice pid: [%d]", service->pid); - INIT_LOGI("\tservice crashCnt: [%d]", service->crashCnt); - INIT_LOGI("\tservice attribute: [%d]", service->attribute); - INIT_LOGI("\tservice importance: [%d]", service->importance); - INIT_LOGI("\tservice startMode: [%s]", startModeMap[service->status].name); - INIT_LOGI("\tservice status: [%s]", statusMap[service->status].name); - INIT_LOGI("\tservice perms uID [%d]", service->servPerm.uID); - DumpServiceArgs("path arg", &service->pathArgs); - DumpServiceArgs("writepid file", &service->writePidArgs); - DumpServiceJobs(service); - DumpServiceSocket(service); - - INIT_LOGI("\tservice perms groupId %d", service->servPerm.gIDCnt); - for (int i = 0; i < service->servPerm.gIDCnt; i++) { - INIT_LOGI("\t\tservice perms groupId %d", service->servPerm.gIDArray[i]); - } - INIT_LOGI("\tservice perms capability %d", service->servPerm.capsCnt); - for (int i = 0; i < (int)service->servPerm.capsCnt; i++) { - INIT_LOGI("\t\tservice perms capability %d", service->servPerm.caps[i]); - } + DumpOneService(service); node = GetNextGroupNode(NODE_TYPE_SERVICES, node); } - INIT_LOGI("Dump all services finished"); + printf("Dump all services finished"); } #endif diff --git a/services/init/module_engine/include/init_cmdexecutor.h b/services/init/module_engine/include/init_cmdexecutor.h old mode 100755 new mode 100644 diff --git a/services/init/standard/device.c b/services/init/standard/device.c old mode 100755 new mode 100644 diff --git a/services/init/standard/init.c b/services/init/standard/init.c old mode 100755 new mode 100644 index b97d818c54423fb46169756fd77a49ff54ccb2ef..111bffbdd58865eb74550e938ca4d3bd2b3a414e --- a/services/init/standard/init.c +++ b/services/init/standard/init.c @@ -29,6 +29,7 @@ #include "device.h" #include "fd_holder_service.h" #include "fs_manager/fs_manager.h" +#include "init_control_fd_service.h" #include "init_log.h" #include "init_mount.h" #include "init_group_manager.h" @@ -106,6 +107,7 @@ void SystemInit(void) if (sock >= 0) { RegisterFdHoldWatcher(sock); } + InitControlFd(); } static void EnableDevKmsg(void) @@ -392,15 +394,15 @@ void SetServiceEnterSandbox(const char *execPath, unsigned int attribute) } else if (strcmp(execPath, "/system/bin/hilogd") == 0) { INIT_LOGI("Hilogd skip enter sandbox."); } else { - INIT_ERROR_CHECK(EnterSandbox("system") == 0, return, - "Service %s failed enter sandbox system.", execPath); + INIT_INFO_CHECK(EnterSandbox("system") == 0, return, + "Service %s skip enter sandbox system.", execPath); } } else if (strncmp(execPath, "/vendor/bin/", strlen("/vendor/bin/")) == 0) { // chipset sandbox will be implemented later. - INIT_ERROR_CHECK(EnterSandbox("system") == 0, return, - "Service %s failed enter sandbox system.", execPath); + INIT_INFO_CHECK(EnterSandbox("system") == 0, return, + "Service %s skip enter sandbox system.", execPath); } else { - INIT_LOGE("Service %s does not enter sandbox", execPath); + INIT_LOGI("Service %s does not enter sandbox", execPath); } return; } diff --git a/services/init/standard/init_cmdexecutor.c b/services/init/standard/init_cmdexecutor.c old mode 100755 new mode 100644 diff --git a/services/init/standard/init_control_fd_service.c b/services/init/standard/init_control_fd_service.c new file mode 100644 index 0000000000000000000000000000000000000000..ddee9e9fd879c20644a26e60d7210b8a3aff97f7 --- /dev/null +++ b/services/init/standard/init_control_fd_service.c @@ -0,0 +1,100 @@ +/* + * 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 +#include +#include +#include + +#include "control_fd.h" +#include "init_service.h" +#include "init_service_manager.h" +#include "init_utils.h" +#include "init_log.h" + +static void ProcessSandboxControlFd(uint16_t type, const char *serviceCmd) +{ + if ((type != ACTION_SANDBOX) || (serviceCmd == NULL)) { + INIT_LOGE("Invaild parameter"); + return; + } + Service *service = GetServiceByName(serviceCmd); + if (service == NULL) { + INIT_LOGE("Failed get service %s", serviceCmd); + return; + } + EnterServiceSandbox(service); + return; +} + +static void ProcessDumpServiceControlFd(uint16_t type, const char *serviceCmd) +{ + if ((type != ACTION_DUMP) || (serviceCmd == NULL)) { + return; + } + Service *service = GetServiceByName(serviceCmd); + + if (service == NULL) { +#ifdef OHOS_SERVICE_DUMP + DumpAllServices(); + } else { + DumpOneService(service); +#endif + } + return; +} + +static void ProcessParamShellControlFd(uint16_t type, const char *serviceCmd) +{ + if ((type != ACTION_PARAM_SHELL) || (serviceCmd == NULL)) { + return; + } + (void)setuid(2000); // 2000 shell group + (void)setgid(2000); // 2000 shell group + char *args[] = {(char *)serviceCmd, NULL}; + int ret = execv(args[0], args); + if (ret < 0) { + INIT_LOGE("error on exec %d \n", errno); + exit(-1); + } + exit(0); +} + +void ProcessControlFd(uint16_t type, const char *serviceCmd, const void *context) +{ + if ((type >= ACTION_MAX) || (serviceCmd == NULL)) { + return; + } + switch (type) { + case ACTION_SANDBOX : + ProcessSandboxControlFd(type, serviceCmd); + break; + case ACTION_DUMP : + ProcessDumpServiceControlFd(type, serviceCmd); + break; + case ACTION_PARAM_SHELL : + ProcessParamShellControlFd(type, serviceCmd); + break; + default : + INIT_LOGW("Unknown control fd type."); + break; + } +} + +void InitControlFd(void) +{ + CmdServiceInit(INIT_CONTROL_FD_SOCKET_PATH, ProcessControlFd); + return; +} diff --git a/services/loopevent/socket/le_socket.c b/services/loopevent/socket/le_socket.c index 150479344d98b1598af06939a722e983d73ae6b0..dba31777536100f4fb431665575b7f2c8fd0793c 100644 --- a/services/loopevent/socket/le_socket.c +++ b/services/loopevent/socket/le_socket.c @@ -69,23 +69,10 @@ static int CreatePipeSocket_(const char *server) LE_CHECK(ret == 0, close(fd); return ret, "Failed to memset_s serverAddr"); serverAddr.sun_family = AF_UNIX; - // bind local - ret = sprintf_s(serverAddr.sun_path, sizeof(serverAddr.sun_path), "%s_%d", server, getpid()); - LE_CHECK(ret > 0, close(fd); - return ret, "Failed to sprintf_s sun_path"); - uint32_t size = offsetof(struct sockaddr_un, sun_path) + strlen(serverAddr.sun_path); - ret = bind(fd, (struct sockaddr *)&serverAddr, size); - LE_CHECK(ret >= 0, close(fd); - return ret, "Failed to bind socket"); - - ret = memset_s(&serverAddr, sizeof(serverAddr), 0, sizeof(serverAddr)); - LE_CHECK(ret == 0, close(fd); - return ret, "Failed to memset_s serverAddr"); - serverAddr.sun_family = AF_UNIX; ret = strcpy_s(serverAddr.sun_path, sizeof(serverAddr.sun_path), server); LE_CHECK(ret == 0, close(fd); return ret, "Failed to strcpy_s sun_path"); - size = offsetof(struct sockaddr_un, sun_path) + strlen(serverAddr.sun_path); + uint32_t size = offsetof(struct sockaddr_un, sun_path) + strlen(serverAddr.sun_path); ret = connect(fd, (struct sockaddr *)&serverAddr, size); LE_CHECK(ret >= 0, close(fd); return ret, "Failed to connect socket"); diff --git a/services/utils/init_utils.c b/services/utils/init_utils.c index b86f8613cd322110a6821d58e35a0376b4ac0807..426663d8c451de00e33c9d6d5ac895b7b01920c4 100644 --- a/services/utils/init_utils.c +++ b/services/utils/init_utils.c @@ -349,6 +349,25 @@ int MakeDirRecursive(const char *dir, mode_t mode) return MakeDir(dir, mode); } +void CheckAndCreateDir(const char *fileName) +{ +#ifndef __LITEOS_M__ + if (fileName == NULL || *fileName == '\0') { + return; + } + char *path = strndup(fileName, strrchr(fileName, '/') - fileName); + if (path == NULL) { + return; + } + if (access(path, F_OK) == 0) { + free(path); + return; + } + MakeDirRecursive(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + free(path); +#endif +} + int StringToInt(const char *str, int defaultValue) { if (str == NULL || *str == '\0') { diff --git a/services/utils/list.c b/services/utils/list.c old mode 100755 new mode 100644