Always take syscall_head/tail into account during the integrity check
Previously it wouldn't be taken into account if currently used by the kernel.
This commit is contained in:
+42
-27
@@ -71,6 +71,14 @@ pub enum HardBlockedReason {
|
||||
|
||||
const CONTEXT_NAME_CAPAC: usize = 32;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SyscallFrame {
|
||||
Free(RaiiFrame),
|
||||
// The field is used by the consistency checker of the kernel debugger
|
||||
Used { _frame: Frame },
|
||||
Dummy,
|
||||
}
|
||||
|
||||
/// A context, which is typically mapped to a userspace thread
|
||||
#[derive(Debug)]
|
||||
pub struct Context {
|
||||
@@ -100,10 +108,10 @@ pub struct Context {
|
||||
|
||||
/// Head buffer to use when system call buffers are not page aligned
|
||||
// TODO: Store in user memory?
|
||||
pub syscall_head: Option<RaiiFrame>,
|
||||
pub syscall_head: SyscallFrame,
|
||||
/// Tail buffer to use when system call buffers are not page aligned
|
||||
// TODO: Store in user memory?
|
||||
pub syscall_tail: Option<RaiiFrame>,
|
||||
pub syscall_tail: SyscallFrame,
|
||||
/// Context should wake up at specified time
|
||||
pub wake: Option<u128>,
|
||||
/// The architecture specific context
|
||||
@@ -168,8 +176,8 @@ impl Context {
|
||||
cpu_time: 0,
|
||||
sched_affinity: LogicalCpuSet::all(),
|
||||
inside_syscall: false,
|
||||
syscall_head: Some(RaiiFrame::allocate()?),
|
||||
syscall_tail: Some(RaiiFrame::allocate()?),
|
||||
syscall_head: SyscallFrame::Free(RaiiFrame::allocate()?),
|
||||
syscall_tail: SyscallFrame::Free(RaiiFrame::allocate()?),
|
||||
wake: None,
|
||||
arch: arch::Context::new(),
|
||||
kfx: AlignedBox::<[u8], { arch::KFX_ALIGN }>::try_zeroed_slice(crate::arch::kfx_size())?,
|
||||
@@ -430,28 +438,36 @@ pub struct BorrowedHtBuf {
|
||||
}
|
||||
impl BorrowedHtBuf {
|
||||
pub fn head(token: &mut CleanLockToken) -> Result<Self> {
|
||||
Ok(Self {
|
||||
inner: Some(
|
||||
context::current()
|
||||
.write(token.token())
|
||||
.syscall_head
|
||||
.take()
|
||||
.ok_or(Error::new(EAGAIN))?,
|
||||
),
|
||||
head_and_not_tail: true,
|
||||
})
|
||||
let current = context::current();
|
||||
let frame = &mut current.write(token.token()).syscall_head;
|
||||
match mem::replace(frame, SyscallFrame::Dummy) {
|
||||
SyscallFrame::Free(free_frame) => {
|
||||
*frame = SyscallFrame::Used {
|
||||
_frame: free_frame.get(),
|
||||
};
|
||||
Ok(Self {
|
||||
inner: Some(free_frame),
|
||||
head_and_not_tail: true,
|
||||
})
|
||||
}
|
||||
SyscallFrame::Used { .. } | SyscallFrame::Dummy => Err(Error::new(EAGAIN)),
|
||||
}
|
||||
}
|
||||
pub fn tail(token: &mut CleanLockToken) -> Result<Self> {
|
||||
Ok(Self {
|
||||
inner: Some(
|
||||
context::current()
|
||||
.write(token.token())
|
||||
.syscall_tail
|
||||
.take()
|
||||
.ok_or(Error::new(EAGAIN))?,
|
||||
),
|
||||
head_and_not_tail: false,
|
||||
})
|
||||
let current = context::current();
|
||||
let frame = &mut current.write(token.token()).syscall_tail;
|
||||
match mem::replace(frame, SyscallFrame::Dummy) {
|
||||
SyscallFrame::Free(free_frame) => {
|
||||
*frame = SyscallFrame::Used {
|
||||
_frame: free_frame.get(),
|
||||
};
|
||||
Ok(Self {
|
||||
inner: Some(free_frame),
|
||||
head_and_not_tail: false,
|
||||
})
|
||||
}
|
||||
SyscallFrame::Used { .. } | SyscallFrame::Dummy => Err(Error::new(EAGAIN)),
|
||||
}
|
||||
}
|
||||
pub fn buf(&self) -> &[u8; PAGE_SIZE] {
|
||||
unsafe {
|
||||
@@ -500,12 +516,11 @@ impl Drop for BorrowedHtBuf {
|
||||
let mut token = unsafe { CleanLockToken::new() };
|
||||
match context.write(token.token()) {
|
||||
mut context => {
|
||||
(if self.head_and_not_tail {
|
||||
*(if self.head_and_not_tail {
|
||||
&mut context.syscall_head
|
||||
} else {
|
||||
&mut context.syscall_tail
|
||||
})
|
||||
.get_or_insert(inner);
|
||||
}) = SyscallFrame::Free(inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-15
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
context::{Context, ContextLock},
|
||||
context::{context::SyscallFrame, Context, ContextLock},
|
||||
memory::{get_page_info, the_zeroed_frame, Frame, RefCount},
|
||||
paging::{RmmA, RmmArch, TableKind, PAGE_SIZE},
|
||||
sync::CleanLockToken,
|
||||
@@ -15,8 +15,6 @@ pub unsafe fn debugger(target_id: Option<*const ContextLock>, token: &mut CleanL
|
||||
let mut tree = HashMap::new();
|
||||
let mut spaces = HashSet::new();
|
||||
|
||||
let mut temporarily_taken_htbufs = 0;
|
||||
|
||||
tree.insert(the_zeroed_frame().0, (1, false));
|
||||
|
||||
let old_table = unsafe { RmmA::table(TableKind::User) };
|
||||
@@ -30,15 +28,23 @@ pub unsafe fn debugger(target_id: Option<*const ContextLock>, token: &mut CleanL
|
||||
let context = context_lock.0.read(context_token.token());
|
||||
println!("{:p}: {}", Arc::as_ptr(&context_lock.0), context.name);
|
||||
|
||||
if let Some(ref head) = context.syscall_head {
|
||||
tree.insert(head.get(), (1, false));
|
||||
} else {
|
||||
temporarily_taken_htbufs += 1;
|
||||
match &context.syscall_head {
|
||||
SyscallFrame::Free(head) => {
|
||||
tree.insert(head.get(), (1, false));
|
||||
}
|
||||
SyscallFrame::Used { _frame: head } => {
|
||||
tree.insert(*head, (1, false));
|
||||
}
|
||||
SyscallFrame::Dummy => {}
|
||||
}
|
||||
if let Some(ref tail) = context.syscall_tail {
|
||||
tree.insert(tail.get(), (1, false));
|
||||
} else {
|
||||
temporarily_taken_htbufs += 1;
|
||||
match &context.syscall_tail {
|
||||
SyscallFrame::Free(tail) => {
|
||||
tree.insert(tail.get(), (1, false));
|
||||
}
|
||||
SyscallFrame::Used { _frame: tail } => {
|
||||
tree.insert(*tail, (1, false));
|
||||
}
|
||||
SyscallFrame::Dummy => {}
|
||||
}
|
||||
|
||||
// Switch to context page table to ensure syscall debug and stack dump will work
|
||||
@@ -156,10 +162,6 @@ pub unsafe fn debugger(target_id: Option<*const ContextLock>, token: &mut CleanL
|
||||
);
|
||||
}
|
||||
}
|
||||
println!(
|
||||
"({} kernel-owned references were not counted)",
|
||||
temporarily_taken_htbufs
|
||||
);
|
||||
|
||||
println!("DEBUGGER END");
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use spin::RwLock;
|
||||
|
||||
use crate::{
|
||||
context::{
|
||||
context::SyscallFrame,
|
||||
memory::{AddrSpace, Grant, PageSpan},
|
||||
ContextRef,
|
||||
},
|
||||
@@ -37,8 +38,8 @@ pub fn exit_this_context(excp: Option<syscall::Exception>, token: &mut CleanLock
|
||||
addrspace_opt = context
|
||||
.set_addr_space(None)
|
||||
.and_then(|a| Arc::try_unwrap(a).ok());
|
||||
drop(context.syscall_head.take());
|
||||
drop(context.syscall_tail.take());
|
||||
drop(mem::replace(&mut context.syscall_head, SyscallFrame::Dummy));
|
||||
drop(mem::replace(&mut context.syscall_tail, SyscallFrame::Dummy));
|
||||
}
|
||||
|
||||
// Files must be closed while context is valid so that messages can be passed
|
||||
|
||||
Reference in New Issue
Block a user