1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:48:10 +00:00

Kernel+SystemServer: Don't hardcode coredump directory path

Instead, allow userspace to decide on the coredump directory path. By
default, SystemServer sets it to the /tmp/coredump directory, but users
can now change this by writing a new path to the sysfs node at
/sys/kernel/variables/coredump_directory, and also to read this node to
check where coredumps are currently generated at.
This commit is contained in:
Liav A 2022-11-26 14:42:35 +02:00 committed by Andrew Kaster
parent 7dcf8f971b
commit 0bb7c8f4c4
10 changed files with 203 additions and 1 deletions

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/Coredump.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CoredumpDirectory.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSCoredumpDirectory::SysFSCoredumpDirectory(SysFSDirectory const& parent_directory)
: SysFSSystemStringVariable(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSCoredumpDirectory> SysFSCoredumpDirectory::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSCoredumpDirectory(parent_directory)).release_nonnull();
}
ErrorOr<NonnullOwnPtr<KString>> SysFSCoredumpDirectory::value() const
{
return Coredump::directory_path().with([&](auto& coredump_directory_path) -> ErrorOr<NonnullOwnPtr<KString>> {
if (coredump_directory_path)
return KString::try_create(coredump_directory_path->view());
return KString::try_create(""sv);
});
}
void SysFSCoredumpDirectory::set_value(NonnullOwnPtr<KString> new_value)
{
Coredump::directory_path().with([&](auto& coredump_directory_path) {
coredump_directory_path = move(new_value);
});
}
mode_t SysFSCoredumpDirectory::permissions() const
{
// NOTE: Let's not allow users to randomly change the coredump path, but only
// allow this for the root user.
return S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/StringVariable.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSCoredumpDirectory final : public SysFSSystemStringVariable {
public:
virtual StringView name() const override { return "coredump_directory"sv; }
static NonnullLockRefPtr<SysFSCoredumpDirectory> must_create(SysFSDirectory const&);
private:
virtual ErrorOr<NonnullOwnPtr<KString>> value() const override;
virtual void set_value(NonnullOwnPtr<KString> new_value) override;
explicit SysFSCoredumpDirectory(SysFSDirectory const&);
virtual mode_t permissions() const override;
};
}

View file

@ -8,6 +8,7 @@
#include <AK/Try.h>
#include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CoredumpDirectory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.h>
@ -21,6 +22,7 @@ UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSGlobalKernelVariablesDirectory> SysFSGlo
list.append(SysFSCapsLockRemap::must_create(*global_variables_directory));
list.append(SysFSDumpKmallocStacks::must_create(*global_variables_directory));
list.append(SysFSUBSANDeadly::must_create(*global_variables_directory));
list.append(SysFSCoredumpDirectory::must_create(*global_variables_directory));
return {};
}));
return global_variables_directory;

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/StringVariable.h>
#include <Kernel/Process.h>
#include <Kernel/Sections.h>
namespace Kernel {
ErrorOr<void> SysFSSystemStringVariable::try_generate(KBufferBuilder& builder)
{
auto string_value = TRY(value());
return builder.appendff("{}\n", string_value->view());
}
ErrorOr<size_t> SysFSSystemStringVariable::write_bytes(off_t, size_t count, UserOrKernelBuffer const& buffer, OpenFileDescription*)
{
MutexLocker locker(m_refresh_lock);
// Note: We do all of this code before taking the spinlock because then we disable
// interrupts so page faults will not work.
char* value = nullptr;
auto new_value = TRY(KString::try_create_uninitialized(count, value));
TRY(buffer.read(value, count));
auto new_value_without_possible_newlines = TRY(KString::try_create(new_value->view().trim("\n"sv)));
return Process::current().jail().with([&](auto& my_jail) -> ErrorOr<size_t> {
// Note: If we are in a jail, don't let the current process to change the variable.
if (my_jail)
return Error::from_errno(EPERM);
set_value(move(new_value_without_possible_newlines));
return count;
});
}
ErrorOr<void> SysFSSystemStringVariable::truncate(u64 size)
{
if (size != 0)
return EPERM;
return {};
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/AtomicRefCounted.h>
#include <AK/Error.h>
#include <AK/Function.h>
#include <AK/OwnPtr.h>
#include <AK/Types.h>
#include <Kernel/FileSystem/File.h>
#include <Kernel/FileSystem/FileSystem.h>
#include <Kernel/FileSystem/OpenFileDescription.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/KString.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/Locking/Mutex.h>
#include <Kernel/Time/TimeManagement.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSSystemStringVariable : public SysFSGlobalInformation {
protected:
explicit SysFSSystemStringVariable(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
virtual ErrorOr<NonnullOwnPtr<KString>> value() const = 0;
virtual void set_value(NonnullOwnPtr<KString> new_value) = 0;
private:
// ^SysFSGlobalInformation
virtual ErrorOr<void> try_generate(KBufferBuilder&) override final;
// ^SysFSExposedComponent
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) override final;
virtual mode_t permissions() const override { return 0644; }
virtual ErrorOr<void> truncate(u64) override final;
};
}