From 0eea8bf79593e65bb5b07cec9d4f1107cee0a44d Mon Sep 17 00:00:00 2001 From: dragon <52032586+eternalcomet@users.noreply.github.com> Date: Wed, 7 May 2025 23:53:48 +0800 Subject: [PATCH 1/6] [fix] fix user stack alignment stack pointer of the user stack must be aligned to 16 --- src/user_stack.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/user_stack.rs b/src/user_stack.rs index 035bc0c..15b96d8 100644 --- a/src/user_stack.rs +++ b/src/user_stack.rs @@ -85,7 +85,15 @@ 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); + + // next things are auxv entries, envp and argv pointers, argc + // auxv entries is 16 bytes each, aligned to 16 bytes + // envp and argv pointers, argc is 8 bytes each, aligned to 8 bytes + let pointers_count = auxv.len() + envs.len() + args.len() + 3; + if pointers_count % 2 != 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 +120,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 } From 37d26d0aa8ae13c594f2f525fb1791c9b710a8a1 Mon Sep 17 00:00:00 2001 From: eternalcomet Date: Thu, 15 May 2025 12:23:00 +0800 Subject: [PATCH 2/6] [fix] fix user stack alignment axuv entries are 16 bytes each and will not affect alignment --- src/info.rs | 3 ++- src/user_stack.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) 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 15b96d8..ac3e5c3 100644 --- a/src/user_stack.rs +++ b/src/user_stack.rs @@ -89,7 +89,7 @@ fn init_stack(args: &[String], envs: &[String], auxv: &mut [AuxvEntry], sp: usiz // next things are auxv entries, envp and argv pointers, argc // auxv entries is 16 bytes each, aligned to 16 bytes // envp and argv pointers, argc is 8 bytes each, aligned to 8 bytes - let pointers_count = auxv.len() + envs.len() + args.len() + 3; + let pointers_count = envs.len() + args.len() + 3; if pointers_count % 2 != 0 { stack.push(padding_null.as_bytes(), &mut data); } From 8dc187b2cb377b7520ae1ff9aec86d7114980aac Mon Sep 17 00:00:00 2001 From: eternalcomet Date: Thu, 15 May 2025 13:14:42 +0800 Subject: [PATCH 3/6] [doc] add more info about stack alignment --- src/user_stack.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/user_stack.rs b/src/user_stack.rs index ac3e5c3..1624de3 100644 --- a/src/user_stack.rs +++ b/src/user_stack.rs @@ -86,11 +86,17 @@ fn init_stack(args: &[String], envs: &[String], auxv: &mut [AuxvEntry], sp: usiz stack.push("\0".repeat(stack.get_sp() % 16).as_bytes(), &mut data); - // next things are auxv entries, envp and argv pointers, argc - // auxv entries is 16 bytes each, aligned to 16 bytes - // envp and argv pointers, argc is 8 bytes each, aligned to 8 bytes - let pointers_count = envs.len() + args.len() + 3; - if pointers_count % 2 != 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 + let item_8bytes_count = envs.len() + args.len() + 3; + if item_8bytes_count % 2 != 0 { stack.push(padding_null.as_bytes(), &mut data); } From fb7a36ae76bd26b29ce5db2cf2586235069e04a7 Mon Sep 17 00:00:00 2001 From: eternalcomet Date: Thu, 15 May 2025 13:27:27 +0800 Subject: [PATCH 4/6] [chore] simplify the code --- src/user_stack.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/user_stack.rs b/src/user_stack.rs index 1624de3..6a977c9 100644 --- a/src/user_stack.rs +++ b/src/user_stack.rs @@ -95,8 +95,7 @@ fn init_stack(args: &[String], envs: &[String], auxv: &mut [AuxvEntry], sp: usiz // 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 - let item_8bytes_count = envs.len() + args.len() + 3; - if item_8bytes_count % 2 != 0 { + if (envs.len() + args.len() + 3) & 1 != 0 { stack.push(padding_null.as_bytes(), &mut data); } From 883884565e4d3b90af59636fc052b820f60aba8c Mon Sep 17 00:00:00 2001 From: dragon <52032586+eternalcomet@users.noreply.github.com> Date: Thu, 15 May 2025 13:32:44 +0800 Subject: [PATCH 5/6] [chore] simplify the code --- src/user_stack.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user_stack.rs b/src/user_stack.rs index 6a977c9..4b316a8 100644 --- a/src/user_stack.rs +++ b/src/user_stack.rs @@ -95,7 +95,7 @@ fn init_stack(args: &[String], envs: &[String], auxv: &mut [AuxvEntry], sp: usiz // 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 { + if (envs.len() + args.len() + 3) & 1 { stack.push(padding_null.as_bytes(), &mut data); } From c69884d8acd22eb0f4a1c7db446d91ba875dbf5c Mon Sep 17 00:00:00 2001 From: dragon <52032586+eternalcomet@users.noreply.github.com> Date: Thu, 15 May 2025 13:36:27 +0800 Subject: [PATCH 6/6] [chore] simplify the code --- src/user_stack.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user_stack.rs b/src/user_stack.rs index 4b316a8..6a977c9 100644 --- a/src/user_stack.rs +++ b/src/user_stack.rs @@ -95,7 +95,7 @@ fn init_stack(args: &[String], envs: &[String], auxv: &mut [AuxvEntry], sp: usiz // 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 { + if (envs.len() + args.len() + 3) & 1 != 0 { stack.push(padding_null.as_bytes(), &mut data); }