diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index 1ca6d4278c..e55d4fb739 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -79,6 +79,7 @@ namespace Kernel { S(setegid) \ S(setuid) \ S(setgid) \ + S(setreuid) \ S(setresuid) \ S(setresgid) \ S(alarm) \ diff --git a/Kernel/Process.h b/Kernel/Process.h index 8908f9ca93..f7bf21463d 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -324,6 +324,7 @@ public: KResultOr sys$setegid(gid_t); KResultOr sys$setuid(uid_t); KResultOr sys$setgid(gid_t); + KResultOr sys$setreuid(uid_t, uid_t); KResultOr sys$setresuid(uid_t, uid_t, uid_t); KResultOr sys$setresgid(gid_t, gid_t, gid_t); KResultOr sys$alarm(unsigned seconds); diff --git a/Kernel/Syscalls/setuid.cpp b/Kernel/Syscalls/setuid.cpp index d94e833308..e5453287c1 100644 --- a/Kernel/Syscalls/setuid.cpp +++ b/Kernel/Syscalls/setuid.cpp @@ -73,6 +73,31 @@ KResultOr Process::sys$setgid(gid_t new_gid) return 0; } +KResultOr Process::sys$setreuid(uid_t new_ruid, uid_t new_euid) +{ + REQUIRE_PROMISE(id); + + if (new_ruid == (uid_t)-1) + new_ruid = uid(); + if (new_euid == (uid_t)-1) + new_euid = euid(); + + auto ok = [this](uid_t id) { return id == uid() || id == euid() || id == suid(); }; + if (!ok(new_ruid) || !ok(new_euid)) + return EPERM; + + if (new_ruid < (uid_t)-1 || new_euid < (uid_t)-1) + return EINVAL; + + if (euid() != new_euid) + set_dumpable(false); + + ProtectedDataMutationScope scope { *this }; + m_uid = new_ruid; + m_euid = new_euid; + return 0; +} + KResultOr Process::sys$setresuid(uid_t new_ruid, uid_t new_euid, uid_t new_suid) { REQUIRE_PROMISE(id); diff --git a/Userland/Libraries/LibC/unistd.cpp b/Userland/Libraries/LibC/unistd.cpp index f1daf87692..0d01ff2f17 100644 --- a/Userland/Libraries/LibC/unistd.cpp +++ b/Userland/Libraries/LibC/unistd.cpp @@ -555,6 +555,12 @@ int setgid(gid_t gid) __RETURN_WITH_ERRNO(rc, rc, -1); } +int setreuid(uid_t ruid, uid_t euid) +{ + int rc = syscall(SC_setreuid, ruid, euid); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + int setresuid(uid_t ruid, uid_t euid, uid_t suid) { int rc = syscall(SC_setresuid, ruid, euid, suid); diff --git a/Userland/Libraries/LibC/unistd.h b/Userland/Libraries/LibC/unistd.h index de2837c92e..7f54106434 100644 --- a/Userland/Libraries/LibC/unistd.h +++ b/Userland/Libraries/LibC/unistd.h @@ -74,6 +74,7 @@ int seteuid(uid_t); int setegid(gid_t); int setuid(uid_t); int setgid(gid_t); +int setreuid(uid_t, uid_t); int setresuid(uid_t, uid_t, uid_t); int setresgid(gid_t, gid_t, gid_t); pid_t tcgetpgrp(int fd);