diff --git a/litebox_runner_linux_on_windows_userland/src/lib.rs b/litebox_runner_linux_on_windows_userland/src/lib.rs index 60053d5681..db2aad82dc 100644 --- a/litebox_runner_linux_on_windows_userland/src/lib.rs +++ b/litebox_runner_linux_on_windows_userland/src/lib.rs @@ -116,6 +116,9 @@ pub fn run(cli_args: CliArgs) -> Result<()> { envp }; + let mut stack_padding = [0u8; 16]; + platform.fill_bytes_crng(&mut stack_padding); + let program = shim .load_program( initial_file_system, @@ -123,6 +126,7 @@ pub fn run(cli_args: CliArgs) -> Result<()> { prog_path, argv, envp, + Some(&stack_padding), ) .unwrap(); unsafe { diff --git a/litebox_runner_linux_userland/src/lib.rs b/litebox_runner_linux_userland/src/lib.rs index f1a7d11b76..a5aa101949 100644 --- a/litebox_runner_linux_userland/src/lib.rs +++ b/litebox_runner_linux_userland/src/lib.rs @@ -4,6 +4,7 @@ use anyhow::{Context as _, Result, anyhow}; use clap::Parser; use litebox::fs::Mode; +use litebox::platform::CrngProvider; use litebox_platform_linux_userland::LinuxUserland as Platform; use memmap2::Mmap; use std::os::linux::fs::MetadataExt as _; @@ -376,7 +377,17 @@ pub fn run(cli_args: CliArgs) -> Result<()> { #[cfg(target_arch = "x86_64")] litebox_platform_linux_userland::LinuxUserland::enable_seccomp_filter(); - let program = shim.load_program(initial_file_system, task_params, prog_path, argv, envp)?; + let mut stack_padding = [0u8; 16]; + platform.fill_bytes_crng(&mut stack_padding); + + let program = shim.load_program( + initial_file_system, + task_params, + prog_path, + argv, + envp, + Some(&stack_padding), + )?; #[cfg(feature = "lock_tracing")] litebox::sync::start_recording(); diff --git a/litebox_runner_linux_userland/tests/loader.rs b/litebox_runner_linux_userland/tests/loader.rs index 6d9769f8e5..ba6a6a9c4e 100644 --- a/litebox_runner_linux_userland/tests/loader.rs +++ b/litebox_runner_linux_userland/tests/loader.rs @@ -104,7 +104,14 @@ impl TestLauncher { let fs = std::sync::Arc::new(self.fs); let shim = self.shim_builder.build(); let program = shim - .load_program(fs, self.platform.init_task(), executable_path, argv, envp) + .load_program( + fs, + self.platform.init_task(), + executable_path, + argv, + envp, + None, + ) .unwrap(); unsafe { litebox_platform_linux_userland::run_thread( diff --git a/litebox_runner_snp/src/main.rs b/litebox_runner_snp/src/main.rs index 9ccb4ecc04..be618a1966 100644 --- a/litebox_runner_snp/src/main.rs +++ b/litebox_runner_snp/src/main.rs @@ -253,8 +253,14 @@ pub extern "C" fn sandbox_process_init( let fs = alloc::sync::Arc::new(litebox::fs::resolver::Resolver::new(litebox, composer)); // Loading a program may trigger page faults, so we need to set SHIM before this. - let program = match shim.load_program(fs, platform.init_task(boot_params), &program, argv, envp) - { + let program = match shim.load_program( + fs, + platform.init_task(boot_params), + &program, + argv, + envp, + None, + ) { Ok(program) => program, Err(err) => { litebox_util_log::error!(err:% = err; "failed to load program"); diff --git a/litebox_shim_linux/src/lib.rs b/litebox_shim_linux/src/lib.rs index c9b17ef5a0..620b031695 100644 --- a/litebox_shim_linux/src/lib.rs +++ b/litebox_shim_linux/src/lib.rs @@ -386,6 +386,7 @@ impl LinuxShim { path: &str, argv: Vec, envp: Vec, + padding: Option<&[u8; 16]>, ) -> Result, loader::elf::ElfLoaderError> { let litebox_common_linux::TaskParams { pid, @@ -434,6 +435,7 @@ impl LinuxShim { loader::elf::ElfLoader::new(&entrypoints.task, &path)?, argv, envp, + padding, )?; let process = LinuxShimProcess(entrypoints.task.process().clone()); Ok(LoadedProgram { diff --git a/litebox_shim_linux/src/loader/elf.rs b/litebox_shim_linux/src/loader/elf.rs index 06fece6e8b..c4ed4e8f8e 100644 --- a/litebox_shim_linux/src/loader/elf.rs +++ b/litebox_shim_linux/src/loader/elf.rs @@ -278,6 +278,7 @@ impl<'a, Platform: ShimPlatform> ElfLoader<'a, Platform> { &mut self, argv: Vec, envp: Vec, + padding: Option<&[u8; 16]>, mut aux: AuxVec, ) -> Result { let global = &self.main.file.task.global; @@ -319,7 +320,7 @@ impl<'a, Platform: ShimPlatform> ElfLoader<'a, Platform> { ) .ok_or(ElfLoaderError::InvalidStackAddr)?; stack - .init(argv, envp, aux) + .init(argv, envp, padding, aux) .ok_or(ElfLoaderError::InvalidStackAddr)?; Ok(ElfLoadInfo { @@ -511,6 +512,7 @@ mod tests { .load( vec![CString::new("/pie").unwrap()], Vec::new(), + None, task.init_auxv(), ) .expect("loader should initialize the process stack"); diff --git a/litebox_shim_linux/src/loader/stack.rs b/litebox_shim_linux/src/loader/stack.rs index bcd10bce70..12f58254fe 100644 --- a/litebox_shim_linux/src/loader/stack.rs +++ b/litebox_shim_linux/src/loader/stack.rs @@ -164,6 +164,7 @@ impl UserStack { &mut self, argv: Vec, env: Vec, + padding: Option<&[u8; 16]>, mut aux: BTreeMap, ) -> Option<()> { // end markers @@ -174,11 +175,11 @@ impl UserStack { let envp = self.push_cstrings(&env)?; let argvp = self.push_cstrings(&argv)?; - // TODO: generate a random value - self.push_bytes(&[ + self.push_bytes(padding.unwrap_or(&[ 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, - ])?; + ]))?; + aux.insert(AuxKey::AT_RANDOM, self.stack_top.as_usize() + self.pos); let align_down = |pos: usize, alignment: usize| -> usize { diff --git a/litebox_shim_linux/src/syscalls/process.rs b/litebox_shim_linux/src/syscalls/process.rs index 43a32be7b9..5d57b84e71 100644 --- a/litebox_shim_linux/src/syscalls/process.rs +++ b/litebox_shim_linux/src/syscalls/process.rs @@ -1522,7 +1522,7 @@ impl Task { .set_arch_specific_register(&ArchSpecificRegister::FsBase, 0) .expect("failed to clear guest TLS on execve"); - self.load_program(loader, argv_vec, envp_vec) + self.load_program(loader, argv_vec, envp_vec, None) .expect("TODO: terminate the process cleanly"); self.init_thread_context(ctx); @@ -1536,8 +1536,9 @@ impl Task { mut loader: crate::loader::elf::ElfLoader<'_, Platform>, argv: Vec, envp: Vec, + padding: Option<&[u8; 16]>, ) -> Result<(), crate::loader::elf::ElfLoaderError> { - let load_info = loader.load(argv, envp, self.init_auxv())?; + let load_info = loader.load(argv, envp, padding, self.init_auxv())?; self.set_task_comm(loader.comm());