Fix difference between PGID and GID. Correctly set UID and GID of new processes. Implement set/get PGID and GID.

This commit is contained in:
Enrico Fraccaroli
2021-12-27 00:49:28 +01:00
parent 2226eebdc8
commit 7c4a4ac0ba
20 changed files with 216 additions and 92 deletions
-2
View File
@@ -15,5 +15,3 @@ int ext2_initialize();
/// @brief De-initializes the EXT2 drivers.
/// @return 0 on success, 1 on error.
int ext2_finalize();
void ext2_test();
+4 -2
View File
@@ -82,9 +82,11 @@ typedef struct task_struct {
pid_t pid;
/// The session id of the process
pid_t sid;
/// The Group Id of the process
/// The Process Group Id of the process
pid_t pgid;
/// The Group ID (GID) of the process
pid_t gid;
/// The uid of the user owning the process.
/// The User ID (UID) of the user owning the process.
pid_t uid;
// -1 unrunnable, 0 runnable, >0 stopped.
/// The current state of the process:
+24 -1
View File
@@ -117,6 +117,19 @@ pid_t sys_getsid(pid_t pid);
/// Otherwise return -1 with errno : EPERM
pid_t sys_setsid();
///@brief returns the Process Group ID (PGID) of the process specified by pid.
/// If pid is zero, the process ID of the calling process is used.
/// @param pid process of which we want to know the PGID.
/// @return the PGID of the specified process.
pid_t sys_getpgid(pid_t pid);
/// @brief Sets the Process Group ID (PGID) of the process specified by pid.
/// If pid is zero, the process ID of the calling process is used.
/// @param pid process of which we want to set the PGID.
/// @param pgid the PGID we want to set.
/// @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.
///@return GID of the current process
pid_t sys_getgid();
@@ -124,13 +137,23 @@ pid_t sys_getgid();
///@brief sets the effective 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
/// Otherwise returns -1 with errno set to :EINVAL or EPERM.
int sys_setgid(pid_t pid);
/// @brief Returns the parent process ID (PPID) of the calling process.
/// @return The parent process ID.
pid_t sys_getppid();
/// @brief Returns the User ID (UID) of the calling process.
/// @return The User ID.
uid_t sys_getuid();
/// @brief Tries to set the User ID (UID) 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.
int sys_setuid(uid_t uid);
/// @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.
+19 -25
View File
@@ -1329,11 +1329,8 @@ static int ext2_allocate_inode_block(ext2_filesystem_t *fs, ext2_inode_t *inode,
/// @return the amount of data we read, or negative value for an error.
static ssize_t ext2_read_inode_block(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_t block_index, uint8_t *buffer)
{
if (block_index >= (inode->blocks_count / fs->blocks_per_block_count)) {
pr_err("Tried to read an invalid block `%d`, but inode only has %d\n",
block_index, (inode->blocks_count / fs->blocks_per_block_count));
if (block_index >= (inode->blocks_count / fs->blocks_per_block_count))
return -1;
}
// Get the real index.
uint32_t real_index = ext2_get_real_block_index(fs, inode, block_index);
if (real_index == 0)
@@ -1352,8 +1349,6 @@ static ssize_t ext2_read_inode_block(ext2_filesystem_t *fs, ext2_inode_t *inode,
static ssize_t ext2_write_inode_block(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_t inode_index, uint32_t block_index, uint8_t *buffer)
{
while (block_index >= (inode->blocks_count / fs->blocks_per_block_count)) {
pr_warning("Tried to read an invalid block `%d`, but inode only has %d!\n",
block_index, (inode->blocks_count / fs->blocks_per_block_count));
ext2_allocate_inode_block(fs, inode, inode_index, (inode->blocks_count / fs->blocks_per_block_count));
ext2_write_inode(fs, inode, inode_index);
}
@@ -1463,11 +1458,8 @@ static ssize_t ext2_write_inode_data(ext2_filesystem_t *fs, ext2_inode_t *inode,
memset(cache, 0, fs->block_size);
if (start_block == end_block) {
// Read the real block.
if (ext2_read_inode_block(fs, inode, start_block, cache) == -1) {
pr_err("Failed to read the inode block `%d`\n", start_block);
//goto free_cache_return_error;
}
// Read the real block, if we fail is not a problem.
ext2_read_inode_block(fs, inode, start_block, cache);
// Copy the content back to the buffer.
memcpy((uint8_t *)(((uintptr_t)cache) + ((uintptr_t)offset % fs->block_size)), buffer, size_to_write);
// Write the block back.
@@ -1478,11 +1470,8 @@ static ssize_t ext2_write_inode_data(ext2_filesystem_t *fs, ext2_inode_t *inode,
} else {
uint32_t block_offset, blocks_read = 0;
for (block_offset = start_block; block_offset < end_block; ++block_offset, ++blocks_read) {
// Read the real block.
if (ext2_read_inode_block(fs, inode, block_offset, cache) == -1) {
pr_err("Failed to read the inode block `%d`\n", block_offset);
//goto free_cache_return_error;
}
// Read the real block, if we fail is not a problem.
ext2_read_inode_block(fs, inode, block_offset, cache);
if (block_offset == start_block) {
// Copy the content back to the buffer.
memcpy((uint8_t *)(((uintptr_t)cache) + ((uintptr_t)offset % fs->block_size)), buffer, fs->block_size - (offset % fs->block_size));
@@ -1497,11 +1486,8 @@ static ssize_t ext2_write_inode_data(ext2_filesystem_t *fs, ext2_inode_t *inode,
}
}
if (end_size) {
// Read the real block.
if (ext2_read_inode_block(fs, inode, end_block, cache) == -1) {
pr_err("Failed to read the inode block `%d`\n", block_offset);
//goto free_cache_return_error;
}
// Read the real block, if we fail is not a problem.
ext2_read_inode_block(fs, inode, end_block, cache);
// Copy the content back to the buffer.
memcpy(cache, buffer + fs->block_size * blocks_read - (offset % fs->block_size), end_size);
// Write the block back.
@@ -1608,6 +1594,13 @@ void ext2_direntry_iterator_next(ext2_direntry_iterator_t *iterator)
iterator->direntry = ext2_direntry_iterator_get(iterator);
}
static inline bool_t ext2_directory_is_empty(ext2_filesystem_t *fs, uint8_t *cache, ext2_inode_t *inode)
{
if (ext2_read_inode_block(fs, inode, 0U, cache) == -1)
return true;
return ((ext2_dirent_t *)cache) == NULL;
}
// ============================================================================
// Directory Entry Management Functions
// ============================================================================
@@ -2043,6 +2036,8 @@ static int ext2_create_inode(
pr_err("Failed to read the newly created inode.\n");
return -1;
}
pr_debug("UID = %d\n", task->uid);
pr_debug("GID = %d\n", task->gid);
// Set the inode mode.
inode->mode = mode;
// Set the user identifiers of the owners.
@@ -2703,9 +2698,8 @@ static int ext2_rmdir(const char *path)
goto free_cache_return_error;
}
// Check if the directory is empty, if it enters the loop then it means it is not empty.
for (ext2_direntry_iterator_t it = ext2_direntry_iterator_begin(fs, cache, &inode);
ext2_direntry_iterator_valid(&it); ext2_direntry_iterator_next(&it)) {
pr_err("The directory is not empty.\n");
if (!ext2_directory_is_empty(fs, cache, &inode)) {
pr_err("The directory is not empty `%s`.\n", direntry.name);
kmem_cache_free(cache);
return -ENOTEMPTY;
}
@@ -3066,6 +3060,6 @@ void ext2_test()
ext2_mkdir("/home/pippo", EXT2_S_IRWXU | EXT2_S_IRGRP | EXT2_S_IXGRP | EXT2_S_IROTH | EXT2_S_IXOTH);
ext2_rmdir("/home/pippo");
ext2_rmdir("/home");
}
-2
View File
@@ -350,8 +350,6 @@ int kmain(boot_info_t *boot_informations)
}
print_ok();
//ext2_test();
// We have completed the booting procedure.
pr_notice("Booting done, jumping into init process.\n");
// Print the welcome message.
+8 -7
View File
@@ -4,14 +4,12 @@
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
/// See LICENSE.md for details.
#include "sys/kernel_levels.h"
// Include the kernel log levels.
#include "sys/kernel_levels.h"
// Change the header.
#define __DEBUG_HEADER__ "[PROC ]"
// Set the log level.
#define __DEBUG_LEVEL__ LOGLEVEL_NOTICE
#define __DEBUG_LEVEL__ LOGLEVEL_DEBUG
#include "process/process.h"
#include "process/scheduler.h"
@@ -180,8 +178,9 @@ static inline task_struct *__alloc_task(task_struct *source, task_struct *parent
memcpy(&proc->thread, &source->thread, sizeof(thread_struct_t));
// Set the statistics of the process.
proc->uid = 0;
proc->sid = 0;
proc->gid = 0;
proc->sid = 0;
proc->pgid = 0;
proc->se.prio = DEFAULT_PRIO;
proc->se.start_runtime = timer_get_ticks();
proc->se.exec_start = timer_get_ticks();
@@ -394,13 +393,15 @@ pid_t sys_fork(pt_regs *f)
proc->thread.regs.eflags = proc->thread.regs.eflags | EFLAG_IF;
// Copy session and group id of the parent into the child
proc->sid = current->sid;
proc->gid = current->gid;
proc->sid = current->sid;
proc->pgid = current->pgid;
proc->uid = current->uid;
proc->gid = current->gid;
// Active the new process.
scheduler_enqueue_task(proc);
pr_debug("Forked '%s' (pid: %d, gid: %d, sid: %d)...\n", proc->name, proc->pid, proc->gid, proc->sid);
pr_debug("Forked '%s' (pid: %d, gid: %d, sid: %d, pgid: %d)...\n", proc->name, proc->pid, proc->gid, proc->sid, proc->pgid);
// Return PID of child process to parent.
return proc->pid;
+61 -33
View File
@@ -259,7 +259,7 @@ wait_queue_entry_t *sleep_on(wait_queue_head_t *wq)
return wait_entry;
}
int is_orphaned_pgrp(pid_t gid)
int is_orphaned_pgrp(pid_t pgid)
{
pid_t sid = 0;
@@ -267,7 +267,7 @@ int is_orphaned_pgrp(pid_t gid)
list_head *it;
list_for_each (it, &runqueue.queue) {
task_struct *task = list_entry(it, task_struct, run_list);
if (task->gid == gid) {
if (task->pgid == pgid) {
sid = task->sid;
break;
}
@@ -309,11 +309,10 @@ pid_t sys_getsid(pid_t pid)
list_head *it;
list_for_each (it, &runqueue.queue) {
task_struct *task = list_entry(it, task_struct, run_list);
if (task->pid == pid)
{
if(runqueue.curr->sid != task->sid)
if (task->pid == pid) {
if (runqueue.curr->sid != task->sid)
return -EPERM;
return task->sid;
}
}
@@ -326,54 +325,83 @@ pid_t sys_setsid()
if (task == NULL) {
kernel_panic("There is no current process!");
}
if (task->sid == task->pid)
{
if (task->sid == task->pid) {
pr_debug("Process %d is already a session leader.", task->pid);
return -EPERM;
}
task->sid = task->pid;
task->gid = task->pid;
task->sid = task->pid;
task->pgid = task->pid;
return task->sid;
}
pid_t sys_getpgid(pid_t pid)
{
task_struct *task = NULL;
if (pid == 0)
task = runqueue.curr;
else
task = scheduler_get_running_process(pid);
if (task)
return task->pgid;
return 0;
}
int sys_setpgid(pid_t pid, pid_t pgid)
{
task_struct *task = NULL;
if (pid == 0)
task = runqueue.curr;
else
task = scheduler_get_running_process(pid);
if (task) {
if (task->pgid == task->pid)
pr_debug("Process %d is already a session leader.", task->pid);
task->pgid = pgid;
}
return 0;
}
uid_t sys_getuid()
{
if (runqueue.curr)
return runqueue.curr->uid;
return -EPERM;
}
int sys_setuid(uid_t uid)
{
if (runqueue.curr && (runqueue.curr->uid == 0)) {
runqueue.curr->uid = uid;
return 0;
}
return -EPERM;
}
pid_t sys_getgid()
{
task_struct *curr = runqueue.curr;
if (curr == NULL) {
kernel_panic("There is no current process!");
if (runqueue.curr) {
return runqueue.curr->gid;
}
return curr->gid;
return -EPERM;
}
int sys_setgid(pid_t gid)
{
task_struct *curr = runqueue.curr;
if (curr == NULL) {
kernel_panic("There is no current process!");
if (runqueue.curr && (runqueue.curr->uid == 0)) {
runqueue.curr->gid = gid;
return 0;
}
if (curr->gid == curr->pid)
pr_debug("Process %d is already a session leader.", task->pid);
curr->gid = curr->pid;
return 0;
return -EPERM;
}
pid_t sys_getppid()
{
// Get the current task.
if (runqueue.curr == NULL) {
kernel_panic("There is no current process!");
}
if (runqueue.curr->parent == NULL) {
return 0;
}
// Return the parent process identifer of the process.
return runqueue.curr->parent->pid;
if (runqueue.curr && runqueue.curr->parent)
return runqueue.curr->parent->pid;
return -EPERM;
}
int sys_nice(int increment)
+1 -1
View File
@@ -457,7 +457,7 @@ int do_signal(struct pt_regs *f)
case SIGTSTP:
case SIGTTIN:
case SIGTTOU:
if (is_orphaned_pgrp(current->gid))
if (is_orphaned_pgrp(current->pgid))
continue;
case SIGSTOP:
+6 -2
View File
@@ -63,8 +63,12 @@ void syscall_init()
sys_call_table[__NR_getpid] = (SystemCall)sys_getpid;
sys_call_table[__NR_getsid] = (SystemCall)sys_getsid;
sys_call_table[__NR_setsid] = (SystemCall)sys_setsid;
sys_call_table[__NR_getgid] =(SystemCall)sys_getgid;
sys_call_table[__NR_setgid] =(SystemCall)sys_setgid;
sys_call_table[__NR_getpgid] = (SystemCall)sys_getpgid;
sys_call_table[__NR_setpgid] = (SystemCall)sys_setpgid;
sys_call_table[__NR_getuid] = (SystemCall)sys_getuid;
sys_call_table[__NR_setuid] = (SystemCall)sys_setuid;
sys_call_table[__NR_getgid] = (SystemCall)sys_getgid;
sys_call_table[__NR_setgid] = (SystemCall)sys_setgid;
sys_call_table[__NR_getppid] = (SystemCall)sys_getppid;
sys_call_table[__NR_sigaction] = (SystemCall)sys_sigaction;
sys_call_table[__NR_fork] = (SystemCall)sys_fork;