fix: SYS_READDIR memory leak

This commit is contained in:
2026-03-27 20:15:37 +01:00
parent c755bc436c
commit 88ff98c325
3 changed files with 30 additions and 7 deletions
+22 -5
View File
@@ -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;
+2
View File
@@ -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;
+4
View File
@@ -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