1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-08 17:57:35 +00:00
serenity/Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.cpp
Liav A 1ca0ac5207 Kernel: Disallow jailed processes to read files in /sys/kernel directory
By default, disallow reading of values in that directory. Later on, we
will enable sparingly read access to specific files.

The idea that led to this mechanism was suggested by Jean-Baptiste
Boric (also known as boricj in GitHub), to prevent access to sensitive
information in the SysFS if someone adds a new file in the /sys/kernel
directory.
2022-12-03 05:47:58 -07:00

68 lines
2.2 KiB
C++

/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/Process.h>
namespace Kernel {
ErrorOr<size_t> SysFSGlobalInformation::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const
{
dbgln_if(SYSFS_DEBUG, "SysFSGlobalInformation @ {}: read_bytes offset: {} count: {}", name(), offset, count);
VERIFY(offset >= 0);
VERIFY(buffer.user_or_kernel_ptr());
if (!description)
return Error::from_errno(EIO);
MutexLocker locker(m_refresh_lock);
if (!description->data()) {
dbgln("SysFSGlobalInformation: Do not have cached data!");
return Error::from_errno(EIO);
}
auto& typed_cached_data = static_cast<SysFSInodeData&>(*description->data());
auto& data_buffer = typed_cached_data.buffer;
if (!data_buffer || (size_t)offset >= data_buffer->size())
return 0;
ssize_t nread = min(static_cast<off_t>(data_buffer->size() - offset), static_cast<off_t>(count));
TRY(buffer.write(data_buffer->data() + offset, nread));
return nread;
}
SysFSGlobalInformation::SysFSGlobalInformation(SysFSDirectory const& parent_directory)
: SysFSComponent(parent_directory)
{
}
ErrorOr<void> SysFSGlobalInformation::refresh_data(OpenFileDescription& description) const
{
MutexLocker lock(m_refresh_lock);
auto& cached_data = description.data();
if (!cached_data) {
cached_data = adopt_own_if_nonnull(new (nothrow) SysFSInodeData);
if (!cached_data)
return ENOMEM;
}
auto builder = TRY(KBufferBuilder::try_create());
TRY(Process::current().jail().with([&](auto& my_jail) -> ErrorOr<void> {
if (my_jail && !is_readable_by_jailed_processes())
return Error::from_errno(EPERM);
TRY(const_cast<SysFSGlobalInformation&>(*this).try_generate(builder));
return {};
}));
auto& typed_cached_data = static_cast<SysFSInodeData&>(*cached_data);
typed_cached_data.buffer = builder.build();
if (!typed_cached_data.buffer)
return ENOMEM;
return {};
}
}