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

View File

@ -111,7 +111,7 @@ impl ProcessVm {
/// Returns a reader for reading contents from /// Returns a reader for reading contents from
/// the `InitStack`. /// the `InitStack`.
pub fn init_stack_reader(&self) -> InitStackReader { 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. /// Returns the top address of the user stack.