mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-04-20 15:18:26 -04:00
Merge pull request #241 from TroyNeubauer/handle-sigsev
This commit is contained in:
@@ -56,6 +56,9 @@ pub async fn do_signal(id: SigId, sa: UserspaceSigAction) -> Result<ExceptionSta
|
||||
.align(PAGE_SIZE)
|
||||
};
|
||||
|
||||
drop(signal);
|
||||
drop(task);
|
||||
|
||||
copy_to_user(addr, frame).await?;
|
||||
|
||||
new_state.sp_el0 = addr.value() as _;
|
||||
|
||||
@@ -17,6 +17,7 @@ per_cpu_private! {
|
||||
pub(super) struct CurrentTaskPtr {
|
||||
pub(super) ptr: Cell<*mut OwnedTask>,
|
||||
pub(super) borrowed: Cell<bool>,
|
||||
location: Cell<Option<core::panic::Location<'static>>>,
|
||||
}
|
||||
|
||||
unsafe impl Send for CurrentTaskPtr {}
|
||||
@@ -42,7 +43,9 @@ impl DerefMut for CurrentTaskGuard<'_> {
|
||||
|
||||
impl<'a> Drop for CurrentTaskGuard<'a> {
|
||||
fn drop(&mut self) {
|
||||
CUR_TASK_PTR.borrow().borrowed.set(false);
|
||||
let current = CUR_TASK_PTR.borrow();
|
||||
current.borrowed.set(false);
|
||||
current.location.set(None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,15 +54,19 @@ impl CurrentTaskPtr {
|
||||
Self {
|
||||
ptr: Cell::new(ptr::null_mut()),
|
||||
borrowed: Cell::new(false),
|
||||
location: Cell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn current(&self) -> CurrentTaskGuard<'static> {
|
||||
if self.borrowed.get() {
|
||||
panic!("Double mutable borrow of current task!");
|
||||
let other = self.location.take();
|
||||
panic!("Double mutable borrow of current task! Borrowed from: {other:?}");
|
||||
}
|
||||
|
||||
self.borrowed.set(true);
|
||||
self.location.set(Some(*core::panic::Location::caller()));
|
||||
|
||||
unsafe {
|
||||
let ptr = self.ptr.get();
|
||||
|
||||
@@ -157,3 +157,63 @@ fn test_interruptible_waitpid() {
|
||||
}
|
||||
|
||||
register_test!(test_interruptible_waitpid);
|
||||
|
||||
fn segfault_child(inner: impl FnOnce()) {
|
||||
unsafe {
|
||||
let pid = libc::fork();
|
||||
if pid < 0 {
|
||||
panic!("fork failed");
|
||||
} else if pid == 0 {
|
||||
// Child process
|
||||
inner()
|
||||
} else {
|
||||
// Parent process
|
||||
let mut status = 0;
|
||||
let rusage = std::ptr::null_mut();
|
||||
libc::wait4(pid, &mut status, 0, rusage);
|
||||
|
||||
assert!(libc::WIFSIGNALED(status));
|
||||
assert_eq!(libc::WTERMSIG(status), libc::SIGSEGV);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_segfault_read() {
|
||||
segfault_child(|| {
|
||||
let addr: *const u8 = std::hint::black_box(std::ptr::null());
|
||||
let _ = unsafe { std::ptr::read(addr) };
|
||||
});
|
||||
segfault_child(|| {
|
||||
// Ensure reading from kernel stack fails
|
||||
let addr = 0xffff_ba00_0000_0000 as *const u8;
|
||||
let _ = unsafe { std::ptr::read(addr) };
|
||||
});
|
||||
}
|
||||
|
||||
register_test!(test_segfault_read);
|
||||
|
||||
fn test_segfault_write() {
|
||||
segfault_child(|| {
|
||||
let addr: *mut u8 = std::hint::black_box(std::ptr::null_mut());
|
||||
unsafe { std::ptr::write(addr, 42) };
|
||||
});
|
||||
segfault_child(|| {
|
||||
let addr = 0xffff_ba00_0000_0000 as *mut u8;
|
||||
unsafe { std::ptr::write(addr, 42) };
|
||||
});
|
||||
}
|
||||
|
||||
register_test!(test_segfault_write);
|
||||
|
||||
fn rust_stack_overflow() {
|
||||
segfault_child(|| {
|
||||
#[allow(unconditional_recursion)]
|
||||
fn recurse(n: usize) -> usize {
|
||||
let m = std::hint::black_box(n) + 1;
|
||||
recurse(m)
|
||||
}
|
||||
recurse(0);
|
||||
});
|
||||
}
|
||||
|
||||
register_test!(rust_stack_overflow);
|
||||
|
||||
Reference in New Issue
Block a user