From 648efaa701a7ecc2c795ff2c0dd40c23737a4096 Mon Sep 17 00:00:00 2001 From: yang1946 Date: Thu, 23 Nov 2023 20:18:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=AD=BE=E5=90=8D=E6=80=A7?= =?UTF-8?q?=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yang1946 --- interfaces/innerkits/code_sign_utils/BUILD.gn | 1 + .../include/code_sign_multi_task.h | 65 ++++++++++++++ .../code_sign_utils/include/code_sign_utils.h | 3 +- .../src/code_sign_multi_task.cpp | 89 +++++++++++++++++++ .../code_sign_utils/src/code_sign_utils.cpp | 39 +++++--- interfaces/innerkits/common/include/errcode.h | 3 +- 6 files changed, 184 insertions(+), 16 deletions(-) create mode 100644 interfaces/innerkits/code_sign_utils/include/code_sign_multi_task.h create mode 100644 interfaces/innerkits/code_sign_utils/src/code_sign_multi_task.cpp diff --git a/interfaces/innerkits/code_sign_utils/BUILD.gn b/interfaces/innerkits/code_sign_utils/BUILD.gn index 88817b0..674445f 100644 --- a/interfaces/innerkits/code_sign_utils/BUILD.gn +++ b/interfaces/innerkits/code_sign_utils/BUILD.gn @@ -22,6 +22,7 @@ ohos_shared_library("libcode_sign_utils") { sources = [ "${code_signature_root_dir}/utils/src/code_sign_block.cpp", "${code_signature_root_dir}/utils/src/file_helper.cpp", + "src/code_sign_multi_task.cpp", "src/code_sign_utils.cpp", "src/stat_utils.cpp", ] diff --git a/interfaces/innerkits/code_sign_utils/include/code_sign_multi_task.h b/interfaces/innerkits/code_sign_utils/include/code_sign_multi_task.h new file mode 100644 index 0000000..da17fd6 --- /dev/null +++ b/interfaces/innerkits/code_sign_utils/include/code_sign_multi_task.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 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 CODE_SIGN_MULTI_TASK_H +#define CODE_SIGN_MULTI_TASK_H + +#include +#include +#include +#include +#include +#include +#include + +#include "thread_pool.h" + +namespace OHOS { +namespace Security { +namespace CodeSign { +typedef int32_t CallbackFunc(const std::string &path, const struct code_sign_enable_arg &arg); + +class CodeSignMultiTask { +public: + CodeSignMultiTask(); + ~CodeSignMultiTask(); + /** + * @brief Add task data for code signing + * @param targetFile hap or so real path on disk + * @param code_sign_enable_arg arg + */ + void AddTaskData(const std::string &targetFile, const struct code_sign_enable_arg &arg); + /** + * @brief Execute code signature addition task + * @param taskRet Returned execution results + * @param func Callback enable function + * @return Timed out or not + */ + bool ExecuteEnableCodeSignTask(int32_t &taskRet, CallbackFunc &func); +private: + void SortTaskData(); + void ExecuteEnableCodeSignTask(int32_t &index, int32_t &taskRet, CallbackFunc &func); +private: + std::mutex cvLock_; + std::condition_variable taskfinish_; + std::vector> enableData_; + OHOS::ThreadPool enableCodeSignTaskWorker_; + int taskCallBack_; +}; +} +} +} + +#endif \ No newline at end of file diff --git a/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h b/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h index 627d173..359b413 100644 --- a/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h +++ b/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h @@ -64,7 +64,7 @@ public: * @param type signature file type * @return err code, see err_code.h */ - static int32_t EnforceCodeSignForAppWithOwnerId(std::string ownerId, const std::string &path, + static int32_t EnforceCodeSignForAppWithOwnerId(const std::string &ownerId, const std::string &path, const EntryMap &entryPathMap, FileType type); /** @@ -108,6 +108,7 @@ private: static int32_t IsFsVerityEnabled(int fd); static int32_t EnableCodeSignForFile(const std::string &path, const struct code_sign_enable_arg &arg); static void ShowCodeSignInfo(const std::string &path, const struct code_sign_enable_arg &arg); + static int32_t PathToRealPath(const std::string &path, std::string &realPath, FileType type); static int32_t CheckOwnerId(const std::string &path, const std::string &ownerId, const uint8_t *sigPtr, uint32_t sigSize); }; diff --git a/interfaces/innerkits/code_sign_utils/src/code_sign_multi_task.cpp b/interfaces/innerkits/code_sign_utils/src/code_sign_multi_task.cpp new file mode 100644 index 0000000..325ca38 --- /dev/null +++ b/interfaces/innerkits/code_sign_utils/src/code_sign_multi_task.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 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 "code_sign_multi_task.h" + +#include "errcode.h" +#include "log.h" + +namespace OHOS { +namespace Security { +namespace CodeSign { +constexpr uint32_t CODE_SIGN_TASK_TIMEOUT_MS = 300000; +constexpr uint32_t DEFAULT_THREADS_NUM = 8; + +CodeSignMultiTask::CodeSignMultiTask(): enableCodeSignTaskWorker_("EnableCodeSign"), taskCallBack_(0) +{ +} + +CodeSignMultiTask::~CodeSignMultiTask() +{ + enableCodeSignTaskWorker_.Stop(); +} + +void CodeSignMultiTask::AddTaskData(const std::string &targetFile, const struct code_sign_enable_arg &arg) +{ + enableData_.push_back(std::pair(targetFile, arg)); +} + +bool CodeSignMultiTask::ExecuteEnableCodeSignTask(int32_t &taskRet, CallbackFunc &func) +{ + SortTaskData(); + for (int32_t i = 0; i < enableData_.size(); i++) { + LOG_DEBUG(LABEL, "index: %{public}d, name:%{public}s, %{public}lld", + i, enableData_[i].first.c_str(), enableData_[i].second.data_size); + ExecuteEnableCodeSignTask(i, taskRet, func); + } + enableCodeSignTaskWorker_.Start(DEFAULT_THREADS_NUM); + + std::unique_lock lock(cvLock_); + auto waitStatus = taskfinish_.wait_for(lock, std::chrono::milliseconds(CODE_SIGN_TASK_TIMEOUT_MS), + [this]() { return this->enableData_.size() == this->taskCallBack_; }); + return waitStatus; +} + +void CodeSignMultiTask::SortTaskData() +{ + auto compareFileDataSize = [](const std::pair &a, + const std::pair &b) { + return a.second.data_size > b.second.data_size; + }; + sort(enableData_.begin(), enableData_.end(), compareFileDataSize); +} + +void CodeSignMultiTask::ExecuteEnableCodeSignTask(int32_t &index, int32_t &taskRet, CallbackFunc &func) +{ + auto enableCodeSignTask = [this, &index, &func, &taskRet]() { + LOG_DEBUG(LABEL, "ExecuteEnableCodeSignTask task called"); + if (taskRet != CS_SUCCESS) { + std::unique_lock lock(cvLock_); + this->taskCallBack_++; + return; + } + + int32_t enableRet = func(this->enableData_[index].first, this->enableData_[index].second); + + std::unique_lock lock(cvLock_); + taskRet = taskRet | enableRet; + this->taskCallBack_++; + if (this->taskCallBack_ == this->enableData_.size()) { + this->taskfinish_.notify_one(); + } + }; + enableCodeSignTaskWorker_.AddTask(enableCodeSignTask); +} +} +} +} \ No newline at end of file diff --git a/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp b/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp index ff847ce..2e4d0a2 100644 --- a/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp +++ b/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp @@ -31,6 +31,7 @@ #include "cs_hisysevent.h" #include "cs_hitrace.h" #include "constants.h" +#include "code_sign_multi_task.h" #include "directory_ex.h" #include "extractor.h" #include "file_helper.h" @@ -250,21 +251,11 @@ int32_t CodeSignUtils::CheckOwnerId(const std::string &path, const std::string & return ret; } -int32_t CodeSignUtils::EnforceCodeSignForAppWithOwnerId(std::string ownerId, const std::string &path, +int32_t CodeSignUtils::EnforceCodeSignForAppWithOwnerId(const std::string &ownerId, const std::string &path, const EntryMap &entryPathMap, FileType type) { - int32_t ret; std::string realPath; - - if (!OHOS::PathToRealPath(path, realPath)) { - return CS_ERR_FILE_PATH; - } - - if (type >= FILE_TYPE_MAX) { - return CS_ERR_PARAM_INVALID; - } - - ret = IsSupportFsVerity(realPath); + int32_t ret = PathToRealPath(path, realPath, type); if (ret != CS_SUCCESS) { return ret; } @@ -277,6 +268,8 @@ int32_t CodeSignUtils::EnforceCodeSignForAppWithOwnerId(std::string ownerId, con } return ret; } + + CodeSignMultiTask multiTask; do { std::string targetFile; struct code_sign_enable_arg arg = {0}; @@ -290,15 +283,20 @@ int32_t CodeSignUtils::EnforceCodeSignForAppWithOwnerId(std::string ownerId, con ret = CheckOwnerId(path, ownerId, reinterpret_cast(arg.sig_ptr), arg.sig_size); if (ret != CS_SUCCESS) { - break; + return ret; } ShowCodeSignInfo(targetFile, arg); if (!CheckFilePathValid(targetFile, Constants::ENABLE_APP_BASE_PATH)) { return CS_ERR_TARGET_FILE_PATH; } - ret = EnableCodeSignForFile(targetFile, arg); + multiTask.AddTaskData(targetFile, arg); } while (ret == CS_SUCCESS); + bool waitStatus = multiTask.ExecuteEnableCodeSignTask(ret, EnableCodeSignForFile); + if (!waitStatus) { + LOG_ERROR(LABEL, "enable code sign timeout"); + return CS_ERR_TIMEOUT; + } return ret; } @@ -307,6 +305,19 @@ int32_t CodeSignUtils::EnforceCodeSignForApp(const std::string &path, const Entr return EnforceCodeSignForAppWithOwnerId("", path, entryPathMap, type); } +int32_t CodeSignUtils::PathToRealPath(const std::string &path, std::string &realPath, FileType type) +{ + if (!OHOS::PathToRealPath(path, realPath)) { + return CS_ERR_FILE_PATH; + } + + if (type >= FILE_TYPE_MAX) { + return CS_ERR_PARAM_INVALID; + } + + return IsSupportFsVerity(realPath); +} + int32_t CodeSignUtils::EnableKeyInProfile(const std::string &bundleName, const ByteBuffer &profileBuffer) { int ret = EnableKeyInProfileByRust(bundleName.c_str(), profileBuffer.GetBuffer(), profileBuffer.GetSize()); diff --git a/interfaces/innerkits/common/include/errcode.h b/interfaces/innerkits/common/include/errcode.h index 290090b..5725bf1 100644 --- a/interfaces/innerkits/common/include/errcode.h +++ b/interfaces/innerkits/common/include/errcode.h @@ -24,7 +24,8 @@ enum CommonErrCode { CS_ERR_MEMORY = -0x1, CS_ERR_NO_PERMISSION = -0x2, CS_ERR_NO_SIGNATURE = -0x3, - CS_ERR_INVALID_SIGNATURE = -0x4 + CS_ERR_INVALID_SIGNATURE = -0x4, + CS_ERR_TIMEOUT = -0x5 }; enum FileOperationErrCode { -- Gitee