Pārlūkot izejas kodu

Kernel: Store coredump metadata properties as KStrings

This patch also replaces the HashMap previously used to store coredump
properties with a plain AK::Array.
Andreas Kling 4 gadi atpakaļ
vecāks
revīzija
33adc3a42d

+ 3 - 3
Kernel/Arch/x86/common/Interrupts.cpp

@@ -382,14 +382,14 @@ void page_fault_handler(TrapFrame* trap)
         if (current_thread) {
             auto& current_process = current_thread->process();
             if (current_process.is_user_process()) {
-                current_process.set_coredump_metadata("fault_address", String::formatted("{:p}", fault_address));
-                current_process.set_coredump_metadata("fault_type", fault.type() == PageFault::Type::PageNotPresent ? "NotPresent" : "ProtectionViolation");
+                (void)current_process.try_set_coredump_property("fault_address", String::formatted("{:p}", fault_address));
+                (void)current_process.try_set_coredump_property("fault_type", fault.type() == PageFault::Type::PageNotPresent ? "NotPresent" : "ProtectionViolation");
                 String fault_access;
                 if (fault.is_instruction_fetch())
                     fault_access = "Execute";
                 else
                     fault_access = fault.access() == PageFault::Access::Read ? "Read" : "Write";
-                current_process.set_coredump_metadata("fault_access", fault_access);
+                (void)current_process.try_set_coredump_property("fault_access", fault_access);
             }
         }
 

+ 3 - 2
Kernel/CoreDump.cpp

@@ -291,8 +291,9 @@ ByteBuffer CoreDump::create_notes_metadata_data() const
     StringBuilder builder;
     {
         JsonObjectSerializer metadata_obj { builder };
-        for (auto& it : m_process->coredump_metadata())
-            metadata_obj.add(it.key, it.value);
+        m_process->for_each_coredump_property([&](auto& key, auto& value) {
+            metadata_obj.add(key.view(), value.view());
+        });
     }
     builder.append(0);
     metadata_data.append(builder.string_view().characters_without_null_termination(), builder.length());

+ 20 - 3
Kernel/Process.cpp

@@ -875,9 +875,26 @@ void Process::set_dumpable(bool dumpable)
     m_dumpable = dumpable;
 }
 
-void Process::set_coredump_metadata(const String& key, String value)
-{
-    m_coredump_metadata.set(key, move(value));
+KResult Process::set_coredump_property(NonnullOwnPtr<KString> key, NonnullOwnPtr<KString> value)
+{
+    // Write it into the first available property slot.
+    for (auto& slot : m_coredump_properties) {
+        if (slot.key)
+            continue;
+        slot.key = move(key);
+        slot.value = move(value);
+        return KSuccess;
+    }
+    return ENOBUFS;
 }
 
+KResult Process::try_set_coredump_property(StringView key, StringView value)
+{
+    auto key_kstring = KString::try_create(key);
+    auto value_kstring = KString::try_create(value);
+    if (key_kstring && value_kstring)
+        return set_coredump_property(key_kstring.release_nonnull(), value_kstring.release_nonnull());
+    return ENOMEM;
+};
+
 }

+ 19 - 6
Kernel/Process.h

@@ -499,9 +499,17 @@ public:
     void unblock_waiters(Thread::WaitBlocker::UnblockFlags, u8 signal = 0);
     Thread::WaitBlockCondition& wait_block_condition() { return m_wait_block_condition; }
 
-    HashMap<String, String>& coredump_metadata() { return m_coredump_metadata; }
-    const HashMap<String, String>& coredump_metadata() const { return m_coredump_metadata; }
-    void set_coredump_metadata(const String& key, String value);
+    template<typename Callback>
+    void for_each_coredump_property(Callback callback) const
+    {
+        for (auto& property : m_coredump_properties) {
+            if (property.key && property.value)
+                callback(*property.key, *property.value);
+        }
+    }
+
+    KResult set_coredump_property(NonnullOwnPtr<KString> key, NonnullOwnPtr<KString> value);
+    KResult try_set_coredump_property(StringView key, StringView value);
 
     const NonnullRefPtrVector<Thread>& threads_for_coredump(Badge<CoreDump>) const { return m_threads_for_coredump; }
 
@@ -757,7 +765,12 @@ private:
 
     Thread::WaitBlockCondition m_wait_block_condition;
 
-    HashMap<String, String> m_coredump_metadata;
+    struct CoredumpProperty {
+        OwnPtr<KString> key;
+        OwnPtr<KString> value;
+    };
+
+    Array<CoredumpProperty, 4> m_coredump_properties;
 
     NonnullRefPtrVector<Thread> m_threads_for_coredump;
 
@@ -915,8 +928,8 @@ inline ProcessID Thread::pid() const
         if (Process::current()->has_promises()                       \
             && !Process::current()->has_promised(Pledge::promise)) { \
             dbgln("Has not pledged {}", #promise);                   \
-            Process::current()->coredump_metadata().set(             \
-                "pledge_violation", #promise);                       \
+            (void)Process::current()->try_set_coredump_property(     \
+                "pledge_violation"sv, #promise);                     \
             Process::current()->crash(SIGABRT, 0);                   \
             VERIFY_NOT_REACHED();                                    \
         }                                                            \

+ 2 - 1
Kernel/Syscalls/execve.cpp

@@ -577,7 +577,8 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description
     m_unveiled_paths.clear();
     m_unveiled_paths.set_metadata({ "/", UnveilAccess::None, false });
 
-    m_coredump_metadata.clear();
+    for (auto& property : m_coredump_properties)
+        property = {};
 
     auto current_thread = Thread::current();
     current_thread->clear_signals();

+ 9 - 10
Kernel/Syscalls/process.cpp

@@ -61,16 +61,15 @@ KResultOr<FlatPtr> Process::sys$set_coredump_metadata(Userspace<const Syscall::S
         return EINVAL;
     if (params.value.length > 16 * KiB)
         return EINVAL;
-    auto copied_key = copy_string_from_user(params.key.characters, params.key.length);
-    if (copied_key.is_null())
-        return EFAULT;
-    auto copied_value = copy_string_from_user(params.value.characters, params.value.length);
-    if (copied_value.is_null())
-        return EFAULT;
-    if (!m_coredump_metadata.contains(copied_key) && m_coredump_metadata.size() >= 16)
-        return EFAULT;
-    m_coredump_metadata.set(move(copied_key), move(copied_value));
-    return 0;
+    auto key_or_error = try_copy_kstring_from_user(params.key);
+    if (key_or_error.is_error())
+        return key_or_error.error();
+    auto key = key_or_error.release_value();
+    auto value_or_error = try_copy_kstring_from_user(params.value);
+    if (value_or_error.is_error())
+        return value_or_error.error();
+    auto value = value_or_error.release_value();
+    return set_coredump_property(move(key), move(value));
 }
 
 }