Fix sleep syscall

This commit is contained in:
Alex 2023-06-11 01:36:39 +03:00
parent f552b8f6f0
commit 85c0de688d
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
14 changed files with 829 additions and 673 deletions

View File

@ -31,16 +31,17 @@ extern "C" void SystemCallHandlerStub();
extern "C" __naked __used __no_stack_protector __aligned(16) void SystemCallHandlerStub() extern "C" __naked __used __no_stack_protector __aligned(16) void SystemCallHandlerStub()
{ {
asmv("swapgs\n"); /* Swap GS to get the CPUData */ asmv("swapgs\n"); /* Swap GS to get the TCB */
asmv("mov %rsp, %gs:0x8\n"); /* We save the current rsp to CPUData->TempStack */ asmv("mov %rsp, %gs:0x8\n"); /* We save the current rsp to TCB->TempStack */
asmv("mov %gs:0x0, %rsp\n"); /* Get CPUData->SystemCallStack and set it as rsp */ asmv("mov %gs:0x0, %rsp\n"); /* Get TCB->SystemCallStack and set it as rsp */
asmv("push $0x1b\n"); /* Push user data segment for SyscallsFrame */ asmv("push $0x1b\n"); /* Push user data segment for SyscallsFrame */
asmv("push %gs:0x8\n"); /* Push CPUData->TempStack (old rsp) for SyscallsFrame */ asmv("push %gs:0x8\n"); /* Push TCB->TempStack (old rsp) for SyscallsFrame */
asmv("push %r11\n"); /* Push the flags for SyscallsFrame */ asmv("push %r11\n"); /* Push the flags for SyscallsFrame */
asmv("push $0x23\n"); /* Push user code segment for SyscallsFrame */ asmv("push $0x23\n"); /* Push user code segment for SyscallsFrame */
asmv("push %rcx\n"); /* Push the return address for SyscallsFrame + sysretq (https://www.felixcloutier.com/x86/sysret) */ asmv("push %rcx\n"); /* Push the return address for SyscallsFrame + sysretq (https://www.felixcloutier.com/x86/sysret) */
asmv("push %rax\n" /* Push registers */ /* Push registers */
asmv("push %rax\n"
"push %rbx\n" "push %rbx\n"
"push %rcx\n" "push %rcx\n"
"push %rdx\n" "push %rdx\n"
@ -56,11 +57,13 @@ extern "C" __naked __used __no_stack_protector __aligned(16) void SystemCallHand
"push %r14\n" "push %r14\n"
"push %r15\n"); "push %r15\n");
asmv("mov %rsp, %rdi\n"); /* Set the first argument to the SyscallsFrame pointer */ /* Set the first argument to the SyscallsFrame pointer */
asmv("mov %rsp, %rdi\n");
asmv("mov $0, %rbp\n"); asmv("mov $0, %rbp\n");
asmv("call SystemCallsHandler\n"); asmv("call SystemCallsHandler\n");
asmv("pop %r15\n" /* Pop registers except rax */ /* Pop registers except rax */
asmv("pop %r15\n"
"pop %r14\n" "pop %r14\n"
"pop %r13\n" "pop %r13\n"
"pop %r12\n" "pop %r12\n"
@ -75,14 +78,16 @@ extern "C" __naked __used __no_stack_protector __aligned(16) void SystemCallHand
"pop %rcx\n" "pop %rcx\n"
"pop %rbx\n"); "pop %rbx\n");
asmv("mov %gs:0x8, %rsp\n"); // Restore rsp from CPUData->TempStack /* Restore rsp from TCB->TempStack */
asmv("mov %gs:0x8, %rsp\n");
#ifdef DEBUG #ifdef DEBUG
asmv("movq $0, %gs:0x8\n"); // Easier to debug stacks // FIXME: Can't use xor /* Easier to debug stacks */
asmv("movq $0, %gs:0x8\n");
#endif #endif
asmv("swapgs\n"); // Swap GS back to the user GS asmv("swapgs\n"); /* Swap GS back to the user GS */
asmv("sti\n"); // Enable interrupts asmv("sti\n"); /* Enable interrupts */
asmv("sysretq\n"); // Return to rcx address in user mode asmv("sysretq\n"); /* Return to rcx address in user mode */
} }
void InitializeSystemCalls() void InitializeSystemCalls()

View File

@ -52,7 +52,6 @@ namespace CrashHandler
if (cpu) if (cpu)
{ {
EHPrint("\eE46CEBCPU Data Address: %#lx\n", cpu); EHPrint("\eE46CEBCPU Data Address: %#lx\n", cpu);
EHPrint("Syscalls Stack: %#lx, TempStack: %#lx\n", cpu->SystemCallStack, cpu->TempStack);
EHPrint("Core Stack: %#lx, Core ID: %ld, Error Code: %ld\n", cpu->Stack, cpu->ID, cpu->ErrorCode); EHPrint("Core Stack: %#lx, Core ID: %ld, Error Code: %ld\n", cpu->Stack, cpu->ID, cpu->ErrorCode);
EHPrint("Is Active: %s\n", cpu->IsActive ? "true" : "false"); EHPrint("Is Active: %s\n", cpu->IsActive ? "true" : "false");
EHPrint("Current Process: %#lx, Current Thread: %#lx\n", cpu->CurrentProcess, cpu->CurrentThread); EHPrint("Current Process: %#lx, Current Thread: %#lx\n", cpu->CurrentProcess, cpu->CurrentThread);

View File

@ -67,7 +67,6 @@ namespace Interrupts
CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, (uint64_t)CoreData); CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
CoreData->ID = Core; CoreData->ID = Core;
CoreData->IsActive = true; CoreData->IsActive = true;
CoreData->SystemCallStack = (uint8_t *)((uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE);
CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE; CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE;
if (CoreData->Checksum != CPU_DATA_CHECKSUM) if (CoreData->Checksum != CPU_DATA_CHECKSUM)
{ {
@ -85,7 +84,6 @@ namespace Interrupts
CPU::x32::wrmsr(CPU::x32::MSR_SHADOW_GS_BASE, (uint64_t)CoreData); CPU::x32::wrmsr(CPU::x32::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
CoreData->ID = Core; CoreData->ID = Core;
CoreData->IsActive = true; CoreData->IsActive = true;
CoreData->SystemCallStack = (uint8_t *)((uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE);
CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE; CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE;
if (CoreData->Checksum != CPU_DATA_CHECKSUM) if (CoreData->Checksum != CPU_DATA_CHECKSUM)
{ {

View File

@ -60,6 +60,7 @@ namespace Memory
uint64_t MemMgr::GetAllocatedMemorySize() uint64_t MemMgr::GetAllocatedMemorySize()
{ {
SmartLock(MgrLock);
uint64_t Size = 0; uint64_t Size = 0;
foreach (auto ap in AllocatedPagesList) foreach (auto ap in AllocatedPagesList)
Size += ap.PageCount; Size += ap.PageCount;
@ -68,6 +69,7 @@ namespace Memory
bool MemMgr::Add(void *Address, size_t Count) bool MemMgr::Add(void *Address, size_t Count)
{ {
SmartLock(MgrLock);
if (Address == nullptr) if (Address == nullptr)
{ {
error("Address is null!"); error("Address is null!");
@ -124,6 +126,7 @@ namespace Memory
void *MemMgr::RequestPages(size_t Count, bool User) void *MemMgr::RequestPages(size_t Count, bool User)
{ {
SmartLock(MgrLock);
void *Address = KernelAllocator.RequestPages(Count); void *Address = KernelAllocator.RequestPages(Count);
for (size_t i = 0; i < Count; i++) for (size_t i = 0; i < Count; i++)
{ {
@ -162,6 +165,7 @@ namespace Memory
void MemMgr::FreePages(void *Address, size_t Count) void MemMgr::FreePages(void *Address, size_t Count)
{ {
SmartLock(MgrLock);
for (size_t i = 0; i < AllocatedPagesList.size(); i++) for (size_t i = 0; i < AllocatedPagesList.size(); i++)
{ {
if (AllocatedPagesList[i].Address == Address) if (AllocatedPagesList[i].Address == Address)
@ -205,6 +209,7 @@ namespace Memory
void MemMgr::DetachAddress(void *Address) void MemMgr::DetachAddress(void *Address)
{ {
SmartLock(MgrLock);
for (size_t i = 0; i < AllocatedPagesList.size(); i++) for (size_t i = 0; i < AllocatedPagesList.size(); i++)
{ {
if (AllocatedPagesList[i].Address == Address) if (AllocatedPagesList[i].Address == Address)
@ -226,6 +231,7 @@ namespace Memory
MemMgr::MemMgr(PageTable *Table, VirtualFileSystem::Node *Directory) MemMgr::MemMgr(PageTable *Table, VirtualFileSystem::Node *Directory)
{ {
SmartLock(MgrLock);
if (Table) if (Table)
this->Table = Table; this->Table = Table;
else else
@ -243,6 +249,7 @@ namespace Memory
MemMgr::~MemMgr() MemMgr::~MemMgr()
{ {
SmartLock(MgrLock);
foreach (auto ap in AllocatedPagesList) foreach (auto ap in AllocatedPagesList)
{ {
KernelAllocator.FreePages(ap.Address, ap.PageCount); KernelAllocator.FreePages(ap.Address, ap.PageCount);

View File

@ -60,22 +60,32 @@ EXTERNC __weak __noreturn __no_stack_protector void __stack_chk_fail(void)
debug("Current stack check guard value: %#lx", __stack_chk_guard); debug("Current stack check guard value: %#lx", __stack_chk_guard);
KPrint("\eFF0000Stack smashing detected!"); KPrint("\eFF0000Stack smashing detected!");
#if defined(a86)
void *Stack = nullptr; void *Stack = nullptr;
#if defined(a86)
#if defined(a64) #if defined(a64)
asmv("movq %%rsp, %0" asmv("movq %%rsp, %0"
: "=r"(Stack)); : "=r"(Stack));
#elif defined(a32) #elif defined(a32)
asmv("movl %%esp, %0" asmv("movl %%esp, %0"
: "=r"(Stack)); : "=r"(Stack));
#endif
#elif defined(aa64)
asmv("mov %%sp, %0"
: "=r"(Stack));
#endif #endif
error("Stack address: %#lx", Stack); error("Stack address: %#lx", Stack);
while (1) if (DebuggerIsAttached)
asmv("cli; hlt"); #ifdef a86
asmv("int $0x3");
#elif defined(aa64) #elif defined(aa64)
asmv("wfe"); asmv("brk #0");
#endif #endif
CPU::Stop(); CPU::Stop();
} }

View File

@ -497,21 +497,20 @@ void KernelMainThread()
TaskManager->WaitForThread(ret.Thread); TaskManager->WaitForThread(ret.Thread);
ExitCode = ret.Thread->GetExitCode(); ExitCode = ret.Thread->GetExitCode();
Exit: Exit:
if (ExitCode != 0) if (ExitCode == 0)
{
KPrint("\eE85230Userspace process exited with code %d (%#x)", ExitCode,
ExitCode < 0 ? ExitCode * -1 : ExitCode);
KPrint("Dropping to recovery screen...");
TaskManager->Sleep(2500);
TaskManager->WaitForThread(blaThread);
RecoveryScreen = new Recovery::KernelRecovery;
}
else
{ {
KPrint("\eFF7900%s process exited with code %d and it didn't invoked the shutdown function.", KPrint("\eFF7900%s process exited with code %d and it didn't invoked the shutdown function.",
Config.InitPath, ExitCode); Config.InitPath, ExitCode);
KPrint("System Halted"); KPrint("System Halted");
CPU::Halt(true);
} }
KPrint("\eE85230Userspace process exited with code %d (%#x)", ExitCode,
ExitCode < 0 ? -ExitCode : ExitCode);
KPrint("Dropping to recovery screen...");
TaskManager->Sleep(2500);
TaskManager->WaitForThread(blaThread);
RecoveryScreen = new Recovery::KernelRecovery;
CPU::Halt(true); CPU::Halt(true);
} }

View File

@ -16,105 +16,75 @@
*/ */
#include <syscalls.hpp> #include <syscalls.hpp>
#include <memory.hpp> #include <memory.hpp>
#include <lock.hpp> #include <lock.hpp>
#include <exec.hpp> #include <exec.hpp>
#include <errno.h> #include <errno.h>
#include <debug.h> #include <debug.h>
#include "../syscalls.h" #include "../syscalls.h"
#include "../kernel.h" #include "../kernel.h"
#include "../ipc.h" #include "../ipc.h"
#define SysFrm SyscallsFrame
using InterProcessCommunication::IPC; using InterProcessCommunication::IPC;
using InterProcessCommunication::IPCID; using InterProcessCommunication::IPCID;
using Tasking::Token; using Tasking::Token;
using Tasking::TTL; using Tasking::TTL;
using Tasking::TaskStatus::Ready;
using Tasking::TaskStatus::Terminated;
using Tasking::TTL::Trusted; using Tasking::TTL::Trusted;
using Tasking::TTL::TrustedByKernel; using Tasking::TTL::TrustedByKernel;
using Tasking::TTL::UnknownTrustLevel; using Tasking::TTL::UnknownTrustLevel;
using Tasking::TTL::Untrusted; using Tasking::TTL::Untrusted;
static inline bool CheckTrust(int TrustLevel) __noreturn static void sys_exit(SysFrm *, int code)
{ {
Token token = TaskManager->GetCurrentThread()->Security.UniqueToken; trace("Userspace thread %s(%d) exited with code %d (%#x)",
if (likely(TaskManager->GetSecurityManager()->IsTokenTrusted(token, TrustLevel))) TaskManager->GetCurrentThread()->Name,
return true; TaskManager->GetCurrentThread()->ID, code,
code < 0 ? -code : code);
warn("Thread %s(%lld) tried to access a system call \"%s\" with insufficient trust level",
TaskManager->GetCurrentThread()->Name, TaskManager->GetCurrentThread()->ID,
KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0))));
debug("token=%#lx, trust=%d", token, TaskManager->GetSecurityManager()->GetTokenTrustLevel(token));
return false;
}
static int sys_exit(SyscallsFrame *Frame, int code)
{
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted | UnknownTrustLevel))
return SYSCALL_ACCESS_DENIED;
trace("Userspace thread %s(%lld) exited with code %#llx", TaskManager->GetCurrentThread()->Name, TaskManager->GetCurrentThread()->ID, code);
TaskManager->GetCurrentThread()->ExitCode = code; TaskManager->GetCurrentThread()->ExitCode = code;
TaskManager->GetCurrentThread()->Status = Tasking::TaskStatus::Terminated; TaskManager->GetCurrentThread()->Status = Terminated;
TaskManager->Schedule(); TaskManager->Schedule();
__builtin_unreachable();
UNUSED(Frame);
return SYSCALL_OK;
} }
static int sys_print(SyscallsFrame *Frame, char Char, int Index) static int sys_print(SysFrm *, char Char, int Index)
{ {
if (!CheckTrust(TrustedByKernel | Trusted))
return SYSCALL_ACCESS_DENIED;
char ret = Display->Print(Char, Index, true); char ret = Display->Print(Char, Index, true);
if (!Config.BootAnimation && Index == 0) if (!Config.BootAnimation && Index == 0)
#ifdef DEBUG
Display->SetBuffer(Index); Display->SetBuffer(Index);
#else
if (Char == '\n')
Display->SetBuffer(Index);
#endif
UNUSED(Frame);
return ret; return ret;
} }
static uintptr_t sys_request_pages(SyscallsFrame *Frame, size_t Count) static uintptr_t sys_request_pages(SysFrm *, size_t Count)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) Memory::MemMgr *MemMgr = TaskManager->GetCurrentThread()->Memory;
return SYSCALL_ACCESS_DENIED; return (uintptr_t)MemMgr->RequestPages(Count + 1, true);
UNUSED(Frame);
return (uintptr_t)TaskManager->GetCurrentThread()->Memory->RequestPages(Count + 1, true);
} }
static int sys_free_pages(SyscallsFrame *Frame, uintptr_t Address, size_t Count) static int sys_free_pages(SysFrm *, uintptr_t Address, size_t Count)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) Memory::MemMgr *MemMgr = TaskManager->GetCurrentThread()->Memory;
return SYSCALL_ACCESS_DENIED; MemMgr->FreePages((void *)Address, Count + 1);
TaskManager->GetCurrentThread()->Memory->FreePages((void *)Address, Count + 1);
UNUSED(Frame);
return SYSCALL_OK; return SYSCALL_OK;
} }
static int sys_detach_address(SyscallsFrame *Frame, uintptr_t Address) static int sys_detach_address(SysFrm *, uintptr_t Address)
{ {
if (!CheckTrust(TrustedByKernel | Trusted)) Memory::MemMgr *MemMgr = TaskManager->GetCurrentThread()->Memory;
return SYSCALL_ACCESS_DENIED; MemMgr->DetachAddress((void *)Address);
TaskManager->GetCurrentThread()->Memory->DetachAddress((void *)Address);
UNUSED(Frame);
return SYSCALL_OK; return SYSCALL_OK;
} }
static int sys_memory_map(SyscallsFrame *Frame, uintptr_t VirtualAddress, uintptr_t PhysicalAddress, size_t Size, enum MemoryMapFlags Flags) static int sys_memory_map(SysFrm *, uintptr_t VirtualAddress,
uintptr_t PhysicalAddress, size_t Size,
enum MemoryMapFlags Flags)
{ {
if (!CheckTrust(TrustedByKernel))
return SYSCALL_ACCESS_DENIED;
if (Flags > 7) /* (MAP_PRESENT | MAP_WRITABLE | MAP_USER) */ if (Flags > 7) /* (MAP_PRESENT | MAP_WRITABLE | MAP_USER) */
return SYSCALL_INVALID_ARGUMENT; return SYSCALL_INVALID_ARGUMENT;
@ -126,15 +96,12 @@ static int sys_memory_map(SyscallsFrame *Frame, uintptr_t VirtualAddress, uintpt
Size, Flags); Size, Flags);
} }
UNUSED(Frame);
return SYSCALL_OK; return SYSCALL_OK;
} }
static int sys_memory_unmap(SyscallsFrame *Frame, uintptr_t VirtualAddress, size_t Size) static int sys_memory_unmap(SysFrm *, uintptr_t VirtualAddress,
size_t Size)
{ {
if (!CheckTrust(TrustedByKernel))
return SYSCALL_ACCESS_DENIED;
Memory::PageTable *PageTable = TaskManager->GetCurrentProcess()->PageTable; Memory::PageTable *PageTable = TaskManager->GetCurrentProcess()->PageTable;
{ {
Memory::Virtual vmm = Memory::Virtual(PageTable); Memory::Virtual vmm = Memory::Virtual(PageTable);
@ -142,19 +109,18 @@ static int sys_memory_unmap(SyscallsFrame *Frame, uintptr_t VirtualAddress, size
Size); Size);
} }
UNUSED(Frame);
return SYSCALL_OK; return SYSCALL_OK;
} }
static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4) static uintptr_t sys_kernelctl(SysFrm *,
enum KCtl Command,
uint64_t Arg1, uint64_t Arg2,
uint64_t Arg3, uint64_t Arg4)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED;
switch (Command) switch (Command)
{ {
case KCTL_GET_PID: case KCTL_GET_PID:
return TaskManager->GetCurrentThread()->Parent->ID; return TaskManager->GetCurrentProcess()->ID;
case KCTL_GET_TID: case KCTL_GET_TID:
return TaskManager->GetCurrentThread()->ID; return TaskManager->GetCurrentThread()->ID;
case KCTL_GET_PAGE_SIZE: case KCTL_GET_PAGE_SIZE:
@ -163,9 +129,6 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
return TaskManager->GetCurrentThread()->Security.IsCritical; return TaskManager->GetCurrentThread()->Security.IsCritical;
case KCTL_REGISTER_ELF_LIB: case KCTL_REGISTER_ELF_LIB:
{ {
if (!CheckTrust(TrustedByKernel | Trusted))
return SYSCALL_ACCESS_DENIED;
char *Identifier = (char *)Arg1; char *Identifier = (char *)Arg1;
const char *Path = (const char *)Arg2; const char *Path = (const char *)Arg2;
@ -175,7 +138,8 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
std::string FullPath = Path; std::string FullPath = Path;
int retries = 0; int retries = 0;
RetryReadPath: RetryReadPath:
debug("KCTL_REGISTER_ELF_LIB: Trying to open %s", FullPath.c_str()); debug("KCTL_REGISTER_ELF_LIB: Trying to open %s",
FullPath.c_str());
VirtualFileSystem::File f = vfs->Open(FullPath.c_str()); VirtualFileSystem::File f = vfs->Open(FullPath.c_str());
if (!f.IsOK()) if (!f.IsOK())
@ -194,7 +158,8 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
break; break;
case 3: case 3:
{ {
VirtualFileSystem::Node *cwd = TaskManager->GetCurrentProcess()->CurrentWorkingDirectory; VirtualFileSystem::Node *cwd =
TaskManager->GetCurrentProcess()->CurrentWorkingDirectory;
FullPath = vfs->GetPathFromNode(cwd).get(); FullPath = vfs->GetPathFromNode(cwd).get();
break; break;
} }
@ -223,9 +188,6 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
} }
case KCTL_GET_ELF_LIB_MEMORY_IMAGE: case KCTL_GET_ELF_LIB_MEMORY_IMAGE:
{ {
if (!CheckTrust(TrustedByKernel | Trusted))
return SYSCALL_ACCESS_DENIED;
char *Identifier = (char *)Arg1; char *Identifier = (char *)Arg1;
if (!Identifier) if (!Identifier)
return 0; return 0;
@ -234,17 +196,16 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
if (!lib.MemoryImage) if (!lib.MemoryImage)
{ {
debug("Failed to get library memory image %#lx", (uintptr_t)lib.MemoryImage); debug("Failed to get library memory image %#lx",
(uintptr_t)lib.MemoryImage);
} }
debug("Returning memory image %#lx (%s)", (uintptr_t)lib.MemoryImage, Identifier); debug("Returning memory image %#lx (%s)",
(uintptr_t)lib.MemoryImage, Identifier);
return (uintptr_t)lib.MemoryImage; return (uintptr_t)lib.MemoryImage;
} }
case KCTL_GET_ABSOLUTE_PATH: case KCTL_GET_ABSOLUTE_PATH:
{ {
if (!CheckTrust(TrustedByKernel | Trusted))
return SYSCALL_ACCESS_DENIED;
char *Identifier = (char *)Arg1; char *Identifier = (char *)Arg1;
void *Buffer = (void *)Arg2; void *Buffer = (void *)Arg2;
size_t BufferSize = Arg3; size_t BufferSize = Arg3;
@ -274,15 +235,11 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
UNUSED(Arg2); UNUSED(Arg2);
UNUSED(Arg3); UNUSED(Arg3);
UNUSED(Arg4); UNUSED(Arg4);
UNUSED(Frame);
} }
static uint64_t sys_file_open(SyscallsFrame *Frame, const char *Path, uint64_t Flags) static uint64_t sys_file_open(SysFrm *, const char *Path, uint64_t Flags)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) function("%s, %#lx", Path, Flags);
return SYSCALL_ACCESS_DENIED;
debug("(Path: %s, Flags: %#lx)", Path, Flags);
VirtualFileSystem::Node *cwd = nullptr; VirtualFileSystem::Node *cwd = nullptr;
if (vfs->PathIsRelative(Path)) if (vfs->PathIsRelative(Path))
cwd = TaskManager->GetCurrentProcess()->CurrentWorkingDirectory; cwd = TaskManager->GetCurrentProcess()->CurrentWorkingDirectory;
@ -297,118 +254,111 @@ static uint64_t sys_file_open(SyscallsFrame *Frame, const char *Path, uint64_t F
return SYSCALL_INTERNAL_ERROR; return SYSCALL_INTERNAL_ERROR;
} }
VirtualFileSystem::File *KernelPrivate = (VirtualFileSystem::File *)TaskManager->GetCurrentThread()->Memory->RequestPages(TO_PAGES(sizeof(VirtualFileSystem::File))); Memory::MemMgr *MemMgr = TaskManager->GetCurrentThread()->Memory;
constexpr size_t FileStructPages =
TO_PAGES(sizeof(VirtualFileSystem::File));
VirtualFileSystem::File *KernelPrivate =
(VirtualFileSystem::File *)MemMgr->RequestPages(FileStructPages);
*KernelPrivate = KPObj; *KernelPrivate = KPObj;
debug("Opened file %s (%d)", KPObj.Name, KPObj.Status); debug("Opened file %s (%d)", KPObj.Name, KPObj.Status);
return (uint64_t)KernelPrivate; return (uint64_t)KernelPrivate;
UNUSED(Frame);
UNUSED(Flags); UNUSED(Flags);
} }
static int sys_file_close(SyscallsFrame *Frame, void *KernelPrivate) static int sys_file_close(SysFrm *, void *KernelPrivate)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) function("%#lx", KernelPrivate);
return SYSCALL_ACCESS_DENIED;
debug("(KernelPrivate: %#lx)", KernelPrivate);
if (KernelPrivate) if (KernelPrivate)
{ {
VirtualFileSystem::File KPObj = *(VirtualFileSystem::File *)KernelPrivate; VirtualFileSystem::File KPObj = *(VirtualFileSystem::File *)KernelPrivate;
debug("Closed file %s (%d)", KPObj.Name, KPObj.Status); debug("Closed file %s (%d)", KPObj.Name, KPObj.Status);
vfs->Close(KPObj); vfs->Close(KPObj);
TaskManager->GetCurrentThread()->Memory->FreePages(KernelPrivate, TO_PAGES(sizeof(VirtualFileSystem::File))); Memory::MemMgr *MemMgr = TaskManager->GetCurrentThread()->Memory;
MemMgr->FreePages(KernelPrivate,
TO_PAGES(sizeof(VirtualFileSystem::File)));
return SYSCALL_OK; return SYSCALL_OK;
} }
return SYSCALL_INVALID_ARGUMENT; return SYSCALL_INVALID_ARGUMENT;
UNUSED(Frame);
} }
static uint64_t sys_file_read(SyscallsFrame *Frame, void *KernelPrivate, uint8_t *Buffer, uint64_t Size) static uint64_t sys_file_read(SysFrm *, void *KernelPrivate,
uint8_t *Buffer, uint64_t Size)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED;
if (KernelPrivate == nullptr) if (KernelPrivate == nullptr)
return 0; return 0;
debug("(KernelPrivate: %#lx, Offset: %#lx, Buffer: %#lx, Size: %#lx)", KernelPrivate, Buffer, Size); debug("(KernelPrivate: %#lx, Offset: %#lx, Buffer: %#lx, Size: %#lx)",
return vfs->Read(*(VirtualFileSystem::File *)KernelPrivate, Buffer, (size_t)Size); KernelPrivate, Buffer, Size);
UNUSED(Frame);
}
static uint64_t sys_file_write(SyscallsFrame *Frame, void *KernelPrivate, uint8_t *Buffer, uint64_t Size)
{
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED;
if (KernelPrivate == nullptr)
return 0;
debug("(KernelPrivate: %#lx, Offset: %#lx, Buffer: %#lx, Size: %#lx)", KernelPrivate, Buffer, Size);
return vfs->Write(*(VirtualFileSystem::File *)KernelPrivate, Buffer, (size_t)Size);
UNUSED(Frame);
}
static off_t sys_file_seek(SyscallsFrame *Frame, void *KernelPrivate, off_t Offset, int Whence)
{
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED;
if (KernelPrivate == nullptr)
return 0;
debug("(KernelPrivate: %#lx, Offset: %#lx, Whence: %d)", KernelPrivate, Offset, Whence);
VirtualFileSystem::File *KPObj = (VirtualFileSystem::File *)KernelPrivate; VirtualFileSystem::File *KPObj = (VirtualFileSystem::File *)KernelPrivate;
return vfs->Read(*KPObj, Buffer, (size_t)Size);
}
static uint64_t sys_file_write(SysFrm *, void *KernelPrivate,
uint8_t *Buffer, uint64_t Size)
{
if (KernelPrivate == nullptr)
return 0;
debug("(KernelPrivate: %#lx, Offset: %#lx, Buffer: %#lx, Size: %#lx)",
KernelPrivate, Buffer, Size);
VirtualFileSystem::File *KPObj = (VirtualFileSystem::File *)KernelPrivate;
return vfs->Write(*KPObj, Buffer, (size_t)Size);
}
static off_t sys_file_seek(SysFrm *, void *KernelPrivate,
off_t Offset, int Whence)
{
if (KernelPrivate == nullptr)
return 0;
debug("(KernelPrivate: %#lx, Offset: %#lx, Whence: %d)",
KernelPrivate, Offset, Whence);
VirtualFileSystem::File *KPObj = (VirtualFileSystem::File *)KernelPrivate;
off_t ret = vfs->Seek(*KPObj, (off_t)Offset, (uint8_t)Whence); off_t ret = vfs->Seek(*KPObj, (off_t)Offset, (uint8_t)Whence);
debug("Seek %s %ld", KPObj->Name, ret); debug("Seek %s %ld", KPObj->Name, ret);
return ret; return ret;
UNUSED(Frame);
} }
static int sys_file_status(SyscallsFrame *Frame) static int sys_file_status(SysFrm *)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) stub;
return SYSCALL_ACCESS_DENIED;
fixme("sys_file_status: %#lx", Frame);
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_ipc(SyscallsFrame *Frame, enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size) static int sys_ipc(SysFrm *, enum IPCCommand Command,
enum IPCType Type, int ID, int Flags,
void *Buffer, size_t Size)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) InterProcessCommunication::IPC *ipc = TaskManager->GetCurrentProcess()->IPC;
return SYSCALL_ACCESS_DENIED; return ipc->HandleSyscall(Command, Type, ID, Flags, Buffer, Size);
UNUSED(Frame);
return TaskManager->GetCurrentProcess()->IPC->HandleSyscall(Command, Type, ID, Flags, Buffer, Size);
} }
static int sys_sleep(SyscallsFrame *Frame, uint64_t Milliseconds) static int sys_sleep(SysFrm *, uint64_t Milliseconds)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted)) TaskManager->Sleep(Milliseconds, true);
return SYSCALL_ACCESS_DENIED;
UNUSED(Frame);
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED;
TaskManager->Sleep(Milliseconds);
return 0; return 0;
} }
static int sys_fork(SyscallsFrame *Frame) static int sys_fork(SysFrm *Frame)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED;
Tasking::PCB *Parent = TaskManager->GetCurrentThread()->Parent; Tasking::PCB *Parent = TaskManager->GetCurrentThread()->Parent;
Tasking::TCB *Thread = TaskManager->GetCurrentThread(); Tasking::TCB *Thread = TaskManager->GetCurrentThread();
Tasking::PCB *NewProcess = TaskManager->CreateProcess(Parent, void *ProcSymTable = nullptr;
if (Parent->ELFSymbolTable)
ProcSymTable = Parent->ELFSymbolTable->GetImage();
Tasking::PCB *NewProcess =
TaskManager->CreateProcess(Parent,
Parent->Name, Parent->Name,
Parent->Security.TrustLevel, Parent->Security.TrustLevel,
Parent->ELFSymbolTable ? Parent->ELFSymbolTable->GetImage() : nullptr); ProcSymTable);
if (!NewProcess) if (!NewProcess)
{ {
@ -419,7 +369,8 @@ static int sys_fork(SyscallsFrame *Frame)
strncpy(NewProcess->Name, Parent->Name, sizeof(NewProcess->Name)); strncpy(NewProcess->Name, Parent->Name, sizeof(NewProcess->Name));
NewProcess->IPC->Fork(Parent->IPC); NewProcess->IPC->Fork(Parent->IPC);
Tasking::TCB *NewThread = TaskManager->CreateThread(NewProcess, Tasking::TCB *NewThread =
TaskManager->CreateThread(NewProcess,
0, 0,
nullptr, nullptr,
nullptr, nullptr,
@ -444,7 +395,9 @@ static int sys_fork(SyscallsFrame *Frame)
if (RetChild--) if (RetChild--)
{ {
/* We can't just return 0; because the CPUData->SystemCallStack is no longer valid */ /* We can't just return 0; because the
CPUData->SystemCallStack is no
longer valid */
asmv("movq %0, %%rcx\n" asmv("movq %0, %%rcx\n"
: :
: "r"(ReturnAddress)); : "r"(ReturnAddress));
@ -454,10 +407,10 @@ static int sys_fork(SyscallsFrame *Frame)
asmv("mov %0, %%rbp\n" asmv("mov %0, %%rbp\n"
: :
: "r"(ChildStackPointer)); : "r"(ChildStackPointer));
asmv("movq $0, %rax\n"); // Return 0 to the child asmv("movq $0, %rax\n"); /* Return 0 to the child */
asmv("swapgs\n"); // Swap GS back to the user GS asmv("swapgs\n"); /* Swap GS back to the user GS */
asmv("sti\n"); // Enable interrupts asmv("sti\n"); /* Enable interrupts */
asmv("sysretq\n"); // Return to rcx address in user mode asmv("sysretq\n"); /* Return to rcx address in user mode */
} }
RetChild = 1; RetChild = 1;
ReturnAddress = Frame->ReturnAddress; ReturnAddress = Frame->ReturnAddress;
@ -470,10 +423,12 @@ static int sys_fork(SyscallsFrame *Frame)
if (Thread->Security.IsCritical) if (Thread->Security.IsCritical)
NewThread->SetCritical(true); NewThread->SetCritical(true);
TaskManager->GetSecurityManager()->TrustToken(NewProcess->Security.UniqueToken,
(Tasking::TTL)TaskManager->GetSecurityManager()->GetTokenTrustLevel(Parent->Security.UniqueToken)); Tasking::Security *Sec = TaskManager->GetSecurityManager();
TaskManager->GetSecurityManager()->TrustToken(NewThread->Security.UniqueToken, Sec->TrustToken(NewProcess->Security.UniqueToken,
(Tasking::TTL)TaskManager->GetSecurityManager()->GetTokenTrustLevel(Thread->Security.UniqueToken)); (TTL)Sec->GetTokenTrustLevel(Parent->Security.UniqueToken));
Sec->TrustToken(NewThread->Security.UniqueToken,
(TTL)Sec->GetTokenTrustLevel(Thread->Security.UniqueToken));
#ifdef a86 #ifdef a86
NewThread->ShadowGSBase = Thread->ShadowGSBase; NewThread->ShadowGSBase = Thread->ShadowGSBase;
@ -482,180 +437,358 @@ static int sys_fork(SyscallsFrame *Frame)
#endif #endif
debug("Forked thread \"%s\"(%d) to \"%s\"(%d)", Thread->Name, Thread->ID, NewThread->Name, NewThread->ID); debug("Forked thread \"%s\"(%d) to \"%s\"(%d)", Thread->Name, Thread->ID, NewThread->Name, NewThread->ID);
NewThread->Status = Tasking::TaskStatus::Ready; NewThread->Status = Ready;
return (int)NewThread->ID; return (int)NewThread->ID;
UNUSED(Frame);
} }
static int sys_wait(SyscallsFrame *Frame) static int sys_wait(SysFrm *)
{ {
fixme("sys_wait: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_kill(SyscallsFrame *Frame) static int sys_kill(SysFrm *)
{ {
fixme("sys_kill: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_spawn(SyscallsFrame *Frame) static int sys_spawn(SysFrm *)
{ {
fixme("sys_spawn: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_spawn_thread(SyscallsFrame *Frame, uint64_t InstructionPointer) static int sys_spawn_thread(SysFrm *, uint64_t InstructionPointer)
{ {
Tasking::TCB *thread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)InstructionPointer); Tasking::TCB *thread =
TaskManager->CreateThread(TaskManager->GetCurrentProcess(),
(Tasking::IP)InstructionPointer);
if (thread) if (thread)
return (int)thread->ID; return (int)thread->ID;
return SYSCALL_ERROR; return SYSCALL_ERROR;
} }
static int sys_get_thread_list_of_process(SyscallsFrame *Frame) static int sys_get_thread_list_of_process(SysFrm *)
{ {
fixme("sys_get_thread_list_of_process: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_get_current_process(SyscallsFrame *Frame) static int sys_get_current_process(SysFrm *)
{ {
fixme("sys_get_current_process: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_get_current_thread(SyscallsFrame *Frame) static int sys_get_current_thread(SysFrm *)
{ {
fixme("sys_get_current_thread: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_get_current_process_id(SyscallsFrame *Frame) static int sys_get_current_process_id(SysFrm *)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED;
return (int)TaskManager->GetCurrentProcess()->ID; return (int)TaskManager->GetCurrentProcess()->ID;
} }
static int sys_get_current_thread_id(SyscallsFrame *Frame) static int sys_get_current_thread_id(SysFrm *)
{ {
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
return SYSCALL_ACCESS_DENIED;
return (int)TaskManager->GetCurrentThread()->ID; return (int)TaskManager->GetCurrentThread()->ID;
} }
static int sys_get_process_by_pid(SyscallsFrame *Frame) static int sys_get_process_by_pid(SysFrm *)
{ {
fixme("sys_get_process_by_pid: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_get_thread_by_tid(SyscallsFrame *Frame) static int sys_get_thread_by_tid(SysFrm *)
{ {
fixme("sys_get_thread_by_tid: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_kill_process(SyscallsFrame *Frame) static int sys_kill_process(SysFrm *)
{ {
fixme("sys_kill_process: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_kill_thread(SyscallsFrame *Frame) static int sys_kill_thread(SysFrm *)
{ {
fixme("sys_kill_thread: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_sys_reserved_create_process(SyscallsFrame *Frame) static int sys_sys_reserved_create_process(SysFrm *)
{ {
fixme("sys_sys_reserved_create_process: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static int sys_sys_reserved_create_thread(SyscallsFrame *Frame) static int sys_sys_reserved_create_thread(SysFrm *)
{ {
fixme("sys_sys_reserved_create_thread: %#lx", Frame); stub;
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
static void *NativeSyscallsTable[_MaxSyscall] = { struct SyscallData
[_Exit] = (void *)sys_exit, {
[_Print] = (void *)sys_print, const char *Name;
void *Handler;
[_RequestPages] = (void *)sys_request_pages, int TrustLevel;
[_FreePages] = (void *)sys_free_pages,
[_DetachAddress] = (void *)sys_detach_address,
[_MemoryMap] = (void *)sys_memory_map,
[_MemoryUnmap] = (void *)sys_memory_unmap,
[_KernelCTL] = (void *)sys_kernelctl,
[_FileOpen] = (void *)sys_file_open,
[_FileClose] = (void *)sys_file_close,
[_FileRead] = (void *)sys_file_read,
[_FileWrite] = (void *)sys_file_write,
[_FileSeek] = (void *)sys_file_seek,
[_FileStatus] = (void *)sys_file_status,
[_IPC] = (void *)sys_ipc,
[_Sleep] = (void *)sys_sleep,
[_Fork] = (void *)sys_fork,
[_Wait] = (void *)sys_wait,
[_Kill] = (void *)sys_kill,
[_Spawn] = (void *)sys_spawn,
[_SpawnThread] = (void *)sys_spawn_thread,
[_GetThreadListOfProcess] = (void *)sys_get_thread_list_of_process,
[_GetCurrentProcess] = (void *)sys_get_current_process,
[_GetCurrentThread] = (void *)sys_get_current_thread,
[_GetCurrentProcessID] = (void *)sys_get_current_process_id,
[_GetCurrentThreadID] = (void *)sys_get_current_thread_id,
[_GetProcessByPID] = (void *)sys_get_process_by_pid,
[_GetThreadByTID] = (void *)sys_get_thread_by_tid,
[_KillProcess] = (void *)sys_kill_process,
[_KillThread] = (void *)sys_kill_thread,
[_SysReservedCreateProcess] = (void *)sys_sys_reserved_create_process,
[_SysReservedCreateThread] = (void *)sys_sys_reserved_create_thread,
}; };
uintptr_t HandleNativeSyscalls(SyscallsFrame *Frame) static SyscallData NativeSyscallsTable[_MaxSyscall] = {
/**
*
* Basic syscalls
*
*/
[_Exit] = {
"Exit",
(void *)sys_exit,
TrustedByKernel | Trusted | Untrusted | UnknownTrustLevel,
},
[_Print] = {
"Print",
(void *)sys_print,
TrustedByKernel | Trusted,
},
/**
*
* Memory syscalls
*
*/
[_RequestPages] = {
"RequestPages",
(void *)sys_request_pages,
TrustedByKernel | Trusted | Untrusted,
},
[_FreePages] = {
"FreePages",
(void *)sys_free_pages,
TrustedByKernel | Trusted | Untrusted,
},
[_DetachAddress] = {
"DetachAddress",
(void *)sys_detach_address,
TrustedByKernel | Trusted,
},
[_MemoryMap] = {
"MemoryMap",
(void *)sys_memory_map,
TrustedByKernel,
},
[_MemoryUnmap] = {
"MemoryUnmap",
(void *)sys_memory_unmap,
TrustedByKernel,
},
/**
*
* Kernel Control syscalls
*
*/
[_KernelCTL] = {
"KernelCTL",
(void *)sys_kernelctl,
TrustedByKernel | Trusted | Untrusted,
},
/**
*
* File syscalls
*
*/
[_FileOpen] = {
"FileOpen",
(void *)sys_file_open,
TrustedByKernel | Trusted | Untrusted,
},
[_FileClose] = {
"FileClose",
(void *)sys_file_close,
TrustedByKernel | Trusted | Untrusted,
},
[_FileRead] = {
"FileRead",
(void *)sys_file_read,
TrustedByKernel | Trusted | Untrusted,
},
[_FileWrite] = {
"FileWrite",
(void *)sys_file_write,
TrustedByKernel | Trusted | Untrusted,
},
[_FileSeek] = {
"FileSeek",
(void *)sys_file_seek,
TrustedByKernel | Trusted | Untrusted,
},
[_FileStatus] = {
"FileStatus",
(void *)sys_file_status,
TrustedByKernel | Trusted | Untrusted,
},
/**
*
* Process syscalls
*
*/
[_IPC] = {
"IPC",
(void *)sys_ipc,
TrustedByKernel | Trusted | Untrusted,
},
[_Sleep] = {
"Sleep",
(void *)sys_sleep,
TrustedByKernel | Trusted | Untrusted,
},
[_Fork] = {
"Fork",
(void *)sys_fork,
TrustedByKernel | Trusted | Untrusted,
},
[_Wait] = {
"Wait",
(void *)sys_wait,
0,
},
[_Kill] = {
"Kill",
(void *)sys_kill,
0,
},
[_Spawn] = {
"Spawn",
(void *)sys_spawn,
0,
},
[_SpawnThread] = {
"SpawnThread",
(void *)sys_spawn_thread,
0,
},
[_GetThreadListOfProcess] = {
"GetThreadListOfProcess",
(void *)sys_get_thread_list_of_process,
0,
},
[_GetCurrentProcess] = {
"GetCurrentProcess",
(void *)sys_get_current_process,
0,
},
[_GetCurrentThread] = {
"GetCurrentThread",
(void *)sys_get_current_thread,
0,
},
[_GetCurrentProcessID] = {
"GetCurrentProcessID",
(void *)sys_get_current_process_id,
TrustedByKernel | Trusted | Untrusted,
},
[_GetCurrentThreadID] = {
"GetCurrentThreadID",
(void *)sys_get_current_thread_id,
TrustedByKernel | Trusted | Untrusted,
},
[_GetProcessByPID] = {
"GetProcessByPID",
(void *)sys_get_process_by_pid,
0,
},
[_GetThreadByTID] = {
"GetThreadByTID",
(void *)sys_get_thread_by_tid,
0,
},
[_KillProcess] = {
"KillProcess",
(void *)sys_kill_process,
0,
},
[_KillThread] = {
"KillThread",
(void *)sys_kill_thread,
0,
},
[_SysReservedCreateProcess] = {
"SysReservedCreateProcess",
(void *)sys_sys_reserved_create_process,
0,
},
[_SysReservedCreateThread] = {
"SysReservedCreateThread",
(void *)sys_sys_reserved_create_thread,
0,
},
};
uintptr_t HandleNativeSyscalls(SysFrm *Frame)
{ {
#if defined(a64) #if defined(a64)
if (Frame->rax > sizeof(NativeSyscallsTable)) if (unlikely(Frame->rax > _MaxSyscall))
{ {
fixme("Syscall %ld not implemented", Frame->rax); fixme("Syscall %ld not implemented.", Frame->rax);
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
} }
uintptr_t (*call)(uintptr_t, ...) = reinterpret_cast<uintptr_t (*)(uintptr_t, ...)>(NativeSyscallsTable[Frame->rax]); SyscallData Syscall = NativeSyscallsTable[Frame->rax];
if (!call)
uintptr_t (*call)(SysFrm *, uintptr_t, ...) =
r_cst(uintptr_t(*)(SysFrm *, uintptr_t, ...),
Syscall.Handler);
if (unlikely(!call))
{ {
error("Syscall %#lx failed.", Frame->rax); error("Syscall %#lx not implemented.", Frame->rax);
return SYSCALL_INTERNAL_ERROR; return SYSCALL_NOT_IMPLEMENTED;
} }
debug("[%#lx]->( %#lx %#lx %#lx %#lx %#lx %#lx )", Token token = TaskManager->GetCurrentThread()->Security.UniqueToken;
Frame->rax, Tasking::Security *Sec = TaskManager->GetSecurityManager();
Frame->rdi, Frame->rsi, Frame->rdx, Frame->rcx, Frame->r8, Frame->r9); if (unlikely(!Sec->IsTokenTrusted(token, Syscall.TrustLevel)))
{
warn("Thread %s(%d) tried to access a system call \"%s\" with insufficient trust level",
TaskManager->GetCurrentThread()->Name,
TaskManager->GetCurrentThread()->ID,
Syscall.Name);
uintptr_t ret = call((uintptr_t)Frame, Frame->rdi, Frame->rsi, Frame->rdx, Frame->r10, Frame->r8, Frame->r9); #ifdef DEBUG
Frame->rax = ret; int TknTl = Sec->GetTokenTrustLevel(token);
return ret; debug("token=%#lx, trust=%d%d%d%d",token,
TknTl & TrustedByKernel ? 1 : 0,
TknTl & Trusted ? 1 : 0,
TknTl & Untrusted ? 1 : 0,
TknTl & UnknownTrustLevel ? 1 : 0);
#endif
return SYSCALL_ACCESS_DENIED;
}
debug("[%d:\"%s\"]->( %#lx %#lx %#lx %#lx %#lx %#lx )",
Frame->rax, Syscall.Name,
Frame->rdi, Frame->rsi, Frame->rdx,
Frame->r10, Frame->r8, Frame->r9);
return call(Frame,
Frame->rdi, Frame->rsi, Frame->rdx,
Frame->r10, Frame->r8, Frame->r9);
#elif defined(a32) #elif defined(a32)
if (Frame->eax > sizeof(NativeSyscallsTable))
{
fixme("Syscall %ld not implemented", Frame->eax);
return SYSCALL_NOT_IMPLEMENTED; return SYSCALL_NOT_IMPLEMENTED;
}
/* ... */
return SYSCALL_INTERNAL_ERROR;
#elif defined(aa64) #elif defined(aa64)
return SYSCALL_INTERNAL_ERROR; return SYSCALL_NOT_IMPLEMENTED;
#endif #endif
} }

View File

@ -21,12 +21,8 @@
#include "../kernel.h" #include "../kernel.h"
NewLock(SyscallsLock);
extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame) extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame)
{ {
SmartLock(SyscallsLock); /* TODO: This should be replaced or moved somewhere else. */
Tasking::TaskInfo *Ptinfo = &TaskManager->GetCurrentProcess()->Info; Tasking::TaskInfo *Ptinfo = &TaskManager->GetCurrentProcess()->Info;
Tasking::TaskInfo *Ttinfo = &TaskManager->GetCurrentThread()->Info; Tasking::TaskInfo *Ttinfo = &TaskManager->GetCurrentThread()->Info;
uint64_t TempTimeCalc = TimeManager->GetCounter(); uint64_t TempTimeCalc = TimeManager->GetCounter();

View File

@ -248,16 +248,23 @@ namespace Tasking
CPU::Pause(); CPU::Pause();
} }
void Task::Sleep(uint64_t Milliseconds) void Task::Sleep(uint64_t Milliseconds, bool NoSwitch)
{ {
SmartLock(TaskingLock);
TCB *thread = this->GetCurrentThread(); TCB *thread = this->GetCurrentThread();
PCB *process = this->GetCurrentProcess();
thread->Status = TaskStatus::Sleeping; thread->Status = TaskStatus::Sleeping;
if (thread->Parent->Threads.size() == 1) if (process->Threads.size() == 1)
thread->Parent->Status = TaskStatus::Sleeping; process->Status = TaskStatus::Sleeping;
thread->Info.SleepUntil = TimeManager->CalculateTarget(Milliseconds, Time::Units::Milliseconds);
tskdbg("Thread \"%s\"(%d) is going to sleep until %llu", thread->Name, thread->ID, thread->Info.SleepUntil); thread->Info.SleepUntil =
TaskingLock.Unlock(); TimeManager->CalculateTarget(Milliseconds,
Time::Units::Milliseconds);
debug("Thread \"%s\"(%d) is going to sleep until %llu",
thread->Name, thread->ID, thread->Info.SleepUntil);
if (!NoSwitch)
this->Schedule(); this->Schedule();
} }
@ -410,6 +417,8 @@ namespace Tasking
{ {
Thread->Security.IsCritical = true; Thread->Security.IsCritical = true;
Thread->Stack = new Memory::StackGuard(false, Parent->PageTable); Thread->Stack = new Memory::StackGuard(false, Parent->PageTable);
Thread->SyscallStack = __UINTPTR_MAX__;
Thread->TempStack = __UINTPTR_MAX__;
#if defined(a64) #if defined(a64)
SecurityManager.TrustToken(Thread->Security.UniqueToken, TTL::TrustedByKernel); SecurityManager.TrustToken(Thread->Security.UniqueToken, TTL::TrustedByKernel);
Thread->ShadowGSBase = CPU::x64::rdmsr(CPU::x64::MSRID::MSR_SHADOW_GS_BASE); Thread->ShadowGSBase = CPU::x64::rdmsr(CPU::x64::MSRID::MSR_SHADOW_GS_BASE);
@ -430,9 +439,11 @@ namespace Tasking
case TaskTrustLevel::User: case TaskTrustLevel::User:
{ {
Thread->Stack = new Memory::StackGuard(true, Parent->PageTable); Thread->Stack = new Memory::StackGuard(true, Parent->PageTable);
Thread->SyscallStack = (uintptr_t)Thread->Memory->RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE;
Thread->TempStack = 0x0;
#if defined(a64) #if defined(a64)
SecurityManager.TrustToken(Thread->Security.UniqueToken, TTL::Untrusted); SecurityManager.TrustToken(Thread->Security.UniqueToken, TTL::Untrusted);
Thread->ShadowGSBase = (uint64_t)GetCurrentCPU(); Thread->ShadowGSBase = (uintptr_t)Thread;
Thread->GSBase = 0; Thread->GSBase = 0;
Thread->FSBase = 0; Thread->FSBase = 0;
Thread->Registers.cs = GDT_USER_CODE; Thread->Registers.cs = GDT_USER_CODE;
@ -742,7 +753,6 @@ namespace Tasking
Task::Task(const IP EntryPoint) : Interrupts::Handler(16) /* IRQ16 */ Task::Task(const IP EntryPoint) : Interrupts::Handler(16) /* IRQ16 */
{ {
SmartLock(TaskingLock);
#if defined(a64) #if defined(a64)
// Map the IRQ16 to the first CPU. // Map the IRQ16 to the first CPU.
((APIC::APIC *)Interrupts::apic[0])->RedirectIRQ(0, CPU::x86::IRQ16 - CPU::x86::IRQ0, 1); ((APIC::APIC *)Interrupts::apic[0])->RedirectIRQ(0, CPU::x86::IRQ16 - CPU::x86::IRQ0, 1);
@ -750,7 +760,6 @@ namespace Tasking
#elif defined(aa64) #elif defined(aa64)
#endif #endif
KPrint("Starting Tasking With Instruction Pointer: %p (\e666666%s\eCCCCCC)", EntryPoint, KernelSymbolTable->GetSymbolFromAddress(EntryPoint)); KPrint("Starting Tasking With Instruction Pointer: %p (\e666666%s\eCCCCCC)", EntryPoint, KernelSymbolTable->GetSymbolFromAddress(EntryPoint));
TaskingLock.Unlock();
#if defined(a64) #if defined(a64)
TaskArchitecture Arch = TaskArchitecture::x64; TaskArchitecture Arch = TaskArchitecture::x64;
@ -765,7 +774,6 @@ namespace Tasking
TCB *kthrd = CreateThread(kproc, EntryPoint, nullptr, nullptr, std::vector<AuxiliaryVector>(), Arch); TCB *kthrd = CreateThread(kproc, EntryPoint, nullptr, nullptr, std::vector<AuxiliaryVector>(), Arch);
kthrd->Rename("Main Thread"); kthrd->Rename("Main Thread");
debug("Created Kernel Process: %s and Thread: %s", kproc->Name, kthrd->Name); debug("Created Kernel Process: %s and Thread: %s", kproc->Name, kthrd->Name);
TaskingLock.Lock(__FUNCTION__);
bool MONITORSupported = false; bool MONITORSupported = false;
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
@ -792,7 +800,6 @@ namespace Tasking
CPU::Interrupts(CPU::Enable); CPU::Interrupts(CPU::Enable);
} }
TaskingLock.Unlock();
IdleProcess = CreateProcess(nullptr, (char *)"Idle", TaskTrustLevel::Kernel); IdleProcess = CreateProcess(nullptr, (char *)"Idle", TaskTrustLevel::Kernel);
IdleProcess->ELFSymbolTable = KernelSymbolTable; IdleProcess->ELFSymbolTable = KernelSymbolTable;
for (int i = 0; i < SMP::CPUCores; i++) for (int i = 0; i < SMP::CPUCores; i++)

View File

@ -1076,6 +1076,7 @@ namespace Memory
~MemMgr(); ~MemMgr();
private: private:
NewLock(MgrLock);
Bitmap PageBitmap; Bitmap PageBitmap;
PageTable *Table; PageTable *Table;
VirtualFileSystem::Node *Directory; VirtualFileSystem::Node *Directory;

View File

@ -41,14 +41,8 @@ struct CPUArchData
struct CPUData struct CPUData
{ {
/** @brief Used by syscall handler */
uint8_t *SystemCallStack; /* gs+0x0 */
/** @brief Used by syscall handler */
uintptr_t TempStack; /* gs+0x8 */
/** @brief Used by CPU */ /** @brief Used by CPU */
uintptr_t Stack; /* gs+0x10 */ uintptr_t Stack;
/** @brief CPU ID. */ /** @brief CPU ID. */
int ID; int ID;

View File

@ -122,6 +122,12 @@ namespace Tasking
struct TCB struct TCB
{ {
/** @brief Used by syscall handler */
uintptr_t SyscallStack; /* gs+0x0 */
/** @brief Used by syscall handler */
uintptr_t TempStack; /* gs+0x8 */
TID ID; TID ID;
char Name[256]; char Name[256];
struct PCB *Parent; struct PCB *Parent;
@ -132,12 +138,12 @@ namespace Tasking
TaskStatus Status; TaskStatus Status;
#if defined(a64) #if defined(a64)
CPU::x64::TrapFrame Registers; CPU::x64::TrapFrame Registers;
uint64_t ShadowGSBase, GSBase, FSBase; uintptr_t ShadowGSBase, GSBase, FSBase;
#elif defined(a32) #elif defined(a32)
CPU::x32::TrapFrame Registers; // TODO CPU::x32::TrapFrame Registers; // TODO
uint64_t ShadowGSBase, GSBase, FSBase; uintptr_t ShadowGSBase, GSBase, FSBase;
#elif defined(aa64) #elif defined(aa64)
uint64_t Registers; // TODO uintptr_t Registers; // TODO
#endif #endif
uintptr_t IPHistory[128]; uintptr_t IPHistory[128];
TaskSecurity Security; TaskSecurity Security;
@ -244,7 +250,8 @@ namespace Tasking
Untrusted = 0b0010, Untrusted = 0b0010,
Trusted = 0b0100, Trusted = 0b0100,
TrustedByKernel = 0b1000, TrustedByKernel = 0b1000,
FullTrust = Trusted | TrustedByKernel FullTrust = Trusted | TrustedByKernel,
AllFlags = 0b1111
}; };
class Security class Security
@ -379,7 +386,7 @@ namespace Tasking
* *
* @param Milliseconds Amount of milliseconds to sleep * @param Milliseconds Amount of milliseconds to sleep
*/ */
void Sleep(uint64_t Milliseconds); void Sleep(uint64_t Milliseconds, bool NoSwitch = false);
PCB *CreateProcess(PCB *Parent, PCB *CreateProcess(PCB *Parent,
const char *Name, const char *Name,

View File

@ -76,13 +76,13 @@ namespace std
#ifdef DEBUG_MEM_ALLOCATION #ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR INIT: vector( <vector> )->Size: %lld", VectorSize); debug("VECTOR INIT: vector( <vector> )->Size: %lld", VectorSize);
#endif #endif
if (VectorSize > 0) if (!v.VectorBuffer || VectorSize <= 0)
{ return;
VectorBuffer = new T[VectorSize]; VectorBuffer = new T[VectorSize];
for (size_t i = 0; i < VectorSize; i++) for (size_t i = 0; i < VectorSize; i++)
VectorBuffer[i] = v.VectorBuffer[i]; VectorBuffer[i] = v.VectorBuffer[i];
} }
}
NIF ~vector() NIF ~vector()
{ {