core: Check the stack is in user memory before changing it to kernel space

Otherwise, we're just adding the physical base to an address that's already in the higher half.
This commit is contained in:
Gabriel 2025-02-21 18:47:24 +01:00
parent 785335bd9a
commit 8156ff57fe
2 changed files with 15 additions and 2 deletions

View File

@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const interrupts = @import("interrupts.zig"); const interrupts = @import("interrupts.zig");
pub inline fn enterTask(regs: *interrupts.InterruptStackFrame, comptime base: u64, directory: u64) noreturn { pub inline fn enterTask(regs: *interrupts.InterruptStackFrame, base: u64, directory: u64) noreturn {
asm volatile ( asm volatile (
\\ addq %[base], %rsp \\ addq %[base], %rsp
\\ push %[ss] \\ push %[ss]
@ -47,6 +47,13 @@ pub fn idleLoop() callconv(.Naked) noreturn {
); );
} }
pub inline fn readStackPointer() usize {
return asm volatile (
\\ mov %rsp, %[result]
: [result] "=r" (-> usize),
);
}
pub fn setAddress(regs: *interrupts.InterruptStackFrame, address: u64) void { pub fn setAddress(regs: *interrupts.InterruptStackFrame, address: u64) void {
regs.rip = address; regs.rip = address;
} }

View File

@ -44,7 +44,13 @@ pub fn enterTask(task: *ThreadControlBlock) noreturn {
task.state = .Running; task.state = .Running;
arch.enterTask(&task.regs, vmm.PHYSICAL_MAPPING_BASE, table.address); // If the stack is in user memory, then we need a pointer to its higher-half version. If it's already in kernel memory, no need to do anything.
var base: usize = 0;
if (arch.readStackPointer() < vmm.PHYSICAL_MAPPING_BASE) {
base += vmm.PHYSICAL_MAPPING_BASE;
}
arch.enterTask(&task.regs, base, table.address);
} }
fn switchTask(regs: *interrupts.InterruptStackFrame, new_task: *ThreadControlBlock) void { fn switchTask(regs: *interrupts.InterruptStackFrame, new_task: *ThreadControlBlock) void {