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

Kernel: Disallow executing SUID binaries if process is jailed

Check if the process we are currently running is in a jail, and if that
is the case, fail early with the EPERM error code.

Also, as Brian noted, we should also disallow attaching to a jail in
case of already running within a setid executable, as this leaves the
user with false thinking of being secure (because you can't exec new
setid binaries), but the current program is still marked setid, which
means that at the very least we gained permissions while we didn't
expect it, so let's block it.
This commit is contained in:
Liav A 2022-12-23 13:51:47 +02:00 committed by Brian Gianforcaro
parent 0e010790a4
commit e598f22768
4 changed files with 23 additions and 2 deletions

View file

@ -472,6 +472,15 @@ ErrorOr<void> Process::do_exec(NonnullLockRefPtr<OpenFileDescription> main_progr
{
VERIFY(is_user_process());
VERIFY(!Processor::in_critical());
auto main_program_metadata = main_program_description->metadata();
// NOTE: Don't allow running SUID binaries at all if we are in a jail.
TRY(Process::current().jail().with([&](auto& my_jail) -> ErrorOr<void> {
if (my_jail && (main_program_metadata.is_setuid() || main_program_metadata.is_setgid())) {
return Error::from_errno(EPERM);
}
return {};
}));
// Although we *could* handle a pseudo_path here, trying to execute something that doesn't have
// a custody (e.g. BlockDevice or RandomDevice) is pretty suspicious anyway.
auto path = TRY(main_program_description->original_absolute_path());
@ -507,8 +516,6 @@ ErrorOr<void> Process::do_exec(NonnullLockRefPtr<OpenFileDescription> main_progr
bool executable_is_setid = false;
if (!(main_program_description->custody()->mount_flags() & MS_NOSUID)) {
auto main_program_metadata = main_program_description->metadata();
auto new_euid = old_credentials->euid();
auto new_egid = old_credentials->egid();
auto new_suid = old_credentials->suid();
@ -551,6 +558,7 @@ ErrorOr<void> Process::do_exec(NonnullLockRefPtr<OpenFileDescription> main_progr
with_mutable_protected_data([&](auto& protected_data) {
protected_data.credentials = move(new_credentials);
protected_data.dumpable = !executable_is_setid;
protected_data.executable_is_setid = executable_is_setid;
});
// We make sure to enter the new address space before destroying the old one.