Make interrupt stack readable on kernel signals

This commit is contained in:
jD91mZM2
2020-07-08 10:54:34 +02:00
parent 92cad589d9
commit 103ed1b17f
2 changed files with 32 additions and 18 deletions

View File

@@ -48,9 +48,8 @@ impl ScratchRegisters {
}
macro_rules! scratch_push {
() => (asm!(
"push rax
push rcx
(without rax) => (asm!(
"push rcx
push rdx
push rdi
push rsi
@@ -60,6 +59,10 @@ macro_rules! scratch_push {
push r11"
: : : : "intel", "volatile"
));
() => ({
asm!("push rax" : : : : "intel", "volatile");
scratch_push!(without rax);
});
}
macro_rules! scratch_pop {
@@ -362,20 +365,14 @@ macro_rules! interrupt_stack {
#[derive(Default)]
#[repr(packed)]
pub struct InterruptErrorStack {
pub fs: usize,
pub preserved: PreservedRegisters,
pub scratch: ScratchRegisters,
pub code: usize,
pub iret: IretRegisters,
pub inner: InterruptStack,
}
impl InterruptErrorStack {
pub fn dump(&self) {
self.iret.dump();
self.inner.dump();
println!("CODE: {:>016X}", { self.code });
self.scratch.dump();
self.preserved.dump();
println!("FS: {:>016X}", { self.fs });
}
}
@@ -385,12 +382,23 @@ macro_rules! interrupt_error {
#[naked]
pub unsafe extern fn $name () {
#[inline(never)]
unsafe fn inner($stack: &$crate::arch::x86_64::macros::InterruptErrorStack) {
unsafe fn inner($stack: &mut $crate::arch::x86_64::macros::InterruptErrorStack) {
let _guard = ptrace::set_process_regs(&mut $stack.inner);
$func
}
// Push scratch registers
interrupt_push!();
// Swap RAX and error code, in order to push the code later and be
// compatible with InterruptStack.
asm!("xchg [rsp], rax" : : : : "intel", "volatile");
// Push all the registers (except for rax which is already pushed,
// in place of the error code)
scratch_push!(without rax);
preserved_push!();
fs_push!();
// Finally, push rax (now containing error code)
asm!("push rax" : : : : "intel", "volatile");
// Get reference to stack variables
let rsp: usize;
@@ -400,14 +408,14 @@ macro_rules! interrupt_error {
$crate::arch::x86_64::pti::map();
// Call inner rust function
inner(&*(rsp as *const $crate::arch::x86_64::macros::InterruptErrorStack));
inner(&mut *(rsp as *mut $crate::arch::x86_64::macros::InterruptErrorStack));
// Unmap kernel
$crate::arch::x86_64::pti::unmap();
// Pop scratch registers, error code, and return
interrupt_pop!();
// Pop error code, registers, and return
asm!("add rsp, 8" : : : : "intel", "volatile"); // pop error code
interrupt_pop!();
iret!();
}
};

View File

@@ -274,5 +274,11 @@ pub extern fn ksignal(signal: usize) {
println!("NAME {}", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) });
}
}
syscall::exit(signal & 0x7F);
// Try running kill(getpid(), signal), but fallback to exiting
syscall::getpid()
.and_then(|pid| syscall::kill(pid, signal).map(|_| ()))
.unwrap_or_else(|_| {
syscall::exit(signal & 0x7F);
});
}