Compare commits

..

No commits in common. "00b5957d6e4849d397d1c398e8ebd7f2c29572db" and "1a1a0bf3e87d6d5ab4c055865fd7a32c11cc3c2e" have entirely different histories.

4 changed files with 21 additions and 64 deletions

View File

@ -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 })
}

View File

@ -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, &[])?;
}
}

View File

@ -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!(

View File

@ -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()