From 97878dee345cfbc20002f37634c35906a6fa91b3 Mon Sep 17 00:00:00 2001 From: Vitaliy Urusovskij Date: Tue, 22 Nov 2022 12:44:56 +0400 Subject: [PATCH] Load plugin libraries safely (#14034) For security purposes load plugin libraries only by absolute path to prevent search from environment variables, working directory etc. --- src/common/util/CMakeLists.txt | 3 +++ .../include/openvino/util/shared_object.hpp | 18 ++++++++++++++++++ .../src/os/lin/lin_shared_object_loader.cpp | 12 ++++++++++++ .../src/os/win/win_shared_object_loader.cpp | 17 +++++++++++++++++ src/inference/src/ie_core.cpp | 2 +- 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/common/util/CMakeLists.txt b/src/common/util/CMakeLists.txt index 9cad18ce17a27a..0a683d583e139b 100644 --- a/src/common/util/CMakeLists.txt +++ b/src/common/util/CMakeLists.txt @@ -33,6 +33,9 @@ add_library(${TARGET_NAME} STATIC ${LIBRARY_SRC} ${PUBLIC_HEADERS}) add_library(openvino::util ALIAS ${TARGET_NAME}) target_link_libraries(${TARGET_NAME} PRIVATE ${CMAKE_DL_LIBS}) +if (WIN32) + target_link_libraries(${TARGET_NAME} PRIVATE Shlwapi) +endif() target_include_directories(${TARGET_NAME} PUBLIC $) diff --git a/src/common/util/include/openvino/util/shared_object.hpp b/src/common/util/include/openvino/util/shared_object.hpp index 3f2b307782b922..f6732ff444b91e 100644 --- a/src/common/util/include/openvino/util/shared_object.hpp +++ b/src/common/util/include/openvino/util/shared_object.hpp @@ -23,6 +23,15 @@ namespace util { */ std::shared_ptr load_shared_object(const char* path); +/** + * @brief Loads a library with absolute path specified. + * Prevents library search in working directory, environment + * variables etc. + * @param path Full path to the plugin library + * @return Reference to shared object + */ +std::shared_ptr load_shared_object_safely(const char* path); + #ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT /** * @brief Loads a library with the wide char name specified. @@ -30,6 +39,15 @@ std::shared_ptr load_shared_object(const char* path); * @return Reference to shared object */ std::shared_ptr load_shared_object(const wchar_t* path); + +/** + * @brief Loads a library with wide char absolute path specified. + * Prevents library search in working directory, environment + * variables etc. + * @param path Full path to the plugin library + * @return Reference to shared object + */ +std::shared_ptr load_shared_object_safely(const wchar_t* path); #endif // OPENVINO_ENABLE_UNICODE_PATH_SUPPORT /** * @brief Searches for a function symbol in the loaded module diff --git a/src/common/util/src/os/lin/lin_shared_object_loader.cpp b/src/common/util/src/os/lin/lin_shared_object_loader.cpp index 80f64d36e38937..b7622466f4e56e 100644 --- a/src/common/util/src/os/lin/lin_shared_object_loader.cpp +++ b/src/common/util/src/os/lin/lin_shared_object_loader.cpp @@ -12,6 +12,14 @@ namespace ov { namespace util { +std::shared_ptr load_shared_object_safely(const char* path) { + if (path == nullptr) + throw std::runtime_error("Cannot load library: path isn't specified."); + if (path[0] == '/') + return load_shared_object(path); + throw std::runtime_error("Cannot load library: path '" + static_cast(path) + "' is not absolute."); +} + std::shared_ptr load_shared_object(const char* path) { auto shared_object = std::shared_ptr{dlopen(path, RTLD_NOW), [](void* shared_object) { if (shared_object != nullptr) { @@ -36,6 +44,10 @@ std::shared_ptr load_shared_object(const char* path) { } #ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT +std::shared_ptr load_shared_object_safely(const wchar_t* path) { + return load_shared_object_safely(ov::util::wstring_to_string(path).c_str()); +} + std::shared_ptr load_shared_object(const wchar_t* path) { return load_shared_object(ov::util::wstring_to_string(path).c_str()); } diff --git a/src/common/util/src/os/win/win_shared_object_loader.cpp b/src/common/util/src/os/win/win_shared_object_loader.cpp index 76da4eed9b687a..16dcaa342fe39f 100644 --- a/src/common/util/src/os/win/win_shared_object_loader.cpp +++ b/src/common/util/src/os/win/win_shared_object_loader.cpp @@ -70,9 +70,18 @@ #endif #include +#include namespace ov { namespace util { +std::shared_ptr load_shared_object_safely(const char* path) { + if (path == nullptr) + throw std::runtime_error("Cannot load library: path isn't specified."); + if (!PathIsRelativeA(path)) + return load_shared_object(path); + throw std::runtime_error("Cannot load library: path '" + static_cast(path) + "' is not absolute."); +} + std::shared_ptr load_shared_object(const char* path) { void* shared_object = nullptr; using GetDllDirectoryA_Fnc = DWORD (*)(DWORD, LPSTR); @@ -124,6 +133,14 @@ std::shared_ptr load_shared_object(const char* path) { } #ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT +std::shared_ptr load_shared_object_safely(const wchar_t* path) { + if (path == nullptr) + throw std::runtime_error("Cannot load library: path isn't specified."); + if (!PathIsRelativeW(path)) + return load_shared_object(path); + throw std::runtime_error("Cannot load library: path '" + ov::util::wstring_to_string(std::wstring(path)) + "' is not absolute."); +} + std::shared_ptr load_shared_object(const wchar_t* path) { void* shared_object = nullptr; using GetDllDirectoryW_Fnc = DWORD (*)(DWORD, LPWSTR); diff --git a/src/inference/src/ie_core.cpp b/src/inference/src/ie_core.cpp index 76fd36349ea1be..e5f68f6567b643 100644 --- a/src/inference/src/ie_core.cpp +++ b/src/inference/src/ie_core.cpp @@ -1161,7 +1161,7 @@ class CoreImpl : public ie::ICore, public std::enable_shared_from_this plugin_impl; reinterpret_cast( ov::util::get_symbol(so, InferenceEngine::create_plugin_function))(plugin_impl);