fix: SYS_READDIR memory leak
This commit is contained in:
@@ -48,16 +48,33 @@ namespace Montauk {
|
||||
auto* proc = Sched::GetCurrentProcessPtr();
|
||||
if (proc == nullptr) return -1;
|
||||
|
||||
// Use a rotating ring of scratch pages below the heap instead of
|
||||
// bumping heapNext on every call. This keeps repeated directory scans
|
||||
// from leaking user heap space while still allowing nested callers to
|
||||
// hold multiple readdir results at once.
|
||||
uint32_t slot = proc->readdirCursor % Sched::UserReadDirSlots;
|
||||
proc->readdirCursor = (slot + 1) % Sched::UserReadDirSlots;
|
||||
|
||||
uint64_t userVa = Sched::UserReadDirBase + (uint64_t)slot * 0x1000ULL;
|
||||
uint64_t physAddr = Memory::VMM::Paging::GetPhysAddr(proc->pml4Phys, userVa);
|
||||
uint8_t* pageBuf = nullptr;
|
||||
|
||||
if (physAddr == 0) {
|
||||
void* page = Memory::g_pfa->AllocateZeroed();
|
||||
if (page == nullptr) return -1;
|
||||
uint64_t physAddr = Memory::SubHHDM((uint64_t)page);
|
||||
uint64_t userVa = proc->heapNext;
|
||||
proc->heapNext += 0x1000;
|
||||
if (!Memory::VMM::Paging::MapUserIn(proc->pml4Phys, physAddr, userVa)) return -1;
|
||||
physAddr = Memory::SubHHDM((uint64_t)page);
|
||||
if (!Memory::VMM::Paging::MapUserIn(proc->pml4Phys, physAddr, userVa)) {
|
||||
Memory::g_pfa->Free(page);
|
||||
return -1;
|
||||
}
|
||||
pageBuf = (uint8_t*)page;
|
||||
} else {
|
||||
pageBuf = (uint8_t*)Memory::HHDM(physAddr);
|
||||
memset(pageBuf, 0, 0x1000);
|
||||
}
|
||||
|
||||
// Copy strings into the user page and write pointers to outNames
|
||||
uint64_t offset = 0;
|
||||
uint8_t* pageBuf = (uint8_t*)Memory::HHDM(physAddr);
|
||||
int copied = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int len = Lib::strlen(kernelNames[i]) + 1;
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace Sched {
|
||||
processTable[i].kernelStackTop = 0;
|
||||
processTable[i].userStackTop = 0;
|
||||
processTable[i].heapNext = 0;
|
||||
processTable[i].readdirCursor = 0;
|
||||
processTable[i].args[0] = '\0';
|
||||
processTable[i].user[0] = '\0';
|
||||
processTable[i].cwd[0] = '\0';
|
||||
@@ -270,6 +271,7 @@ namespace Sched {
|
||||
proc.kernelStackTop = kernelStackTop;
|
||||
proc.userStackTop = UserStackTop - 8;
|
||||
proc.heapNext = UserHeapBase;
|
||||
proc.readdirCursor = 0;
|
||||
proc.runningOnCpu = -1;
|
||||
proc.killPending = false;
|
||||
proc.waitingForPid = -1;
|
||||
|
||||
@@ -17,6 +17,9 @@ namespace Sched {
|
||||
static constexpr uint64_t UserStackSize = UserStackPages * 0x1000;
|
||||
static constexpr uint64_t UserStackTop = 0x7FFFFFF000ULL; // User stack top VA
|
||||
static constexpr uint64_t UserHeapBase = 0x40000000ULL; // User heap start VA
|
||||
static constexpr uint32_t UserReadDirSlots = 64; // rotating scratch pages for SYS_READDIR
|
||||
static constexpr uint64_t UserReadDirBase =
|
||||
UserHeapBase - (uint64_t)UserReadDirSlots * 0x1000ULL;
|
||||
static constexpr uint64_t ExitStubAddr = 0x3FF000ULL; // User-space exit stub page
|
||||
static constexpr uint64_t TimeSliceMs = 10; // 10 ms time slice
|
||||
|
||||
@@ -42,6 +45,7 @@ namespace Sched {
|
||||
uint64_t kernelStackTop; // Top of kernel stack (for TSS RSP0 / SYSCALL)
|
||||
uint64_t userStackTop; // User-space stack top
|
||||
uint64_t heapNext; // Simple bump allocator for user heap
|
||||
uint32_t readdirCursor; // Next SYS_READDIR scratch slot
|
||||
char args[256]; // Command-line arguments (set by parent via Spawn)
|
||||
char user[32]; // Owner user name (inherited from parent on spawn)
|
||||
char cwd[256]; // Absolute current working directory
|
||||
|
||||
Reference in New Issue
Block a user