X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fsyscalls.c;h=5774dbe57e84e09b48eb2da380fc7430b458b31e;hb=d1f16adf5f2e94e836ea6658186a6ff6d94f54d8;hp=f1e08904ecfedac944a2c08c2a2fca58ddb86d3f;hpb=220826af27a1f78cab0f36119f717dfc0bf8cb99;p=tpg%2Facess2.git diff --git a/Kernel/syscalls.c b/Kernel/syscalls.c index f1e08904..5774dbe5 100644 --- a/Kernel/syscalls.c +++ b/Kernel/syscalls.c @@ -17,13 +17,20 @@ extern int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer); extern int Proc_Execve(char *File, char **ArgV, char **EnvP); extern Uint Binary_Load(char *file, Uint *entryPoint); extern int VFS_FInfo(int FD, void *Dest, int MaxACLs); +extern int VFS_GetACL(int FD, void *Dest); +extern int VFS_ChDir(char *Dest); extern int Threads_SetName(char *NewName); extern int Threads_GetPID(); extern int Threads_GetTID(); extern int Threads_GetUID(); extern int Threads_GetGID(); +// === PROTOTYPES === + int Syscall_ValidString(Uint Addr); + int Syscall_Valid(int Size, Uint Addr); + // === CODE === +// TODO: Do sanity checking on arguments, ATM the user can really fuck with the kernel void SyscallHandler(tSyscallRegs *Regs) { Uint64 ret = 0; @@ -34,10 +41,11 @@ void SyscallHandler(tSyscallRegs *Regs) LOG("Syscall %s", cSYSCALL_NAMES[Regs->Num]); LOG("Arg1: 0x%x, Arg2: 0x%x, Arg3: 0x%x", Regs->Arg1, Regs->Arg2, Regs->Arg3); #endif + switch(Regs->Num) { // -- Exit the current thread - case SYS_EXIT: Threads_Exit(); break; + case SYS_EXIT: Threads_Exit(0, Regs->Arg1); break; // -- Put the current thread to sleep case SYS_SLEEP: Threads_Sleep(); break; @@ -49,7 +57,7 @@ void SyscallHandler(tSyscallRegs *Regs) case SYS_CLONE: // Call clone system call ret = Proc_Clone(&err, Regs->Arg1); - // Change user stack if requested + // Change user stack if a new stack address is passed if(ret == 0 && Regs->Arg2) Regs->StackPointer = Regs->Arg2; break; @@ -87,6 +95,10 @@ void SyscallHandler(tSyscallRegs *Regs) case SYS_GETUID: ret = Threads_GetUID(); break; case SYS_GETGID: ret = Threads_GetGID(); break; + // -- Set User/Group IDs + case SYS_SETUID: Log("Setting User ID to %i", Regs->Arg1); break; + case SYS_SETGID: Log("Setting Group ID to %i", Regs->Arg1); break; + // -- Send Message case SYS_SENDMSG: ret = Proc_SendMessage(&err, Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3); @@ -107,9 +119,20 @@ void SyscallHandler(tSyscallRegs *Regs) // Binary Control // --- case SYS_EXECVE: + if( !Syscall_ValidString(Regs->Arg1) ) { + err = -EINVAL; + ret = -1; + break; + } ret = Proc_Execve((char*)Regs->Arg1, (char**)Regs->Arg2, (char**)Regs->Arg3); break; case SYS_LOADBIN: + if( !Syscall_ValidString(Regs->Arg1) + || !Syscall_Valid(sizeof(Uint), Regs->Arg2) ) { + err = -EINVAL; + ret = -1; + break; + } ret = Binary_Load((char*)Regs->Arg1, (Uint*)Regs->Arg2); break; @@ -117,6 +140,11 @@ void SyscallHandler(tSyscallRegs *Regs) // Virtual Filesystem // --- case SYS_OPEN: + if( !Syscall_ValidString(Regs->Arg1) ) { + err = -EINVAL; + ret = -1; + break; + } ret = VFS_Open((char*)Regs->Arg1, Regs->Arg2 | VFS_OPENFLAG_USER); break; @@ -126,28 +154,54 @@ void SyscallHandler(tSyscallRegs *Regs) case SYS_WRITE: #if BITS < 64 - VFS_Write( Regs->Arg1, Regs->Arg2|((Uint64)Regs->Arg3<<32), (void*)Regs->Arg4 ); + ret = VFS_Write( Regs->Arg1, Regs->Arg2|((Uint64)Regs->Arg3<<32), (void*)Regs->Arg4 ); #else - VFS_Write( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 ); + ret = VFS_Write( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 ); #endif break; case SYS_READ: #if BITS < 64 - VFS_Read( Regs->Arg1, Regs->Arg2|((Uint64)Regs->Arg3<<32), (void*)Regs->Arg4 ); + ret = VFS_Read( Regs->Arg1, Regs->Arg2|((Uint64)Regs->Arg3<<32), (void*)Regs->Arg4 ); #else - VFS_Read( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 ); + ret = VFS_Read( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 ); #endif break; case SYS_FINFO: ret = VFS_FInfo( Regs->Arg1, (void*)Regs->Arg2, Regs->Arg3 ); break; - + + // Get ACL Value + case SYS_GETACL: + if( !Syscall_Valid(8, Regs->Arg1) ) { + err = -EINVAL; + ret = -1; + break; + } + ret = VFS_GetACL( Regs->Arg1, (void*)Regs->Arg2 ); + break; + + // Read Directory case SYS_READDIR: + if( !Syscall_ValidString(Regs->Arg2) ) { + err = -EINVAL; + ret = -1; + break; + } ret = VFS_ReadDir( Regs->Arg1, (void*)Regs->Arg2 ); break; + // Change Directory + case SYS_CHDIR: + if( !Syscall_ValidString(Regs->Arg1) ) { + err = -EINVAL; + ret = -1; + break; + } + ret = VFS_ChDir( (void*)Regs->Arg1 ); + break; + // -- Debug case SYS_DEBUG: Log((char*)Regs->Arg1, @@ -176,3 +230,36 @@ void SyscallHandler(tSyscallRegs *Regs) #endif } +/** + * \fn int Syscall_ValidString(Uint Addr) + * \brief Checks if a memory address contains a valid string + */ +int Syscall_ValidString(Uint Addr) +{ + // Check 1st page + if(!MM_GetPhysAddr(Addr)) return 0; + + // Traverse String + while(*(char*)Addr) + { + if(!MM_GetPhysAddr(Addr)) return 0; + // Increment string pointer + Addr ++; + } + + return 1; +} + +/** + * \fn int Syscall_Valid(int Size, Uint Addr) + * \brief Checks if a memory address is valid + */ +int Syscall_Valid(int Size, Uint Addr) +{ + while(Size--) + { + if(!MM_GetPhysAddr(Addr)) return 0; + Addr ++; + } + return 1; +}