diff --git a/kernel/sys/process.c b/kernel/sys/process.c index c8fdbf72..3763d157 100644 --- a/kernel/sys/process.c +++ b/kernel/sys/process.c @@ -220,6 +220,10 @@ process_t * spawn_process(volatile process_t * parent) { proc->name = default_name; /* Use the default name */ proc->description = NULL; /* No description */ + /* Copy permissions */ + proc->user = parent->user; + proc->group = parent->group; + /* Zero out the ESP/EBP/EIP */ proc->thread.esp = 0; proc->thread.ebp = 0; diff --git a/kernel/sys/syscall.c b/kernel/sys/syscall.c index 40257336..8ac8ca44 100644 --- a/kernel/sys/syscall.c +++ b/kernel/sys/syscall.c @@ -238,7 +238,7 @@ static int getuid() { } static int setuid(user_t new_uid) { - if (current_process->user != USER_ROOT_UID) { + if (current_process->user == USER_ROOT_UID) { current_process->user = new_uid; return 0; } @@ -261,6 +261,23 @@ static int kernel_name_XXX(char * buffer) { __kernel_arch); } +static int reboot() { + kprintf("[kernel] Reboot requested from process %d by user #%d\n", current_process->id, current_process->user); + kprintf("[kernel] Good bye!\n"); + if (current_process->user != 0) { + return -1; + } else { + /* Goodbye, cruel world */ + uint8_t out = 0x02; + while ((out & 0x02) != 0) { + out = inportb(0x64); + } + outportb(0x64, 0xFE); /* Reset */ + STOP; + } + return 0; +} + /* * System Call Internals */ @@ -293,6 +310,7 @@ static uintptr_t syscalls[] = { (uintptr_t)&getuid, (uintptr_t)&setuid, /* 24 */ (uintptr_t)&kernel_name_XXX, + (uintptr_t)&reboot, 0 }; uint32_t num_syscalls; diff --git a/userspace/reboot.c b/userspace/reboot.c new file mode 100644 index 00000000..33680222 --- /dev/null +++ b/userspace/reboot.c @@ -0,0 +1,13 @@ +#include +#include + +DEFN_SYSCALL0(getuid, 23); +DEFN_SYSCALL0(reboot, 26); + +int main(int argc, char ** argv) { + printf("uid is %d\n", syscall_getuid()); + if (syscall_reboot() < 0) { + printf("%s: need to be root.\n", argv[0]); + } + return 1; +}