From 72231b405ac9f92922d933d2c73098881488fbcd Mon Sep 17 00:00:00 2001 From: Liav A Date: Wed, 23 Aug 2023 21:10:02 +0300 Subject: [PATCH] AK+Kernel: Introduce StdLib function to copy FixedStringBuffer to user This new Kernel StdLib function will be used to copy contents of a FixedStringBuffer with a null character to a user process. The first user of this new function is the prctl option of PR_GET_PROCESS_NAME which would copy a process name including a null character to a user provided buffer. --- AK/FixedStringBuffer.h | 7 ++++++- Kernel/Library/StdLib.h | 11 +++++++++++ Kernel/Syscalls/prctl.cpp | 6 ++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/AK/FixedStringBuffer.h b/AK/FixedStringBuffer.h index ec34f0e4df..20e03a6d31 100644 --- a/AK/FixedStringBuffer.h +++ b/AK/FixedStringBuffer.h @@ -95,8 +95,13 @@ public: return m_storage.span(); } StringView representable_view() const { return StringView(m_storage.data(), m_stored_length); } + Span span_view_ensuring_ending_null_char() + { + VERIFY(m_stored_length + 1 <= Size); + m_storage[m_stored_length] = '\0'; + return Span(m_storage.data(), m_stored_length + 1); + } - size_t fixed_length() const { return Size; } size_t stored_length() const { return m_stored_length; } FixedStringBuffer() diff --git a/Kernel/Library/StdLib.h b/Kernel/Library/StdLib.h index c1aa94ff9f..9887400068 100644 --- a/Kernel/Library/StdLib.h +++ b/Kernel/Library/StdLib.h @@ -201,3 +201,14 @@ inline ErrorOr copy_typed_from_user(Userspace user_data) TRY(copy_from_user(&data, user_data)); return data; } + +template +ErrorOr copy_fixed_string_buffer_including_null_char_to_user(Userspace dest, size_t buffer_size, FixedStringBuffer const& buffer) +{ + FixedStringBuffer name_with_null_char {}; + name_with_null_char.store_characters(buffer.representable_view()); + if (name_with_null_char.stored_length() + 1 > buffer_size) + return ENAMETOOLONG; + auto name_with_null_char_view = name_with_null_char.span_view_ensuring_ending_null_char(); + return copy_to_user(dest, name_with_null_char_view.data(), name_with_null_char_view.size()); +} diff --git a/Kernel/Syscalls/prctl.cpp b/Kernel/Syscalls/prctl.cpp index 8de0d7d72c..bbcb902b1e 100644 --- a/Kernel/Syscalls/prctl.cpp +++ b/Kernel/Syscalls/prctl.cpp @@ -66,10 +66,8 @@ ErrorOr Process::sys$prctl(int option, FlatPtr arg1, FlatPtr arg2) Userspace buffer = arg1; size_t buffer_size = static_cast(arg2); TRY(m_name.with([&buffer, buffer_size](auto& name) -> ErrorOr { - auto view = name.representable_view(); - if (view.length() + 1 > buffer_size) - return ENAMETOOLONG; - return copy_to_user(buffer, view.characters_without_null_termination(), view.length() + 1); + VERIFY(!name.representable_view().is_null()); + return copy_fixed_string_buffer_including_null_char_to_user(buffer, buffer_size, name); })); return 0; }