POSIX-2024: add getresuid(), setresuid(), getresgid(), setresgid()

remove syscalls for getuid and getgid

Change-Id: Ic6608bb65a654ff7d8fa25c8f39b71777b62b99c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9339
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Jérôme Duval
2026-01-29 17:06:11 +00:00
committed by waddlesplash
parent 83da6699df
commit afbcaac486
5 changed files with 150 additions and 58 deletions
+92 -40
View File
@@ -37,7 +37,7 @@ is_privileged(Team* team)
static status_t
common_setregid(gid_t rgid, gid_t egid, bool setAllIfPrivileged, bool kernel)
common_setresgid(gid_t rgid, gid_t egid, gid_t ssgid, bool setAllIfPrivileged, bool kernel)
{
Team* team = thread_get_current_thread()->team;
@@ -45,7 +45,8 @@ common_setregid(gid_t rgid, gid_t egid, bool setAllIfPrivileged, bool kernel)
bool privileged = kernel || is_privileged(team);
gid_t ssgid = team->saved_set_gid;
if (ssgid == (gid_t)-1 || !privileged)
ssgid = team->saved_set_gid;
// real gid
if (rgid == (gid_t)-1) {
@@ -100,7 +101,7 @@ common_setregid(gid_t rgid, gid_t egid, bool setAllIfPrivileged, bool kernel)
static status_t
common_setreuid(uid_t ruid, uid_t euid, bool setAllIfPrivileged, bool kernel)
common_setresuid(uid_t ruid, uid_t euid, uid_t ssuid, bool setAllIfPrivileged, bool kernel)
{
Team* team = thread_get_current_thread()->team;
@@ -108,7 +109,14 @@ common_setreuid(uid_t ruid, uid_t euid, bool setAllIfPrivileged, bool kernel)
bool privileged = kernel || is_privileged(team);
uid_t ssuid = team->saved_set_uid;
if (ssuid == (uid_t)-1)
ssuid = team->saved_set_uid;
else {
if (!privileged && ssuid != team->effective_uid
&& ssuid != team->real_uid && ssuid != team->saved_set_uid) {
return EPERM;
}
}
// real uid
if (ruid == (uid_t)-1) {
@@ -308,35 +316,45 @@ is_in_group(Team* team, gid_t gid)
}
gid_t
_kern_getgid(bool effective)
status_t
_kern_setresgid(gid_t rgid, gid_t egid, gid_t ssgid, bool setAllIfPrivileged)
{
Team* team = thread_get_current_thread()->team;
return effective ? team->effective_gid : team->real_gid;
}
uid_t
_kern_getuid(bool effective)
{
Team* team = thread_get_current_thread()->team;
return effective ? team->effective_uid : team->real_uid;
return common_setresgid(rgid, egid, ssgid, setAllIfPrivileged, true);
}
status_t
_kern_setregid(gid_t rgid, gid_t egid, bool setAllIfPrivileged)
_kern_setresuid(uid_t ruid, uid_t euid, uid_t ssuid, bool setAllIfPrivileged)
{
return common_setregid(rgid, egid, setAllIfPrivileged, true);
return common_setresuid(ruid, euid, ssuid, setAllIfPrivileged, true);
}
status_t
_kern_setreuid(uid_t ruid, uid_t euid, bool setAllIfPrivileged)
_kern_getresgid(gid_t *rgid, gid_t *egid, gid_t *ssgid)
{
return common_setreuid(ruid, euid, setAllIfPrivileged, true);
Team* team = thread_get_current_thread()->team;
if (rgid != NULL)
*rgid = team->real_gid;
if (egid != NULL)
*egid = team->effective_gid;
if (ssgid != NULL)
*ssgid = team->saved_set_gid;
return B_OK;
}
status_t
_kern_getresuid(uid_t *ruid, uid_t *euid, gid_t *ssuid)
{
Team* team = thread_get_current_thread()->team;
if (ruid != NULL)
*ruid = team->real_uid;
if (euid != NULL)
*euid = team->effective_uid;
if (ssuid != NULL)
*ssuid = team->saved_set_uid;
return B_OK;
}
@@ -357,35 +375,69 @@ _kern_setgroups(int groupCount, const gid_t* groupList)
// #pragma mark - Syscalls
gid_t
_user_getgid(bool effective)
status_t
_user_setresgid(gid_t rgid, gid_t egid, gid_t ssgid, bool setAllIfPrivileged)
{
Team* team = thread_get_current_thread()->team;
return effective ? team->effective_gid : team->real_gid;
}
uid_t
_user_getuid(bool effective)
{
Team* team = thread_get_current_thread()->team;
return effective ? team->effective_uid : team->real_uid;
return common_setresgid(rgid, egid, ssgid, setAllIfPrivileged, false);
}
status_t
_user_setregid(gid_t rgid, gid_t egid, bool setAllIfPrivileged)
_user_setresuid(uid_t ruid, uid_t euid, uid_t ssuid, bool setAllIfPrivileged)
{
return common_setregid(rgid, egid, setAllIfPrivileged, false);
return common_setresuid(ruid, euid, ssuid, setAllIfPrivileged, false);
}
status_t
_user_setreuid(uid_t ruid, uid_t euid, bool setAllIfPrivileged)
_user_getresgid(gid_t *rgid, gid_t *egid, gid_t *ssgid)
{
return common_setreuid(ruid, euid, setAllIfPrivileged, false);
Team* team = thread_get_current_thread()->team;
if (rgid != NULL) {
if (!IS_USER_ADDRESS(rgid)
|| user_memcpy(rgid, &team->real_gid, sizeof(uid_t)) != B_OK) {
return B_BAD_ADDRESS;
}
}
if (egid != NULL) {
if (!IS_USER_ADDRESS(egid)
|| user_memcpy(egid, &team->effective_gid, sizeof(uid_t)) != B_OK) {
return B_BAD_ADDRESS;
}
}
if (ssgid != NULL) {
if (!IS_USER_ADDRESS(ssgid)
|| user_memcpy(ssgid, &team->saved_set_gid, sizeof(uid_t)) != B_OK) {
return B_BAD_ADDRESS;
}
}
return B_OK;
}
status_t
_user_getresuid(uid_t *ruid, uid_t *euid, gid_t *ssuid)
{
Team* team = thread_get_current_thread()->team;
if (ruid != NULL) {
if (!IS_USER_ADDRESS(ruid)
|| user_memcpy(ruid, &team->real_uid, sizeof(uid_t)) != B_OK) {
return B_BAD_ADDRESS;
}
}
if (euid != NULL) {
if (!IS_USER_ADDRESS(euid)
|| user_memcpy(euid, &team->effective_uid, sizeof(uid_t)) != B_OK) {
return B_BAD_ADDRESS;
}
}
if (ssuid != NULL) {
if (!IS_USER_ADDRESS(ssuid)
|| user_memcpy(ssuid, &team->saved_set_uid, sizeof(uid_t)) != B_OK) {
return B_BAD_ADDRESS;
}
}
return B_OK;
}
+46 -10
View File
@@ -39,70 +39,106 @@ set_errno_if_necessary(const T& result)
gid_t
getegid(void)
{
return _kern_getgid(true);
gid_t egid = 0;
_kern_getresgid(NULL, &egid, NULL);
return egid;
}
uid_t
geteuid(void)
{
return _kern_getuid(true);
uid_t euid = 0;
_kern_getresuid(NULL, &euid, NULL);
return euid;
}
gid_t
getgid(void)
{
return _kern_getgid(false);
gid_t rgid = 0;
_kern_getresgid(&rgid, NULL, NULL);
return rgid;
}
uid_t
getuid(void)
{
return _kern_getuid(false);
uid_t ruid = 0;
_kern_getresuid(&ruid, NULL, NULL);
return ruid;
}
int
getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
{
return set_errno_if_necessary(_kern_getresgid(rgid, egid, sgid));
}
int
getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
{
return set_errno_if_necessary(_kern_getresuid(ruid, euid, suid));
}
int
setgid(gid_t gid)
{
return set_errno_if_necessary(_kern_setregid(gid, (gid_t)-1, true));
return set_errno_if_necessary(_kern_setresgid(gid, (gid_t)-1, (gid_t)-1, true));
}
int
setuid(uid_t uid)
{
return set_errno_if_necessary(_kern_setreuid(uid, (uid_t)-1, true));
return set_errno_if_necessary(_kern_setresuid(uid, (uid_t)-1, (uid_t)-1, true));
}
int
setegid(gid_t gid)
{
return set_errno_if_necessary(_kern_setregid((gid_t)-1, gid, false));
return set_errno_if_necessary(_kern_setresgid((gid_t)-1, gid, (gid_t)-1, false));
}
int
seteuid(uid_t uid)
{
return set_errno_if_necessary(_kern_setreuid((uid_t)-1, uid, false));
return set_errno_if_necessary(_kern_setresuid((uid_t)-1, uid, (uid_t)-1, false));
}
int
setregid(gid_t rgid, gid_t egid)
{
return set_errno_if_necessary(_kern_setregid(rgid, egid, false));
return set_errno_if_necessary(_kern_setresgid(rgid, egid, (gid_t)-1, false));
}
int
setreuid(uid_t ruid, uid_t euid)
{
return set_errno_if_necessary(_kern_setreuid(ruid, euid, false));
return set_errno_if_necessary(_kern_setresuid(ruid, euid, (uid_t)-1, false));
}
int
setresgid(gid_t rgid, gid_t egid, gid_t sgid)
{
return set_errno_if_necessary(_kern_setresgid(rgid, egid, sgid, false));
}
int
setresuid(uid_t ruid, uid_t euid, uid_t suid)
{
return set_errno_if_necessary(_kern_setresuid(ruid, euid, suid, false));
}