Skip to content

Commit 1146ebe

Browse files
committed
work
1 parent f9729ed commit 1146ebe

File tree

8 files changed

+59
-57
lines changed

8 files changed

+59
-57
lines changed

minion-ffi/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{
55
ffi::{CStr, OsString},
66
mem::{self},
77
os::raw::c_char,
8+
sync::Arc,
89
};
910

1011
#[repr(i32)]
@@ -119,7 +120,7 @@ pub struct SandboxOptions {
119120
}
120121

121122
#[derive(Clone)]
122-
pub struct Sandbox(Box<dyn minion::erased::Sandbox>);
123+
pub struct Sandbox(Arc<dyn minion::erased::Sandbox>);
123124

124125
/// # Safety
125126
/// `out` must be valid

src/command.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ use crate::{erased, InputSpecification, OutputSpecification, StdioSpecification}
22
use std::{
33
ffi::{OsStr, OsString},
44
path::{Path, PathBuf},
5+
sync::Arc,
56
};
67

78
/// Child process builder
89
#[derive(Default, Debug)]
910
pub struct Command {
10-
sandbox: Option<Box<dyn erased::Sandbox>>,
11+
sandbox: Option<Arc<dyn erased::Sandbox>>,
1112
exe: Option<PathBuf>,
1213
argv: Vec<OsString>,
1314
env: Vec<OsString>,
@@ -56,7 +57,7 @@ impl Command {
5657
backend.spawn(options)
5758
}
5859

59-
pub fn sandbox(&mut self, sandbox: Box<dyn erased::Sandbox>) -> &mut Self {
60+
pub fn sandbox(&mut self, sandbox: Arc<dyn erased::Sandbox>) -> &mut Self {
6061
self.sandbox.replace(sandbox);
6162
self
6263
}

src/erased.rs

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,20 @@
33
//!
44
//! Please note that this API is not type-safe. For example, if you pass
55
//! `Sandbox` instance to another backend, it will panic.
6+
use std::{any::Any, sync::Arc};
67

78
/// Type-erased `Sandbox`
89
pub trait Sandbox: std::fmt::Debug {
9-
fn id(&self) -> String;
10+
fn id(&self) -> &str;
1011
fn check_cpu_tle(&self) -> anyhow::Result<bool>;
1112
fn check_real_tle(&self) -> anyhow::Result<bool>;
1213
fn kill(&self) -> anyhow::Result<()>;
1314
fn resource_usage(&self) -> anyhow::Result<crate::ResourceUsageData>;
14-
#[doc(hidden)]
15-
fn clone_to_box(&self) -> Box<dyn Sandbox>;
16-
#[doc(hidden)]
17-
fn clone_into_box_any(&self) -> Box<dyn std::any::Any>;
18-
}
19-
20-
impl Clone for Box<dyn Sandbox> {
21-
fn clone(&self) -> Self {
22-
self.clone_to_box()
23-
}
15+
fn into_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync + 'static>;
2416
}
2517

2618
impl<S: crate::Sandbox> Sandbox for S {
27-
fn id(&self) -> String {
19+
fn id(&self) -> &str {
2820
self.id()
2921
}
3022
fn check_cpu_tle(&self) -> anyhow::Result<bool> {
@@ -39,12 +31,8 @@ impl<S: crate::Sandbox> Sandbox for S {
3931
fn resource_usage(&self) -> anyhow::Result<crate::ResourceUsageData> {
4032
self.resource_usage().map_err(Into::into)
4133
}
42-
fn clone_to_box(&self) -> Box<dyn Sandbox> {
43-
Box::new(self.clone())
44-
}
45-
46-
fn clone_into_box_any(&self) -> Box<dyn std::any::Any> {
47-
Box::new(self.clone())
34+
fn into_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync + 'static> {
35+
self
4836
}
4937
}
5038

@@ -96,36 +84,33 @@ impl<C: crate::ChildProcess> ChildProcess for C {
9684

9785
/// Type-erased `Backend`
9886
pub trait Backend {
99-
fn new_sandbox(&self, options: crate::SandboxOptions) -> anyhow::Result<Box<dyn Sandbox>>;
87+
fn new_sandbox(&self, options: crate::SandboxOptions) -> anyhow::Result<Arc<dyn Sandbox>>;
10088
fn spawn(&self, options: ChildProcessOptions) -> anyhow::Result<Box<dyn ChildProcess>>;
10189
}
10290

10391
impl<B: crate::Backend> Backend for B {
104-
fn new_sandbox(&self, options: crate::SandboxOptions) -> anyhow::Result<Box<dyn Sandbox>> {
92+
fn new_sandbox(&self, options: crate::SandboxOptions) -> anyhow::Result<Arc<dyn Sandbox>> {
10593
let sb = <Self as crate::Backend>::new_sandbox(&self, options)?;
106-
Ok(Box::new(sb))
94+
Ok(Arc::new(sb))
10795
}
10896

10997
fn spawn(&self, options: ChildProcessOptions) -> anyhow::Result<Box<dyn ChildProcess>> {
110-
let down_sandbox = options
111-
.sandbox
112-
.clone_into_box_any()
113-
.downcast()
114-
.expect("sandbox type mismatch");
98+
let any_sandbox = options.sandbox.clone().into_arc_any();
99+
let down_sandbox = any_sandbox.downcast().expect("sandbox type mismatch");
115100
let down_options = crate::ChildProcessOptions {
116101
arguments: options.arguments,
117102
environment: options.environment,
118103
path: options.path,
119104
pwd: options.pwd,
120105
stdio: options.stdio,
121-
sandbox: *down_sandbox,
106+
sandbox: down_sandbox,
122107
};
123108
let cp = <Self as crate::Backend>::spawn(&self, down_options)?;
124109
Ok(Box::new(cp))
125110
}
126111
}
127112

128-
pub type ChildProcessOptions = crate::ChildProcessOptions<Box<dyn Sandbox>>;
113+
pub type ChildProcessOptions = crate::ChildProcessOptions<dyn Sandbox>;
129114

130115
/// Returns backend instance
131116
pub fn setup() -> anyhow::Result<Box<dyn Backend>> {

src/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub mod windows;
1717

1818
pub mod erased;
1919

20+
mod util;
21+
2022
use serde::{Deserialize, Serialize};
2123

2224
#[cfg(target_os = "linux")]
@@ -27,6 +29,7 @@ use std::{
2729
fmt::Debug,
2830
io::{Read, Write},
2931
time::Duration,
32+
sync::Arc,
3033
};
3134

3235
/// This functions checks for system configurations issues.
@@ -123,9 +126,9 @@ impl SandboxOptions {
123126
}
124127

125128
/// Represents highly-isolated sandbox
126-
pub trait Sandbox: Clone + Debug + 'static {
129+
pub trait Sandbox: Send + Sync + Debug + 'static {
127130
type Error: StdError + Send + Sync + 'static;
128-
fn id(&self) -> String;
131+
fn id(&self) -> &str;
129132

130133
/// Returns true if sandbox exceeded CPU time limit
131134
fn check_cpu_tle(&self) -> Result<bool, Self::Error>;
@@ -255,11 +258,11 @@ pub struct StdioSpecification {
255258
/// This type should only be used by Backend implementations
256259
/// Use `Command` instead
257260
#[derive(Debug, Clone)]
258-
pub struct ChildProcessOptions<Sandbox> {
261+
pub struct ChildProcessOptions<Sandbox: ?Sized> {
259262
pub path: PathBuf,
260263
pub arguments: Vec<OsString>,
261264
pub environment: Vec<OsString>,
262-
pub sandbox: Sandbox,
265+
pub sandbox: Arc<Sandbox>,
263266
pub stdio: StdioSpecification,
264267
/// Child's working dir. Relative to `sandbox` isolation_root
265268
pub pwd: PathBuf,

src/linux/jail_common.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use crate::{
22
linux::util::{Fd, Pid},
33
SharedDir,
44
};
5-
use rand::seq::SliceRandom;
65
use serde::{Deserialize, Serialize};
76
use std::{ffi::OsString, path::PathBuf, time::Duration};
87
use tiny_nix_ipc::Socket;
@@ -23,18 +22,6 @@ pub(crate) struct JailOptions {
2322
pub(crate) allow_mount_ns_failure: bool,
2423
}
2524

26-
const ID_CHARS: &[u8] = b"qwertyuiopasdfghjklzxcvbnm1234567890";
27-
const ID_SIZE: usize = 8;
28-
29-
pub(crate) fn gen_jail_id() -> String {
30-
let mut gen = rand::thread_rng();
31-
let mut out = Vec::new();
32-
for _i in 0..ID_SIZE {
33-
let ch = *(ID_CHARS.choose(&mut gen).unwrap());
34-
out.push(ch);
35-
}
36-
String::from_utf8_lossy(&out[..]).to_string()
37-
}
3825

3926
#[derive(Serialize, Deserialize, Clone, Debug)]
4027
pub(crate) struct JobQuery {

src/linux/sandbox.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,9 @@ impl SandboxState {
5050
}
5151
}
5252

53-
#[derive(Clone)]
54-
pub struct LinuxSandbox(Arc<LinuxSandboxInner>);
5553

5654
#[repr(C)]
57-
struct LinuxSandboxInner {
55+
pub struct LinuxSandbox {
5856
id: String,
5957
options: SandboxOptions,
6058
zygote_sock: Mutex<Socket>,
@@ -93,7 +91,7 @@ impl Sandbox for LinuxSandbox {
9391
type Error = Error;
9492

9593
fn id(&self) -> String {
96-
self.0.id.clone()
94+
self.0.id
9795
}
9896

9997
fn check_cpu_tle(&self) -> Result<bool, Error> {
@@ -133,7 +131,7 @@ impl LinuxSandbox {
133131
fn poll_state(&self) -> Result<(), Error> {
134132
for _ in 0..5 {
135133
let mut buf = [0; 4];
136-
let num_read = nix::unistd::read(self.0.watchdog_chan, &mut buf).or_else(|err| {
134+
let num_read = nix::unistd::read(self.watchdog_chan, &mut buf).or_else(|err| {
137135
if let Some(errno) = err.as_errno() {
138136
if errno as i32 == libc::EAGAIN {
139137
return Ok(0);

src/util.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use rand::seq::SliceRandom;
2+
3+
const ID_CHARS: &[u8] = b"qwertyuiopasdfghjklzxcvbnm1234567890";
4+
const ID_SIZE: usize = 8;
5+
6+
pub(crate) fn gen_jail_id() -> String {
7+
let mut gen = rand::thread_rng();
8+
let mut out = Vec::new();
9+
for _i in 0..ID_SIZE {
10+
let ch = *(ID_CHARS.choose(&mut gen).unwrap());
11+
out.push(ch);
12+
}
13+
String::from_utf8_lossy(&out[..]).to_string()
14+
}

src/windows/sandbox.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
use std::ffi::OsString;
2+
use std::os::windows::ffi::OsStrExt;
3+
14
use crate::{
25
windows::{Cvt, Error},
36
ResourceUsageData,
47
};
58

69
use winapi::um::{
7-
jobapi2::{QueryInformationJobObject, TerminateJobObject},
10+
jobapi2::{CreateJobObjectW, QueryInformationJobObject, TerminateJobObject},
811
winnt::{
912
JobObjectBasicAccountingInformation, JobObjectExtendedLimitInformation,
1013
JobObjectLimitViolationInformation, HANDLE, JOBOBJECT_BASIC_ACCOUNTING_INFORMATION,
@@ -13,21 +16,31 @@ use winapi::um::{
1316
},
1417
};
1518

16-
#[derive(Debug, Clone)]
19+
#[derive(Debug)]
1720
pub struct WindowsSandbox {
1821
job: HANDLE,
22+
id: String,
1923
}
2024

25+
unsafe impl Send for WindowsSandbox {}
26+
unsafe impl Sync for WindowsSandbox {}
27+
2128
impl WindowsSandbox {
2229
pub(in crate::windows) fn create() -> Result<Self, Error> {
23-
todo!()
30+
let id = crate::util::gen_jail_id();
31+
let name: OsString = format!("minion-sandbox-{}", id).into();
32+
let wide_name: Vec<u16> = name.encode_wide().collect();
33+
let job = unsafe {
34+
Cvt::nonzero(CreateJobObjectW(std::ptr::null_mut(), wide_name.as_ptr()) as i32)? as HANDLE
35+
};
36+
Ok(Self { job, id })
2437
}
2538
}
2639

2740
impl crate::Sandbox for WindowsSandbox {
2841
type Error = Error;
2942

30-
fn id(&self) -> String {
43+
fn id(&self) -> &str {
3144
todo!()
3245
}
3346

0 commit comments

Comments
 (0)