diff options
author | sin-ack <sin-ack@users.noreply.github.com> | 2022-10-01 12:47:38 +0000 |
---|---|---|
committer | Andrew Kaster <andrewdkaster@gmail.com> | 2022-12-11 19:55:37 -0700 |
commit | 70337f3a4b07e6d6c2be357187e37653f74ac772 (patch) | |
tree | 4f6c0279059fb58a4cbc442fb8df656d0209b2aa /Kernel/Syscalls | |
parent | 2a502fe2326778ba7f5bded6b5e45476865b0ab1 (diff) | |
download | serenity-70337f3a4b07e6d6c2be357187e37653f74ac772.zip |
Kernel+LibC: Implement `setregid(2)`
This copies and adapts the setresgid syscall, following in the footsteps
of setreuid and setresuid.
Diffstat (limited to 'Kernel/Syscalls')
-rw-r--r-- | Kernel/Syscalls/setuid.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/Kernel/Syscalls/setuid.cpp b/Kernel/Syscalls/setuid.cpp index 5193a4b77b..71070bdacf 100644 --- a/Kernel/Syscalls/setuid.cpp +++ b/Kernel/Syscalls/setuid.cpp @@ -206,6 +206,40 @@ ErrorOr<FlatPtr> Process::sys$setresuid(UserID new_ruid, UserID new_euid, UserID }); } +ErrorOr<FlatPtr> Process::sys$setregid(GroupID new_rgid, GroupID new_egid) +{ + VERIFY_NO_PROCESS_BIG_LOCK(this); + TRY(require_promise(Pledge::id)); + + return with_mutable_protected_data([&](auto& protected_data) -> ErrorOr<FlatPtr> { + auto credentials = this->credentials(); + + if (new_rgid == (gid_t)-1) + new_rgid = credentials->gid(); + if (new_egid == (gid_t)-1) + new_egid = credentials->egid(); + + auto ok = [&credentials](GroupID id) { return id == credentials->gid() || id == credentials->egid() || id == credentials->sgid(); }; + if (!ok(new_rgid) || !ok(new_egid)) + return EPERM; + + auto new_credentials = TRY(Credentials::create( + credentials->uid(), + new_rgid, + credentials->euid(), + new_egid, + credentials->suid(), + credentials->sgid(), + credentials->extra_gids())); + + if (credentials->egid() != new_egid) + protected_data.dumpable = false; + + protected_data.credentials = move(new_credentials); + return 0; + }); +} + ErrorOr<FlatPtr> Process::sys$setresgid(GroupID new_rgid, GroupID new_egid, GroupID new_sgid) { VERIFY_NO_PROCESS_BIG_LOCK(this); |