implement effective and real user and group id separation

New syscalls:
  * geteuid
  * setreuid
  * getegid
  * setregid
This commit is contained in:
Florian Fischer
2024-01-12 14:19:21 +01:00
parent 9de28df51a
commit 9f0d8eca0d
6 changed files with 122 additions and 40 deletions
+4 -4
View File
@@ -59,8 +59,8 @@ If the column is empty it means that it's not implemented yet.
2 | 46 | sys_setgid | process/scheduler.c | gid_t | - | - | - | - |
2 | 47 | sys_getgid | process/scheduler.c | - | - | - | - | - |
1 | 48 | sys_signal | system/signal.c | int | __sighandler_t | - | - | - |
| 49 | sys_geteuid | | - | - | - | - | - |
| 50 | sys_getegid | | - | - | - | - | - |
1 | 49 | sys_geteuid | process/scheduler.c | - | - | - | - | - |
1 | 50 | sys_getegid | process/scheduler.c | - | - | - | - | - |
| 51 | sys_acct | | const char * | - | - | - | - |
| 52 | sys_umount | | char * | int | - | - | - |
1 | 54 | sys_ioctl | fs/ioctl.c | unsigned int | unsigned int | unsigned long | - | - |
@@ -77,8 +77,8 @@ If the column is empty it means that it's not implemented yet.
1 | 67 | sys_sigaction | system/signal.c | int | const struct old_sigaction * | struct old_sigaction * | - | - |
X | 68 | sys_sgetmask | | - | - | - | - | - |
X | 69 | sys_ssetmask | | int | - | - | - | - |
| 70 | sys_setreuid | | uid_t | uid_t | - | - | - |
| 71 | sys_setregid | | gid_t | gid_t | - | - | - |
1 | 70 | sys_setreuid | process/scheduler.c | uid_t | uid_t | - | - | - |
1 | 71 | sys_setregid | process/scheduler.c | gid_t | gid_t | - | - | - |
| 72 | sys_sigsuspend | | int | int | old_sigset_t | - | - |
| 73 | sys_sigpending | | old_sigset_t * | - | - | - | - |
| 74 | sys_sethostname | | char * | int | - | - | - |
+5 -1
View File
@@ -87,9 +87,13 @@ typedef struct task_struct {
/// The Process Group Id of the process
pid_t pgid;
/// The Group ID (GID) of the process
pid_t rgid;
/// The effective Group ID (GID) of the process
pid_t gid;
/// The User ID (UID) of the user owning the process.
pid_t uid;
uid_t ruid;
/// The effective User ID (UID) of the process.
uid_t uid;
// -1 unrunnable, 0 runnable, >0 stopped.
/// The current state of the process:
__volatile__ long state;
+25 -3
View File
@@ -131,21 +131,32 @@ pid_t sys_getpgid(pid_t pid);
/// @return returns zero. On error, -1 is returned, and errno is set appropriately.
int sys_setpgid(pid_t pid, pid_t pgid);
///@brief returns the group ID of the calling process.
///@brief returns the real group ID of the calling process.
///@return GID of the current process
pid_t sys_getgid(void);
///@brief sets the effective group ID of the calling process.
///@brief sets the group ID of the calling process.
///@param pid process identifier to
///@return On success, zero is returned.
/// Otherwise returns -1 with errno set to :EINVAL or EPERM.
int sys_setgid(pid_t pid);
///@brief returns the effective group ID of the calling process.
///@return GID of the current process
gid_t sys_getegid(void);
///@brief sets the real and effective group ID of the calling process.
///@param rgid real group id
///@param egid effective group id
///@return On success, zero is returned.
/// Otherwise returns -1 with errno set to EPERM.
int sys_setregid(gid_t rgid, gid_t egid);
/// @brief Returns the parent process ID (PPID) of the calling process.
/// @return The parent process ID.
pid_t sys_getppid(void);
/// @brief Returns the User ID (UID) of the calling process.
/// @brief Returns the real User ID (UID) of the calling process.
/// @return The User ID.
uid_t sys_getuid(void);
@@ -155,6 +166,17 @@ uid_t sys_getuid(void);
/// Otherwise returns -1 with errno set to :EINVAL or EPERM.
int sys_setuid(uid_t uid);
/// @brief Returns the effective User ID (UID) of the calling process.
/// @return The User ID.
uid_t sys_geteuid(void);
/// @brief Set the real and effective User ID (UID) of the calling process.
/// @param ruid the new real User ID.
/// @param euid the new effective User ID.
///@return On success, zero is returned.
/// Otherwise returns -1 with errno set to EPERM.
int sys_setreuid(uid_t ruid, uid_t euid);
/// @brief Adds the increment to the priority value of the task.
/// @param increment The modifier to apply to the nice value.
/// @return The new nice value.
+4
View File
@@ -179,7 +179,9 @@ static inline task_struct *__alloc_task(task_struct *source, task_struct *parent
}
// Set the statistics of the process.
proc->uid = 0;
proc->ruid = 0;
proc->gid = 0;
proc->rgid = 0;
proc->sid = 0;
proc->pgid = 0;
proc->se.prio = DEFAULT_PRIO;
@@ -425,7 +427,9 @@ pid_t sys_fork(pt_regs *f)
proc->sid = current->sid;
proc->pgid = current->pgid;
proc->uid = current->uid;
proc->ruid = current->ruid;
proc->gid = current->gid;
proc->rgid = current->rgid;
// Active the new process.
scheduler_enqueue_task(proc);
+80 -28
View File
@@ -376,46 +376,98 @@ int sys_setpgid(pid_t pid, pid_t pgid)
return 0;
}
uid_t sys_getuid(void)
{
if (runqueue.curr) {
return runqueue.curr->uid;
}
#define RETURN_PROCESS_ATTR_OR_EPERM(attr) \
if (runqueue.curr) { return runqueue.curr->attr; } \
return -EPERM;
}
uid_t sys_getuid(void) { RETURN_PROCESS_ATTR_OR_EPERM(ruid); }
uid_t sys_geteuid(void) { RETURN_PROCESS_ATTR_OR_EPERM(uid); }
pid_t sys_getgid(void) { RETURN_PROCESS_ATTR_OR_EPERM(rgid); }
gid_t sys_getegid(void) { RETURN_PROCESS_ATTR_OR_EPERM(gid); }
#define FAIL_ON_INV_ID(id) \
if (id < 0) { return -EINVAL; }
#define FAIL_ON_INV_ID_OR_PROC(id) \
FAIL_ON_INV_ID(id) \
if (!runqueue.curr) { return -EPERM; }
#define IF_PRIVILEGED_SET_ALL_AND_RETURN(attr) \
if (runqueue.curr->uid == 0) { \
runqueue.curr->r ## attr = runqueue.curr->attr = attr; \
return 0; \
}
#define IF_RESET_SET_AND_RETURN(attr) \
if (runqueue.curr->r ## attr == attr) { \
runqueue.curr->attr = attr; \
return 0; \
}
#define SET_IF_PRIVILEGED_OR_FAIL(attr) \
if (runqueue.curr->uid == 0) { \
runqueue.curr->attr = attr; \
} else { return -EPERM; }
int sys_setuid(uid_t uid)
{
if (uid < 0) {
return -EINVAL;
}
if (runqueue.curr && (runqueue.curr->uid == 0)) {
runqueue.curr->uid = uid;
return 0;
}
return -EPERM;
}
pid_t sys_getgid(void)
{
if (runqueue.curr) {
return runqueue.curr->gid;
}
FAIL_ON_INV_ID_OR_PROC(uid);
IF_PRIVILEGED_SET_ALL_AND_RETURN(uid);
IF_RESET_SET_AND_RETURN(uid);
return -EPERM;
}
int sys_setgid(pid_t gid)
{
if (gid < 0) {
return -EINVAL;
}
if (runqueue.curr && (runqueue.curr->uid == 0)) {
runqueue.curr->gid = gid;
return 0;
}
FAIL_ON_INV_ID_OR_PROC(gid);
IF_PRIVILEGED_SET_ALL_AND_RETURN(gid);
IF_RESET_SET_AND_RETURN(gid);
return -EPERM;
}
int sys_setreuid(uid_t ruid, uid_t euid)
{
if (!runqueue.curr) { return -EPERM; }
if (euid != -1) {
FAIL_ON_INV_ID(euid);
// Privileged or reset?
if ((runqueue.curr->uid == 0) || (runqueue.curr->ruid == euid)) {
runqueue.curr->uid = euid;
} else {
return -EPERM;
}
}
if (ruid != -1) {
FAIL_ON_INV_ID(ruid);
SET_IF_PRIVILEGED_OR_FAIL(ruid);
}
return 0;
}
int sys_setregid(gid_t rgid, gid_t egid)
{
if (!runqueue.curr) { return -EPERM; }
if (egid != -1) {
FAIL_ON_INV_ID(rgid);
// Privileged or reset?
if ((runqueue.curr->uid == 0) || (runqueue.curr->rgid == egid)) {
runqueue.curr->gid = egid;
} else {
return -EPERM;
}
}
if (rgid != -1) {
FAIL_ON_INV_ID(rgid);
SET_IF_PRIVILEGED_OR_FAIL(rgid);
}
return 0;
}
pid_t sys_getppid(void)
{
// Get the current task.
+4 -4
View File
@@ -98,8 +98,8 @@ void syscall_init(void)
sys_call_table[__NR_setgid] = (SystemCall)sys_setgid;
sys_call_table[__NR_getgid] = (SystemCall)sys_getgid;
sys_call_table[__NR_signal] = (SystemCall)sys_signal;
sys_call_table[__NR_geteuid] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_getegid] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_geteuid] = (SystemCall)sys_geteuid;
sys_call_table[__NR_getegid] = (SystemCall)sys_getegid;
sys_call_table[__NR_acct] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_umount] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_ioctl] = (SystemCall)sys_ioctl;
@@ -116,8 +116,8 @@ void syscall_init(void)
sys_call_table[__NR_sigaction] = (SystemCall)sys_sigaction;
sys_call_table[__NR_sgetmask] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_ssetmask] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_setreuid] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_setregid] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_setreuid] = (SystemCall)sys_setreuid;
sys_call_table[__NR_setregid] = (SystemCall)sys_setregid;
sys_call_table[__NR_sigsuspend] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_sigpending] = (SystemCall)sys_ni_syscall;
sys_call_table[__NR_sethostname] = (SystemCall)sys_ni_syscall;