From 1bc950d224c42506c9ef339cf997a402bd65c8ce Mon Sep 17 00:00:00 2001 From: hwyml Date: Wed, 3 Jul 2024 16:14:14 +0800 Subject: [PATCH] =?UTF-8?q?usb=5Fhost=E5=86=85=E5=AD=98=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hwyml Change-Id: Ic80b6b1e39aeee11e0df62df7be0f60dd1342d43 --- usb/ddk_service/BUILD.gn | 25 +++++++- usb/ddk_service/include/usb_ddk_permission.h | 3 +- .../src/usb_ddk_dynamic_library_wrapper.cpp | 29 +++++++++ usb/ddk_service/src/usb_ddk_permission.cpp | 52 ++++++++++++++-- usb/ddk_service/src/usb_ddk_service.cpp | 1 + usb/hdi_service/BUILD.gn | 1 - usb/hdi_service/src/usbd_function.cpp | 60 ++++++++++++++++++- 7 files changed, 160 insertions(+), 11 deletions(-) create mode 100644 usb/ddk_service/src/usb_ddk_dynamic_library_wrapper.cpp diff --git a/usb/ddk_service/BUILD.gn b/usb/ddk_service/BUILD.gn index e430ffbe52..466c0a655a 100644 --- a/usb/ddk_service/BUILD.gn +++ b/usb/ddk_service/BUILD.gn @@ -56,7 +56,6 @@ ohos_shared_library("libusb_ddk_service_1.0") { if (is_standard_system) { external_deps = [ - "access_token:libaccesstoken_sdk", "drivers_interface_usb:usb_ddk_idl_headers", "hdf_core:libhdf_host", "hdf_core:libhdf_ipc_adapter", @@ -80,6 +79,29 @@ ohos_shared_library("libusb_ddk_service_1.0") { part_name = "drivers_peripheral_usb" } +ohos_shared_library("usb_ddk_dynamic_library_wrapper") { + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + branch_protector_ret = "pac_ret" + + sources = [ "src/usb_ddk_dynamic_library_wrapper.cpp" ] + + external_deps = [ "access_token:libaccesstoken_sdk" ] + if (usb_c_utils_enable) { + external_deps += [ "c_utils:utils" ] + } + + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_usb" +} + ohos_shared_library("libusb_ddk_driver") { sanitize = { integer_overflow = true @@ -121,5 +143,6 @@ group("usb_ddk_target") { deps = [ ":libusb_ddk_driver", ":libusb_ddk_service_1.0", + ":usb_ddk_dynamic_library_wrapper", ] } diff --git a/usb/ddk_service/include/usb_ddk_permission.h b/usb/ddk_service/include/usb_ddk_permission.h index 8d4a95dad6..c047e4d798 100644 --- a/usb/ddk_service/include/usb_ddk_permission.h +++ b/usb/ddk_service/include/usb_ddk_permission.h @@ -25,7 +25,8 @@ namespace Ddk { namespace V1_0 { class DdkPermissionManager { public: - static bool VerifyPermission(std::string permissionName); + static bool VerifyPermission(const std::string &permissionName); + static void Reset(); }; } // namespace V1_0 } // namespace Ddk diff --git a/usb/ddk_service/src/usb_ddk_dynamic_library_wrapper.cpp b/usb/ddk_service/src/usb_ddk_dynamic_library_wrapper.cpp new file mode 100644 index 0000000000..6e3bd8ad1e --- /dev/null +++ b/usb/ddk_service/src/usb_ddk_dynamic_library_wrapper.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 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 "accesstoken_kit.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int VerifyAccessToken(uint32_t callerToken, const std::string &permissionName) +{ + return OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName); +} + +#ifdef __cplusplus +} +#endif /* __cplusplus */ \ No newline at end of file diff --git a/usb/ddk_service/src/usb_ddk_permission.cpp b/usb/ddk_service/src/usb_ddk_permission.cpp index c7a60bd2cf..d187fb159e 100644 --- a/usb/ddk_service/src/usb_ddk_permission.cpp +++ b/usb/ddk_service/src/usb_ddk_permission.cpp @@ -15,8 +15,8 @@ #include "usb_ddk_permission.h" #include +#include -#include "accesstoken_kit.h" #include "ipc_skeleton.h" namespace OHOS { @@ -24,12 +24,54 @@ namespace HDI { namespace Usb { namespace Ddk { namespace V1_0 { -using namespace OHOS::Security::AccessToken; +using VerifyAccessTokenFunc = int(*)(uint32_t callerToken, const std::string &permissionName); -bool DdkPermissionManager::VerifyPermission(std::string permissionName) +static constexpr int PERMISSION_GRANTED = 0; + +static void *g_libHandle = nullptr; +static VerifyAccessTokenFunc g_verifyAccessToken = nullptr; + +static void InitVerifyAccessToken() +{ + if (g_verifyAccessToken != nullptr) { + return; + } + + g_libHandle = dlopen("libusb_ddk_dynamic_library_wrapper.z.so", RTLD_LAZY); + if (g_libHandle == nullptr) { + HDF_LOGE("%{public}s dlopen failed: %{public}s", __func__, dlerror()); + return; + } + + void *funcPtr = dlsym(g_libHandle, "VerifyAccessToken"); + if (funcPtr == nullptr) { + HDF_LOGE("%{public}s dlsym failed: %{public}s", __func__, dlerror()); + dlclose(g_libHandle); + g_libHandle = nullptr; + return; + } + + g_verifyAccessToken = reinterpret_cast(funcPtr); +} + +void DdkPermissionManager::Reset() +{ + g_verifyAccessToken = nullptr; + if (g_libHandle != nullptr) { + dlclose(g_libHandle); + g_libHandle = nullptr; + } +} + +bool DdkPermissionManager::VerifyPermission(const std::string &permissionName) { - AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID(); - int result = AccessTokenKit::VerifyAccessToken(callerToken, permissionName); + InitVerifyAccessToken(); + if (g_verifyAccessToken == nullptr) { + return false; + } + + uint32_t callerToken = IPCSkeleton::GetCallingTokenID(); + int result = g_verifyAccessToken(callerToken, permissionName); HDF_LOGI("%{public}s VerifyAccessToken: %{public}d", __func__, result); return result == PERMISSION_GRANTED; } diff --git a/usb/ddk_service/src/usb_ddk_service.cpp b/usb/ddk_service/src/usb_ddk_service.cpp index ec0c99e3cc..7468b96669 100644 --- a/usb/ddk_service/src/usb_ddk_service.cpp +++ b/usb/ddk_service/src/usb_ddk_service.cpp @@ -132,6 +132,7 @@ int32_t UsbDdkService::Release() return HDF_ERR_NOPERM; } + DdkPermissionManager::Reset(); return UsbExitHostSdk(nullptr); } diff --git a/usb/hdi_service/BUILD.gn b/usb/hdi_service/BUILD.gn index 13876decb2..dfeb80b7eb 100644 --- a/usb/hdi_service/BUILD.gn +++ b/usb/hdi_service/BUILD.gn @@ -66,7 +66,6 @@ ohos_shared_library("libusb_interface_service_1.1") { if (is_standard_system) { external_deps = [ - "drivers_interface_usb:libusbfn_mtp_stub_1.0", "drivers_interface_usb:usb_idl_headers_1.1", "drivers_interface_usb:usbfn_mtp_idl_headers", "hdf_core:libhdf_host", diff --git a/usb/hdi_service/src/usbd_function.cpp b/usb/hdi_service/src/usbd_function.cpp index 623a44bdd1..f9a7a5ddda 100644 --- a/usb/hdi_service/src/usbd_function.cpp +++ b/usb/hdi_service/src/usbd_function.cpp @@ -15,6 +15,7 @@ #include "usbd_function.h" +#include #include #include "devmgr_hdi.h" @@ -42,13 +43,64 @@ uint32_t UsbdFunction::currentFuncs_ = USB_FUNCTION_HDC; using OHOS::HDI::DeviceManager::V1_0::IDeviceManager; using OHOS::HDI::ServiceManager::V1_0::IServiceManager; using OHOS::HDI::Usb::Gadget::Mtp::V1_0::IUsbfnMtpInterface; -using OHOS::HDI::Usb::Gadget::Mtp::V1_0::UsbfnMtpImpl; +using GetMtpImplFunc = void*(*)(); + constexpr uint32_t UDC_NAME_MAX_LEN = 32; constexpr int32_t WAIT_UDC_MAX_LOOP = 30; constexpr uint32_t WAIT_UDC_TIME = 100000; /* mtp and ptp use same driver and same service */ static std::string MTP_PTP_SERVICE_NAME {"usbfn_mtp_interface_service"}; #define UDC_PATH "/config/usb_gadget/g1/UDC" + +static void *g_libHandle = nullptr; +static GetMtpImplFunc g_getMtpImpl = nullptr; + +static void InitGetMtpImpl() +{ + if (g_getMtpImpl != nullptr) { + return; + } + + g_libHandle = dlopen("libusbfn_mtp_interface_service_1.0.z.so", RTLD_LAZY); + if (g_libHandle == nullptr) { + HDF_LOGE("%{public}s dlopen failed: %{public}s", __func__, dlerror()); + return; + } + + void *funcPtr = dlsym(g_libHandle, "UsbfnMtpInterfaceImplGetInstance"); + if (funcPtr == nullptr) { + HDF_LOGE("%{public}s dlsym failed: %{public}s", __func__, dlerror()); + dlclose(g_libHandle); + g_libHandle = nullptr; + return; + } + + g_getMtpImpl = reinterpret_cast(funcPtr); +} + +static void ReleaseGetMtpImpl() +{ + g_getMtpImpl = nullptr; + if (g_libHandle != nullptr) { + dlclose(g_libHandle); + g_libHandle = nullptr; + } +} + +static IUsbfnMtpInterface *GetUsbfnMtpImpl() +{ + InitGetMtpImpl(); + if (g_getMtpImpl == nullptr) { + return nullptr; + } + + void *instance = g_getMtpImpl(); + if (instance != nullptr) { + return reinterpret_cast(instance); + } + return nullptr; +} + int32_t UsbdFunction::SendCmdToService(const char *name, int32_t cmd, unsigned char funcMask) { auto servMgr = IServiceManager::Get(); @@ -92,7 +144,7 @@ int32_t UsbdFunction::InitMtp() HDF_LOGE("%{public}s: register mtp device failed: %{public}d", __func__, ret); return ret; } - auto serviceImpl = UsbfnMtpImpl::Get(true); + auto serviceImpl = GetUsbfnMtpImpl(); if (serviceImpl == nullptr) { HDF_LOGE("%{public}s: failed to get of implement service", __func__); return HDF_FAILURE; @@ -108,7 +160,7 @@ int32_t UsbdFunction::InitMtp() int32_t UsbdFunction::ReleaseMtp() { - auto serviceImpl = UsbfnMtpImpl::Get(true); + auto serviceImpl = GetUsbfnMtpImpl(); if (serviceImpl == nullptr) { HDF_LOGE("%{public}s: failed to get of implement service", __func__); return HDF_FAILURE; @@ -117,6 +169,8 @@ int32_t UsbdFunction::ReleaseMtp() if (ret != HDF_SUCCESS) { HDF_LOGE("%{public}s: release mtp device failed: %{public}d", __func__, ret); } + ReleaseGetMtpImpl(); + UsbdUnregisterDevice(MTP_PTP_SERVICE_NAME); HDF_LOGI("%{public}s: release Mtp done", __func__); return ret; -- Gitee