mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 18:03:25 +00:00
Fix InitStackReader
to access given stack instead of current task
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
3ad1ea4d66
commit
f287110001
@ -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(¤t_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(¤t_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
Reference in New Issue
Block a user