diff --git a/src/info.rs b/src/info.rs index e385c97..85f9c8a 100644 --- a/src/info.rs +++ b/src/info.rs @@ -142,7 +142,7 @@ impl<'a> ELFParser<'a> { /// * `pagesz` - The page size of the system /// /// Details about auxiliary vectors are described in - pub fn auxv_vector(&self, pagesz: usize) -> [AuxvEntry; 16] { + pub fn auxv_vector(&self, pagesz: usize) -> [AuxvEntry; 17] { [ AuxvEntry::new(AuxvType::PHDR, self.phdr()), AuxvEntry::new(AuxvType::PHENT, self.phent()), @@ -160,6 +160,7 @@ impl<'a> ELFParser<'a> { AuxvEntry::new(AuxvType::EGID, 0), AuxvEntry::new(AuxvType::RANDOM, 0), AuxvEntry::new(AuxvType::EXECFN, 0), + AuxvEntry::new(AuxvType::NULL, 0), ] } diff --git a/src/user_stack.rs b/src/user_stack.rs index 035bc0c..6a977c9 100644 --- a/src/user_stack.rs +++ b/src/user_stack.rs @@ -85,7 +85,20 @@ fn init_stack(args: &[String], envs: &[String], auxv: &mut [AuxvEntry], sp: usiz stack.push(padding_null.as_bytes(), &mut data); stack.push("\0".repeat(stack.get_sp() % 16).as_bytes(), &mut data); - assert!(stack.get_sp() % 16 == 0); + + // Align stack to 16 bytes by padding if needed. + // We will push following 8-byte items into stack: + // - auxv (each entry is 2 * usize, so item count = auxv.len() * 2) + // - envp (len + 1 for NULL terminator) + // - argv (len + 1 for NULL terminator) + // - argc (1 item) + // Total items = auxv.len() * 2 + (envs.len() + 1) + (args.len() + 1) + 1 + // = auxv.len() * 2 + envs.len() + args.len() + 3 + // If odd, the stack top will not be aligned to 16 bytes unless we add 8-byte padding + if (envs.len() + args.len() + 3) & 1 != 0 { + stack.push(padding_null.as_bytes(), &mut data); + } + // Push auxiliary vectors for auxv_entry in auxv.iter_mut() { if auxv_entry.get_type() == AuxvType::RANDOM { @@ -112,6 +125,7 @@ fn init_stack(args: &[String], envs: &[String], auxv: &mut [AuxvEntry], sp: usiz stack.push_usize_slice(argv_slice.as_slice(), &mut data); // Push argc stack.push_usize_slice(&[args.len()], &mut data); + assert!(stack.get_sp() % 16 == 0); data }