summaryrefslogtreecommitdiff
path: root/Kernel/Syscalls
diff options
context:
space:
mode:
authorsin-ack <sin-ack@users.noreply.github.com>2022-10-01 12:47:38 +0000
committerAndrew Kaster <andrewdkaster@gmail.com>2022-12-11 19:55:37 -0700
commit70337f3a4b07e6d6c2be357187e37653f74ac772 (patch)
tree4f6c0279059fb58a4cbc442fb8df656d0209b2aa /Kernel/Syscalls
parent2a502fe2326778ba7f5bded6b5e45476865b0ab1 (diff)
downloadserenity-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.cpp34
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);