diff --git a/kernel/src/Api/BuildNo.hpp b/kernel/src/Api/BuildNo.hpp index 5ca920d..95c263b 100644 --- a/kernel/src/Api/BuildNo.hpp +++ b/kernel/src/Api/BuildNo.hpp @@ -12,4 +12,4 @@ #pragma once -#define MONTAUK_BUILD_NUMBER 220 +#define MONTAUK_BUILD_NUMBER 221 diff --git a/kernel/src/Api/Process.hpp b/kernel/src/Api/Process.hpp index 817506a..e477ba0 100644 --- a/kernel/src/Api/Process.hpp +++ b/kernel/src/Api/Process.hpp @@ -140,6 +140,16 @@ namespace montauk::abi { return childPid; } + // The calling process's own capability masks. + static int Sys_GetCaps(SpawnCapabilities* out) { + auto* proc = Sched::GetCurrentProcessPtr(); + if (proc == nullptr || out == nullptr) return -1; + out->permitted = proc->permittedCaps; + out->effective = proc->effectiveCaps; + out->delegable = proc->delegableCaps; + return 0; + } + // Copy the absolute path this process was spawned from (argv[0]). static int Sys_GetExecPath(char* buf, uint64_t maxLen) { auto* proc = Sched::GetCurrentProcessPtr(); diff --git a/kernel/src/Api/Syscall.cpp b/kernel/src/Api/Syscall.cpp index 701fb0b..45e568d 100644 --- a/kernel/src/Api/Syscall.cpp +++ b/kernel/src/Api/Syscall.cpp @@ -510,6 +510,9 @@ namespace montauk::abi { // holds no device capability to spend on it. if (!UserMemory::Writable(frame->arg1)) return -1; return Sys_BatteryInfo((BatteryInfo*)frame->arg1); + case SYS_GETCAPS: + if (!UserMemory::Writable(frame->arg1)) return -1; + return Sys_GetCaps((SpawnCapabilities*)frame->arg1); case SYS_THREAD_SPAWN: return Sys_ThreadSpawn(frame->arg1, frame->arg2, frame->arg3); case SYS_THREAD_EXIT: diff --git a/kernel/src/Api/Syscall.hpp b/kernel/src/Api/Syscall.hpp index 1b72f48..565c2aa 100644 --- a/kernel/src/Api/Syscall.hpp +++ b/kernel/src/Api/Syscall.hpp @@ -346,6 +346,9 @@ namespace montauk::abi { /* Battery.hpp -- ACPI battery status */ static constexpr uint64_t SYS_BATTERYINFO = 188; // (BatteryInfo*) -> 0, -1 no battery device + /* Process.hpp -- the caller's own capability masks. */ + static constexpr uint64_t SYS_GETCAPS = 189; // (SpawnCapabilities*) -> 0, -1 bad pointer + /* Kernel-owned process capabilities. User identities may namespace per-user resources, but never participate in authorization decisions. */ static constexpr uint64_t CAP_PROCESS_ADMIN = 1ULL << 0; diff --git a/programs/include/Api/Syscall.hpp b/programs/include/Api/Syscall.hpp index 3cb63a4..34dd643 100644 --- a/programs/include/Api/Syscall.hpp +++ b/programs/include/Api/Syscall.hpp @@ -259,6 +259,9 @@ namespace montauk::abi { /* Battery.hpp -- ACPI battery status */ static constexpr uint64_t SYS_BATTERYINFO = 188; // (BatteryInfo*) -> 0, -1 no battery device + // The caller's own capability masks. + static constexpr uint64_t SYS_GETCAPS = 189; // (SpawnCapabilities*) -> 0, -1 bad pointer + /* Kernel-owned process capabilities. User identities may namespace per-user resources, but never participate in authorization decisions. */ static constexpr uint64_t CAP_PROCESS_ADMIN = 1ULL << 0; diff --git a/programs/include/libc/montauk.h b/programs/include/libc/montauk.h index 49b3066..fcbecf1 100644 --- a/programs/include/libc/montauk.h +++ b/programs/include/libc/montauk.h @@ -212,6 +212,7 @@ extern "C" { #define MTK_SYS_SPAWN_REDIR_CAPS 186 #define MTK_SYS_ALLOC_EAGER 187 #define MTK_SYS_BATTERYINFO 188 +#define MTK_SYS_GETCAPS 189 /* @SYSCALLS-END */ #define MTK_SOCK_TCP 1 diff --git a/programs/include/montauk/capabilities.h b/programs/include/montauk/capabilities.h index bba9fad..8f70a2f 100644 --- a/programs/include/montauk/capabilities.h +++ b/programs/include/montauk/capabilities.h @@ -15,7 +15,6 @@ namespace caps { inline constexpr const char* GRANT_CONFIG = "capabilities"; inline constexpr const char* GRANT_PREFIX = "grant."; - inline constexpr int MAX_SCAN_PROCS = 256; struct CapName { const char* name; @@ -134,26 +133,7 @@ namespace caps { // The calling process's own capability masks. inline bool self(montauk::abi::SpawnCapabilities& out) { out = {0, 0, 0}; - - auto* table = (montauk::abi::ProcInfo*)montauk::malloc( - sizeof(montauk::abi::ProcInfo) * MAX_SCAN_PROCS); - if (table == nullptr) return false; - - int count = montauk::proclist(table, MAX_SCAN_PROCS); - int self_pid = montauk::getpid(); - - bool found = false; - for (int i = 0; i < count; i++) { - if (table[i].pid != self_pid) continue; - out.permitted = table[i].permittedCaps; - out.effective = table[i].effectiveCaps; - out.delegable = table[i].delegableCaps; - found = true; - break; - } - - montauk::mfree(table); - return found; + return montauk::getcaps(&out) == 0; } inline uint64_t self_delegable() { diff --git a/programs/include/montauk/syscall.h b/programs/include/montauk/syscall.h index 5bdee4b..943f5ce 100644 --- a/programs/include/montauk/syscall.h +++ b/programs/include/montauk/syscall.h @@ -127,6 +127,10 @@ namespace montauk { (uint64_t)args, (uint64_t)user, (uint64_t)&capabilities); } + // The calling process's own capability masks. Returns 0 on success. + inline int getcaps(montauk::abi::SpawnCapabilities* out) { + return (int)syscall1(montauk::abi::SYS_GETCAPS, (uint64_t)out); + } inline int chdir(const char* path) { return (int)syscall1(montauk::abi::SYS_CHDIR, (uint64_t)path); }