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:
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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");
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user