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:
@@ -1,7 +1,10 @@
|
||||
use crate::hw::uart::Uart;
|
||||
use crate::kernel_ref;
|
||||
use types::id::ProcessId;
|
||||
|
||||
fn kern() -> &'static mut kernel::Kernel<crate::platform::RiscVPlatform> {
|
||||
unsafe { &mut *crate::kernel_ptr() }
|
||||
}
|
||||
|
||||
pub fn grant_all(
|
||||
uart: &Uart,
|
||||
init_pid: ProcessId,
|
||||
@@ -19,48 +22,37 @@ pub fn grant_all(
|
||||
.with(types::permission::Permission::Read)
|
||||
.with(types::permission::Permission::Execute);
|
||||
|
||||
// Storage endpoint
|
||||
let storage_ep = kernel_ref().create_endpoint()
|
||||
let storage_ep = kern().create_endpoint()
|
||||
.unwrap_or_else(|_| crate::halt(uart, "storage endpoint failed"));
|
||||
|
||||
// Init: slot 0 = ProcessCreate (from boot)
|
||||
// slot 1 = Process(storage)
|
||||
// slot 2 = Endpoint(storage)
|
||||
kernel_ref().grant_capability(init_pid, domain::resource::Resource::Process(storage_pid), all_perms)
|
||||
kern().grant_capability(init_pid, domain::resource::Resource::Process(storage_pid), all_perms)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
kernel_ref().grant_capability(init_pid, domain::resource::Resource::Endpoint(storage_ep), all_perms)
|
||||
kern().grant_capability(init_pid, domain::resource::Resource::Endpoint(storage_ep), all_perms)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
// Storage: slot 0 = Endpoint
|
||||
kernel_ref().grant_capability(storage_pid, domain::resource::Resource::Endpoint(storage_ep), ipc_perms)
|
||||
kern().grant_capability(storage_pid, domain::resource::Resource::Endpoint(storage_ep), ipc_perms)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
// Display endpoint
|
||||
let display_ep = kernel_ref().create_endpoint()
|
||||
let display_ep = kern().create_endpoint()
|
||||
.unwrap_or_else(|_| crate::halt(uart, "display endpoint failed"));
|
||||
|
||||
// Display: slot 0 = Endpoint
|
||||
kernel_ref().grant_capability(display_pid, domain::resource::Resource::Endpoint(display_ep), ipc_perms)
|
||||
kern().grant_capability(display_pid, domain::resource::Resource::Endpoint(display_ep), ipc_perms)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
// Init: slot 3 = Endpoint(display), slot 4 = Process(display)
|
||||
kernel_ref().grant_capability(init_pid, domain::resource::Resource::Endpoint(display_ep), all_perms)
|
||||
kern().grant_capability(init_pid, domain::resource::Resource::Endpoint(display_ep), all_perms)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
kernel_ref().grant_capability(init_pid, domain::resource::Resource::Process(display_pid), all_perms)
|
||||
kern().grant_capability(init_pid, domain::resource::Resource::Process(display_pid), all_perms)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
// Input endpoint
|
||||
let input_ep = kernel_ref().create_endpoint()
|
||||
let input_ep = kern().create_endpoint()
|
||||
.unwrap_or_else(|_| crate::halt(uart, "input endpoint failed"));
|
||||
|
||||
// Input: slot 0 = Endpoint
|
||||
kernel_ref().grant_capability(input_pid, domain::resource::Resource::Endpoint(input_ep), ipc_perms)
|
||||
kern().grant_capability(input_pid, domain::resource::Resource::Endpoint(input_ep), ipc_perms)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
// Init: slot 5 = Endpoint(input), slot 6 = Process(input)
|
||||
kernel_ref().grant_capability(init_pid, domain::resource::Resource::Endpoint(input_ep), all_perms)
|
||||
kern().grant_capability(init_pid, domain::resource::Resource::Endpoint(input_ep), all_perms)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
kernel_ref().grant_capability(init_pid, domain::resource::Resource::Process(input_pid), all_perms)
|
||||
kern().grant_capability(init_pid, domain::resource::Resource::Process(input_pid), all_perms)
|
||||
.unwrap_or_else(|_| crate::halt(uart, "grant failed"));
|
||||
|
||||
uart.write_str("k-os: capabilities granted\n");
|
||||
|
||||
Reference in New Issue
Block a user