Fix InitStackReader to access given stack instead of current task

This commit is contained in:
Marsman1996
2024-11-08 14:42:24 +08:00
committed by Tate, Hongliang Tian
parent 3ad1ea4d66
commit f287110001
2 changed files with 44 additions and 25 deletions

View File

@ -20,14 +20,10 @@ use core::{
use align_ext::AlignExt;
use aster_rights::Full;
use ostd::{
mm::{VmIo, MAX_USERSPACE_VADDR},
task::Task,
};
use ostd::mm::{vm_space::VmItem, VmIo, VmSpace, MAX_USERSPACE_VADDR};
use self::aux_vec::{AuxKey, AuxVec};
use crate::{
get_current_userspace,
prelude::*,
util::random::getrandom,
vm::{
@ -187,10 +183,11 @@ impl InitStack {
/// Constructs a reader to parse the content of an `InitStack`.
/// The `InitStack` should only be read after initialized
pub(super) fn reader(&self) -> InitStackReader {
pub(super) fn reader<'a>(&self, vm_space: &'a Arc<VmSpace>) -> InitStackReader<'a> {
debug_assert!(self.is_initialized());
InitStackReader {
base: self.pos(),
vm_space,
map_addr: self.initial_top - self.max_size,
}
}
@ -366,17 +363,27 @@ fn generate_random_for_aux_vec() -> [u8; 16] {
}
/// A reader to parse the content of an `InitStack`.
pub struct InitStackReader {
pub struct InitStackReader<'a> {
base: Vaddr,
vm_space: &'a Arc<VmSpace>,
/// The mapping address of the `InitStack`.
map_addr: usize,
}
impl InitStackReader {
impl InitStackReader<'_> {
/// Reads argc from the process init stack
pub fn argc(&self) -> Result<u64> {
let stack_base = self.init_stack_bottom();
get_current_userspace!().read_val(stack_base)
let page_base_addr = stack_base.align_down(PAGE_SIZE);
let mut cursor = self
.vm_space
.cursor(&(page_base_addr..page_base_addr + PAGE_SIZE))?;
let VmItem::Mapped { frame, .. } = cursor.query()? else {
return_errno_with_message!(Errno::EACCES, "Page not accessible");
};
Ok(frame.read_val::<u64>(stack_base - page_base_addr)?)
}
/// Reads argv from the process init stack
@ -387,15 +394,20 @@ impl InitStackReader {
let read_offset = self.init_stack_bottom() + size_of::<usize>();
let mut argv = Vec::with_capacity(argc);
let page_base_addr = read_offset.align_down(PAGE_SIZE);
let mut cursor = self
.vm_space
.cursor(&(page_base_addr..page_base_addr + PAGE_SIZE))?;
let VmItem::Mapped { frame, .. } = cursor.query()? else {
return_errno_with_message!(Errno::EACCES, "Page not accessible");
};
let current_task = Task::current().unwrap();
let user_space = CurrentUserSpace::new(&current_task);
let mut argv_reader = user_space.reader(read_offset, argc * size_of::<usize>())?;
let mut arg_ptr_reader = frame.reader().skip(read_offset - page_base_addr);
for _ in 0..argc {
let arg = {
let arg_ptr = argv_reader.read_val::<Vaddr>()?;
user_space.read_cstring(arg_ptr, MAX_ARG_LEN)?
let arg_ptr = arg_ptr_reader.read_val::<Vaddr>()?;
let mut arg_reader = frame.reader().skip(arg_ptr - page_base_addr).to_fallible();
arg_reader.read_cstring()?
};
argv.push(arg);
}
@ -417,19 +429,26 @@ impl InitStackReader {
+ size_of::<usize>();
let mut envp = Vec::new();
let page_base_addr = read_offset.align_down(PAGE_SIZE);
let mut cursor = self
.vm_space
.cursor(&(page_base_addr..page_base_addr + PAGE_SIZE))?;
let VmItem::Mapped { frame, .. } = cursor.query()? else {
return_errno_with_message!(Errno::EACCES, "Page not accessible");
};
let current_task = Task::current().unwrap();
let user_space = CurrentUserSpace::new(&current_task);
let mut envp_reader = user_space.reader(read_offset, MAX_ENVP_NUMBER)?;
let mut envp_ptr_reader = frame.reader().skip(read_offset - page_base_addr);
for _ in 0..MAX_ENVP_NUMBER {
let envp_ptr = envp_reader.read_val::<Vaddr>()?;
let env = {
let envp_ptr = envp_ptr_reader.read_val::<Vaddr>()?;
if envp_ptr == 0 {
break;
}
if envp_ptr == 0 {
break;
}
let env = user_space.read_cstring(envp_ptr, MAX_ENV_LEN)?;
let mut envp_reader = frame.reader().skip(envp_ptr - page_base_addr).to_fallible();
envp_reader.read_cstring()?
};
envp.push(env);
}

View File

@ -111,7 +111,7 @@ impl ProcessVm {
/// Returns a reader for reading contents from
/// the `InitStack`.
pub fn init_stack_reader(&self) -> InitStackReader {
self.init_stack.reader()
self.init_stack.reader(self.root_vmar().vm_space())
}
/// Returns the top address of the user stack.