mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-03 03:19:18 +00:00
Stack guard implementation
This commit is contained in:
@ -299,6 +299,24 @@ namespace CrashHandler
|
||||
if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA)
|
||||
{
|
||||
debug("Exception in kernel mode");
|
||||
if (Frame->InterruptNumber == CPU::x64::PageFault)
|
||||
{
|
||||
CPUData *data = GetCurrentCPU();
|
||||
if (data)
|
||||
{
|
||||
if (data->CurrentThread->Stack->Expand(CPU::x64::readcr2().raw))
|
||||
{
|
||||
debug("Stack expanded");
|
||||
CPU::Interrupts(CPU::Enable);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
error("Stack expansion failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TaskManager)
|
||||
TaskManager->Panic();
|
||||
Display->CreateBuffer(0, 0, SBIdx);
|
||||
|
@ -30,7 +30,8 @@ __no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
CriticalSection cs;
|
||||
debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No");
|
||||
fixme("Handling user mode exception");
|
||||
TaskManager->GetCurrentThread()->Status = Tasking::TaskStatus::Terminated;
|
||||
TaskManager->GetCurrentThread()->Status = Tasking::TaskStatus::Stopped;
|
||||
CPUData *CurCPU = GetCurrentCPU();
|
||||
|
||||
{
|
||||
CPU::x64::CR0 cr0 = CPU::x64::readcr0();
|
||||
@ -41,7 +42,7 @@ __no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
CPU::x64::EFER efer;
|
||||
efer.raw = CPU::x64::rdmsr(CPU::x64::MSR_EFER);
|
||||
|
||||
error("Technical Informations on CPU %lld:", GetCurrentCPU()->ID);
|
||||
error("Technical Informations on CPU %lld:", CurCPU->ID);
|
||||
#if defined(__amd64__)
|
||||
uint64_t ds;
|
||||
asmv("mov %%ds, %0"
|
||||
@ -176,6 +177,13 @@ __no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
}
|
||||
case CPU::x64::PageFault:
|
||||
{
|
||||
if (CurCPU)
|
||||
if (CurCPU->CurrentThread->Stack->Expand(CPU::x64::readcr2().raw))
|
||||
{
|
||||
debug("Stack expanded");
|
||||
return;
|
||||
}
|
||||
|
||||
CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode};
|
||||
#if defined(__amd64__)
|
||||
error("An exception occurred at %#lx by %#lx", CPU::x64::readcr2().PFLA, Frame->rip);
|
||||
@ -226,6 +234,9 @@ __no_stack_protector void UserModeExceptionHandler(CHArchTrapFrame *Frame)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TaskManager->GetCurrentThread()->Status = Tasking::TaskStatus::Terminated;
|
||||
__sync_synchronize();
|
||||
error("End of report.");
|
||||
CPU::Interrupts(CPU::Enable);
|
||||
debug("Interrupts enabled back.");
|
||||
|
@ -43,8 +43,8 @@ void MapFromZero(PageTable *PT, BootInfo *Info)
|
||||
uint64_t VirtualOffsetNormalVMA = NORMAL_VMA_OFFSET;
|
||||
for (uint64_t t = 0; t < Info->Memory.Size; t += PAGE_SIZE)
|
||||
{
|
||||
va.Map((void *)t, (void *)t, PTFlag::RW | PTFlag::US);
|
||||
va.Map((void *)VirtualOffsetNormalVMA, (void *)t, PTFlag::RW | PTFlag::US);
|
||||
va.Map((void *)t, (void *)t, PTFlag::RW);
|
||||
va.Map((void *)VirtualOffsetNormalVMA, (void *)t, PTFlag::RW);
|
||||
VirtualOffsetNormalVMA += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
@ -174,8 +174,10 @@ void InitializeMemoryManagement(BootInfo *Info)
|
||||
UserspaceKernelOnlyPageTable = (PageTable *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE));
|
||||
memset(UserspaceKernelOnlyPageTable, 0, PAGE_SIZE);
|
||||
|
||||
debug("Mapping from %#llx to %#llx", 0, Info->Memory.Size);
|
||||
debug("Mapping from 0x0 to %#llx", Info->Memory.Size);
|
||||
MapFromZero(KernelPageTable, Info);
|
||||
debug("Mapping from 0x0 %#llx for Userspace Page Table", Info->Memory.Size);
|
||||
MapFromZero(UserspaceKernelOnlyPageTable, Info);
|
||||
|
||||
/* Mapping Framebuffer address */
|
||||
debug("Mapping Framebuffer");
|
||||
@ -289,14 +291,20 @@ void HeapFree(void *Address)
|
||||
}
|
||||
}
|
||||
|
||||
void *operator new(size_t Size) { return HeapMalloc(Size); }
|
||||
void *operator new[](size_t Size) { return HeapMalloc(Size); }
|
||||
void *operator new(size_t Size) {
|
||||
return HeapMalloc(Size); }
|
||||
void *operator new[](size_t Size) {
|
||||
return HeapMalloc(Size); }
|
||||
void *operator new(unsigned long Size, std::align_val_t Alignment)
|
||||
{
|
||||
fixme("operator new with alignment(%#lx) is not implemented", Alignment);
|
||||
return HeapMalloc(Size);
|
||||
}
|
||||
void operator delete(void *Pointer) { HeapFree(Pointer); }
|
||||
void operator delete[](void *Pointer) { HeapFree(Pointer); }
|
||||
void operator delete(void *Pointer, long unsigned int Size) { HeapFree(Pointer); }
|
||||
void operator delete[](void *Pointer, long unsigned int Size) { HeapFree(Pointer); }
|
||||
void operator delete(void *Pointer) {
|
||||
HeapFree(Pointer); }
|
||||
void operator delete[](void *Pointer) {
|
||||
HeapFree(Pointer); }
|
||||
void operator delete(void *Pointer, long unsigned int Size) {
|
||||
HeapFree(Pointer); }
|
||||
void operator delete[](void *Pointer, long unsigned int Size) {
|
||||
HeapFree(Pointer); }
|
||||
|
66
Core/Memory/StackGuard.cpp
Normal file
66
Core/Memory/StackGuard.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
#include <memory.hpp>
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
StackGuard::StackGuard(bool User, PageTable *Table)
|
||||
{
|
||||
this->UserMode = User;
|
||||
this->Table = Table;
|
||||
if (this->UserMode)
|
||||
{
|
||||
void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE));
|
||||
memset(AllocatedStack, 0, USER_STACK_SIZE);
|
||||
for (uint64_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++)
|
||||
{
|
||||
Virtual(Table).Map((void *)((uint64_t)AllocatedStack + (i * PAGE_SIZE)),
|
||||
(void *)(USER_STACK_BASE + (i * PAGE_SIZE)),
|
||||
PTFlag::RW | PTFlag::US);
|
||||
}
|
||||
this->StackBottom = (void *)USER_STACK_BASE;
|
||||
this->StackTop = (void *)(USER_STACK_BASE + USER_STACK_SIZE);
|
||||
this->Size = USER_STACK_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->StackBottom = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE));
|
||||
memset(this->StackBottom, 0, STACK_SIZE);
|
||||
this->StackTop = (void *)((uint64_t)this->StackBottom + STACK_SIZE);
|
||||
this->Size = STACK_SIZE;
|
||||
}
|
||||
trace("Allocated stack at %p", this->StackBottom);
|
||||
}
|
||||
|
||||
StackGuard::~StackGuard() { KernelAllocator.FreePages(this->StackBottom, TO_PAGES(this->Size)); }
|
||||
|
||||
bool StackGuard::Expand(uint64_t FaultAddress)
|
||||
{
|
||||
if (this->UserMode)
|
||||
{
|
||||
if (FaultAddress < (uint64_t)this->StackBottom - USER_STACK_SIZE ||
|
||||
FaultAddress > (uint64_t)this->StackTop)
|
||||
{
|
||||
return false; // It's not about the stack.
|
||||
}
|
||||
else
|
||||
{
|
||||
void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE));
|
||||
memset(AllocatedStack, 0, USER_STACK_SIZE);
|
||||
for (uint64_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++)
|
||||
Virtual(this->Table).Map((void *)((uint64_t)AllocatedStack + (i * PAGE_SIZE)), (void *)((uint64_t)this->StackBottom - (i * PAGE_SIZE)), PTFlag::RW | PTFlag::US);
|
||||
this->StackBottom = (void *)((uint64_t)this->StackBottom - USER_STACK_SIZE);
|
||||
this->Size += USER_STACK_SIZE;
|
||||
info("Stack expanded to %p", this->StackBottom);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fixme("Not implemented and probably not needed");
|
||||
return false;
|
||||
}
|
||||
error("Reached end of function! How?");
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user