From 57297684d4dcb1ad6d81ab59af4e3c097941e046 Mon Sep 17 00:00:00 2001 From: lihehe Date: Tue, 20 Aug 2024 22:02:29 +0800 Subject: [PATCH] add retry and verify result Change-Id: I733149b48db5e8490d552b734caa675d2dc87ab8 Signed-off-by: lihehe --- .../include/code_sign_enable_multi_task.h | 12 +++- .../include/code_sign_helper.h | 2 +- .../code_sign_utils/include/code_sign_utils.h | 1 - .../src/code_sign_enable_multi_task.cpp | 62 ++++++++++++++++++- .../code_sign_utils/src/code_sign_helper.cpp | 11 +--- .../code_sign_utils/src/code_sign_utils.cpp | 42 +++++-------- interfaces/innerkits/common/include/errcode.h | 3 +- 7 files changed, 91 insertions(+), 42 deletions(-) diff --git a/interfaces/innerkits/code_sign_utils/include/code_sign_enable_multi_task.h b/interfaces/innerkits/code_sign_utils/include/code_sign_enable_multi_task.h index 64ef9b0..46f504a 100644 --- a/interfaces/innerkits/code_sign_utils/include/code_sign_enable_multi_task.h +++ b/interfaces/innerkits/code_sign_utils/include/code_sign_enable_multi_task.h @@ -43,15 +43,21 @@ public: 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 ownerId app-identifier of the signature * @param path hap real path on disk * @param func Callback enable function - * @return Timed out or not + * @return err code, see err_code.h */ - bool ExecuteEnableCodeSignTask(int32_t &taskRet, const std::string &ownerId, + int32_t ExecuteEnableCodeSignTask(const std::string &ownerId, const std::string &path, CallbackFunc &func); + /** + * @brief Check whether file is verity enabled by fd + * @param fd file descriptor + * @return err code, see err_code.h + */ + static int32_t IsFsVerityEnabled(int fd); private: + static int32_t IsFsVerityEnabled(const std::string &path); void SortTaskData(); void ExecuteEnableCodeSignTask(uint32_t &index, int32_t &taskRet, const std::string &ownerId, const std::string &path, CallbackFunc &func); diff --git a/interfaces/innerkits/code_sign_utils/include/code_sign_helper.h b/interfaces/innerkits/code_sign_utils/include/code_sign_helper.h index aa4ddeb..9f9dfd7 100644 --- a/interfaces/innerkits/code_sign_utils/include/code_sign_helper.h +++ b/interfaces/innerkits/code_sign_utils/include/code_sign_helper.h @@ -43,7 +43,7 @@ public: int32_t ProcessMultiTask(const std::string &ownerId, const std::string &path, CallbackFunc &func); private: int32_t ProcessOneFile(); - int32_t ExecuteMultiTask(int32_t ret, const std::string &ownerId, const std::string &path, CallbackFunc &func); + int32_t ExecuteMultiTask(const std::string &ownerId, const std::string &path, CallbackFunc &func); void ShowCodeSignInfo(const std::string &path, const struct code_sign_enable_arg &arg); private: CodeSignBlock codeSignBlock_; 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 822aef7..6f06b68 100644 --- a/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h +++ b/interfaces/innerkits/code_sign_utils/include/code_sign_utils.h @@ -123,7 +123,6 @@ public: */ static int32_t IsSupportFsVerity(const std::string &path); private: - static int32_t IsFsVerityEnabled(int fd); static int32_t EnableCodeSignForFile(const std::string &path, const struct code_sign_enable_arg &arg); int32_t ProcessCodeSignBlock(const std::string &ownerId, const std::string &path, FileType type); int32_t HandleCodeSignBlockFailure(const std::string &realPath, int32_t ret); diff --git a/interfaces/innerkits/code_sign_utils/src/code_sign_enable_multi_task.cpp b/interfaces/innerkits/code_sign_utils/src/code_sign_enable_multi_task.cpp index 3e3d7d9..ee12582 100644 --- a/interfaces/innerkits/code_sign_utils/src/code_sign_enable_multi_task.cpp +++ b/interfaces/innerkits/code_sign_utils/src/code_sign_enable_multi_task.cpp @@ -15,11 +15,19 @@ #include "code_sign_enable_multi_task.h" +#include +#include +#include +#include +#include +#include + #include "byte_buffer.h" #include "cs_hisysevent.h" #include "errcode.h" #include "log.h" #include "signer_info.h" +#include "stat_utils.h" namespace OHOS { namespace Security { @@ -29,11 +37,13 @@ constexpr uint32_t DEFAULT_THREADS_NUM = 8; CodeSignEnableMultiTask::CodeSignEnableMultiTask(): enableCodeSignTaskWorker_("EnableCodeSign"), taskCallBack_(0) { + LOG_INFO("Tasks init."); enableCodeSignTaskWorker_.Start(DEFAULT_THREADS_NUM); } CodeSignEnableMultiTask::~CodeSignEnableMultiTask() { + LOG_INFO("Tasks finish."); enableCodeSignTaskWorker_.Stop(); } @@ -42,11 +52,44 @@ void CodeSignEnableMultiTask::AddTaskData(const std::string &targetFile, const s enableData_.push_back(std::pair(targetFile, arg)); } -bool CodeSignEnableMultiTask::ExecuteEnableCodeSignTask(int32_t &taskRet, const std::string &ownerId, +int32_t CodeSignEnableMultiTask::IsFsVerityEnabled(int fd) +{ + unsigned int flags; + int ret = ioctl(fd, FS_IOC_GETFLAGS, &flags); + if (ret < 0) { + LOG_ERROR("Get verity flags by ioctl failed. errno = <%{public}d, %{public}s>", + errno, strerror(errno)); + return CS_ERR_FILE_INVALID; + } + if (flags & FS_VERITY_FL) { + return CS_SUCCESS; + } + return CS_ERR_FSVERITY_NOT_ENABLED; +} + +int32_t CodeSignEnableMultiTask::IsFsVerityEnabled(const std::string &path) +{ + int32_t fd = open(path.c_str(), O_RDONLY); + if (fd < 0) { + LOG_ERROR("Open file failed, path = %{public}s, errno = <%{public}d, %{public}s>", + path.c_str(), errno, strerror(errno)); + return CS_ERR_FILE_OPEN; + } + int32_t ret = IsFsVerityEnabled(fd); + if (ret != CS_SUCCESS) { + LOG_INFO("Fs-verity is not enable for file = %{public}s.", path.c_str()); + } + close(fd); + return ret; +} + +int32_t CodeSignEnableMultiTask::ExecuteEnableCodeSignTask(const std::string &ownerId, const std::string &path, CallbackFunc &func) { SortTaskData(); + LOG_INFO("Tasks num = %{public}zu", enableData_.size()); + int32_t taskRet = CS_SUCCESS; for (uint32_t i = 0; i < enableData_.size(); i++) { LOG_DEBUG("index: %{public}d, name:%{public}s, %{public}lld", i, enableData_[i].first.c_str(), enableData_[i].second.data_size); @@ -56,7 +99,22 @@ bool CodeSignEnableMultiTask::ExecuteEnableCodeSignTask(int32_t &taskRet, const 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; + if (!waitStatus) { + LOG_ERROR("enable code sign timeout, finished tasks = %{public}u", taskCallBack_); + return CS_ERR_ENABLE_TIMEOUT; + } + if (taskRet != CS_SUCCESS) { + return taskRet; + } + int32_t ret = CS_SUCCESS; + for (auto &data : enableData_) { + const std::string &filePath = data.first; + if (IsFsVerityEnabled(filePath) != CS_SUCCESS) { + ret = CS_ERR_FSVERITY_NOT_ENABLED; + ReportEnableError(filePath, ret); + } + } + return ret; } void CodeSignEnableMultiTask::SortTaskData() diff --git a/interfaces/innerkits/code_sign_utils/src/code_sign_helper.cpp b/interfaces/innerkits/code_sign_utils/src/code_sign_helper.cpp index 7b085b6..6b2cce5 100644 --- a/interfaces/innerkits/code_sign_utils/src/code_sign_helper.cpp +++ b/interfaces/innerkits/code_sign_utils/src/code_sign_helper.cpp @@ -41,7 +41,7 @@ int32_t CodeSignHelper::ProcessMultiTask(const std::string &ownerId, const std:: return ret; } } while (ret == CS_SUCCESS); - return ExecuteMultiTask(ret, ownerId, path, func); + return ExecuteMultiTask(ownerId, path, func); } int32_t CodeSignHelper::ProcessOneFile() @@ -64,15 +64,10 @@ int32_t CodeSignHelper::ProcessOneFile() return ret; } -int32_t CodeSignHelper::ExecuteMultiTask(int32_t ret, const std::string &ownerId, +int32_t CodeSignHelper::ExecuteMultiTask(const std::string &ownerId, const std::string &path, CallbackFunc &func) { - bool waitStatus = multiTask_.ExecuteEnableCodeSignTask(ret, ownerId, path, func); - if (!waitStatus) { - LOG_ERROR("enable code sign timeout"); - return CS_ERR_ENABLE_TIMEOUT; - } - return ret; + return multiTask_.ExecuteEnableCodeSignTask(ownerId, path, func); } void CodeSignHelper::ShowCodeSignInfo(const std::string &path, const struct code_sign_enable_arg &arg) 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 dc5eeb9..9a4a331 100644 --- a/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp +++ b/interfaces/innerkits/code_sign_utils/src/code_sign_utils.cpp @@ -122,21 +122,6 @@ int32_t CodeSignUtils::IsSupportFsVerity(const std::string &path) return CS_ERR_FSVREITY_NOT_SUPPORTED; } -int32_t CodeSignUtils::IsFsVerityEnabled(int fd) -{ - unsigned int flags; - int ret = ioctl(fd, FS_IOC_GETFLAGS, &flags); - if (ret < 0) { - LOG_ERROR("Get verity flags by ioctl failed. errno = <%{public}d, %{public}s>", - errno, strerror(errno)); - return CS_ERR_FILE_INVALID; - } - if (flags & FS_VERITY_FL) { - return CS_SUCCESS; - } - return CS_ERR_FSVERITY_NOT_ENABLED; -} - int32_t CodeSignUtils::EnforceCodeSignForFile(const std::string &path, const ByteBuffer &signature) { return EnforceCodeSignForFile(path, signature.GetBuffer(), signature.GetSize()); @@ -154,7 +139,7 @@ int32_t CodeSignUtils::EnableCodeSignForFile(const std::string &path, const stru } do { - ret = IsFsVerityEnabled(fd); + ret = CodeSignEnableMultiTask::IsFsVerityEnabled(fd); if (ret == CS_SUCCESS) { LOG_INFO("Fs-verity has been enabled."); break; @@ -179,7 +164,7 @@ int32_t CodeSignUtils::EnableCodeSignForFile(const std::string &path, const stru ret = CS_SUCCESS; } while (0); close(fd); - LOG_INFO("Enforcing file complete and ret = %{public}d", ret); + LOG_INFO("Enforcing file complete, path = %{public}s, ret = %{public}d", path.c_str(), ret); return ret; } @@ -226,7 +211,15 @@ int32_t CodeSignUtils::EnforceCodeSignForAppWithOwnerId(const std::string &owner } else if (type >= FILE_TYPE_MAX) { return CS_ERR_PARAM_INVALID; } - return ProcessCodeSignBlock(ownerId, path, type); + std::lock_guard lock(storedEntryMapLock_); + int ret = ProcessCodeSignBlock(ownerId, path, type); + if (ret != CS_SUCCESS) { + // retry once to make sure stability + ret = ProcessCodeSignBlock(ownerId, path, type); + } + storedEntryMap_.clear(); + LOG_INFO("Enforcing done, ret = %{public}d", ret); + return ret; } int32_t CodeSignUtils::ProcessCodeSignBlock(const std::string &ownerId, const std::string &path, FileType type) @@ -237,15 +230,12 @@ int32_t CodeSignUtils::ProcessCodeSignBlock(const std::string &ownerId, const st } int32_t ret; CodeSignHelper codeSignHelper; - { - std::lock_guard lock(storedEntryMapLock_); - ret = codeSignHelper.ParseCodeSignBlock(realPath, storedEntryMap_, type); - storedEntryMap_.clear(); - } + ret = codeSignHelper.ParseCodeSignBlock(realPath, storedEntryMap_, type); if (ret != CS_SUCCESS) { return HandleCodeSignBlockFailure(realPath, ret); } - return codeSignHelper.ProcessMultiTask(ownerId, path, EnableCodeSignForFile); + ret = codeSignHelper.ProcessMultiTask(ownerId, path, EnableCodeSignForFile); + return ret; } int32_t CodeSignUtils::HandleCodeSignBlockFailure(const std::string &realPath, int32_t ret) @@ -269,7 +259,7 @@ int32_t CodeSignUtils::EnableKeyInProfile(const std::string &bundleName, const B if (ret == CS_SUCCESS) { return ret; } - LOG_ERROR("Enable key in profile failed. errno = <%{public}d, %{public}s>", errno, strerror(errno)); + LOG_ERROR("Enable key in profile failed. ret = %{public}d", ret); return CS_ERR_PROFILE; } @@ -279,7 +269,7 @@ int32_t CodeSignUtils::RemoveKeyInProfile(const std::string &bundleName) if (ret == CS_SUCCESS) { return ret; } - LOG_ERROR("Remove key in profile failed. errno = <%{public}d, %{public}s>", errno, strerror(errno)); + LOG_ERROR("Remove key in profile failed. ret = %{public}d", ret); return CS_ERR_PROFILE; } diff --git a/interfaces/innerkits/common/include/errcode.h b/interfaces/innerkits/common/include/errcode.h index 4652b4a..541be0e 100644 --- a/interfaces/innerkits/common/include/errcode.h +++ b/interfaces/innerkits/common/include/errcode.h @@ -58,7 +58,8 @@ enum VerifyErrCode { CS_ERR_INVALID_OWNER_ID = -0x303, CS_CODE_SIGN_NOT_EXISTS = -0x304, CS_ERR_PROFILE = -0x305, - CS_ERR_ENABLE_TIMEOUT = -0x306 + CS_ERR_ENABLE_TIMEOUT = -0x306, + CS_ERR_FSVREITY_NOT_ENABLED = -0x307, }; enum IPCErrCode { -- Gitee