llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Minsoo Choo (mchoo7) <details> <summary>Changes</summary> Implement `ProcessFreeBSDKernelCore::DoWriteMemory()` to write data on kernel dump or `/dev/mem`. Due to security concerns (e.g. writing wrong value on `/dev/mem` can trigger kernel panic), this feature is only enabled when `plugin.process.freebsd-kernel-core.read-only` is set to false (true by default). --- Full diff: https://github.com/llvm/llvm-project/pull/183553.diff 5 Files Affected: - (modified) lldb/source/Plugins/Process/FreeBSD-Kernel-Core/CMakeLists.txt (+12) - (modified) lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp (+69-2) - (modified) lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.h (+6) - (added) lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCoreProperties.td (+8) - (modified) llvm/docs/ReleaseNotes.md (+2) ``````````diff diff --git a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/CMakeLists.txt b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/CMakeLists.txt index 8aafee3e43314..399baf432dcf8 100644 --- a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/CMakeLists.txt +++ b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/CMakeLists.txt @@ -1,3 +1,11 @@ +lldb_tablegen(ProcessFreeBSDKernelCoreProperties.inc -gen-lldb-property-defs + SOURCE ProcessFreeBSDKernelCoreProperties.td + TARGET LLDBPluginProcessFreeBSDKernelCorePropertiesGen) + +lldb_tablegen(ProcessFreeBSDKernelCorePropertiesEnum.inc -gen-lldb-property-enum-defs + SOURCE ProcessFreeBSDKernelCoreProperties.td + TARGET LLDBPluginProcessFreeBSDKernelCorePropertiesEnumGen) + add_lldb_library(lldbPluginProcessFreeBSDKernelCore PLUGIN ProcessFreeBSDKernelCore.cpp RegisterContextFreeBSDKernelCore_arm64.cpp @@ -12,3 +20,7 @@ add_lldb_library(lldbPluginProcessFreeBSDKernelCore PLUGIN lldbTarget kvm ) + +add_dependencies(lldbPluginProcessFreeBSDKernelCore + LLDBPluginProcessFreeBSDKernelCorePropertiesGen + LLDBPluginProcessFreeBSDKernelCorePropertiesEnumGen) diff --git a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp index ebbf89669cc40..577d8e0d50cf1 100644 --- a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp +++ b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.cpp @@ -6,7 +6,6 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -25,6 +24,42 @@ using namespace lldb_private; LLDB_PLUGIN_DEFINE(ProcessFreeBSDKernelCore) +namespace { + +#define LLDB_PROPERTIES_processfreebsdkernelcore +#include "ProcessFreeBSDKernelCoreProperties.inc" + +enum { +#define LLDB_PROPERTIES_processfreebsdkernelcore +#include "ProcessFreeBSDKernelCorePropertiesEnum.inc" +}; + +class PluginProperties : public Properties { +public: + static llvm::StringRef GetSettingName() { + return ProcessFreeBSDKernelCore::GetPluginNameStatic(); + } + + PluginProperties() : Properties() { + m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName()); + m_collection_sp->Initialize(g_processfreebsdkernelcore_properties_def); + } + + ~PluginProperties() override = default; + + bool GetReadOnly() const { + const uint32_t idx = ePropertyReadOnly; + return GetPropertyAtIndexAs<bool>(idx, true); + } +}; + +} // namespace + +static PluginProperties &GetGlobalPluginProperties() { + static PluginProperties g_settings; + return g_settings; +} + ProcessFreeBSDKernelCore::ProcessFreeBSDKernelCore(lldb::TargetSP target_sp, ListenerSP listener_sp, kvm_t *kvm, @@ -56,10 +91,22 @@ void ProcessFreeBSDKernelCore::Initialize() { llvm::call_once(g_once_flag, []() { PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), CreateInstance); + GetPluginDescriptionStatic(), CreateInstance, + DebuggerInitialize); }); } +void ProcessFreeBSDKernelCore::DebuggerInitialize(Debugger &debugger) { + if (!PluginManager::GetSettingForProcessPlugin( + debugger, PluginProperties::GetSettingName())) { + const bool is_global_setting = true; + PluginManager::CreateSettingForProcessPlugin( + debugger, GetGlobalPluginProperties().GetValueProperties(), + "Properties for the freebsd-kernel process plug-in.", + is_global_setting); + } +} + void ProcessFreeBSDKernelCore::Terminate() { PluginManager::UnregisterPlugin(ProcessFreeBSDKernelCore::CreateInstance); } @@ -90,6 +137,26 @@ void ProcessFreeBSDKernelCore::RefreshStateAfterStop() { } } +size_t ProcessFreeBSDKernelCore::DoWriteMemory(lldb::addr_t addr, + const void *buf, size_t size, + Status &error) { + if (GetGlobalPluginProperties().GetReadOnly()) { + error = Status::FromErrorString( + "Memory writes are currently disabled. You can enable them with " + "`settings set plugin.process.freebsd-kernel-core.read-only false`."); + return 0; + } + + ssize_t rd = 0; + rd = kvm_write(m_kvm, addr, buf, size); + if (rd < 0 || static_cast<size_t>(rd) != size) { + error = Status::FromErrorStringWithFormat("Writing memory failed: %s", + GetError()); + return rd > 0 ? rd : 0; + } + return rd; +} + bool ProcessFreeBSDKernelCore::DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) { if (old_thread_list.GetSize(false) == 0) { diff --git a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.h b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.h index c677c236ddc21..67cfae13d2a4d 100644 --- a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.h +++ b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCore.h @@ -9,6 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNELCORE_H #define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNELCORE_H +#include "lldb/Core/Debugger.h" #include "lldb/Target/PostMortemProcess.h" #include <kvm.h> @@ -27,6 +28,8 @@ class ProcessFreeBSDKernelCore : public lldb_private::PostMortemProcess { static void Initialize(); + static void DebuggerInitialize(lldb_private::Debugger &debugger); + static void Terminate(); static llvm::StringRef GetPluginNameStatic() { return "freebsd-kernel-core"; } @@ -48,6 +51,9 @@ class ProcessFreeBSDKernelCore : public lldb_private::PostMortemProcess { void RefreshStateAfterStop() override; + size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, + lldb_private::Status &error) override; + protected: bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override; diff --git a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCoreProperties.td b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCoreProperties.td new file mode 100644 index 0000000000000..22bf3c8bfefca --- /dev/null +++ b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ProcessFreeBSDKernelCoreProperties.td @@ -0,0 +1,8 @@ +include "../../../../include/lldb/Core/PropertiesBase.td" + +let Definition = "processfreebsdkernelcore", Path = "plugin.process.freebsd-kernel-core" in { + def ReadOnly: Property<"read-only", "Boolean">, + Global, + DefaultTrue, + Desc<"Disable memory writes to the core. This is enabled by default for safety reasons.">; +} diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index d9fb4ddc36c9d..e69605b9d9cce 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -220,6 +220,8 @@ Changes to LLDB * Threads are listed in incrmental order by pid then by tid. * Unread kernel messages saved in msgbufp are now printed when lldb starts. This information is printed only when lldb is in the interactive mode (i.e. not in batch mode). +* Writing to core is now supported. For safety reasons, this feature is off by default. To enable it, + `plugin.process.freebsd-kernel-core.read-only` must be set to `false`. ### Linux `````````` </details> https://github.com/llvm/llvm-project/pull/183553 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
