mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 01:37:36 +00:00
Kernel: Don't allocate memory for names of processes and threads
Instead, use the FixedCharBuffer class to ensure we always use a static buffer storage for these names. This ensures that if a Process or a Thread were created, there's a guarantee that setting a new name will never fail, as only copying of strings should be done to that static storage. The limits which are set are 32 characters for processes' names and 64 characters for thread names - this is because threads' names could be more verbose than processes' names.
This commit is contained in:
parent
0d30f558f4
commit
3fd4997fc2
22 changed files with 102 additions and 110 deletions
|
@ -480,9 +480,6 @@ ErrorOr<void> Process::do_exec(NonnullRefPtr<OpenFileDescription> main_program_d
|
|||
|
||||
auto last_part = path->view().find_last_split_view('/');
|
||||
|
||||
auto new_process_name = TRY(KString::try_create(last_part));
|
||||
auto new_main_thread_name = TRY(new_process_name->try_clone());
|
||||
|
||||
auto allocated_space = TRY(Memory::AddressSpace::try_create(*this, nullptr));
|
||||
OwnPtr<Memory::AddressSpace> old_space;
|
||||
auto old_master_tls_region = m_master_tls_region;
|
||||
|
@ -659,8 +656,9 @@ ErrorOr<void> Process::do_exec(NonnullRefPtr<OpenFileDescription> main_program_d
|
|||
// 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)));
|
||||
|
||||
set_name(move(new_process_name));
|
||||
new_main_thread->set_name(move(new_main_thread_name));
|
||||
// NOTE: The Process and its first thread share the same name.
|
||||
set_name(last_part);
|
||||
new_main_thread->set_name(last_part);
|
||||
|
||||
if (wait_for_tracer_at_next_execve()) {
|
||||
// Make sure we release the ptrace lock here or the tracer will block forever.
|
||||
|
|
|
@ -20,9 +20,8 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
|
|||
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
||||
TRY(require_promise(Pledge::proc));
|
||||
|
||||
auto child_name = TRY(name().with([](auto& name) { return name->try_clone(); }));
|
||||
auto credentials = this->credentials();
|
||||
auto child_and_first_thread = TRY(Process::create(move(child_name), credentials->uid(), credentials->gid(), pid(), m_is_kernel_process, current_directory(), executable(), tty(), this));
|
||||
auto child_and_first_thread = TRY(Process::create_with_forked_name(credentials->uid(), credentials->gid(), pid(), m_is_kernel_process, current_directory(), executable(), tty(), this));
|
||||
auto& child = child_and_first_thread.process;
|
||||
auto& child_first_thread = child_and_first_thread.first_thread;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ ErrorOr<void> Process::do_kill(Process& process, int signal)
|
|||
return EPERM;
|
||||
if (process.is_kernel_process()) {
|
||||
process.name().with([&](auto& process_name) {
|
||||
dbgln("Attempted to send signal {} to kernel process {} ({})", signal, process_name->view(), process.pid());
|
||||
dbgln("Attempted to send signal {} to kernel process {} ({})", signal, process_name.representable_view(), process.pid());
|
||||
});
|
||||
return EPERM;
|
||||
}
|
||||
|
|
|
@ -55,14 +55,13 @@ ErrorOr<FlatPtr> Process::sys$prctl(int option, FlatPtr arg1, FlatPtr arg2)
|
|||
int user_buffer_size = static_cast<int>(arg2);
|
||||
if (user_buffer_size < 0)
|
||||
return EINVAL;
|
||||
if (user_buffer_size > 256)
|
||||
return ENAMETOOLONG;
|
||||
size_t buffer_size = static_cast<size_t>(user_buffer_size);
|
||||
auto name = TRY(try_copy_kstring_from_user(buffer, buffer_size));
|
||||
Process::Name process_name {};
|
||||
TRY(try_copy_name_from_user_into_fixed_string_buffer<32>(buffer, process_name, buffer_size));
|
||||
// NOTE: Reject empty and whitespace-only names, as they only confuse users.
|
||||
if (name->view().is_whitespace())
|
||||
if (process_name.representable_view().is_whitespace())
|
||||
return EINVAL;
|
||||
set_name(move(name));
|
||||
set_name(process_name.representable_view());
|
||||
return 0;
|
||||
}
|
||||
case PR_GET_PROCESS_NAME: {
|
||||
|
@ -73,9 +72,10 @@ ErrorOr<FlatPtr> Process::sys$prctl(int option, FlatPtr arg1, FlatPtr arg2)
|
|||
return EINVAL;
|
||||
size_t buffer_size = static_cast<size_t>(arg2);
|
||||
TRY(m_name.with([&buffer, buffer_size](auto& name) -> ErrorOr<void> {
|
||||
if (name->length() + 1 > buffer_size)
|
||||
auto view = name.representable_view();
|
||||
if (view.length() + 1 > buffer_size)
|
||||
return ENAMETOOLONG;
|
||||
return copy_to_user(buffer, name->characters(), name->length() + 1);
|
||||
return copy_to_user(buffer, view.characters_without_null_termination(), view.length() + 1);
|
||||
}));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -48,9 +48,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(name().with([&](auto& process_name) {
|
||||
return KString::formatted("{} [{}]", process_name->view(), thread->tid().value());
|
||||
return KString::formatted("{} [{}]", process_name.representable_view(), thread->tid().value());
|
||||
}));
|
||||
thread->set_name(move(new_thread_name));
|
||||
thread->set_name(new_thread_name->view());
|
||||
|
||||
if (!is_thread_joinable)
|
||||
thread->detach();
|
||||
|
@ -194,17 +194,14 @@ ErrorOr<FlatPtr> Process::sys$set_thread_name(pid_t tid, Userspace<char const*>
|
|||
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
||||
TRY(require_promise(Pledge::stdio));
|
||||
|
||||
auto name = TRY(try_copy_kstring_from_user(user_name, user_name_length));
|
||||
|
||||
const size_t max_thread_name_size = 64;
|
||||
if (name->length() > max_thread_name_size)
|
||||
return ENAMETOOLONG;
|
||||
Thread::Name thread_name {};
|
||||
TRY(try_copy_name_from_user_into_fixed_string_buffer<64>(user_name, thread_name, user_name_length));
|
||||
|
||||
auto thread = Thread::from_tid(tid);
|
||||
if (!thread || thread->pid() != pid())
|
||||
return ESRCH;
|
||||
|
||||
thread->set_name(move(name));
|
||||
thread->set_name(thread_name.representable_view());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -220,16 +217,12 @@ ErrorOr<FlatPtr> Process::sys$get_thread_name(pid_t tid, Userspace<char*> buffer
|
|||
return ESRCH;
|
||||
|
||||
TRY(thread->name().with([&](auto& thread_name) -> ErrorOr<void> {
|
||||
if (thread_name->view().is_null()) {
|
||||
char null_terminator = '\0';
|
||||
TRY(copy_to_user(buffer, &null_terminator, sizeof(null_terminator)));
|
||||
return {};
|
||||
}
|
||||
|
||||
if (thread_name->length() + 1 > buffer_size)
|
||||
VERIFY(!thread_name.representable_view().is_null());
|
||||
auto thread_name_view = thread_name.representable_view();
|
||||
if (thread_name_view.length() + 1 > buffer_size)
|
||||
return ENAMETOOLONG;
|
||||
|
||||
return copy_to_user(buffer, thread_name->characters(), thread_name->length() + 1);
|
||||
return copy_to_user(buffer, thread_name_view.characters_without_null_termination(), thread_name_view.length() + 1);
|
||||
}));
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue