Compare commits
No commits in common. "00b5957d6e4849d397d1c398e8ebd7f2c29572db" and "1a1a0bf3e87d6d5ab4c055865fd7a32c11cc3c2e" have entirely different histories.
00b5957d6e
...
1a1a0bf3e8
|
@ -1,8 +1,3 @@
|
|||
use std::{
|
||||
io::{BufRead, BufReader},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use crate::platform::{self, Platform};
|
||||
use crate::result::{Context, Result};
|
||||
|
||||
|
@ -17,31 +12,6 @@ pub struct Config {
|
|||
pub platform: Option<Box<dyn Platform>>,
|
||||
pub mode: Mode,
|
||||
pub target: String,
|
||||
pub environment: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn get_environment() -> Result<Vec<String>> {
|
||||
let mut environment = vec![];
|
||||
let environment_file = PathBuf::from("/etc/environment");
|
||||
|
||||
// NOTE: We should never have to care about permissions. Therefore, we don't use .try_exists()
|
||||
// As for TOCTOU... we're init, and this is the first code to run.
|
||||
if environment_file.exists() {
|
||||
let file = std::fs::File::open(&environment_file).context(format_args!(
|
||||
"could not open: {environment_file}",
|
||||
environment_file = environment_file.display(),
|
||||
))?;
|
||||
let reader = BufReader::new(file);
|
||||
for line in reader.lines() {
|
||||
let line = line.context(format_args!(
|
||||
"could not read line from: {environment_file}",
|
||||
environment_file = environment_file.display()
|
||||
))?;
|
||||
environment.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(environment)
|
||||
}
|
||||
|
||||
pub fn get_config() -> Result<Config> {
|
||||
|
@ -69,16 +39,7 @@ pub fn get_config() -> Result<Config> {
|
|||
|
||||
let platform = platform::get_current_platform(values.remove("platform").as_deref())?;
|
||||
|
||||
let target = values
|
||||
.remove("target")
|
||||
.unwrap_or(String::from("/usr/bin/hello"));
|
||||
let target = values.remove("target").unwrap_or(String::from("/usr/bin/hello"));
|
||||
|
||||
let environment = get_environment()?;
|
||||
|
||||
Ok(Config {
|
||||
platform,
|
||||
mode,
|
||||
target,
|
||||
environment,
|
||||
})
|
||||
Ok(Config { platform, mode, target })
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
extern "C" fn handle_sigchld(_sig: i32) {
|
||||
// wait on all dead processes
|
||||
while system::syscall::waitpid(-1, libc::WNOHANG).is_ok() {
|
||||
|
@ -67,8 +66,7 @@ fn init() -> Result<()> {
|
|||
}
|
||||
config::Mode::Exec => {
|
||||
dmesg(format!("pivoting to {command}"));
|
||||
let envs = config.environment.iter().map(|e| &**e).collect::<Vec<_>>();
|
||||
system::syscall::execve(command, &[], &envs)?;
|
||||
system::syscall::execv(command, &[])?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,10 +81,7 @@ impl Mount {
|
|||
"Making directory: {target}",
|
||||
target = self.target.display()
|
||||
));
|
||||
std::fs::create_dir_all(&self.target).context(format_args!(
|
||||
"could not create directory: {target}",
|
||||
target = self.target.display()
|
||||
))?;
|
||||
syscall::mkdir(&self.target)?;
|
||||
}
|
||||
|
||||
dmesg(format!(
|
||||
|
|
|
@ -89,6 +89,21 @@ pub fn mount(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn mkdir(path: impl AsRef<Path>) -> Result<()> {
|
||||
let path = path.as_ref();
|
||||
let path_cs = CString::new(path.as_os_str().as_encoded_bytes())
|
||||
.context(format_args!("bad path: {path}", path = path.display()))?;
|
||||
|
||||
match unsafe { libc::mkdir(path_cs.as_ptr(), 0o755) } {
|
||||
0 => Ok(()),
|
||||
-1 => ctx_os_error(format_args!(
|
||||
"error calling mkdir({path}, 0o755)",
|
||||
path = path.display()
|
||||
)),
|
||||
n => unreachable!("mount() syscall returned bad value: {n}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn freopen(path: impl AsRef<Path>, mode: impl AsRef<str>, fd: &impl AsRawFd) -> Result<()> {
|
||||
let path = path.as_ref();
|
||||
let mode = mode.as_ref();
|
||||
|
@ -193,7 +208,7 @@ pub fn close(fd: RawFd) -> Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn execve(command: impl AsRef<Path>, args: &[&str], envs: &[&str]) -> Result<()> {
|
||||
pub fn execv(command: impl AsRef<Path>, args: &[&str]) -> Result<()> {
|
||||
let command = command.as_ref();
|
||||
|
||||
let command_cstr = CString::new(command.as_os_str().as_encoded_bytes())
|
||||
|
@ -213,21 +228,7 @@ pub fn execve(command: impl AsRef<Path>, args: &[&str], envs: &[&str]) -> Result
|
|||
.chain(std::iter::once(std::ptr::null()))
|
||||
.collect();
|
||||
|
||||
let mut envs_cstr = vec![command_cstr.clone()];
|
||||
for env in envs {
|
||||
let cur_env_cstr = CString::new(env.as_bytes()).context(format_args!("bad env: {env}"))?;
|
||||
envs_cstr.push(cur_env_cstr);
|
||||
}
|
||||
|
||||
// NOTE: The last env must be a null pointer, but we can't construct a CString from nullptr, so
|
||||
// we construct an array of pointers and use that
|
||||
let envs_ptrs: Vec<_> = envs_cstr
|
||||
.iter()
|
||||
.map(|s| s.as_ptr())
|
||||
.chain(std::iter::once(std::ptr::null()))
|
||||
.collect();
|
||||
|
||||
if unsafe { libc::execve(command_cstr.as_ptr().cast(), args_ptrs.as_ptr().cast(), envs_ptrs.as_ptr().cast()) } == -1 {
|
||||
if unsafe { libc::execv(command_cstr.as_ptr().cast(), args_ptrs.as_ptr().cast()) } == -1 {
|
||||
return ctx_os_error(format_args!(
|
||||
"error calling exec({command}, {args:?})",
|
||||
command = command.display()
|
||||
|
|
Loading…
Reference in New Issue