core: Add "tokens" to determine what processes can call which syscalls
This commit is contained in:
parent
6fa70693a5
commit
c24bc8ed27
@ -1,4 +1,5 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const system = @import("system");
|
||||||
const easyboot = @cImport(@cInclude("easyboot.h"));
|
const easyboot = @cImport(@cInclude("easyboot.h"));
|
||||||
const debug = @import("arch/debug.zig");
|
const debug = @import("arch/debug.zig");
|
||||||
const cpu = @import("arch/cpu.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.address_space = space;
|
||||||
init.user_priority = 255;
|
init.user_priority = 255;
|
||||||
|
init.tokens = @intFromEnum(system.kernel.Token.Root);
|
||||||
thread.arch.initUserRegisters(&init.regs);
|
thread.arch.initUserRegisters(&init.regs);
|
||||||
thread.arch.setArguments(&init.regs, base, space.phys.address);
|
thread.arch.setArguments(&init.regs, base, space.phys.address);
|
||||||
|
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
|
const system = @import("system");
|
||||||
const platform = @import("../arch/platform.zig");
|
const platform = @import("../arch/platform.zig");
|
||||||
const sys = @import("syscall.zig");
|
const sys = @import("syscall.zig");
|
||||||
const pmm = @import("../pmm.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 {
|
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();
|
const allocator = pmm.lockGlobalAllocator();
|
||||||
defer pmm.unlockGlobalAllocator();
|
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 {
|
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();
|
const allocator = pmm.lockGlobalAllocator();
|
||||||
defer pmm.unlockGlobalAllocator();
|
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 {
|
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();
|
const allocator = pmm.lockGlobalAllocator();
|
||||||
defer pmm.unlockGlobalAllocator();
|
defer pmm.unlockGlobalAllocator();
|
||||||
|
|
||||||
try pmm.lockFrame(allocator, args.arg0);
|
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);
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@ const RingBuffer = system.ring_buffer.RingBuffer;
|
|||||||
const SyscallError = error{
|
const SyscallError = error{
|
||||||
NoSuchThread,
|
NoSuchThread,
|
||||||
ThreadQueueAlreadySet,
|
ThreadQueueAlreadySet,
|
||||||
|
NotAuthorized,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn yield(regs: *platform.Registers, _: *sys.Arguments, _: *isize) anyerror!void {
|
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 {
|
pub fn setPriority(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||||
const core = cpu.thisCore();
|
const core = cpu.thisCore();
|
||||||
|
|
||||||
|
if (!sys.checkToken(core, system.kernel.Token.ThreadPriority)) return error.NotAuthorized;
|
||||||
|
|
||||||
core.current_thread.user_priority = @truncate(args.arg0);
|
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 {
|
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;
|
const target = thread.lookupThreadById(args.arg0) orelse return error.NoSuchThread;
|
||||||
|
|
||||||
if (target.event_queue) |_| return error.ThreadQueueAlreadySet;
|
if (target.event_queue) |_| return error.ThreadQueueAlreadySet;
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const system = @import("system");
|
||||||
const platform = @import("../arch/platform.zig");
|
const platform = @import("../arch/platform.zig");
|
||||||
const print = @import("print.zig");
|
const print = @import("print.zig");
|
||||||
const mem = @import("mem.zig");
|
const mem = @import("mem.zig");
|
||||||
const sched = @import("sched.zig");
|
const sched = @import("sched.zig");
|
||||||
|
const tokens = @import("token.zig");
|
||||||
|
const cpu = @import("../arch/cpu.zig");
|
||||||
|
|
||||||
pub const Arguments = struct {
|
pub const Arguments = struct {
|
||||||
arg0: usize,
|
arg0: usize,
|
||||||
@ -15,7 +18,18 @@ pub const Arguments = struct {
|
|||||||
|
|
||||||
const SystemCall = *const fn (frame: *platform.Registers, args: *Arguments, retval: *isize) anyerror!void;
|
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 {
|
pub fn invokeSyscall(number: usize, frame: *platform.Registers, args: *Arguments, retval: *isize) void {
|
||||||
if (number >= syscalls.len) {
|
if (number >= syscalls.len) {
|
||||||
@ -28,3 +42,7 @@ pub fn invokeSyscall(number: usize, frame: *platform.Registers, args: *Arguments
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn checkToken(core: *cpu.arch.Core, token: system.kernel.Token) bool {
|
||||||
|
return (core.current_thread.tokens & @intFromEnum(token)) > 0;
|
||||||
|
}
|
||||||
|
14
core/src/sys/token.zig
Normal file
14
core/src/sys/token.zig
Normal file
@ -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;
|
||||||
|
}
|
@ -24,6 +24,7 @@ pub const ThreadControlBlock = struct {
|
|||||||
state: ThreadState,
|
state: ThreadState,
|
||||||
user_priority: u8,
|
user_priority: u8,
|
||||||
event_queue: ?RingBuffer,
|
event_queue: ?RingBuffer,
|
||||||
|
tokens: u64,
|
||||||
|
|
||||||
// Managed by addThreadToGlobalList(), no need to set manually.
|
// Managed by addThreadToGlobalList(), no need to set manually.
|
||||||
tag: GlobalThreadList.Node,
|
tag: GlobalThreadList.Node,
|
||||||
@ -151,6 +152,7 @@ pub fn createThreadControlBlock(allocator: *pmm.FrameAllocator) !*ThreadControlB
|
|||||||
thread.state = .Inactive;
|
thread.state = .Inactive;
|
||||||
thread.user_priority = 127;
|
thread.user_priority = 127;
|
||||||
thread.event_queue = null;
|
thread.event_queue = null;
|
||||||
|
thread.tokens = 0;
|
||||||
|
|
||||||
addThreadToGlobalList(thread);
|
addThreadToGlobalList(thread);
|
||||||
|
|
||||||
|
@ -7,17 +7,30 @@ const buffer = system.ring_buffer;
|
|||||||
// FIXME: Make arch-specific.
|
// FIXME: Make arch-specific.
|
||||||
const PAGE_SIZE = 4096;
|
const PAGE_SIZE = 4096;
|
||||||
|
|
||||||
|
const SELF_PID = 1;
|
||||||
|
|
||||||
fn setupKernelRingBuffer(base: u64) !buffer.RingBuffer {
|
fn setupKernelRingBuffer(base: u64) !buffer.RingBuffer {
|
||||||
const phys = vm.PhysFrame{ .address = try syscalls.allocFrame() };
|
const phys = vm.PhysFrame{ .address = try syscalls.allocFrame() };
|
||||||
|
|
||||||
const data: [*]u8 = @ptrCast(phys.virtualPointer(u8, base));
|
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);
|
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 {
|
export fn _start(base: u64, address: u64) callconv(.C) noreturn {
|
||||||
|
setTokens();
|
||||||
|
|
||||||
const mapper = vm.MemoryMapper.create(.{ .address = address }, base);
|
const mapper = vm.MemoryMapper.create(.{ .address = address }, base);
|
||||||
|
|
||||||
syscalls.print(base);
|
syscalls.print(base);
|
||||||
|
@ -8,9 +8,20 @@ pub const SystemCall = enum(u64) {
|
|||||||
GetPriority,
|
GetPriority,
|
||||||
Sleep,
|
Sleep,
|
||||||
SetEventQueue,
|
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{
|
pub const SystemError = error{
|
||||||
OutOfMemory,
|
OutOfMemory,
|
||||||
NoSuchThread,
|
NoSuchThread,
|
||||||
|
NotAuthorized,
|
||||||
};
|
};
|
||||||
|
@ -51,3 +51,8 @@ pub fn setEventQueue(pid: u64, address: u64) !void {
|
|||||||
const retval = syscall(.SetEventQueue, pid, address);
|
const retval = syscall(.SetEventQueue, pid, address);
|
||||||
if (retval < 0) return error.NoSuchThread;
|
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;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user