1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-09-14 14:27:34 +00:00

Kernel: Protect Process::m_name with a spinlock

This also lets us remove the `get_process_name` and `set_process_name`
syscalls from the big lock. :^)
This commit is contained in:
Sam Atkins 2023-02-04 13:01:46 +00:00 committed by Andreas Kling
parent b26ecca970
commit fe7b08dad7
13 changed files with 102 additions and 42 deletions

View file

@ -647,7 +647,7 @@ ErrorOr<void> Process::do_exec(NonnullLockRefPtr<OpenFileDescription> main_progr
// and we don't want to deal with faults after this point.
auto new_userspace_sp = TRY(make_userspace_context_for_main_thread(new_main_thread->regs(), *load_result.stack_region.unsafe_ptr(), m_arguments, m_environment, move(auxv)));
m_name = move(new_process_name);
set_name(move(new_process_name));
new_main_thread->set_name(move(new_main_thread_name));
if (wait_for_tracer_at_next_execve()) {

View file

@ -27,7 +27,7 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
}
};
auto child_name = TRY(m_name->try_clone());
auto child_name = TRY(name().with([](auto& name) { return name->try_clone(); }));
auto credentials = this->credentials();
auto child = TRY(Process::try_create(child_first_thread, move(child_name), credentials->uid(), credentials->gid(), pid(), m_is_kernel_process, current_directory(), executable(), m_tty, this));

View file

@ -22,7 +22,9 @@ ErrorOr<void> Process::do_kill(Process& process, int signal)
if (!can_send_signal)
return EPERM;
if (process.is_kernel_process()) {
dbgln("Attempted to send signal {} to kernel process {} ({})", signal, process.name(), process.pid());
process.name().with([&](auto& process_name) {
dbgln("Attempted to send signal {} to kernel process {} ({})", signal, process_name->view(), process.pid());
});
return EPERM;
}
if (signal != 0)

View file

@ -25,18 +25,22 @@ ErrorOr<FlatPtr> Process::sys$getppid()
ErrorOr<FlatPtr> Process::sys$get_process_name(Userspace<char*> buffer, size_t buffer_size)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
VERIFY_NO_PROCESS_BIG_LOCK(this);
TRY(require_promise(Pledge::stdio));
if (m_name->length() + 1 > buffer_size)
return ENAMETOOLONG;
TRY(copy_to_user(buffer, m_name->characters(), m_name->length() + 1));
TRY(m_name.with([&buffer, buffer_size](auto& name) -> ErrorOr<void> {
if (name->length() + 1 > buffer_size)
return ENAMETOOLONG;
return copy_to_user(buffer, name->characters(), name->length() + 1);
}));
return 0;
}
ErrorOr<FlatPtr> Process::sys$set_process_name(Userspace<char const*> user_name, size_t user_name_length)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
VERIFY_NO_PROCESS_BIG_LOCK(this);
TRY(require_promise(Pledge::proc));
if (user_name_length > 256)
return ENAMETOOLONG;
@ -44,7 +48,7 @@ ErrorOr<FlatPtr> Process::sys$set_process_name(Userspace<char const*> user_name,
// Empty and whitespace-only names only exist to confuse users.
if (name->view().is_whitespace())
return EINVAL;
m_name = move(name);
set_name(move(name));
return 0;
}

View file

@ -47,7 +47,9 @@ ErrorOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<Sys
// We know this thread is not the main_thread,
// So give it a unique name until the user calls $set_thread_name on it
auto new_thread_name = TRY(KString::formatted("{} [{}]", m_name, thread->tid().value()));
auto new_thread_name = TRY(name().with([&](auto& process_name) {
return KString::formatted("{} [{}]", process_name->view(), thread->tid().value());
}));
thread->set_name(move(new_thread_name));
if (!is_thread_joinable)