diff --git a/backup.gni b/backup.gni index 767cb94c649e8d299bef39f80ae492109ea9e2bf..c5d63676279bec513d5b3188f8f0f38c7a8cfdf9 100644 --- a/backup.gni +++ b/backup.gni @@ -25,6 +25,7 @@ path_file_api = "//foundation/filemanagement/file_api" path_googletest = "//third_party/googletest" path_ipc = "//foundation/communication/ipc" path_jsoncpp = "//third_party/jsoncpp" +path_rust = "//third_party/rust" path_napi = "//foundation/arkui/napi" path_samgr = "//foundation/systemabilitymgr/samgr" path_init = "//base/startup/init" diff --git a/frameworks/native/backup_ext/src/ext_backup_js.cpp b/frameworks/native/backup_ext/src/ext_backup_js.cpp index 5c03fa628fdff69487b680ddfbbac4396d8613d9..5c5eb87711bc356e285d81b3b94ef18519872503 100644 --- a/frameworks/native/backup_ext/src/ext_backup_js.cpp +++ b/frameworks/native/backup_ext/src/ext_backup_js.cpp @@ -33,7 +33,6 @@ namespace OHOS::FileManagement::Backup { using namespace std; -using namespace BExcepUltils; void ExtBackupJs::OnStart(const AAFwk::Want &want) { @@ -62,7 +61,7 @@ void ExtBackupJs::Init(const shared_ptr &record, HILOGI("Init the BackupExtensionAbility(JS)"); try { ExtBackup::Init(record, application, handler, token); - BAssert(abilityInfo_, BError::Codes::EXT_BROKEN_FRAMEWORK, "Invalid abilityInfo_"); + BExcepUltils::BAssert(abilityInfo_, BError::Codes::EXT_BROKEN_FRAMEWORK, "Invalid abilityInfo_"); // 获取应用扩展的 BackupExtensionAbility 的路径 const AppExecFwk::AbilityInfo &info = *abilityInfo_; string bundleName = info.bundleName; @@ -137,7 +136,7 @@ string ExtBackupJs::GetUsrConfig() const { vector config; AppExecFwk::BundleMgrClient client; - BAssert(abilityInfo_, BError::Codes::EXT_BROKEN_FRAMEWORK, "Invalid abilityInfo_"); + BExcepUltils::BAssert(abilityInfo_, BError::Codes::EXT_BROKEN_FRAMEWORK, "Invalid abilityInfo_"); const AppExecFwk::AbilityInfo &info = *abilityInfo_; if (!client.GetProfileFromAbility(info, "ohos.extension.backup", config)) { throw BError(BError::Codes::EXT_INVAL_ARG, "Failed to invoke the GetProfileFromAbility method."); @@ -166,7 +165,7 @@ static BConstants::ExtensionAction VerifyAndGetAction(const AAFwk::Want &want, std::shared_ptr abilityInfo) { string pendingMsg = "Received an empty ability. You must missed the init proc"; - BAssert(abilityInfo, BError::Codes::EXT_INVAL_ARG, pendingMsg); + BExcepUltils::BAssert(abilityInfo, BError::Codes::EXT_INVAL_ARG, pendingMsg); using namespace BConstants; ExtensionAction extAction {want.GetIntParam(EXTENSION_ACTION_PARA, static_cast(ExtensionAction::INVALID))}; if (extAction == ExtensionAction::INVALID) { @@ -182,7 +181,7 @@ sptr ExtBackupJs::OnConnect(const AAFwk::Want &want) { try { HILOGI("begin"); - BAssert(abilityInfo_, BError::Codes::EXT_BROKEN_FRAMEWORK, "Invalid abilityInfo_"); + BExcepUltils::BAssert(abilityInfo_, BError::Codes::EXT_BROKEN_FRAMEWORK, "Invalid abilityInfo_"); // 发起者必须是备份服务 auto extAction = VerifyAndGetAction(want, abilityInfo_); if (extAction_ != BConstants::ExtensionAction::INVALID && extAction == BConstants::ExtensionAction::INVALID && diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index 6cea0bd311034a88726906562bc705ac480ea183..032d0f683c17b315f50280d577c6165a7d055e19 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -31,6 +31,7 @@ #include "accesstoken_kit.h" #include "b_error/b_error.h" +#include "b_error/b_excep_utils.h" #include "b_filesystem/b_dir.h" #include "b_filesystem/b_file.h" #include "b_json/b_json_cached_entity.h" @@ -194,6 +195,7 @@ ErrCode BackupExtExtension::PublishFile(const string &fileName) string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE); string tarName = path + fileName; { + BExcepUltils::VerifyPath(tarName, true); unique_lock lock(lock_); if (find(tars_.begin(), tars_.end(), fileName) != tars_.end() || access(tarName.data(), F_OK) != 0) { return BError(-EPERM); diff --git a/frameworks/native/backup_ext/src/ext_extension_stub.cpp b/frameworks/native/backup_ext/src/ext_extension_stub.cpp index ea15ecb6d9b42dd5d2b79cafc2e25c9015a0e51e..4c41179e7ed2366e53d11a6e310600c2b424ca8e 100644 --- a/frameworks/native/backup_ext/src/ext_extension_stub.cpp +++ b/frameworks/native/backup_ext/src/ext_extension_stub.cpp @@ -24,7 +24,6 @@ namespace OHOS::FileManagement::Backup { using namespace std; -using namespace BExcepUltils; ExtExtensionStub::ExtExtensionStub() { @@ -52,7 +51,8 @@ int32_t ExtExtensionStub::OnRemoteRequest(uint32_t code, return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } - return ExceptionCatcherLocked([&]() { return ErrCode((this->*(interfaceIndex->second))(data, reply)); }); + return BExcepUltils::ExceptionCatcherLocked( + [&]() { return ErrCode((this->*(interfaceIndex->second))(data, reply)); }); } ErrCode ExtExtensionStub::CmdGetFileHandle(MessageParcel &data, MessageParcel &reply) diff --git a/frameworks/native/backup_kit_inner/src/service_proxy.cpp b/frameworks/native/backup_kit_inner/src/service_proxy.cpp index e6b2dc95c7693c2d17fbac698d70e62a00b5dea5..707a5468a6e857190c45a1eedd4d750571162e36 100644 --- a/frameworks/native/backup_kit_inner/src/service_proxy.cpp +++ b/frameworks/native/backup_kit_inner/src/service_proxy.cpp @@ -24,12 +24,11 @@ namespace OHOS::FileManagement::Backup { using namespace std; -using namespace BExcepUltils; ErrCode ServiceProxy::InitRestoreSession(sptr remote) { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); @@ -55,7 +54,7 @@ ErrCode ServiceProxy::InitRestoreSession(sptr remote) ErrCode ServiceProxy::InitBackupSession(sptr remote) { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); @@ -81,7 +80,7 @@ ErrCode ServiceProxy::InitBackupSession(sptr remote) ErrCode ServiceProxy::Start() { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); @@ -100,7 +99,7 @@ ErrCode ServiceProxy::Start() UniqueFd ServiceProxy::GetLocalCapabilities() { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { HILOGE("Failed to write descriptor"); @@ -121,7 +120,7 @@ UniqueFd ServiceProxy::GetLocalCapabilities() ErrCode ServiceProxy::PublishFile(const BFileInfo &fileInfo) { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); @@ -145,7 +144,7 @@ ErrCode ServiceProxy::PublishFile(const BFileInfo &fileInfo) ErrCode ServiceProxy::AppFileReady(const string &fileName, UniqueFd fd) { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); @@ -171,7 +170,7 @@ ErrCode ServiceProxy::AppFileReady(const string &fileName, UniqueFd fd) ErrCode ServiceProxy::AppDone(ErrCode errCode) { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); @@ -194,7 +193,7 @@ ErrCode ServiceProxy::AppDone(ErrCode errCode) ErrCode ServiceProxy::GetFileHandle(const string &bundleName, const string &fileName) { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); @@ -221,7 +220,7 @@ ErrCode ServiceProxy::GetFileHandle(const string &bundleName, const string &file ErrCode ServiceProxy::AppendBundlesRestoreSession(UniqueFd fd, const vector &bundleNames) { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); @@ -247,7 +246,7 @@ ErrCode ServiceProxy::AppendBundlesRestoreSession(UniqueFd fd, const vector &bundleNames) { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); @@ -270,7 +269,7 @@ ErrCode ServiceProxy::AppendBundlesBackupSession(const vector &bundl ErrCode ServiceProxy::Finish() { HILOGI("Begin"); - BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); + BExcepUltils::BAssert(Remote(), BError::Codes::SDK_INVAL_ARG, "Remote is nullptr"); MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { return BError(BError::Codes::SDK_INVAL_ARG, "Failed to write descriptor").GetCode(); diff --git a/services/backup_sa/src/module_ipc/service_stub.cpp b/services/backup_sa/src/module_ipc/service_stub.cpp index 64a5a01e3aa80ca2e9aff1cb518c3d9cddc009b6..5d1ccce4e17c50529bb017845231114c57f8e4ed 100644 --- a/services/backup_sa/src/module_ipc/service_stub.cpp +++ b/services/backup_sa/src/module_ipc/service_stub.cpp @@ -30,7 +30,6 @@ namespace OHOS::FileManagement::Backup { using namespace std; -using namespace BExcepUltils; ServiceStub::ServiceStub() { @@ -62,7 +61,8 @@ int32_t ServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Message return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } - return ExceptionCatcherLocked([&]() { return ErrCode((this->*(interfaceIndex->second))(data, reply)); }); + return BExcepUltils::ExceptionCatcherLocked( + [&]() { return ErrCode((this->*(interfaceIndex->second))(data, reply)); }); } int32_t ServiceStub::CmdInitRestoreSession(MessageParcel &data, MessageParcel &reply) diff --git a/utils/BUILD.gn b/utils/BUILD.gn index 2bc20ad1b47d190e48d7db12ce3ba47c5f1dd620..d31d500c6412c030dc66b39f9e51ea69005035d7 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -32,10 +32,38 @@ config("utils_public_config") { ] } +rust_cxx("backup_cxx_gen") { + sources = [ "rust/src/lib.rs" ] +} + +ohos_rust_static_ffi("backup_cxx_rust") { + sources = [ "rust/src/lib.rs" ] + deps = [ "//third_party/rust/crates/cxx:lib" ] + part_name = "app_file_service" + subsystem_name = "filemanagement" +} + +ohos_static_library("backup_cxx_cppdeps") { + part_name = "app_file_service" + subsystem_name = "filemanagement" + defines = [ "RUST_CXX_NO_EXCEPTIONS" ] + sources = [ + "//third_party/rust/crates/cxx/include/cxx.h", + "//third_party/rust/crates/cxx/src/cxx.cc", + ] + deps = [ "//third_party/rust/crates/cxx:lib" ] + if (is_win) { + defines += [ "CXX_RS_EXPORT=__declspec(dllexport)" ] + } else { + defines += [ "CXX_RS_EXPORT=__attribute__((visibility(\"default\")))" ] + } +} + ohos_shared_library("backup_utils") { sources = [ "src/b_encryption/b_encryption.cpp", "src/b_error/b_error.cpp", + "src/b_error/b_excep_utils.cpp", "src/b_filesystem/b_dir.cpp", "src/b_filesystem/b_file.cpp", "src/b_json/b_json_entity_ext_manage.cpp", @@ -47,6 +75,7 @@ ohos_shared_library("backup_utils") { "src/b_tarball/b_tarball_cmdline.cpp", "src/b_tarball/b_tarball_factory.cpp", ] + sources += get_target_outputs(":backup_cxx_gen") configs = [ ":utils_private_config" ] public_configs = [ ":utils_public_config" ] @@ -62,9 +91,16 @@ ohos_shared_library("backup_utils") { include_dirs = [ "${path_init}/interfaces/innerkits/include/syspara", "${path_backup}/interfaces/inner_api/native/backup_kit_inner/impl", + "${path_rust}/crates/cxx/include", + "${target_gen_dir}/rust/src", ] - deps = [ "${path_init}/interfaces/innerkits:libbegetutil" ] + deps = [ + ":backup_cxx_cppdeps", + ":backup_cxx_gen", + ":backup_cxx_rust", + "${path_init}/interfaces/innerkits:libbegetutil", + ] use_exceptions = true part_name = "app_file_service" diff --git a/utils/include/b_error/b_excep_utils.h b/utils/include/b_error/b_excep_utils.h index 57e1baaa68fcfa7b10b6effd885c1756adccb950..25275d602623c22ded2e8977fde6bc92b0794a0f 100644 --- a/utils/include/b_error/b_excep_utils.h +++ b/utils/include/b_error/b_excep_utils.h @@ -16,52 +16,62 @@ #ifndef OHOS_FILEMGMT_BACKUP_B_EXCEP_UTILES_H #define OHOS_FILEMGMT_BACKUP_B_EXCEP_UTILES_H -#include "b_error/b_error.h" - #include +#include "b_error/b_error.h" #include "filemgmt_libhilog.h" -namespace OHOS::FileManagement::Backup::BExcepUltils { -/** - * @brief 异常捕获 - * - * @param callBack 回调 - * @return ErrCode 错误码 - */ -[[maybe_unused]] static ErrCode ExceptionCatcherLocked(std::function callBack) -{ - try { - return callBack(); - } catch (const BError &e) { - return e.GetCode(); - } catch (const std::exception &e) { - HILOGE("Catched an unexpected low-level exception %{public}s", e.what()); - return EPERM; - } catch (...) { - HILOGE("Unexpected exception"); - return EPERM; +namespace OHOS::FileManagement::Backup { +class BExcepUltils { +public: + /** + * @brief 异常捕获 + * + * @param callBack 回调 + * @return ErrCode 错误码 + */ + static ErrCode ExceptionCatcherLocked(std::function callBack) + { + try { + return callBack(); + } catch (const BError &e) { + return e.GetCode(); + } catch (const std::exception &e) { + HILOGE("Catched an unexpected low-level exception %{public}s", e.what()); + return EPERM; + } catch (...) { + HILOGE("Unexpected exception"); + return EPERM; + } } -} -/** - * @brief 检查 AbilityInfo 是否有效 - * - * @param AbilityInfo - * @param code 错误码 - * @param msg 错误信息 - * @return 无 - */ -template -[[maybe_unused]] static void BAssert(const T &t, const BError::Codes &code, const std::string_view msg = "") -{ - if (!t) { - if (msg.empty()) { - throw BError(code); - } else { - throw BError(code, msg); + /** + * @brief 检查 AbilityInfo 是否有效 + * + * @param AbilityInfo + * @param code 错误码 + * @param msg 错误信息 + * @return 无 + */ + template + static void BAssert(const T &t, const BError::Codes &code, const std::string_view msg = "") + { + if (!t) { + if (msg.empty()) { + throw BError(code); + } else { + throw BError(code, msg); + } } } -} -} // namespace OHOS::FileManagement::Backup::BExcepUltils + + /** + * @brief 校验路径 + * + * @param path + * @param isExtension + */ + static void VerifyPath(const std::string_view &path, bool isExtension = false); +}; +} // namespace OHOS::FileManagement::Backup #endif // OHOS_FILEMGMT_BACKUP_B_EXCEP_UTILES_H \ No newline at end of file diff --git a/utils/rust/src/lib.rs b/utils/rust/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..2f2f697f4e55aff1de5121ba356ce09829812673 --- /dev/null +++ b/utils/rust/src/lib.rs @@ -0,0 +1,38 @@ +/* + * 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. + */ + +//! Rust utils for cxx +#[cxx::bridge] +mod ffi{ + #![allow(dead_code)] + extern "Rust"{ + fn canonicalize(path: String) -> Result; + } +} + +use std::fs; +use std::io::{Error, ErrorKind}; + +fn canonicalize(path: String) -> Result { + match fs::canonicalize(path) { + Ok(abs_path) => { + match abs_path.to_str() { + Some(path) => Ok(path.to_string()), + None => Err(Error::new(ErrorKind::Other, "canonicalize failed")), + } + }, + Err(_) => Err(Error::new(ErrorKind::Other, "canonicalize failed")), + } +} \ No newline at end of file diff --git a/utils/src/b_error/b_excep_utils.cpp b/utils/src/b_error/b_excep_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..09b5bef369b68bc5aa9258c9df8dffd87e6f8b19 --- /dev/null +++ b/utils/src/b_error/b_excep_utils.cpp @@ -0,0 +1,41 @@ +/* + * 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 "b_error/b_excep_utils.h" + +#include + +#include "b_resources/b_constants.h" +#include "cxx.h" +#include "lib.rs.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +void BExcepUltils::VerifyPath(const string_view &path, bool isExtension) +{ + try { + auto ret = canonicalize(path.data()); + string absPath = ret.c_str(); + if (isExtension && + absPath.find(string(BConstants::PATH_BUNDLE_BACKUP_HOME) + .append(BConstants::SA_BUNDLE_BACKUP_RESTORE)) != 0) { + throw BError(BError::Codes::EXT_INVAL_ARG, "Invalid path, not in backup restore path"); + } + } catch (const rust::Error &e) { + throw BError(BError::Codes::EXT_INVAL_ARG, "Invalid path"); + } +} +} // namespace OHOS::FileManagement::Backup