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
+4
View File
@@ -467,6 +467,8 @@ extern gid_t getegid(void);
extern uid_t geteuid(void); extern uid_t geteuid(void);
extern gid_t getgid(void); extern gid_t getgid(void);
extern uid_t getuid(void); extern uid_t getuid(void);
extern int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
extern int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
extern int setgid(gid_t gid); extern int setgid(gid_t gid);
extern int setuid(uid_t uid); extern int setuid(uid_t uid);
@@ -474,6 +476,8 @@ extern int setegid(gid_t gid);
extern int seteuid(uid_t uid); extern int seteuid(uid_t uid);
extern int setregid(gid_t rgid, gid_t egid); extern int setregid(gid_t rgid, gid_t egid);
extern int setreuid(uid_t ruid, uid_t euid); extern int setreuid(uid_t ruid, uid_t euid);
extern int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
extern int setresuid(uid_t ruid, uid_t euid, uid_t suid);
extern int getgrouplist(const char* user, gid_t baseGroup, extern int getgrouplist(const char* user, gid_t baseGroup,
gid_t* groupList, int* groupCount); gid_t* groupList, int* groupCount);
+4 -4
View File
@@ -31,10 +31,10 @@ extern "C" {
// syscalls // syscalls
gid_t _user_getgid(bool effective); status_t _user_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
uid_t _user_getuid(bool effective); status_t _user_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
status_t _user_setregid(gid_t rgid, gid_t egid, bool setAllIfPrivileged); status_t _user_setresgid(gid_t rgid, gid_t egid, gid_t sgid, bool setAllIfPrivileged);
status_t _user_setreuid(uid_t ruid, uid_t euid, bool setAllIfPrivileged); status_t _user_setresuid(uid_t ruid, uid_t euid, uid_t suid, bool setAllIfPrivileged);
ssize_t _user_getgroups(int groupCount, gid_t* groupList); ssize_t _user_getgroups(int groupCount, gid_t* groupList);
ssize_t _user_setgroups(int groupCount, const gid_t* groupList); ssize_t _user_setgroups(int groupCount, const gid_t* groupList);
+4 -4
View File
@@ -216,11 +216,11 @@ extern int32 _kern_get_scheduler_mode(void);
extern status_t _kern_get_loadavg(struct loadavg* info, size_t size); extern status_t _kern_get_loadavg(struct loadavg* info, size_t size);
// user/group functions // user/group functions
extern gid_t _kern_getgid(bool effective); extern status_t _kern_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
extern uid_t _kern_getuid(bool effective); extern status_t _kern_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
extern status_t _kern_setregid(gid_t rgid, gid_t egid, extern status_t _kern_setresgid(gid_t rgid, gid_t egid, gid_t sgid,
bool setAllIfPrivileged); bool setAllIfPrivileged);
extern status_t _kern_setreuid(uid_t ruid, uid_t euid, extern status_t _kern_setresuid(uid_t ruid, uid_t euid, uid_t suid,
bool setAllIfPrivileged); bool setAllIfPrivileged);
extern ssize_t _kern_getgroups(int groupCount, gid_t* groupList); extern ssize_t _kern_getgroups(int groupCount, gid_t* groupList);
extern status_t _kern_setgroups(int groupCount, const gid_t* groupList); extern status_t _kern_setgroups(int groupCount, const gid_t* groupList);
+92 -40
View File
@@ -37,7 +37,7 @@ is_privileged(Team* team)
static status_t 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; 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); 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 // real gid
if (rgid == (gid_t)-1) { if (rgid == (gid_t)-1) {
@@ -100,7 +101,7 @@ common_setregid(gid_t rgid, gid_t egid, bool setAllIfPrivileged, bool kernel)
static status_t 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; 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); 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 // real uid
if (ruid == (uid_t)-1) { if (ruid == (uid_t)-1) {
@@ -308,35 +316,45 @@ is_in_group(Team* team, gid_t gid)
} }
gid_t status_t
_kern_getgid(bool effective) _kern_setresgid(gid_t rgid, gid_t egid, gid_t ssgid, bool setAllIfPrivileged)
{ {
Team* team = thread_get_current_thread()->team; return common_setresgid(rgid, egid, ssgid, setAllIfPrivileged, true);
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;
} }
status_t 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 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 // #pragma mark - Syscalls
gid_t status_t
_user_getgid(bool effective) _user_setresgid(gid_t rgid, gid_t egid, gid_t ssgid, bool setAllIfPrivileged)
{ {
Team* team = thread_get_current_thread()->team; return common_setresgid(rgid, egid, ssgid, setAllIfPrivileged, false);
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;
} }
status_t 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 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 gid_t
getegid(void) getegid(void)
{ {
return _kern_getgid(true); gid_t egid = 0;
_kern_getresgid(NULL, &egid, NULL);
return egid;
} }
uid_t uid_t
geteuid(void) geteuid(void)
{ {
return _kern_getuid(true); uid_t euid = 0;
_kern_getresuid(NULL, &euid, NULL);
return euid;
} }
gid_t gid_t
getgid(void) getgid(void)
{ {
return _kern_getgid(false); gid_t rgid = 0;
_kern_getresgid(&rgid, NULL, NULL);
return rgid;
} }
uid_t uid_t
getuid(void) 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 int
setgid(gid_t gid) 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 int
setuid(uid_t uid) 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 int
setegid(gid_t gid) 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 int
seteuid(uid_t uid) 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 int
setregid(gid_t rgid, gid_t egid) 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 int
setreuid(uid_t ruid, uid_t euid) 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));
} }