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

Kernel+LibCore+LibC: Implement support for forcing unveil on exec

To accomplish this, we add another VeilState which is called
LockedInherited. The idea is to apply exec unveil data, similar to
execpromises of the pledge syscall, on the current exec'ed program
during the execve sequence. When applying the forced unveil data, the
veil state is set to be locked but the special state of LockedInherited
ensures that if the new program tries to unveil paths, the request will
silently be ignored, so the program will continue running without
receiving an error, but is still can only use the paths that were
unveiled before the exec syscall. This in turn, allows us to use the
unveil syscall with a special utility to sandbox other userland programs
in terms of what is visible to them on the filesystem, and is usable on
both programs that use or don't use the unveil syscall in their code.
This commit is contained in:
Liav A 2022-11-04 19:20:11 +02:00 committed by Andrew Kaster
parent 35efdb17f9
commit 718ae68621
11 changed files with 161 additions and 48 deletions

View file

@ -320,13 +320,14 @@ ErrorOr<NonnullLockRefPtr<Process>> Process::try_create(LockRefPtr<Thread>& firs
new_address_space = TRY(Memory::AddressSpace::try_create(nullptr));
}
auto unveil_tree = UnveilNode { TRY(KString::try_create("/"sv)), UnveilMetadata(TRY(KString::try_create("/"sv))) };
auto exec_unveil_tree = UnveilNode { TRY(KString::try_create("/"sv)), UnveilMetadata(TRY(KString::try_create("/"sv))) };
auto credentials = TRY(Credentials::create(uid, gid, uid, gid, uid, gid, {}));
auto process = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Process(move(name), move(credentials), ppid, is_kernel_process, move(current_directory), move(executable), tty, move(unveil_tree))));
auto process = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Process(move(name), move(credentials), ppid, is_kernel_process, move(current_directory), move(executable), tty, move(unveil_tree), move(exec_unveil_tree))));
TRY(process->attach_resources(new_address_space.release_nonnull(), first_thread, fork_parent));
return process;
}
Process::Process(NonnullOwnPtr<KString> name, NonnullRefPtr<Credentials> credentials, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, TTY* tty, UnveilNode unveil_tree)
Process::Process(NonnullOwnPtr<KString> name, NonnullRefPtr<Credentials> credentials, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, TTY* tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree)
: m_name(move(name))
, m_space(LockRank::None)
, m_protected_data_lock(LockRank::None)
@ -335,6 +336,7 @@ Process::Process(NonnullOwnPtr<KString> name, NonnullRefPtr<Credentials> credent
, m_current_directory(LockRank::None, move(current_directory))
, m_tty(tty)
, m_unveil_data(LockRank::None, move(unveil_tree))
, m_exec_unveil_data(LockRank::None, move(exec_unveil_tree))
, m_wait_blocker_set(*this)
{
// Ensure that we protect the process data when exiting the constructor.