diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md new file mode 100755 index 0000000000000000000000000000000000000000..f09d98dde9597de75ffcdb237c2b580b8fffa3f9 --- /dev/null +++ b/.gitee/ISSUE_TEMPLATE.zh-CN.md @@ -0,0 +1,13 @@ +### 该问题是怎么引起的? + + + +### 重现步骤 + + + +### 报错信息 + + + + diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md new file mode 100755 index 0000000000000000000000000000000000000000..33948fdcb51264545ce5ae797f5310a1c06f871d --- /dev/null +++ b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md @@ -0,0 +1,15 @@ +### 相关的Issue + + +### 原因(目的、解决的问题等) + + +### 描述(做了什么,变更了什么) + + +### 测试用例(新增、改动、可能影响的功能) + + + + + diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000000000000000000000000000000000000..12771ccb325016083dded34b872ee6ddaed2da64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/moduletest diff --git a/BUILD.gn b/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..2cbd4c67e12be604e0ea9e114e10cbfb48422bfa --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,68 @@ +# Copyright (c) 2020 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("//build/lite/config/component/lite_component.gni") + +lite_component("appspawn_lite") { + features = [ + ":appspawn", + ] +} + +# feature: appspawn +executable("appspawn") { + sources = [ + "src/main.c", + "src/appspawn_process.c", + "src/appspawn_service.c", + "src/appspawn_message.c", + "src/appspawn_adapter.c", + ] + + cflags = [ + "-Wall", + "-Wno-format", + "-Wno-format-extra-args", + ] + + include_dirs = [ + "include", + "//utils/native/lite/include", + "//foundation/distributedschedule/interfaces/kits/samgr_lite/samgr", + "//foundation/distributedschedule/interfaces/kits/samgr_lite/registry", + "//third_party/bounds_checking_function/include/", + "//third_party/cJSON", + ] + + deps = [ + "//third_party/bounds_checking_function:libsec_shared", + "//foundation/distributedschedule/services/samgr_lite/samgr:samgr", + "//foundation/communication/frameworks/ipc_lite:liteipc_adapter", + "//third_party/cJSON:cjson_shared", + ] + + if (ohos_kernel_type == "liteos_a") { + include_dirs += [ + "//kernel/liteos_a/kernel/include", + "//kernel/liteos_a/kernel/common", + ] + deps += [ + "//base/hiviewdfx/frameworks/hilog_lite/featured:hilog_shared", + ] + } + + if (ohos_kernel_type == "linux") { + ldflags = ["-lstdc++"] + include_dirs += [ + ] + } +} diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000000000000000000000000000000000000..4a459866a57c25462afad17f3fe0b50d440da080 --- /dev/null +++ b/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/include/appspawn_adapter.h b/include/appspawn_adapter.h new file mode 100755 index 0000000000000000000000000000000000000000..016171e6cd2cc99c221760ef833c568002f5c2b8 --- /dev/null +++ b/include/appspawn_adapter.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 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 BASE_STARTUP_APPSPAWN_ADAPTER_H +#define BASE_STARTUP_APPSPAWN_ADAPTER_H +#ifdef __LINUX__ +#include +#else +#include +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifdef __LINUX__ +extern int capset(void *a, void *b); +#endif + +int KeepCapability(); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // BASE_STARTUP_APPSPAWN_ADAPTER_H diff --git a/include/appspawn_message.h b/include/appspawn_message.h new file mode 100755 index 0000000000000000000000000000000000000000..6edd3b38a57e076317c188e7ec0211fd1a53e3f9 --- /dev/null +++ b/include/appspawn_message.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 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 BASE_STARTUP_APPSPAWN_MESSAGE_H +#define BASE_STARTUP_APPSPAWN_MESSAGE_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +typedef struct { + char* bundleName; + char* sharedLibPaths; + unsigned long long identityID; + int uID; + int gID; +} MessageSt; + +int SplitMessage(const char* msg, unsigned int msgLen, MessageSt* msgSt); + +void FreeMessageSt(MessageSt* targetSt); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // BASE_STARTUP_APPSPAWN_SERVICE_H \ No newline at end of file diff --git a/include/appspawn_process.h b/include/appspawn_process.h new file mode 100755 index 0000000000000000000000000000000000000000..d0566bc9df5aef53ebb540256bc1e5dc0ac5801b --- /dev/null +++ b/include/appspawn_process.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 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 BASE_STARTUP_APPSPAWN_PROCESS_H +#define BASE_STARTUP_APPSPAWN_PROCESS_H + +#include +#include "appspawn_message.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +pid_t CreateProcess(const MessageSt* msgSt); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // BASE_STARTUP_APPSPAWN_SERVICE_H \ No newline at end of file diff --git a/include/appspawn_service.h b/include/appspawn_service.h new file mode 100755 index 0000000000000000000000000000000000000000..221a8d2eaf352cab198712631e4c91ba97d0604c --- /dev/null +++ b/include/appspawn_service.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 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 BASE_STARTUP_APPSPAWN_SERVICE_H +#define BASE_STARTUP_APPSPAWN_SERVICE_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define APPSPAWN_SERVICE_NAME "appspawn" + +enum APPSPAWN_FUNCID { + ID_CALL_CREATE_SERVICE = 0, + ID_CALL_BUT +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // BASE_STARTUP_APPSPAWN_SERVICE_H \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100755 index 0000000000000000000000000000000000000000..5f8dd4ece1124bd7568ab5d12506cca4c786141f --- /dev/null +++ b/readme.md @@ -0,0 +1 @@ +详见:https://gitee.com/openharmony/docs/blob/master/readme/启动恢复README.md diff --git a/src/appspawn_adapter.c b/src/appspawn_adapter.c new file mode 100755 index 0000000000000000000000000000000000000000..9c56c0a303ec5a49139dd6e5a222e80b27768331 --- /dev/null +++ b/src/appspawn_adapter.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 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 "appspawn_adapter.h" +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +int KeepCapability() +{ +#ifdef __LINUX__ + if (prctl(PR_SET_KEEPCAPS, 1)) { + printf("prctl failed\n"); + return -1; + } +#endif + return 0; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/appspawn_message.c b/src/appspawn_message.c new file mode 100755 index 0000000000000000000000000000000000000000..f0741f47e7526d18722c42229bd957f09b54e834 --- /dev/null +++ b/src/appspawn_message.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2020 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 "appspawn_message.h" +#include +#include +#include +#include +#include "cJSON.h" +#include "log.h" +#include "ohos_errno.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static const size_t MAX_BUNDLE_NAME_LEN = 127; +static const size_t MIN_BUNDLE_NAME_LEN = 7; +static const size_t MAX_SHARED_LIB_PATH_LEN = 2048; +static const size_t MIN_SHARED_LIB_PATH_LEN = 0; + +void FreeMessageSt(MessageSt* targetSt) +{ + if (targetSt != NULL) { + if (targetSt->bundleName != NULL) { + free(targetSt->bundleName); + targetSt->bundleName = NULL; + } + + if (targetSt->sharedLibPaths != NULL) { + free(targetSt->sharedLibPaths); + targetSt->sharedLibPaths = NULL; + } + + targetSt->identityID = 0; + targetSt->uID = -1; + targetSt->gID = -1; + } +} + +static int ReadStringItem(cJSON* strItem, char** buf, size_t maxLen, size_t minLen) +{ + if (strItem == NULL || !cJSON_IsString(strItem)) { + return EC_INVALID; + } + + char* strPtr = cJSON_GetStringValue(strItem); + if (strPtr == NULL) { + return EC_PROTOCOL; + } + + size_t strLength = strlen(strPtr); + if (strLength > maxLen || strLength < minLen) { + return EC_PROTOCOL; + } + + char* bufTmp = (char*)malloc(strLength + 1); + if (bufTmp == NULL) { + return EC_NOMEMORY; + } + + if (strLength > 0 && memcpy_s(bufTmp, strLength, strPtr, strLength) != EOK) { + free(bufTmp); + bufTmp = NULL; + return EC_FAILURE; + } + + bufTmp[strLength] = '\0'; + *buf = bufTmp; + return EC_SUCCESS; +} + +static double ReadNumberItem(cJSON* strItem) +{ + if (strItem == NULL || !cJSON_IsNumber(strItem)) { + return -1; + } + + return cJSON_GetNumberValue(strItem); +} + +int SplitMessage(const char* msg, unsigned int msgLen, MessageSt* msgSt) +{ + if (msg == NULL || msgLen == 0 || msgSt == NULL) { + return EC_INVALID; + } + + cJSON* rootJ = cJSON_ParseWithLength(msg, msgLen); + if (rootJ == NULL) { + return EC_PROTOCOL; + } + + cJSON* bundleNameItem = cJSON_GetObjectItem(rootJ, "bundleName"); + int ret = ReadStringItem(bundleNameItem, &(msgSt->bundleName), MAX_BUNDLE_NAME_LEN, MIN_BUNDLE_NAME_LEN); + if (ret != EC_SUCCESS) { + cJSON_Delete(rootJ); + return ret; + } + + cJSON* libPathsItem = cJSON_GetObjectItem(rootJ, "sharedLibPaths"); + ret = ReadStringItem(libPathsItem, &(msgSt->sharedLibPaths), MAX_SHARED_LIB_PATH_LEN, MIN_SHARED_LIB_PATH_LEN); + if (ret != EC_SUCCESS) { + FreeMessageSt(msgSt); + cJSON_Delete(rootJ); + return ret; + } + + cJSON* identityIDItem = cJSON_GetObjectItem(rootJ, "identityID"); + cJSON* uIDItem = cJSON_GetObjectItem(rootJ, "uID"); + cJSON* gIDItem = cJSON_GetObjectItem(rootJ, "gID"); + + msgSt->identityID = (unsigned long long)ReadNumberItem(identityIDItem); + msgSt->uID = (int)ReadNumberItem(uIDItem); + msgSt->gID = (int)ReadNumberItem(gIDItem); + cJSON_Delete(rootJ); + + if (msgSt->identityID == 0 || msgSt->uID <= 0 || msgSt->gID <= 0 || + msgSt->identityID == ULLONG_MAX || msgSt->uID == INT_MAX || msgSt->gID == INT_MAX) { + FreeMessageSt(msgSt); + return EC_PROTOCOL; + } + return EC_SUCCESS; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/appspawn_process.c b/src/appspawn_process.c new file mode 100755 index 0000000000000000000000000000000000000000..902837f159e88181a8c2c76eab939a4c5adc542b --- /dev/null +++ b/src/appspawn_process.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2020 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. + */ +#define _GNU_SOURCE +#include "appspawn_process.h" +#include +#include +#include +#include +#include +#include "appspawn_adapter.h" +#include "log.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define DEFAULT_UMASK 022 +#define CAP_NUM 2 +#define ABILITY_EXE_FILE_FULL_PATH "/bin/abilityMain" +#define ABILITY_EXE_FILE_NAME "abilityMain" +#define ENV_TITLE "LD_LIBRARY_PATH=" +#define UPPER_BOUND_GID 999 +#define LOWER_BOUND_GID 100 +#define GRP_NUM 2 +#define DEVMGR_GRP 99 + +static const unsigned int MAX_IDENTITY_ID_LENGTH = 25; +static const unsigned int MAX_PROCESS_NAME_LENGTH = 130; + +static int SetPerms(uid_t uID, gid_t gID) +{ + gid_t groups[GRP_NUM]; + + if (KeepCapability() != 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] KeepCapability failed, uID %{public}u, err: %{public}d.",\ + uID, errno); + return -1; + } + + if (setuid(uID) != 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] setuid failed, uID %{public}u, err: %{public}d.",\ + uID, errno); + return -1; + } + + if (setgid(gID) != 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] setgid failed, gID %{public}u, err: %{public}d.",\ + gID, errno); + return -1; + } + + // add device groups for system app + if (gID >= LOWER_BOUND_GID && gID <= UPPER_BOUND_GID) { + groups[0] = gID; + groups[1] = DEVMGR_GRP; + if (setgroups(GRP_NUM, groups)) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] setgroups failed, uID %{public}u, err: %{public}d.",\ + uID, errno); + return -1; + } + } + + // umask call always succeeds and return the previous mask value which is not needed here + (void)umask(DEFAULT_UMASK); + + struct __user_cap_header_struct capHeader; + capHeader.version = _LINUX_CAPABILITY_VERSION_3; + capHeader.pid = 0; + + // common user, clear all caps + struct __user_cap_data_struct capData[CAP_NUM] = {0}; + + if (capset(&capHeader, capData) != 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] capset failed, err: %{public}d.", errno); + return -1; + } + return 0; +} + +static char* GetEnvStrs(const MessageSt* msgSt) +{ + size_t totalLen = strlen(ENV_TITLE) + strlen(msgSt->sharedLibPaths); + char* envStr = (char*)malloc(totalLen + 1); + if (envStr == NULL) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] malloc for env failed! len %{public}u.", totalLen); + return NULL; + } + + if (memset_s(envStr, totalLen + 1, '\0', totalLen + 1) != EOK) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] memset_s for env failed."); + free(envStr); + return NULL; + } + + if (sprintf_s(envStr, totalLen + 1, "%s%s", ENV_TITLE, msgSt->sharedLibPaths) <= 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] sprintf_s for env failed. libPath %{public}s",\ + msgSt->sharedLibPaths); + free(envStr); + return NULL; + } + return envStr; +} + +pid_t CreateProcess(const MessageSt* msgSt) +{ + char identityIDStr[MAX_IDENTITY_ID_LENGTH]; + char processNameStr[MAX_PROCESS_NAME_LENGTH]; + if (memset_s(identityIDStr, MAX_IDENTITY_ID_LENGTH, '\0', MAX_IDENTITY_ID_LENGTH) != EOK || + memset_s(processNameStr, MAX_PROCESS_NAME_LENGTH, '\0', MAX_PROCESS_NAME_LENGTH) != EOK) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] create service, memset_s failed."); + return -1; + } + + if (sprintf_s(identityIDStr, MAX_IDENTITY_ID_LENGTH, "%llu", msgSt->identityID) <= 0 || + sprintf_s(processNameStr, MAX_PROCESS_NAME_LENGTH, "%s", msgSt->bundleName) <= 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] sprintf_s failed. id %{public}llu, name %{public}s.",\ + msgSt->identityID, msgSt->bundleName); + return -1; + } + + char* envStr = GetEnvStrs(msgSt); + if (envStr == NULL) { + return -1; + } + + // check if the exe file exists + struct stat pathStat = {0}; + if (stat(ABILITY_EXE_FILE_FULL_PATH, &pathStat) != 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] stat %{public}s failed, err %{public}d.",\ + ABILITY_EXE_FILE_FULL_PATH, errno); + free(envStr); + return -1; + } + + pid_t newPID = fork(); + if (newPID < 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] create process, fork failed! err %{public}d.", errno); + free(envStr); + return -1; + } + + // in child process + if (newPID == 0) { + // set permissions + if (SetPerms(msgSt->uID, msgSt->gID) != 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] process %{public}s exit!", processNameStr); + _exit(0x7f); // 0x7f: user specified + } + + char* argv[] = {ABILITY_EXE_FILE_NAME, identityIDStr, processNameStr, NULL}; + char* env[] = {envStr, NULL}; + if (execve(ABILITY_EXE_FILE_FULL_PATH, argv, env) != 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] execve %{public}s failed! err %{public}d.",\ + ABILITY_EXE_FILE_FULL_PATH, errno); + } + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] sub-process exit, pid %{public}d.", getpid()); + _exit(0x7f); // 0x7f: user specified + } + + free(envStr); + return newPID; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/appspawn_service.c b/src/appspawn_service.c new file mode 100755 index 0000000000000000000000000000000000000000..70dd9a289187d7a152aeafbee82e47ed7fbd6f66 --- /dev/null +++ b/src/appspawn_service.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2020 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 "appspawn_service.h" +#include +#include "appspawn_message.h" +#include "appspawn_process.h" +#include "iproxy_server.h" +#include "iunknown.h" +#include "liteipc_adapter.h" +#include "log.h" +#include "message.h" +#include "ohos_errno.h" +#include "ohos_init.h" +#include "samgr_lite.h" +#include "service.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +static const int INVALID_PID = -1; + +typedef struct AppSpawnFeatureApi { + INHERIT_SERVER_IPROXY; +} AppSpawnFeatureApi; + +typedef struct AppSpawnService { + INHERIT_SERVICE; + INHERIT_IUNKNOWNENTRY(AppSpawnFeatureApi); + Identity identity; +} AppSpawnService; + +static const char* GetName(Service* service) +{ + (void)service; + HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] get service name %{public}s.", APPSPAWN_SERVICE_NAME); + return APPSPAWN_SERVICE_NAME; +} + +static BOOL Initialize(Service* service, Identity identity) +{ + if (service == NULL) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] initialize, service NULL!"); + return FALSE; + } + + AppSpawnService* spawnService = (AppSpawnService*)service; + spawnService->identity = identity; + + HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] initialize, identity<%{public}d, %{public}d, %{public}p>",\ + identity.serviceId, identity.featureId, identity.queueId); + return TRUE; +} + +static BOOL MessageHandle(Service* service, Request* msg) +{ + (void)service; + (void)msg; + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] message handle not support yet!"); + return FALSE; +} + +static TaskConfig GetTaskConfig(Service* service) +{ + (void)service; + TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL, 0x800, 20, SHARED_TASK}; + return config; +} + +static int Invoke(IServerProxy* iProxy, int funcId, void* origin, IpcIo* req, IpcIo* reply) +{ + (void)iProxy; + (void)origin; + if (reply == NULL) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] invoke, reply NULL!"); + return EC_BADPTR; + } + + if (funcId != ID_CALL_CREATE_SERVICE || req == NULL) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] invoke, funcId %{public}d invalid, reply %{public}d.",\ + funcId, INVALID_PID); + IpcIoPushInt64(reply, INVALID_PID); + return EC_BADPTR; + } + + BuffPtr* dataPtr = IpcIoPopDataBuff(req); + if (dataPtr == NULL) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] invoke, get data failed, reply %{public}d.", INVALID_PID); + IpcIoPushInt64(reply, INVALID_PID); + return EC_FAILURE; + } + + MessageSt msgSt = {0}; + int ret = SplitMessage((char*)dataPtr->buff, dataPtr->buffSz, &msgSt); + + // release buffer + if (FreeBuffer(NULL, dataPtr->buff) != LITEIPC_OK) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] invoke, free buffer failed!"); + } + + if (ret != EC_SUCCESS) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] invoke, parse failed! err %{public}d, reply %{public}d.",\ + ret, INVALID_PID); + IpcIoPushInt64(reply, INVALID_PID); + return EC_FAILURE; + } + + HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] msg<%{public}s,%{public}s,%{public}llu,%{public}d,%{public}d>",\ + msgSt.bundleName, msgSt.sharedLibPaths, msgSt.identityID, msgSt.uID, msgSt.gID); + + pid_t newPid = CreateProcess(&msgSt); + FreeMessageSt(&msgSt); + IpcIoPushInt64(reply, newPid); + HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] invoke, reply pid %{public}d.", newPid); + + return ((newPid > 0) ? EC_SUCCESS : EC_FAILURE); +} + +static AppSpawnService g_appSpawnService = { + .GetName = GetName, + .Initialize = Initialize, + .MessageHandle = MessageHandle, + .GetTaskConfig = GetTaskConfig, + SERVER_IPROXY_IMPL_BEGIN, + .Invoke = Invoke, + IPROXY_END, +}; + +void AppSpawnInit(void) +{ + if (SAMGR_GetInstance()->RegisterService((Service *)&g_appSpawnService) != TRUE) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] register service failed!"); + return; + } + + HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] register service succeed. %{public}p.", &g_appSpawnService); + + if (SAMGR_GetInstance()->RegisterDefaultFeatureApi(APPSPAWN_SERVICE_NAME, \ + GET_IUNKNOWN(g_appSpawnService)) != TRUE) { + (void)SAMGR_GetInstance()->UnregisterService(APPSPAWN_SERVICE_NAME); + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] register featureapi failed!"); + return; + } + + HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] register featureapi succeed."); +} + +SYSEX_SERVICE_INIT(AppSpawnInit); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/src/main.c b/src/main.c new file mode 100755 index 0000000000000000000000000000000000000000..c37697e22a83160de6827ceaf1b9097c5355f705 --- /dev/null +++ b/src/main.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020 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 "log.h" +#include "samgr_lite.h" + +void __attribute__((weak)) HOS_SystemInit(void) +{ + SAMGR_Bootstrap(); + HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] HOS_SystemInit is called!"); +} + +static void SignalHandler(int sig) +{ + switch (sig) { + case SIGCHLD: { + pid_t sigPID; + int procStat = 0; + while (1) { + sigPID = waitpid(-1, &procStat, WNOHANG); + if (sigPID <= 0) { + break; + } + } + break; + } + default: + break; + } +} + +void SignalRegist() +{ + struct sigaction act; + act.sa_handler = SignalHandler; + act.sa_flags = SA_RESTART; + if (sigfillset(&act.sa_mask) != 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] sigfillset failed! err %{public}d.", errno); + } + + if (sigaction(SIGCHLD, &act, NULL) != 0) { + HILOG_ERROR(HILOG_MODULE_HIVIEW, "[appspawn] sigaction failed! err %{public}d.", errno); + } +} + +int main(int argc, char * const argv[]) +{ + HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] main, enter."); + + // 1. ipc module init + HOS_SystemInit(); + + // 2. register signal for SIGCHLD + SignalRegist(); + + // 3. keep process alive + HILOG_INFO(HILOG_MODULE_HIVIEW, "[appspawn] main, entering wait."); + while (1) { + // pause only returns when a signal was caught and the signal-catching function returned. + // pause only returns -1, no need to process the return value. + (void)pause(); + } +}