From c24bc8ed278a6929eae0d7276b5fa3528b469222 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Sat, 22 Feb 2025 20:11:07 +0100 Subject: [PATCH] core: Add "tokens" to determine what processes can call which syscalls --- core/src/main.zig | 2 ++ core/src/sys/mem.zig | 22 ++++++++++++++++++++++ core/src/sys/sched.zig | 6 ++++++ core/src/sys/syscall.zig | 20 +++++++++++++++++++- core/src/sys/token.zig | 14 ++++++++++++++ core/src/thread.zig | 2 ++ system/init/main.zig | 15 ++++++++++++++- system/lib/kernel.zig | 11 +++++++++++ system/lib/syscalls.zig | 5 +++++ 9 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 core/src/sys/token.zig diff --git a/core/src/main.zig b/core/src/main.zig index cfe340a..b0e104a 100644 --- a/core/src/main.zig +++ b/core/src/main.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const system = @import("system"); const easyboot = @cImport(@cInclude("easyboot.h")); const debug = @import("arch/debug.zig"); const cpu = @import("arch/cpu.zig"); @@ -70,6 +71,7 @@ export fn _start(magic: u32, info: MultibootInfo) callconv(.C) noreturn { init.address_space = space; init.user_priority = 255; + init.tokens = @intFromEnum(system.kernel.Token.Root); thread.arch.initUserRegisters(&init.regs); thread.arch.setArguments(&init.regs, base, space.phys.address); diff --git a/core/src/sys/mem.zig b/core/src/sys/mem.zig index 7301084..985298d 100644 --- a/core/src/sys/mem.zig +++ b/core/src/sys/mem.zig @@ -1,8 +1,15 @@ +const system = @import("system"); const platform = @import("../arch/platform.zig"); const sys = @import("syscall.zig"); const pmm = @import("../pmm.zig"); +const cpu = @import("../arch/cpu.zig"); +const thread = @import("../thread.zig"); +const vmm = @import("../arch/vmm.zig"); pub fn allocFrame(_: *platform.Registers, _: *sys.Arguments, retval: *isize) anyerror!void { + const core = cpu.thisCore(); + if (!sys.checkToken(core, system.kernel.Token.PhysicalMemory)) return error.NotAuthorized; + const allocator = pmm.lockGlobalAllocator(); defer pmm.unlockGlobalAllocator(); @@ -12,6 +19,9 @@ pub fn allocFrame(_: *platform.Registers, _: *sys.Arguments, retval: *isize) any } pub fn freeFrame(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void { + const core = cpu.thisCore(); + if (!sys.checkToken(core, system.kernel.Token.PhysicalMemory)) return error.NotAuthorized; + const allocator = pmm.lockGlobalAllocator(); defer pmm.unlockGlobalAllocator(); @@ -19,8 +29,20 @@ pub fn freeFrame(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerr } pub fn lockFrame(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void { + const core = cpu.thisCore(); + if (!sys.checkToken(core, system.kernel.Token.PhysicalMemory)) return error.NotAuthorized; + const allocator = pmm.lockGlobalAllocator(); defer pmm.unlockGlobalAllocator(); try pmm.lockFrame(allocator, args.arg0); } + +pub fn setAddressSpace(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void { + const core = cpu.thisCore(); + if (!sys.checkToken(core, system.kernel.Token.VirtualMemory)) return error.NotAuthorized; + + const target = thread.lookupThreadById(args.arg0) orelse return error.NoSuchThread; + + target.address_space = vmm.AddressSpace.create(.{ .address = args.arg1 }, vmm.PHYSICAL_MAPPING_BASE); +} diff --git a/core/src/sys/sched.zig b/core/src/sys/sched.zig index 865746d..244874c 100644 --- a/core/src/sys/sched.zig +++ b/core/src/sys/sched.zig @@ -12,6 +12,7 @@ const RingBuffer = system.ring_buffer.RingBuffer; const SyscallError = error{ NoSuchThread, ThreadQueueAlreadySet, + NotAuthorized, }; pub fn yield(regs: *platform.Registers, _: *sys.Arguments, _: *isize) anyerror!void { @@ -23,6 +24,9 @@ pub fn yield(regs: *platform.Registers, _: *sys.Arguments, _: *isize) anyerror!v pub fn setPriority(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void { const core = cpu.thisCore(); + + if (!sys.checkToken(core, system.kernel.Token.ThreadPriority)) return error.NotAuthorized; + core.current_thread.user_priority = @truncate(args.arg0); } @@ -36,6 +40,8 @@ pub fn sleep(regs: *platform.Registers, args: *sys.Arguments, _: *isize) anyerro } pub fn setEventQueue(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void { + const core = cpu.thisCore(); + if (!sys.checkToken(core, system.kernel.Token.EventQueue)) return error.NotAuthorized; const target = thread.lookupThreadById(args.arg0) orelse return error.NoSuchThread; if (target.event_queue) |_| return error.ThreadQueueAlreadySet; diff --git a/core/src/sys/syscall.zig b/core/src/sys/syscall.zig index 9c14fb5..4616530 100644 --- a/core/src/sys/syscall.zig +++ b/core/src/sys/syscall.zig @@ -1,8 +1,11 @@ const std = @import("std"); +const system = @import("system"); const platform = @import("../arch/platform.zig"); const print = @import("print.zig"); const mem = @import("mem.zig"); const sched = @import("sched.zig"); +const tokens = @import("token.zig"); +const cpu = @import("../arch/cpu.zig"); pub const Arguments = struct { arg0: usize, @@ -15,7 +18,18 @@ pub const Arguments = struct { const SystemCall = *const fn (frame: *platform.Registers, args: *Arguments, retval: *isize) anyerror!void; -const syscalls = [_]SystemCall{ print.print, mem.allocFrame, mem.lockFrame, mem.freeFrame, sched.yield, sched.setPriority, sched.getPriority, sched.sleep, sched.setEventQueue }; +const syscalls = [_]SystemCall{ + print.print, + mem.allocFrame, + mem.lockFrame, + mem.freeFrame, + sched.yield, + sched.setPriority, + sched.getPriority, + sched.sleep, + sched.setEventQueue, + tokens.setTokens, +}; pub fn invokeSyscall(number: usize, frame: *platform.Registers, args: *Arguments, retval: *isize) void { if (number >= syscalls.len) { @@ -28,3 +42,7 @@ pub fn invokeSyscall(number: usize, frame: *platform.Registers, args: *Arguments return; }; } + +pub fn checkToken(core: *cpu.arch.Core, token: system.kernel.Token) bool { + return (core.current_thread.tokens & @intFromEnum(token)) > 0; +} diff --git a/core/src/sys/token.zig b/core/src/sys/token.zig new file mode 100644 index 0000000..48ca2b5 --- /dev/null +++ b/core/src/sys/token.zig @@ -0,0 +1,14 @@ +const system = @import("system"); +const platform = @import("../arch/platform.zig"); +const sys = @import("syscall.zig"); +const cpu = @import("../arch/cpu.zig"); +const thread = @import("../thread.zig"); + +pub fn setTokens(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void { + const core = cpu.thisCore(); + if (!sys.checkToken(core, system.kernel.Token.Root)) return error.NotAuthorized; + + const target = thread.lookupThreadById(args.arg0) orelse return error.NoSuchThread; + + target.tokens = args.arg1; +} diff --git a/core/src/thread.zig b/core/src/thread.zig index 7a4daba..a815bcb 100644 --- a/core/src/thread.zig +++ b/core/src/thread.zig @@ -24,6 +24,7 @@ pub const ThreadControlBlock = struct { state: ThreadState, user_priority: u8, event_queue: ?RingBuffer, + tokens: u64, // Managed by addThreadToGlobalList(), no need to set manually. tag: GlobalThreadList.Node, @@ -151,6 +152,7 @@ pub fn createThreadControlBlock(allocator: *pmm.FrameAllocator) !*ThreadControlB thread.state = .Inactive; thread.user_priority = 127; thread.event_queue = null; + thread.tokens = 0; addThreadToGlobalList(thread); diff --git a/system/init/main.zig b/system/init/main.zig index 8950d73..caf7e8b 100644 --- a/system/init/main.zig +++ b/system/init/main.zig @@ -7,17 +7,30 @@ const buffer = system.ring_buffer; // FIXME: Make arch-specific. const PAGE_SIZE = 4096; +const SELF_PID = 1; + fn setupKernelRingBuffer(base: u64) !buffer.RingBuffer { const phys = vm.PhysFrame{ .address = try syscalls.allocFrame() }; const data: [*]u8 = @ptrCast(phys.virtualPointer(u8, base)); - try syscalls.setEventQueue(1, phys.address); + try syscalls.setEventQueue(SELF_PID, phys.address); return buffer.RingBuffer.init(data, PAGE_SIZE, true); } +fn setTokens() void { + var tokens: u64 = 0; + tokens |= @intFromEnum(system.kernel.Token.Root); + tokens |= @intFromEnum(system.kernel.Token.PhysicalMemory); + tokens |= @intFromEnum(system.kernel.Token.EventQueue); + tokens |= @intFromEnum(system.kernel.Token.VirtualMemory); + syscalls.setTokens(SELF_PID, tokens) catch {}; +} + export fn _start(base: u64, address: u64) callconv(.C) noreturn { + setTokens(); + const mapper = vm.MemoryMapper.create(.{ .address = address }, base); syscalls.print(base); diff --git a/system/lib/kernel.zig b/system/lib/kernel.zig index 44abc67..0d457a1 100644 --- a/system/lib/kernel.zig +++ b/system/lib/kernel.zig @@ -8,9 +8,20 @@ pub const SystemCall = enum(u64) { GetPriority, Sleep, SetEventQueue, + SetTokens, + SetAddressSpace, +}; + +pub const Token = enum(u64) { + Root = 1 << 0, + PhysicalMemory = 1 << 1, + ThreadPriority = 1 << 2, + EventQueue = 1 << 3, + VirtualMemory = 1 << 4, }; pub const SystemError = error{ OutOfMemory, NoSuchThread, + NotAuthorized, }; diff --git a/system/lib/syscalls.zig b/system/lib/syscalls.zig index cb16857..3de13b9 100644 --- a/system/lib/syscalls.zig +++ b/system/lib/syscalls.zig @@ -51,3 +51,8 @@ pub fn setEventQueue(pid: u64, address: u64) !void { const retval = syscall(.SetEventQueue, pid, address); if (retval < 0) return error.NoSuchThread; } + +pub fn setTokens(pid: u64, tokens: u64) !void { + const retval = syscall(.SetTokens, pid, tokens); + if (retval < 0) return error.NoSuchThread; +}