implement effective and real user and group id separation
New syscalls: * geteuid * setreuid * getegid * setregid
This commit is contained in:
+4
-4
@@ -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 | - | - | - |
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user