fix: kernel concurrency, interrupt context, and user VA safety

This commit is contained in:
daniel committed 2026-08-01 15:43:38 +02:00
1 parent f222bf1f04
commit b1c55073c7
71 files changed
+2654 -1092

No files matched your search

+39 -19
View File
@@ -13,6 +13,8 @@
#include <Terminal/Terminal.hpp>
#include <Libraries/Memory.hpp>
#include <Libraries/String.hpp>
#include <CppLib/Spinlock.hpp>
#include <Ipc/Ipc.hpp>
namespace montauk::abi {
@@ -34,16 +36,19 @@ namespace montauk::abi {
// Per-process library table
inline LibEntry g_libTable[MaxProcesses][MaxLibsPerProcess] = {};
inline kcp::Mutex g_libLocks[MaxProcesses];
// Initialize library table for a process slot
inline void InitLibTable(int slot) {
if (slot < 0 || slot >= MaxProcesses) return;
g_libLocks[slot].Acquire();
for (int i = 0; i < MaxLibsPerProcess; i++) {
g_libTable[slot][i].inUse = false;
g_libTable[slot][i].refcount = 0;
g_libTable[slot][i].loadBias = 0;
g_libTable[slot][i].path[0] = '\0';
}
g_libLocks[slot].Release();
}
// Load a shared library into the current process's address space.
@@ -61,6 +66,8 @@ namespace montauk::abi {
size_t pathLen = Lib::strlen(path);
if (pathLen == 0 || pathLen >= sizeof(LibEntry::path)) return 0;
g_libLocks[slot].Acquire();
// Find a free slot or reuse an existing slot with the same path
int libSlot = -1;
for (int i = 0; i < MaxLibsPerProcess; i++) {
@@ -68,6 +75,7 @@ namespace montauk::abi {
if (Lib::strncmp(g_libTable[slot][i].path, path, sizeof(LibEntry::path)) == 0) {
// Same library already loaded - just increment refcount
g_libTable[slot][i].refcount++;
g_libLocks[slot].Release();
return (uint64_t)(i + 1); // Handle = slot + 1 (0 = invalid)
}
} else if (libSlot < 0) {
@@ -77,6 +85,7 @@ namespace montauk::abi {
if (libSlot < 0) {
Kt::KernelLogStream(Kt::ERROR, "Lib") << "No free library slots";
g_libLocks[slot].Release();
return 0;
}
@@ -84,6 +93,7 @@ namespace montauk::abi {
uint64_t loadBias = Sched::ElfLoadLib(path, proc->pml4Phys, libSlot);
if (loadBias == 0) {
Kt::KernelLogStream(Kt::ERROR, "Lib") << "Failed to load library: " << path;
g_libLocks[slot].Release();
return 0;
}
@@ -93,6 +103,8 @@ namespace montauk::abi {
g_libTable[slot][libSlot].loadBias = loadBias;
Lib::strncpy(g_libTable[slot][libSlot].path, path, sizeof(LibEntry::path));
g_libLocks[slot].Release();
Kt::KernelLogStream(Kt::OK, "Lib") << "Loaded library: " << path << " with load bias " << kcp::hex << loadBias << kcp::dec;
return (uint64_t)(libSlot + 1); // Handle = slot + 1 (0 = invalid)
@@ -107,7 +119,11 @@ namespace montauk::abi {
int libSlot = (int)handle - 1;
if (libSlot < 0 || libSlot >= MaxLibsPerProcess) return -1;
if (!g_libTable[slot][libSlot].inUse) return -1;
g_libLocks[slot].Acquire();
if (!g_libTable[slot][libSlot].inUse) {
g_libLocks[slot].Release();
return -1;
}
g_libTable[slot][libSlot].refcount--;
if (g_libTable[slot][libSlot].refcount == 0) {
@@ -117,14 +133,8 @@ namespace montauk::abi {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc != nullptr) {
// Unmap all pages in the library region
for (uint64_t va = libBase; va < libEnd; va += 0x1000) {
uint64_t physAddr = Memory::VMM::Paging::GetPhysAddr(proc->pml4Phys, va);
if (physAddr != 0) {
Memory::g_pfa->Free((void*)Memory::HHDM(physAddr));
Memory::VMM::Paging::UnmapUserIn(proc->pml4Phys, va);
}
}
Ipc::UnmapAndFreeUserRange(proc->pml4Phys, libBase,
(libEnd - libBase) / 0x1000ULL);
}
g_libTable[slot][libSlot].inUse = false;
@@ -132,6 +142,7 @@ namespace montauk::abi {
g_libTable[slot][libSlot].path[0] = '\0';
}
g_libLocks[slot].Release();
return 0;
}
@@ -146,9 +157,14 @@ namespace montauk::abi {
int libSlot = (int)handle - 1;
if (libSlot < 0 || libSlot >= MaxLibsPerProcess) return 0;
if (!g_libTable[slot][libSlot].inUse) return 0;
g_libLocks[slot].Acquire();
if (!g_libTable[slot][libSlot].inUse) {
g_libLocks[slot].Release();
return 0;
}
uint64_t loadBias = g_libTable[slot][libSlot].loadBias;
g_libLocks[slot].Release();
return loadBias + symbolOffset;
}
@@ -160,9 +176,15 @@ namespace montauk::abi {
int libSlot = (int)handle - 1;
if (libSlot < 0 || libSlot >= MaxLibsPerProcess) return 0;
if (!g_libTable[slot][libSlot].inUse) return 0;
g_libLocks[slot].Acquire();
if (!g_libTable[slot][libSlot].inUse) {
g_libLocks[slot].Release();
return 0;
}
return g_libTable[slot][libSlot].loadBias;
uint64_t loadBias = g_libTable[slot][libSlot].loadBias;
g_libLocks[slot].Release();
return loadBias;
}
// Cleanup library table for a process slot
@@ -172,25 +194,23 @@ namespace montauk::abi {
auto* proc = Sched::GetProcessSlot(slot);
if (proc == nullptr) return;
g_libLocks[slot].Acquire();
// Unmap all libraries for this process
for (int i = 0; i < MaxLibsPerProcess; i++) {
if (g_libTable[slot][i].inUse) {
uint64_t libBase = GetLibSlotBase(i);
uint64_t libEnd = libBase + Sched::LIB_MAX_SIZE;
for (uint64_t va = libBase; va < libEnd; va += 0x1000) {
uint64_t physAddr = Memory::VMM::Paging::GetPhysAddr(proc->pml4Phys, va);
if (physAddr != 0) {
Memory::g_pfa->Free((void*)Memory::HHDM(physAddr));
Memory::VMM::Paging::UnmapUserIn(proc->pml4Phys, va);
}
}
Ipc::UnmapAndFreeUserRange(proc->pml4Phys, libBase,
(libEnd - libBase) / 0x1000ULL);
g_libTable[slot][i].inUse = false;
g_libTable[slot][i].refcount = 0;
g_libTable[slot][i].loadBias = 0;
}
}
g_libLocks[slot].Release();
}
}