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

Reply via email to