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.
This commit is contained in:
Liav A 2023-09-09 15:48:07 +03:00 committed by Andrew Kaster
parent 9836a9ad0e
commit 93e172895a
6 changed files with 91 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -23,6 +23,7 @@
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/PowerStateSwitch.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/RequestPanic.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.h>
@ -44,6 +45,7 @@ UNMAP_AFTER_INIT NonnullRefPtr<SysFSGlobalKernelStatsDirectory> 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));

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/RequestPanic.h>
#include <Kernel/Library/Panic.h>
#include <Kernel/Security/Jail.h>
#include <Kernel/Tasks/Process.h>
namespace Kernel {
UNMAP_AFTER_INIT NonnullRefPtr<SysFSSystemRequestPanic> SysFSSystemRequestPanic::must_create(SysFSDirectory const& parent_directory)
{
return adopt_ref_if_nonnull(new (nothrow) SysFSSystemRequestPanic(parent_directory)).release_nonnull();
}
static ErrorOr<void> check_current_process_not_jailed()
{
return Process::current().jail().with([&](auto const& my_jail) -> ErrorOr<void> {
if (my_jail)
return Error::from_errno(EPERM);
return {};
});
}
ErrorOr<size_t> SysFSSystemRequestPanic::read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const
{
TRY(check_current_process_not_jailed());
return Error::from_errno(ENOTSUP);
}
ErrorOr<size_t> SysFSSystemRequestPanic::write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*)
{
TRY(check_current_process_not_jailed());
PANIC("SysFSSystemRequestPanic::write_bytes");
VERIFY_NOT_REACHED();
}
ErrorOr<void> SysFSSystemRequestPanic::truncate(u64)
{
TRY(check_current_process_not_jailed());
PANIC("SysFSSystemRequestPanic::truncate");
VERIFY_NOT_REACHED();
}
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Error.h>
#include <AK/Function.h>
#include <AK/RefPtr.h>
#include <AK/Types.h>
#include <Kernel/FileSystem/OpenFileDescription.h>
#include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/Library/KBufferBuilder.h>
#include <Kernel/Library/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSSystemRequestPanic final : public SysFSComponent {
public:
static NonnullRefPtr<SysFSSystemRequestPanic> 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<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) override;
virtual mode_t permissions() const override { return 0600; }
virtual ErrorOr<void> truncate(u64) override;
};
}

View file

@ -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",