mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-12-27 05:43:43 +00:00
crosvm: use sys_util::clone_process to create proxy device
The `clone_process` function was created to safely encapsulate fork/clone usage for the proxy device. This patch changes proxy device to do utilize that. TEST=cargo run -- -u <other crosvm args>... BUG=None Change-Id: I2d9f1794be61be31f3aae21037c7df14b7691172 Reviewed-on: https://chromium-review.googlesource.com/518935 Commit-Ready: Stephen Barber <smbarber@chromium.org> Tested-by: Zach Reizner <zachr@chromium.org> Reviewed-by: Dylan Reid <dgreid@chromium.org>
This commit is contained in:
parent
2b2952ff1f
commit
f651357433
3 changed files with 13 additions and 35 deletions
|
@ -15,7 +15,6 @@ x86_64 = { path = "x86_64" }
|
||||||
kernel_loader = { path = "kernel_loader" }
|
kernel_loader = { path = "kernel_loader" }
|
||||||
libc = "0.2.21"
|
libc = "0.2.21"
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
syscall_defines = { path = "syscall_defines" }
|
|
||||||
|
|
||||||
[dependencies.clap]
|
[dependencies.clap]
|
||||||
version = "*"
|
version = "*"
|
||||||
|
|
|
@ -4,18 +4,14 @@
|
||||||
|
|
||||||
//! Runs hardware devices in child processes.
|
//! Runs hardware devices in child processes.
|
||||||
|
|
||||||
use std::process;
|
use std::io::{Error, ErrorKind, Result};
|
||||||
use std::io::{Error, Result};
|
|
||||||
use std::os::unix::net::UnixDatagram;
|
use std::os::unix::net::UnixDatagram;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use libc;
|
|
||||||
use libc::pid_t;
|
|
||||||
|
|
||||||
use byteorder::{NativeEndian, ByteOrder};
|
use byteorder::{NativeEndian, ByteOrder};
|
||||||
|
|
||||||
use hw::BusDevice;
|
use hw::BusDevice;
|
||||||
use syscall_defines::linux::LinuxSyscall::SYS_clone;
|
use sys_util::{clone_process, CloneNamespace};
|
||||||
|
|
||||||
const SOCKET_TIMEOUT_MS: u64 = 2000;
|
const SOCKET_TIMEOUT_MS: u64 = 2000;
|
||||||
const MSG_SIZE: usize = 24;
|
const MSG_SIZE: usize = 24;
|
||||||
|
@ -27,7 +23,7 @@ enum Command {
|
||||||
Shutdown = 2,
|
Shutdown = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn child_proc(sock: UnixDatagram, device: &mut BusDevice) -> ! {
|
fn child_proc(sock: UnixDatagram, device: &mut BusDevice) {
|
||||||
let mut running = true;
|
let mut running = true;
|
||||||
|
|
||||||
let res = handle_eintr!(sock.send(&CHILD_SIGNATURE));
|
let res = handle_eintr!(sock.send(&CHILD_SIGNATURE));
|
||||||
|
@ -75,23 +71,6 @@ fn child_proc(sock: UnixDatagram, device: &mut BusDevice) -> ! {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! Never returns
|
|
||||||
process::exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn do_clone() -> Result<pid_t> {
|
|
||||||
// Forking is unsafe, this function must be unsafe as there is no way to
|
|
||||||
// guarantee saftey without more context about the state of the program.
|
|
||||||
let pid = libc::syscall(SYS_clone as i64,
|
|
||||||
libc::CLONE_NEWUSER | libc::CLONE_NEWPID |
|
|
||||||
libc::SIGCHLD as i32,
|
|
||||||
0);
|
|
||||||
if pid < 0 {
|
|
||||||
Err(Error::last_os_error())
|
|
||||||
} else {
|
|
||||||
Ok(pid as pid_t)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps an inner `hw::BusDevice` that is run inside a child process via fork.
|
/// Wraps an inner `hw::BusDevice` that is run inside a child process via fork.
|
||||||
|
@ -107,20 +86,21 @@ impl ProxyDevice {
|
||||||
///
|
///
|
||||||
/// The forked process will automatically be terminated when this is dropped, so be sure to keep
|
/// The forked process will automatically be terminated when this is dropped, so be sure to keep
|
||||||
/// a reference.
|
/// a reference.
|
||||||
/// `post_clone_cb` - Called after forking the child process, passed the
|
///
|
||||||
/// child end of the pipe that must be kep open.
|
/// # Arguments
|
||||||
|
/// * `device` - The device to isolate to another process.
|
||||||
|
/// * `post_clone_cb` - Called after forking the child process, passed the child end of the pipe
|
||||||
|
/// that must be kept open.
|
||||||
pub fn new<D: BusDevice, F>(mut device: D, post_clone_cb: F) -> Result<ProxyDevice>
|
pub fn new<D: BusDevice, F>(mut device: D, post_clone_cb: F) -> Result<ProxyDevice>
|
||||||
where F: FnOnce(&UnixDatagram) {
|
where F: FnOnce(&UnixDatagram)
|
||||||
|
{
|
||||||
let (child_sock, parent_sock) = UnixDatagram::pair()?;
|
let (child_sock, parent_sock) = UnixDatagram::pair()?;
|
||||||
|
|
||||||
// Forking a new process is unsafe, we must ensure no resources required
|
clone_process(CloneNamespace::NewUserPid, move || {
|
||||||
// by the other side are freed after the two processes start.
|
|
||||||
let ret = unsafe { do_clone()? };
|
|
||||||
if ret == 0 {
|
|
||||||
post_clone_cb(&child_sock);
|
post_clone_cb(&child_sock);
|
||||||
// ! Never returns
|
|
||||||
child_proc(child_sock, &mut device);
|
child_proc(child_sock, &mut device);
|
||||||
}
|
})
|
||||||
|
.map_err(|e| Error::new(ErrorKind::Other, format!("{:?}", e)))?;
|
||||||
|
|
||||||
let mut buf = [0; MSG_SIZE];
|
let mut buf = [0; MSG_SIZE];
|
||||||
parent_sock
|
parent_sock
|
||||||
|
|
|
@ -12,7 +12,6 @@ extern crate x86_64;
|
||||||
extern crate kernel_loader;
|
extern crate kernel_loader;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
#[macro_use] extern crate sys_util;
|
#[macro_use] extern crate sys_util;
|
||||||
extern crate syscall_defines;
|
|
||||||
|
|
||||||
use std::ffi::{CString, CStr};
|
use std::ffi::{CString, CStr};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
Loading…
Reference in a new issue