1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:07:35 +00:00

Kernel: Use FixedStringBuffer for fixed-length strings in syscalls

Using the kernel stack is preferable, especially when the examined
strings should be limited to a reasonable length.

This is a small improvement, because if we don't actually move these
strings then we don't need to own heap allocations for them during the
syscall handler function scope.

In addition to that, some kernel strings are known to be limited, like
the hostname string, for these strings we also can use FixedStringBuffer
to store and copy to and from these buffers, without using any heap
allocations at all.
This commit is contained in:
Liav A 2023-07-17 19:22:01 +03:00 committed by Andrew Kaster
parent 3fd4997fc2
commit d8b514873f
13 changed files with 100 additions and 46 deletions

View file

@ -41,7 +41,7 @@
namespace Kernel {
MutexProtected<OwnPtr<KString>>& hostname();
MutexProtected<FixedStringBuffer<UTSNAME_ENTRY_LEN - 1>>& hostname();
UnixDateTime kgettimeofday();
#define ENUMERATE_PLEDGE_PROMISES \
@ -74,6 +74,15 @@ UnixDateTime kgettimeofday();
__ENUMERATE_PLEDGE_PROMISE(mount) \
__ENUMERATE_PLEDGE_PROMISE(no_error)
#define __ENUMERATE_PLEDGE_PROMISE(x) sizeof(#x) + 1 +
// NOTE: We truncate the last space from the string as it's not needed (with 0 - 1).
constexpr static unsigned all_promises_strings_length_with_spaces = ENUMERATE_PLEDGE_PROMISES 0 - 1;
#undef __ENUMERATE_PLEDGE_PROMISE
// NOTE: This is a sanity check because length of more than 1024 characters
// is not reasonable.
static_assert(all_promises_strings_length_with_spaces <= 1024);
enum class Pledge : u32 {
#define __ENUMERATE_PLEDGE_PROMISE(x) x,
ENUMERATE_PLEDGE_PROMISES
@ -605,6 +614,36 @@ public:
ErrorOr<void> validate_mmap_prot(int prot, bool map_stack, bool map_anonymous, Memory::Region const* region = nullptr) const;
ErrorOr<void> validate_inode_mmap_prot(int prot, bool description_readable, bool description_writable, bool map_shared) const;
template<size_t Size>
static ErrorOr<FixedStringBuffer<Size>> get_syscall_string_fixed_buffer(Syscall::StringArgument const& argument)
{
// NOTE: If the string is too much big for the FixedStringBuffer,
// we return E2BIG error here.
FixedStringBuffer<Size> buffer;
TRY(try_copy_string_from_user_into_fixed_string_buffer<Size>(reinterpret_cast<FlatPtr>(argument.characters), buffer, argument.length));
return buffer;
}
template<size_t Size>
static ErrorOr<FixedStringBuffer<Size>> get_syscall_name_string_fixed_buffer(Userspace<char const*> user_buffer, size_t user_length = Size)
{
// NOTE: If the string is too much big for the FixedStringBuffer,
// we return E2BIG error here.
FixedStringBuffer<Size> buffer;
TRY(try_copy_string_from_user_into_fixed_string_buffer<Size>(user_buffer, buffer, user_length));
return buffer;
}
template<size_t Size>
static ErrorOr<FixedStringBuffer<Size>> get_syscall_name_string_fixed_buffer(Syscall::StringArgument const& argument)
{
// NOTE: If the string is too much big for the FixedStringBuffer,
// we return ENAMETOOLONG error here.
FixedStringBuffer<Size> buffer;
TRY(try_copy_name_from_user_into_fixed_string_buffer<Size>(reinterpret_cast<FlatPtr>(argument.characters), buffer, argument.length));
return buffer;
}
private:
friend class MemoryManager;
friend class Scheduler;