================ @@ -0,0 +1,99 @@ +//===-- PythonPathSetup.cpp -----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/PythonPathSetup/PythonPathSetup.h" + +#ifdef _WIN32 +#include "lldb/Host/windows/windows.h" +#include "llvm/Support/Windows/WindowsSupport.h" + +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/WithColor.h" + +using namespace llvm; + +#ifdef LLDB_PYTHON_DLL_RELATIVE_PATH +/// Returns the full path to the lldb.exe executable. +inline std::wstring GetPathToExecutableW() { + // Iterate until we reach the Windows API maximum path length (32,767). + std::vector<WCHAR> buffer; + buffer.resize(MAX_PATH /*=260*/); + while (buffer.size() < 32767) { + if (GetModuleFileNameW(NULL, buffer.data(), buffer.size()) < buffer.size()) + return std::wstring(buffer.begin(), buffer.end()); + buffer.resize(buffer.size() * 2); + } + return L""; +} + +/// \brief Resolve the full path of the directory defined by +/// LLDB_PYTHON_DLL_RELATIVE_PATH. If it exists, add it to the list of DLL +/// search directories. +/// \return `true` if the library was added to the search path. +/// `false` otherwise. +bool AddPythonDLLToSearchPath() { + std::wstring modulePath = GetPathToExecutableW(); + if (modulePath.empty()) + return false; + + SmallVector<char, MAX_PATH> utf8Path; + if (sys::windows::UTF16ToUTF8(modulePath.c_str(), modulePath.length(), + utf8Path)) + return false; + sys::path::remove_filename(utf8Path); + sys::path::append(utf8Path, LLDB_PYTHON_DLL_RELATIVE_PATH); + sys::fs::make_absolute(utf8Path); + + SmallVector<wchar_t, 1> widePath; + if (sys::windows::widenPath(utf8Path.data(), widePath)) + return false; + + if (sys::fs::exists(utf8Path)) + return SetDllDirectoryW(widePath.data()); + return false; +} +#endif + +#ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME +/// Returns true if `python3x.dll` can be loaded. +static bool IsPythonDLLInPath() { +#define WIDEN2(x) L##x +#define WIDEN(x) WIDEN2(x) + HMODULE h = LoadLibraryW(WIDEN(LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME)); + if (!h) + return false; + FreeLibrary(h); + return true; +#undef WIDEN2 +#undef WIDEN +} +#endif + +#endif // _WIN32 + +void SetupPythonRuntimeLibrary() { +#ifdef _WIN32 +#ifdef LLDB_PYTHON_RUNTIME_LIBRARY_FILENAME + if (IsPythonDLLInPath()) + return; +#ifdef LLDB_PYTHON_DLL_RELATIVE_PATH + if (AddPythonDLLToSearchPath() && IsPythonDLLInPath()) ---------------- charles-zablit wrote:
If we don't find the library, lldb will most likely crash unless the user has a matching version of Python available in their PATH (matching as lldb was built with Python3.10 and the user has Python3.10 installed). > I just wondered if there's some strange hijack you could do here. Then again, > if LLDB_PYTHON_DLL_RELATIVE_PATH is set by the builder of lldb, you've > already decided to trust that lldb build. These parameters are meant for distributing python3xx.dll alongside lldb. A malicious actor could swap out the python.dll that is shipped with the toolchain for a malicious one, but they could also do the same for `liblldb.dll`. https://github.com/llvm/llvm-project/pull/179306 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
