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:
2026-10-18 22:22:48 +02:00
parent 61e28f0af5
commit ea2ac5d1d9
12 changed files with 100 additions and 92 deletions

View File

@@ -1,9 +1,13 @@
use crate::hw::uart::Uart;
use crate::hw::virtio_gpu::VirtioGpu;
use crate::{kernel_ref, mmu};
use crate::mmu;
use types::display::Dimension;
use types::id::ProcessId;
fn kern() -> &'static mut kernel::Kernel<crate::platform::RiscVPlatform> {
unsafe { &mut *crate::kernel_ptr() }
}
const GPU_VA: usize = 0x20000;
const VQUEUE_VA: usize = 0x21000;
const CMDBUF_VA: usize = 0x23000;
@@ -23,7 +27,7 @@ pub fn configure(uart: &Uart, display_pid: ProcessId) {
}
};
let pt_addr = kernel_ref().platform_mut().page_table_for(display_pid);
let pt_addr = kern().platform_mut().page_table_for(display_pid);
let pt = unsafe { &mut *(pt_addr as *mut mmu::PageTable) };
map_page(pt, GPU_VA, gpu.base());

View File

@@ -1,11 +1,12 @@
use crate::hw::uart::Uart;
use crate::{board, kernel_ref, mmu};
use crate::{board, mmu};
use types::id::ProcessId;
const UART_VA: usize = 0x20000;
pub fn configure(uart: &Uart, input_pid: ProcessId) {
let pt_addr = kernel_ref().platform_mut().page_table_for(input_pid);
let kern = unsafe { &mut *crate::kernel_ptr() };
let pt_addr = kern.platform_mut().page_table_for(input_pid);
let pt = unsafe { &mut *(pt_addr as *mut mmu::PageTable) };
mmu::map(pt, mmu::Mapping {

View File

@@ -1,7 +1,11 @@
use crate::hw::uart::Uart;
use crate::{kernel_ref, mmu};
use crate::mmu;
use types::id::ProcessId;
fn kern() -> &'static mut kernel::Kernel<crate::platform::RiscVPlatform> {
unsafe { &mut *crate::kernel_ptr() }
}
const VIRTIO_VA: usize = 0x20000;
const VQUEUE_VA: usize = 0x21000;
const REQHDR_VA: usize = 0x23000;
@@ -30,7 +34,7 @@ pub fn configure(
}
fn get_pt(pid: ProcessId) -> &'static mut mmu::PageTable {
let addr = kernel_ref().platform_mut().page_table_for(pid);
let addr = kern().platform_mut().page_table_for(pid);
unsafe { &mut *(addr as *mut mmu::PageTable) }
}