From 93e172895adcb31fad5b41cc8c998139c2b87534 Mon Sep 17 00:00:00 2001 From: Liav A Date: Sat, 9 Sep 2023 15:48:07 +0300 Subject: [PATCH] Kernel: Add /sys/kernel/request_panic node to simulate a kernel panic When writing to /sys/kernel/request_panic it will do a kernel panic. Trying to truncate the node will result in kernel panic with a slightly different message. --- Base/usr/share/man/man7/sys.md | 1 + Kernel/CMakeLists.txt | 1 + .../SysFS/Subsystems/Kernel/Directory.cpp | 2 + .../SysFS/Subsystems/Kernel/RequestPanic.cpp | 48 +++++++++++++++++++ .../SysFS/Subsystems/Kernel/RequestPanic.h | 38 +++++++++++++++ Meta/gn/secondary/Kernel/BUILD.gn | 1 + 6 files changed, 91 insertions(+) create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/RequestPanic.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/RequestPanic.h diff --git a/Base/usr/share/man/man7/sys.md b/Base/usr/share/man/man7/sys.md index 467ac20202..a202597e91 100644 --- a/Base/usr/share/man/man7/sys.md +++ b/Base/usr/share/man/man7/sys.md @@ -58,6 +58,7 @@ in system reboot. A written value of `2` results in system shutdown. * **`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. +* **`request_panic`** - This node allows userspace to trigger (an artificial) kernel panic by writing/truncating it. #### `net` directory diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 677081aea0..d479d338da 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -203,6 +203,7 @@ set(KERNEL_SOURCES FileSystem/SysFS/Subsystems/Kernel/Directory.cpp FileSystem/SysFS/Subsystems/Kernel/DiskUsage.cpp FileSystem/SysFS/Subsystems/Kernel/Log.cpp + FileSystem/SysFS/Subsystems/Kernel/RequestPanic.cpp FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.cpp FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.cpp FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.cpp diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp index 1fd17aac15..192bcb1991 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,7 @@ UNMAP_AFTER_INIT NonnullRefPtr SysFSGlobalKerne list.append(SysFSProfile::must_create(*global_kernel_stats_directory)); list.append(SysFSPowerStateSwitchNode::must_create(*global_kernel_stats_directory)); list.append(SysFSJails::must_create(*global_kernel_stats_directory)); + list.append(SysFSSystemRequestPanic::must_create(*global_kernel_stats_directory)); list.append(SysFSGlobalNetworkStatsDirectory::must_create(*global_kernel_stats_directory)); list.append(SysFSKernelConfigurationDirectory::must_create(*global_kernel_stats_directory)); diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/RequestPanic.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/RequestPanic.cpp new file mode 100644 index 0000000000..efc12a9e56 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/RequestPanic.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT NonnullRefPtr SysFSSystemRequestPanic::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_ref_if_nonnull(new (nothrow) SysFSSystemRequestPanic(parent_directory)).release_nonnull(); +} + +static ErrorOr check_current_process_not_jailed() +{ + return Process::current().jail().with([&](auto const& my_jail) -> ErrorOr { + if (my_jail) + return Error::from_errno(EPERM); + return {}; + }); +} + +ErrorOr SysFSSystemRequestPanic::read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const +{ + TRY(check_current_process_not_jailed()); + return Error::from_errno(ENOTSUP); +} + +ErrorOr SysFSSystemRequestPanic::write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) +{ + TRY(check_current_process_not_jailed()); + PANIC("SysFSSystemRequestPanic::write_bytes"); + VERIFY_NOT_REACHED(); +} + +ErrorOr SysFSSystemRequestPanic::truncate(u64) +{ + TRY(check_current_process_not_jailed()); + PANIC("SysFSSystemRequestPanic::truncate"); + VERIFY_NOT_REACHED(); +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/RequestPanic.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/RequestPanic.h new file mode 100644 index 0000000000..a4daaf9835 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/RequestPanic.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSSystemRequestPanic final : public SysFSComponent { +public: + static NonnullRefPtr must_create(SysFSDirectory const& parent_directory); + virtual StringView name() const override { return "request_panic"sv; } + +private: + explicit SysFSSystemRequestPanic(SysFSDirectory const& parent_directory) + : SysFSComponent(parent_directory) + { + } + + // ^SysFSComponent + virtual ErrorOr read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const override; + virtual ErrorOr write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) override; + virtual mode_t permissions() const override { return 0600; } + virtual ErrorOr truncate(u64) override; +}; + +} diff --git a/Meta/gn/secondary/Kernel/BUILD.gn b/Meta/gn/secondary/Kernel/BUILD.gn index 89532cc0cd..11632d212e 100644 --- a/Meta/gn/secondary/Kernel/BUILD.gn +++ b/Meta/gn/secondary/Kernel/BUILD.gn @@ -657,6 +657,7 @@ executable("Kernel_bin") { "FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.cpp", "FileSystem/SysFS/Subsystems/Kernel/Processes.cpp", "FileSystem/SysFS/Subsystems/Kernel/Profile.cpp", + "FileSystem/SysFS/Subsystems/Kernel/RequestPanic.cpp", "FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.cpp", "FileSystem/SysFS/Subsystems/Kernel/Uptime.cpp", "FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.cpp",