diff --git a/Base/usr/share/man/man7/sys.md b/Base/usr/share/man/man7/sys.md index c16d361734..18e6ac95b5 100644 --- a/Base/usr/share/man/man7/sys.md +++ b/Base/usr/share/man/man7/sys.md @@ -41,19 +41,16 @@ and other kernel-related data to userspace. #### `kernel` directory entries * **`processes`** - This node exports a list of all processes that currently exist. -* **`cmdline`** - This node exports the kernel boot commandline that was passed from the bootloader. * **`cpuinfo`** - This node exports information on the CPU. * **`df`** - This node exports information on mounted filesystems and basic statistics on them. * **`dmesg`** - This node exports information from the kernel log. * **`interrupts`** - This node exports information on all IRQ handlers and basic statistics on them. -* **`load_base`** - This node reveals the loading address of the kernel. * **`keymap`** - This node exports information on the currently used keymap. * **`memstat`** - This node exports statistics on memory allocation in the kernel. * **`profile`** - This node exports statistics on profiling data. * **`stats`** - This node exports statistics on scheduler timing data. -* **`system_mode`** - This node exports the chosen system mode as it was decided based on the kernel commandline or a default value. * **`uptime`** - This node exports the uptime data. * **`jails`** - This node exports information about existing jails (only if the current process is not in jail). * **`power_state`** - This node only responds to write requests on it. A written value of `1` results @@ -76,6 +73,16 @@ This subdirectory includes global settings of the kernel. * **`ubsan_is_deadly`** - This node controls the deadliness of the kernel undefined behavior sanitizer errors. +#### `constants` directory + +This subdirectory includes global constants of the kernel. +Those nodes are generated during the boot sequence and are completely static, +therefore making them very fast to read (no kmalloc or locking is needed). + +* **`load_base`** - This node reveals the loading address of the kernel. +* **`system_mode`** - This node exports the chosen system mode as it was decided based on the kernel commandline or a default value. +* **`cmdline`** - This node exports the kernel boot commandline that was passed from the bootloader. + ### Consistency and stability of data across multiple read operations When opening a data node, the kernel generates the required data so it's prepared diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 5a0c8d896a..3fc97ac722 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -170,7 +170,6 @@ set(KERNEL_SOURCES FileSystem/SysFS/Subsystems/Firmware/BIOS/Component.cpp FileSystem/SysFS/Subsystems/Firmware/BIOS/Directory.cpp FileSystem/SysFS/Subsystems/Firmware/Directory.cpp - FileSystem/SysFS/Subsystems/Kernel/CommandLine.cpp FileSystem/SysFS/Subsystems/Kernel/Interrupts.cpp FileSystem/SysFS/Subsystems/Kernel/Processes.cpp FileSystem/SysFS/Subsystems/Kernel/CPUInfo.cpp @@ -178,8 +177,6 @@ set(KERNEL_SOURCES FileSystem/SysFS/Subsystems/Kernel/Keymap.cpp FileSystem/SysFS/Subsystems/Kernel/Profile.cpp FileSystem/SysFS/Subsystems/Kernel/Directory.cpp - FileSystem/SysFS/Subsystems/Kernel/LoadBase.cpp - FileSystem/SysFS/Subsystems/Kernel/SystemMode.cpp FileSystem/SysFS/Subsystems/Kernel/DiskUsage.cpp FileSystem/SysFS/Subsystems/Kernel/Log.cpp FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.cpp @@ -194,6 +191,8 @@ set(KERNEL_SOURCES FileSystem/SysFS/Subsystems/Kernel/Network/Route.cpp FileSystem/SysFS/Subsystems/Kernel/Network/TCP.cpp FileSystem/SysFS/Subsystems/Kernel/Network/UDP.cpp + FileSystem/SysFS/Subsystems/Kernel/Constants/ConstantInformation.cpp + FileSystem/SysFS/Subsystems/Kernel/Constants/Directory.cpp FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.cpp FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.cpp FileSystem/SysFS/Subsystems/Kernel/Variables/CoredumpDirectory.cpp diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.cpp deleted file mode 100644 index 8d77808fc3..0000000000 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2022, Liav A. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include - -namespace Kernel { - -UNMAP_AFTER_INIT NonnullLockRefPtr SysFSCommandLine::must_create(SysFSDirectory const& parent_directory) -{ - return adopt_lock_ref_if_nonnull(new (nothrow) SysFSCommandLine(parent_directory)).release_nonnull(); -} - -UNMAP_AFTER_INIT SysFSCommandLine::SysFSCommandLine(SysFSDirectory const& parent_directory) - : SysFSGlobalInformation(parent_directory) -{ -} - -ErrorOr SysFSCommandLine::try_generate(KBufferBuilder& builder) -{ - TRY(builder.append(kernel_command_line().string())); - TRY(builder.append('\n')); - return {}; -} - -} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.h deleted file mode 100644 index 24e8873b61..0000000000 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2022, Liav A. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include -#include -#include - -namespace Kernel { - -class SysFSCommandLine final : public SysFSGlobalInformation { -public: - virtual StringView name() const override { return "cmdline"sv; } - - static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); - -private: - SysFSCommandLine(SysFSDirectory const& parent_directory); - virtual ErrorOr try_generate(KBufferBuilder& builder) override; -}; - -} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/ConstantInformation.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/ConstantInformation.cpp new file mode 100644 index 0000000000..35b86f2796 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/ConstantInformation.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +StringView SysFSSystemConstantInformation::name() const +{ + switch (m_node_name) { + case NodeName::LoadBase: + return "load_base"sv; + case NodeName::CommandLine: + return "cmdline"sv; + case NodeName::SystemMode: + return "system_mode"sv; + default: + VERIFY_NOT_REACHED(); + } +} + +NonnullLockRefPtr SysFSSystemConstantInformation::must_create(SysFSDirectory const& parent_directory, NonnullOwnPtr constant_data_buffer, mode_t mode, ReadableByJailedProcesses readable_by_jailed_processes, NodeName name) +{ + auto node = adopt_lock_ref_if_nonnull(new (nothrow) SysFSSystemConstantInformation(parent_directory, move(constant_data_buffer), mode, readable_by_jailed_processes, name)).release_nonnull(); + return node; +} + +ErrorOr SysFSSystemConstantInformation::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription*) const +{ + if (offset < 0) + return EINVAL; + if (static_cast(offset) >= m_constant_data_buffer->size()) + return 0; + TRY(Process::current().jail().with([&](auto const& my_jail) -> ErrorOr { + if (my_jail && m_readable_by_jailed_processes == ReadableByJailedProcesses::No) + return Error::from_errno(EPERM); + return {}; + })); + ssize_t nread = min(static_cast(m_constant_data_buffer->size() - offset), static_cast(count)); + TRY(buffer.write(m_constant_data_buffer->data() + offset, nread)); + return nread; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/ConstantInformation.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/ConstantInformation.h new file mode 100644 index 0000000000..7e26b88ba6 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/ConstantInformation.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSSystemConstantInformation final : public SysFSComponent { +public: + enum class NodeName { + LoadBase, + CommandLine, + SystemMode, + }; + + enum class ReadableByJailedProcesses { + Yes, + No, + }; + + virtual StringView name() const override; + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory, NonnullOwnPtr constant_data_buffer, mode_t mode, ReadableByJailedProcesses readable_by_jailed_processes, NodeName name); + + virtual ErrorOr read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const override; + +private: + SysFSSystemConstantInformation(SysFSDirectory const& parent_directory, NonnullOwnPtr constant_data_buffer, mode_t mode, ReadableByJailedProcesses readable_by_jailed_processes, NodeName name) + : SysFSComponent(parent_directory) + , m_constant_data_buffer(move(constant_data_buffer)) + , m_permissions(mode) + , m_readable_by_jailed_processes(readable_by_jailed_processes) + , m_node_name(name) + { + } + + virtual size_t size() const override { return m_constant_data_buffer->size(); } + virtual mode_t permissions() const override { return m_permissions; } + + NonnullOwnPtr m_constant_data_buffer; + mode_t const m_permissions { 0644 }; + ReadableByJailedProcesses const m_readable_by_jailed_processes { ReadableByJailedProcesses::No }; + NodeName const m_node_name { NodeName::LoadBase }; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/Directory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/Directory.cpp new file mode 100644 index 0000000000..865d14401e --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/Directory.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSGlobalKernelConstantsDirectory::must_create(SysFSDirectory const& parent_directory) +{ + auto global_constants_directory = adopt_lock_ref_if_nonnull(new (nothrow) SysFSGlobalKernelConstantsDirectory(parent_directory)).release_nonnull(); + MUST(global_constants_directory->m_child_components.with([&](auto& list) -> ErrorOr { + { + auto builder = TRY(KBufferBuilder::try_create()); + MUST(builder.appendff("{}", kernel_load_base)); + auto load_base_buffer = builder.build(); + VERIFY(load_base_buffer); + list.append(SysFSSystemConstantInformation::must_create(*global_constants_directory, load_base_buffer.release_nonnull(), S_IRUSR, SysFSSystemConstantInformation::ReadableByJailedProcesses::No, SysFSSystemConstantInformation::NodeName::LoadBase)); + } + + { + auto builder = TRY(KBufferBuilder::try_create()); + MUST(builder.append(kernel_command_line().string())); + MUST(builder.append('\n')); + auto command_line_buffer = builder.build(); + VERIFY(command_line_buffer); + list.append(SysFSSystemConstantInformation::must_create(*global_constants_directory, command_line_buffer.release_nonnull(), S_IRUSR | S_IRGRP | S_IROTH, SysFSSystemConstantInformation::ReadableByJailedProcesses::No, SysFSSystemConstantInformation::NodeName::CommandLine)); + } + + { + auto builder = TRY(KBufferBuilder::try_create()); + MUST(builder.append(kernel_command_line().system_mode())); + MUST(builder.append('\n')); + auto system_mode_buffer = builder.build(); + VERIFY(system_mode_buffer); + list.append(SysFSSystemConstantInformation::must_create(*global_constants_directory, system_mode_buffer.release_nonnull(), S_IRUSR | S_IRGRP | S_IROTH, SysFSSystemConstantInformation::ReadableByJailedProcesses::No, SysFSSystemConstantInformation::NodeName::SystemMode)); + } + return {}; + })); + return global_constants_directory; +} + +UNMAP_AFTER_INIT SysFSGlobalKernelConstantsDirectory::SysFSGlobalKernelConstantsDirectory(SysFSDirectory const& parent_directory) + : SysFSDirectory(parent_directory) +{ +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/Directory.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/Directory.h new file mode 100644 index 0000000000..1a27949744 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Constants/Directory.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Kernel { + +class SysFSGlobalKernelConstantsDirectory : public SysFSDirectory { +public: + static NonnullLockRefPtr must_create(SysFSDirectory const&); + virtual StringView name() const override { return "constants"sv; } + +private: + explicit SysFSGlobalKernelConstantsDirectory(SysFSDirectory const&); +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp index 469f7d3fb5..187fba5ef5 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp @@ -8,21 +8,19 @@ #include #include #include -#include +#include #include #include #include #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include @@ -32,7 +30,9 @@ namespace Kernel { UNMAP_AFTER_INIT NonnullLockRefPtr SysFSGlobalKernelStatsDirectory::must_create(SysFSRootDirectory const& root_directory) { auto global_kernel_stats_directory = adopt_lock_ref_if_nonnull(new (nothrow) SysFSGlobalKernelStatsDirectory(root_directory)).release_nonnull(); + auto global_constants_directory = SysFSGlobalKernelConstantsDirectory::must_create(*global_kernel_stats_directory); MUST(global_kernel_stats_directory->m_child_components.with([&](auto& list) -> ErrorOr { + list.append(global_constants_directory); list.append(SysFSDiskUsage::must_create(*global_kernel_stats_directory)); list.append(SysFSMemoryStatus::must_create(*global_kernel_stats_directory)); list.append(SysFSSystemStatistics::must_create(*global_kernel_stats_directory)); @@ -42,10 +42,7 @@ UNMAP_AFTER_INIT NonnullLockRefPtr SysFSGlobalK list.append(SysFSInterrupts::must_create(*global_kernel_stats_directory)); list.append(SysFSKeymap::must_create(*global_kernel_stats_directory)); list.append(SysFSUptime::must_create(*global_kernel_stats_directory)); - list.append(SysFSCommandLine::must_create(*global_kernel_stats_directory)); - list.append(SysFSSystemMode::must_create(*global_kernel_stats_directory)); list.append(SysFSProfile::must_create(*global_kernel_stats_directory)); - list.append(SysFSKernelLoadBase::must_create(*global_kernel_stats_directory)); list.append(SysFSPowerStateSwitchNode::must_create(*global_kernel_stats_directory)); list.append(SysFSJails::must_create(*global_kernel_stats_directory)); diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.cpp deleted file mode 100644 index d5e519ecd5..0000000000 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2022, Liav A. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include - -namespace Kernel { - -UNMAP_AFTER_INIT SysFSKernelLoadBase::SysFSKernelLoadBase(SysFSDirectory const& parent_directory) - : SysFSGlobalInformation(parent_directory) -{ -} - -UNMAP_AFTER_INIT NonnullLockRefPtr SysFSKernelLoadBase::must_create(SysFSDirectory const& parent_directory) -{ - return adopt_lock_ref_if_nonnull(new (nothrow) SysFSKernelLoadBase(parent_directory)).release_nonnull(); -} - -ErrorOr SysFSKernelLoadBase::try_generate(KBufferBuilder& builder) -{ - auto current_process_credentials = Process::current().credentials(); - if (!current_process_credentials->is_superuser()) - return EPERM; - return builder.appendff("{}", kernel_load_base); -} - -mode_t SysFSKernelLoadBase::permissions() const -{ - // Note: The kernel load address should not be exposed to non-root users - // as it will help defeat KASLR. - return S_IRUSR; -} - -} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.h deleted file mode 100644 index 4a0e92fd8f..0000000000 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2022, Liav A. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include -#include -#include - -namespace Kernel { - -class SysFSKernelLoadBase final : public SysFSGlobalInformation { -public: - virtual StringView name() const override { return "load_base"sv; } - - static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); - -private: - explicit SysFSKernelLoadBase(SysFSDirectory const& parent_directory); - - virtual mode_t permissions() const override; - - virtual ErrorOr try_generate(KBufferBuilder& builder) override; -}; - -} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.cpp deleted file mode 100644 index 36a4716fa3..0000000000 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2022, Liav A. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include - -namespace Kernel { - -UNMAP_AFTER_INIT SysFSSystemMode::SysFSSystemMode(SysFSDirectory const& parent_directory) - : SysFSGlobalInformation(parent_directory) -{ -} - -UNMAP_AFTER_INIT NonnullLockRefPtr SysFSSystemMode::must_create(SysFSDirectory const& parent_directory) -{ - return adopt_lock_ref_if_nonnull(new (nothrow) SysFSSystemMode(parent_directory)).release_nonnull(); -} - -ErrorOr SysFSSystemMode::try_generate(KBufferBuilder& builder) -{ - TRY(builder.append(kernel_command_line().system_mode())); - TRY(builder.append('\n')); - return {}; -} - -} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.h deleted file mode 100644 index e137000cab..0000000000 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2022, Liav A. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include -#include -#include - -namespace Kernel { - -class SysFSSystemMode final : public SysFSGlobalInformation { -public: - virtual StringView name() const override { return "system_mode"sv; } - - static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); - -private: - explicit SysFSSystemMode(SysFSDirectory const& parent_directory); - virtual ErrorOr try_generate(KBufferBuilder& builder) override; -}; - -} diff --git a/Userland/Libraries/LibSymbolication/Symbolication.cpp b/Userland/Libraries/LibSymbolication/Symbolication.cpp index 911be1fc41..485a99782e 100644 --- a/Userland/Libraries/LibSymbolication/Symbolication.cpp +++ b/Userland/Libraries/LibSymbolication/Symbolication.cpp @@ -37,7 +37,7 @@ static KernelBaseState s_kernel_base_state = KernelBaseState::Uninitialized; Optional kernel_base() { if (s_kernel_base_state == KernelBaseState::Uninitialized) { - auto file = Core::DeprecatedFile::open("/sys/kernel/load_base", Core::OpenMode::ReadOnly); + auto file = Core::DeprecatedFile::open("/sys/kernel/constants/load_base", Core::OpenMode::ReadOnly); if (file.is_error()) { s_kernel_base_state = KernelBaseState::Invalid; return {}; diff --git a/Userland/Services/SystemServer/main.cpp b/Userland/Services/SystemServer/main.cpp index 98700269d9..748c199ba9 100644 --- a/Userland/Services/SystemServer/main.cpp +++ b/Userland/Services/SystemServer/main.cpp @@ -72,7 +72,7 @@ static ErrorOr determine_system_mode() g_system_mode = "text"; }); - auto f = Core::DeprecatedFile::construct("/sys/kernel/system_mode"); + auto f = Core::DeprecatedFile::construct("/sys/kernel/constants/system_mode"); if (!f->open(Core::OpenMode::ReadOnly)) { dbgln("Failed to read system_mode: {}", f->error_string()); // Continue and assume "text" mode.