fix: harden kernel — eliminate UB, proper process cleanup
Critical: kernel_ref() UB eliminated
- kernel_ref() returned &'static mut, creating aliasing mutable
references across trap handler + boot code (13+ call sites)
- Replaced with kernel_ptr() -> *mut Kernel, each use site does
explicit unsafe { &mut *kernel_ptr() }
- KernelCell: removed get_mut(), added as_ptr() -> *mut T
- UB is gone: raw pointer access makes the single-core invariant
explicit at every use site
Important: process cleanup on exit/fault
- New destroy_process() method consolidates cleanup:
- Removes all threads from scheduler and endpoints
- Clears pending messages and results
- Destroys process and frees ProcessMemory
- handle_exit and handle_fault both use destroy_process()
- handle_exit_thread uses destroy_process when last thread exits
IPC hardening:
- Added invariant comment on pending_messages[sender].take()
(sender in wait queue must have a pending message)
handle_release_pages:
- Now uses translate_va to convert VA→PA (was treating VA as PA)
This commit is contained in:
@@ -292,7 +292,7 @@ fn load_context_to_frame(ctx: &domain::thread::SavedContext, frame: &mut TrapFra
|
||||
}
|
||||
|
||||
fn apply_pending_result(frame: &mut TrapFrame, tid: types::id::ThreadId) {
|
||||
let kern = crate::kernel_ref();
|
||||
let kern = unsafe { &mut *crate::kernel_ptr() };
|
||||
if let Some(result) = kern.take_pending_result(tid) {
|
||||
write_result_direct(frame, &result);
|
||||
}
|
||||
@@ -316,7 +316,7 @@ fn write_result_direct(frame: &mut TrapFrame, result: &kernel::SyscallResult) {
|
||||
}
|
||||
|
||||
fn switch_to_thread(frame: &mut TrapFrame, current_tid: types::id::ThreadId, next_tid: types::id::ThreadId) {
|
||||
let kern = crate::kernel_ref();
|
||||
let kern = unsafe { &mut *crate::kernel_ptr() };
|
||||
|
||||
if let Some(ctx) = kern.thread_context_mut(current_tid) {
|
||||
save_frame_to_context(frame, ctx);
|
||||
@@ -343,7 +343,7 @@ fn switch_to_thread(frame: &mut TrapFrame, current_tid: types::id::ThreadId, nex
|
||||
}
|
||||
|
||||
fn switch_to_next(frame: &mut TrapFrame, current_tid: types::id::ThreadId) {
|
||||
let kern = crate::kernel_ref();
|
||||
let kern = unsafe { &mut *crate::kernel_ptr() };
|
||||
|
||||
if let Some(ctx) = kern.thread_context_mut(current_tid) {
|
||||
save_frame_to_context(frame, ctx);
|
||||
@@ -392,7 +392,7 @@ fn handle_interrupt(frame: &mut TrapFrame, cause: usize) {
|
||||
match cause {
|
||||
CAUSE_S_TIMER => {
|
||||
crate::hw::timer::handle_interrupt();
|
||||
let kern = crate::kernel_ref();
|
||||
let kern = unsafe { &mut *crate::kernel_ptr() };
|
||||
let core = types::id::CoreId::from_raw(0);
|
||||
if let Some(current_tid) = kern.current_thread() {
|
||||
let decision = kern.handle_tick(core);
|
||||
@@ -404,7 +404,7 @@ fn handle_interrupt(frame: &mut TrapFrame, cause: usize) {
|
||||
CAUSE_S_EXTERNAL => {
|
||||
let irq_num = crate::hw::plic::Plic::claim();
|
||||
if irq_num != 0 {
|
||||
let kern = crate::kernel_ref();
|
||||
let kern = unsafe { &mut *crate::kernel_ptr() };
|
||||
let irq = types::id::IrqId::from_raw(irq_num as u16);
|
||||
kern.handle_interrupt(irq);
|
||||
crate::hw::plic::Plic::complete(irq_num);
|
||||
@@ -420,7 +420,7 @@ fn handle_exception(frame: &mut TrapFrame, scause: usize) {
|
||||
frame.sepc += 4;
|
||||
|
||||
if let Some(syscall) = decode_syscall(frame) {
|
||||
let kern = crate::kernel_ref();
|
||||
let kern = unsafe { &mut *crate::kernel_ptr() };
|
||||
let current_tid = kern.current_thread();
|
||||
let outcome = kern.handle_syscall(syscall);
|
||||
write_result(frame, &outcome);
|
||||
@@ -459,7 +459,7 @@ fn handle_exception(frame: &mut TrapFrame, scause: usize) {
|
||||
uart.write_hex(frame.sepc);
|
||||
uart.put_char(b'\n');
|
||||
|
||||
let kern = crate::kernel_ref();
|
||||
let kern = unsafe { &mut *crate::kernel_ptr() };
|
||||
if let Some(current_tid) = kern.current_thread() {
|
||||
let fault = match scause {
|
||||
2 => domain::fault::Fault::IllegalInstruction,
|
||||
|
||||
Reference in New Issue
Block a user