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