void file descriptors
This commit is contained in:
parent
c511d12a5a
commit
04c2a85e3a
@ -11,7 +11,6 @@ use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
use close_fds::CloseFdsBuilder;
|
||||
use nix::unistd;
|
||||
|
||||
const BUFFER_SIZE: usize = 1024;
|
||||
@ -53,24 +52,17 @@ impl<'a> Spawner<'a> {
|
||||
Trigger::Pipe(s) => {
|
||||
let pipe = self.pipes.get_mut(s).unwrap().take_read();
|
||||
|
||||
let closure = || {
|
||||
let mut closer = CloseFdsBuilder::new();
|
||||
let keep = [pipe.as_raw_fd()];
|
||||
closer.keep_fds(&keep);
|
||||
unsafe {
|
||||
closer.closefrom(3);
|
||||
}
|
||||
let mut builder = VoidBuilder::new();
|
||||
builder.keep_fd(&pipe);
|
||||
|
||||
match self.pipe_trigger(pipe, entrypoint, name) {
|
||||
Ok(()) => std::process::exit(exitcode::OK),
|
||||
Err(e) => {
|
||||
error!("error in pipe_trigger: {}", e);
|
||||
std::process::exit(1)
|
||||
}
|
||||
let closure = || match self.pipe_trigger(pipe, entrypoint, name) {
|
||||
Ok(()) => std::process::exit(exitcode::OK),
|
||||
Err(e) => {
|
||||
error!("error in pipe_trigger: {}", e);
|
||||
std::process::exit(1)
|
||||
}
|
||||
};
|
||||
|
||||
let mut builder = VoidBuilder::new();
|
||||
builder.spawn(closure)?;
|
||||
}
|
||||
}
|
||||
|
27
src/void.rs
27
src/void.rs
@ -3,8 +3,9 @@ use log::{debug, error};
|
||||
use crate::clone::{clone3, CloneArgs, CloneFlags};
|
||||
use crate::{Error, Result};
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use nix::mount::{mount, umount2, MntFlags, MsFlags};
|
||||
@ -12,17 +13,20 @@ use nix::sched::unshare;
|
||||
use nix::sys::signal::Signal;
|
||||
use nix::unistd::{pivot_root, Pid};
|
||||
|
||||
use close_fds::CloseFdsBuilder;
|
||||
|
||||
pub struct VoidHandle {}
|
||||
|
||||
pub struct VoidBuilder {
|
||||
#[allow(dead_code)]
|
||||
mounts: HashMap<PathBuf, PathBuf>,
|
||||
fds: HashSet<RawFd>,
|
||||
}
|
||||
|
||||
impl VoidBuilder {
|
||||
pub fn new() -> VoidBuilder {
|
||||
VoidBuilder {
|
||||
mounts: HashMap::new(),
|
||||
fds: HashSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +36,11 @@ impl VoidBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn keep_fd(&mut self, fd: &impl AsRawFd) -> &mut Self {
|
||||
self.fds.insert(fd.as_raw_fd());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn spawn(&mut self, child_fn: impl FnOnce() -> i32) -> Result<VoidHandle> {
|
||||
let mut args = CloneArgs::new(
|
||||
CloneFlags::CLONE_NEWCGROUP
|
||||
@ -50,6 +59,7 @@ impl VoidBuilder {
|
||||
|
||||
if child == Pid::from_raw(0) {
|
||||
let result = {
|
||||
self.void_files()?;
|
||||
self.void_mount_namespace()?;
|
||||
self.void_user_namespace()?; // last to maintain permissions
|
||||
|
||||
@ -77,6 +87,19 @@ impl VoidBuilder {
|
||||
}
|
||||
|
||||
// per-namespace void creation
|
||||
fn void_files(&self) -> Result<()> {
|
||||
let mut closer = CloseFdsBuilder::new();
|
||||
|
||||
let keep: Box<[RawFd]> = self.fds.iter().copied().collect();
|
||||
closer.keep_fds(&keep);
|
||||
|
||||
unsafe {
|
||||
closer.closefrom(3);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn void_mount_namespace(&self) -> Result<()> {
|
||||
// change the propagation type of the old root to private
|
||||
mount(
|
||||
|
Loading…
Reference in New Issue
Block a user