Merge pull request #36 from fischerling/implement-id-separation

Implement user and group ID separation
This commit is contained in:
Enrico Fraccaroli
2024-02-29 13:58:04 -05:00
committed by GitHub
15 changed files with 211 additions and 43 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 | - | - | - |
+15
View File
@@ -0,0 +1,15 @@
SYNOPSIS
id [OPTIONS]
DESCRIPTION
Print user and group information for the current process.
The following options are available:
-g, --group
print only the effective group ID
-u, --user
print only the effective user ID
--help display a help message and exit
+2 -2
View File
@@ -37,10 +37,10 @@ typedef unsigned int ino_t;
typedef unsigned int dev_t;
/// The type of user-id.
typedef unsigned int uid_t;
typedef int uid_t;
/// The type of group-id.
typedef unsigned int gid_t;
typedef int gid_t;
/// The type of offset.
typedef long int off_t;
+29 -7
View File
@@ -106,26 +106,48 @@ pid_t getpgid(pid_t pid);
/// @return returns zero. On error, -1 is returned, and errno is set appropriately.
int 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
extern pid_t getgid(void);
extern gid_t getgid(void);
///@brief sets the effective group ID of the calling process.
///@param pid process identifier to
///@brief returns the effective group ID of the calling process.
///@return GID of the current process
extern gid_t getegid(void);
///@brief sets the group IDs of the calling process.
///@param gid the Group ID to set
///@return On success, zero is returned.
/// Otherwise returns -1 with errno set to :EINVAL or EPERM
extern int setgid(pid_t pid);
extern int setgid(gid_t gid);
///@brief Returns the User ID of the calling process.
///@brief sets the real and effective group IDs of the calling process.
///@param rgid the new real Group ID.
///@param egid the effective real Group ID.
///@return On success, zero is returned.
/// Otherwise returns -1 with errno set EPERM
extern int setregid(gid_t rgid, gid_t egid);
///@brief Returns the real User ID of the calling process.
///@return User ID of the current process.
extern uid_t getuid(void);
///@brief Sets the effective User ID of the calling process.
///@brief Returns the effective User ID of the calling process.
///@return User ID of the current process.
extern uid_t geteuid(void);
///@brief Sets the User IDs of the calling process.
///@param uid the new User ID.
///@return On success, zero is returned.
/// Otherwise returns -1 with errno set to :EINVAL or EPERM
extern int setuid(uid_t uid);
///@brief Sets the effective and real User IDs of the calling process.
///@param ruid the new real User ID.
///@param euid the effective real User ID.
///@return On success, zero is returned.
/// Otherwise returns -1 with errno set to EPERM
extern int setreuid(uid_t ruid, uid_t euid);
/// @brief Returns the parent process ID (PPID) of the calling process.
/// @return pid_t parent process identifier.
extern pid_t getppid(void);
+1
View File
@@ -8,3 +8,4 @@
#include "system/syscall_types.h"
_syscall0(pid_t, getgid)
_syscall0(gid_t, getegid)
+1
View File
@@ -8,3 +8,4 @@
#include "system/syscall_types.h"
_syscall0(uid_t, getuid)
_syscall0(uid_t, geteuid)
+1
View File
@@ -8,3 +8,4 @@
#include "system/syscall_types.h"
_syscall1(int, setgid, pid_t, pid)
_syscall2(int, setregid, gid_t, rgid, gid_t, egid)
+1
View File
@@ -8,3 +8,4 @@
#include "system/syscall_types.h"
_syscall1(int, setuid, uid_t, pid)
_syscall2(int, setreuid, uid_t, ruid, uid_t, euid)
+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;
+28 -6
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);
gid_t sys_getgid(void);
///@brief sets the effective group ID of the calling process.
///@param pid process identifier to
///@brief sets the group ID of the calling process.
///@param gid group id
///@return On success, zero is returned.
/// Otherwise returns -1 with errno set to :EINVAL or EPERM.
int sys_setgid(pid_t pid);
int sys_setgid(gid_t gid);
///@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.
+12
View File
@@ -124,6 +124,14 @@ static int __load_executable(const char *path, task_struct *task, uint32_t *entr
pr_err("This is not a valid ELF executable `%s`!\n", path);
return 0;
}
// Set the effective uid if the setuid bit is present.
if (bitmask_check(file->mask, S_ISUID)) {
task->uid = file->uid;
}
// Set the effective gid if the setgid bit is present.
if (bitmask_check(file->mask, S_ISGID)) {
task->gid = file->gid;
}
// FIXME: When threads will be implemented
// they should share the mm, so the destroy_process_image must be called
// only when all the threads are terminated. This can be accomplished by using
@@ -179,7 +187,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 +435,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);
+77 -19
View File
@@ -376,38 +376,96 @@ 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); }
gid_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 (runqueue.curr && (runqueue.curr->uid == 0)) {
runqueue.curr->uid = uid;
return 0;
}
FAIL_ON_INV_ID_OR_PROC(uid);
IF_PRIVILEGED_SET_ALL_AND_RETURN(uid);
IF_RESET_SET_AND_RETURN(uid);
return -EPERM;
}
pid_t sys_getgid(void)
int sys_setgid(gid_t gid)
{
if (runqueue.curr) {
return runqueue.curr->gid;
}
FAIL_ON_INV_ID_OR_PROC(gid);
IF_PRIVILEGED_SET_ALL_AND_RETURN(gid);
IF_RESET_SET_AND_RETURN(gid);
return -EPERM;
}
int sys_setgid(pid_t gid)
int sys_setreuid(uid_t ruid, uid_t euid)
{
if (runqueue.curr && (runqueue.curr->uid == 0)) {
runqueue.curr->gid = gid;
return 0;
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;
}
}
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)
+4 -4
View File
@@ -99,8 +99,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;
@@ -117,8 +117,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;
+1
View File
@@ -1,5 +1,6 @@
# List of programs.
set(PROGRAM_LIST
id.c
stat.c
false.c
nice.c
+30
View File
@@ -0,0 +1,30 @@
/// @file id.c
/// @brief
/// @copyright (c) 2024 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include <sys/unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc == 1) {
printf("uid=%d gid=%d\n", geteuid(), getegid());
} else if (strncmp(argv[1], "--help", 6) == 0) {
printf("Usage: %s [OPTION]\n", argv[0]);
printf("Print user and group information\n\n");
printf(" -g, --group print only the effective group ID");
printf(" -u, --user print only the effective user ID");
printf(" --help display this help and exit");
} else if (strncmp(argv[1], "-u", 2) == 0 || strncmp(argv[1], "--user", 6) == 0) {
printf("%d\n", geteuid());
} else if (strncmp(argv[1], "-g", 2) == 0 || strncmp(argv[1], "--group", 7) == 0) {
printf("%d\n", getegid());
} else {
printf("%s: invalid option '%s'\n", argv[0], argv[1]);
printf("Try '%s --help' for more information\n", argv[0]);
}
return 0;
}