feat: implement kernel capability model
This commit is contained in:
1 parent
9051b8a16e
commit
e7646bbbdb
47 files changed
+1507
-264
No files matched your search
@@ -4,6 +4,7 @@
|
||||
* Copyright (c) 2025-2026 Daniel Hammer
|
||||
*/
|
||||
|
||||
#include <Memory/UserRange.hpp>
|
||||
#include "Scheduler.hpp"
|
||||
#include "ElfLoader.hpp"
|
||||
#include <Memory/PageFrameAllocator.hpp>
|
||||
@@ -298,6 +299,9 @@ namespace Sched {
|
||||
processTable[i].environment[0] = '\0';
|
||||
processTable[i].environmentLength = 1;
|
||||
processTable[i].user[0] = '\0';
|
||||
processTable[i].permittedCaps = 0;
|
||||
processTable[i].effectiveCaps = 0;
|
||||
processTable[i].delegableCaps = 0;
|
||||
processTable[i].sessionId = -1;
|
||||
processTable[i].cwd[0] = '\0';
|
||||
processTable[i].runningOnCpu = -1;
|
||||
@@ -342,7 +346,9 @@ namespace Sched {
|
||||
}
|
||||
|
||||
int Spawn(const char* vfsPath, const char* args, bool startReady,
|
||||
const char* environment, uint32_t environmentLength) {
|
||||
const char* environment, uint32_t environmentLength,
|
||||
const montauk::abi::SpawnCapabilities* capabilities,
|
||||
const char* userOverride) {
|
||||
schedLock.Acquire();
|
||||
|
||||
int slot = -1;
|
||||
@@ -547,9 +553,37 @@ namespace Sched {
|
||||
proc.environmentLength = 1;
|
||||
}
|
||||
|
||||
// Inherit user string from parent, or default to "system" if no parent
|
||||
// Capabilities are kernel-owned and never inferred from the user name.
|
||||
// A normal userspace spawn receives no privileged authority; callers
|
||||
// must use SYS_SPAWN_CAPS for an explicit, kernel-validated delegation.
|
||||
if (parentPrimarySlot >= 0) {
|
||||
if (capabilities != nullptr) {
|
||||
proc.permittedCaps = capabilities->permitted;
|
||||
proc.effectiveCaps = capabilities->effective;
|
||||
proc.delegableCaps = capabilities->delegable;
|
||||
} else {
|
||||
proc.permittedCaps = 0;
|
||||
proc.effectiveCaps = 0;
|
||||
proc.delegableCaps = 0;
|
||||
}
|
||||
} else {
|
||||
// The kernel-created init process is the root of the capability
|
||||
// delegation tree. No userspace pathname or PID receives this
|
||||
// treatment; it is reached only with no current parent process.
|
||||
proc.permittedCaps = montauk::abi::CAP_ALL;
|
||||
proc.effectiveCaps = montauk::abi::CAP_ALL;
|
||||
proc.delegableCaps = montauk::abi::CAP_ALL;
|
||||
}
|
||||
|
||||
// Inherit user string from parent, or default to "system" if no parent.
|
||||
// An explicit override is accepted only through the validated
|
||||
// SYS_SPAWN_CAPS path.
|
||||
{
|
||||
if (parentSlot >= 0) {
|
||||
if (userOverride != nullptr) {
|
||||
int i = 0;
|
||||
for (; i < 31 && userOverride[i]; i++) proc.user[i] = userOverride[i];
|
||||
proc.user[i] = '\0';
|
||||
} else if (parentSlot >= 0) {
|
||||
int i = 0;
|
||||
for (; i < 31 && processTable[parentSlot].user[i]; i++)
|
||||
proc.user[i] = processTable[parentSlot].user[i];
|
||||
@@ -684,7 +718,7 @@ namespace Sched {
|
||||
mappedPages++;
|
||||
}
|
||||
if (!ok) {
|
||||
Ipc::UnmapAndFreeUserRange(sharedPml4, base, mappedPages);
|
||||
Memory::UnmapAndFreeUserRange(sharedPml4, base, mappedPages);
|
||||
ReleaseUserHeapRange(primarySlot_, base, numPages * 0x1000ULL);
|
||||
Kt::KernelLogStream(Kt::ERROR, "Sched")
|
||||
<< "Thread TLS allocation failed";
|
||||
@@ -711,7 +745,7 @@ namespace Sched {
|
||||
void* stackMem = Memory::g_pfa->ReallocConsecutive(nullptr, StackPages);
|
||||
if (stackMem == nullptr) {
|
||||
if (threadTlsPages != 0) {
|
||||
Ipc::UnmapAndFreeUserRange(sharedPml4, threadTlsBase, threadTlsPages);
|
||||
Memory::UnmapAndFreeUserRange(sharedPml4, threadTlsBase, threadTlsPages);
|
||||
ReleaseUserHeapRange(primarySlot_, threadTlsBase,
|
||||
threadTlsPages * 0x1000ULL);
|
||||
}
|
||||
@@ -737,7 +771,7 @@ namespace Sched {
|
||||
schedLock.Release();
|
||||
Memory::g_pfa->Free(stackMem, StackPages);
|
||||
if (threadTlsPages != 0) {
|
||||
Ipc::UnmapAndFreeUserRange(sharedPml4, threadTlsBase, threadTlsPages);
|
||||
Memory::UnmapAndFreeUserRange(sharedPml4, threadTlsBase, threadTlsPages);
|
||||
ReleaseUserHeapRange(primarySlot_, threadTlsBase,
|
||||
threadTlsPages * 0x1000ULL);
|
||||
}
|
||||
@@ -885,7 +919,7 @@ namespace Sched {
|
||||
uint64_t base = thr.fsBase - blockSize;
|
||||
uint64_t pages = (blockSize + 16 + 0xFFF) / 0x1000;
|
||||
thr.fsBase = 0;
|
||||
Ipc::UnmapAndFreeUserRange(primary.pml4Phys, base, pages);
|
||||
Memory::UnmapAndFreeUserRange(primary.pml4Phys, base, pages);
|
||||
ReleaseUserHeapRange(primarySlot_, base, pages * 0x1000ULL);
|
||||
}
|
||||
|
||||
@@ -1418,6 +1452,11 @@ namespace Sched {
|
||||
return &processTable[primary];
|
||||
}
|
||||
|
||||
bool HasCapability(uint64_t capability) {
|
||||
Process* proc = GetCurrentProcessPtr();
|
||||
return proc != nullptr && (proc->effectiveCaps & capability) == capability;
|
||||
}
|
||||
|
||||
Process* GetCurrentThreadPtr() {
|
||||
auto* cpu = Smp::GetCurrentCpuData();
|
||||
int slot = cpu->currentSlot;
|
||||
|
||||
Reference in new issue
Block a user