mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 18:20:34 +00:00
io_jail: use minijail-sys crate
BUG=chromium:1032360 TEST=cargo build outside of chroot; emerge-board crosvm Cq-Depend: chromium:2055725 Change-Id: I2493f563b07aeaff4627c8b8c4b578901393dc58 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1959449 Reviewed-by: Stephen Barber <smbarber@chromium.org> Tested-by: Stephen Barber <smbarber@chromium.org> Commit-Queue: Stephen Barber <smbarber@chromium.org>
This commit is contained in:
parent
c0cbedd8d2
commit
a2d845a569
3 changed files with 58 additions and 66 deletions
|
@ -58,6 +58,7 @@ kvm = { path = "kvm" }
|
|||
kvm_sys = { path = "kvm_sys" }
|
||||
libc = "0.2.44"
|
||||
libcras = "*"
|
||||
minijail-sys = "*" # provided by ebuild
|
||||
msg_socket = { path = "msg_socket" }
|
||||
net_util = { path = "net_util" }
|
||||
p9 = { path = "p9" }
|
||||
|
@ -85,6 +86,7 @@ assertions = { path = "assertions" }
|
|||
audio_streams = { path = "../../third_party/adhd/audio_streams" } # ignored by ebuild
|
||||
data_model = { path = "data_model" }
|
||||
libcras = { path = "../../third_party/adhd/cras/client/libcras" } # ignored by ebuild
|
||||
minijail-sys = { path = "../../aosp/external/minijail" } # ignored by ebuild
|
||||
poll_token_derive = { path = "sys_util/poll_token_derive" }
|
||||
sync = { path = "sync" }
|
||||
sys_util = { path = "sys_util" }
|
||||
|
|
|
@ -6,4 +6,4 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
libc = "*"
|
||||
net_sys = { path = "../net_sys" }
|
||||
minijail-sys = "*"
|
||||
|
|
|
@ -2,19 +2,13 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_snake_case)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
mod libminijail;
|
||||
|
||||
use libc::pid_t;
|
||||
use net_sys::{sock_filter, sock_fprog};
|
||||
use minijail_sys::*;
|
||||
use std::ffi::CString;
|
||||
use std::fmt::{self, Display};
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::os::raw::{c_ulong, c_ushort};
|
||||
use std::os::raw::{c_char, c_ulong, c_ushort};
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::ptr::{null, null_mut};
|
||||
|
@ -206,7 +200,7 @@ pub type Result<T> = std::result::Result<T, Error>;
|
|||
/// partial jail is not recoverable and will instead result in killing the
|
||||
/// process.
|
||||
pub struct Minijail {
|
||||
jail: *mut libminijail::minijail,
|
||||
jail: *mut minijail,
|
||||
}
|
||||
|
||||
impl Minijail {
|
||||
|
@ -215,7 +209,7 @@ impl Minijail {
|
|||
let j = unsafe {
|
||||
// libminijail actually owns the minijail structure. It will live until we call
|
||||
// minijail_destroy.
|
||||
libminijail::minijail_new()
|
||||
minijail_new()
|
||||
};
|
||||
if j.is_null() {
|
||||
return Err(Error::CreatingMinijail);
|
||||
|
@ -229,22 +223,22 @@ impl Minijail {
|
|||
|
||||
pub fn change_uid(&mut self, uid: libc::uid_t) {
|
||||
unsafe {
|
||||
libminijail::minijail_change_uid(self.jail, uid);
|
||||
minijail_change_uid(self.jail, uid);
|
||||
}
|
||||
}
|
||||
pub fn change_gid(&mut self, gid: libc::gid_t) {
|
||||
unsafe {
|
||||
libminijail::minijail_change_gid(self.jail, gid);
|
||||
minijail_change_gid(self.jail, gid);
|
||||
}
|
||||
}
|
||||
pub fn set_supplementary_gids(&mut self, ids: &[libc::gid_t]) {
|
||||
unsafe {
|
||||
libminijail::minijail_set_supplementary_gids(self.jail, ids.len(), ids.as_ptr());
|
||||
minijail_set_supplementary_gids(self.jail, ids.len(), ids.as_ptr());
|
||||
}
|
||||
}
|
||||
pub fn keep_supplementary_gids(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_keep_supplementary_gids(self.jail);
|
||||
minijail_keep_supplementary_gids(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn set_rlimit(
|
||||
|
@ -253,7 +247,7 @@ impl Minijail {
|
|||
cur: libc::rlim64_t,
|
||||
max: libc::rlim64_t,
|
||||
) -> Result<()> {
|
||||
let errno = unsafe { libminijail::minijail_rlimit(self.jail, kind, cur, max) };
|
||||
let errno = unsafe { minijail_rlimit(self.jail, kind, cur, max) };
|
||||
if errno == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
|
@ -262,22 +256,22 @@ impl Minijail {
|
|||
}
|
||||
pub fn use_seccomp(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_use_seccomp(self.jail);
|
||||
minijail_use_seccomp(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn no_new_privs(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_no_new_privs(self.jail);
|
||||
minijail_no_new_privs(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn use_seccomp_filter(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_use_seccomp_filter(self.jail);
|
||||
minijail_use_seccomp_filter(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn set_seccomp_filter_tsync(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_set_seccomp_filter_tsync(self.jail);
|
||||
minijail_set_seccomp_filter_tsync(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn parse_seccomp_program(&mut self, path: &Path) -> Result<()> {
|
||||
|
@ -298,7 +292,7 @@ impl Minijail {
|
|||
filter: buffer.as_ptr() as *mut sock_filter,
|
||||
};
|
||||
unsafe {
|
||||
libminijail::minijail_set_seccomp_filters(self.jail, &header);
|
||||
minijail_set_seccomp_filters(self.jail, &header);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -314,98 +308,98 @@ impl Minijail {
|
|||
let filename =
|
||||
CString::new(pathstring).map_err(|_| Error::PathToCString(path.to_owned()))?;
|
||||
unsafe {
|
||||
libminijail::minijail_parse_seccomp_filters(self.jail, filename.as_ptr());
|
||||
minijail_parse_seccomp_filters(self.jail, filename.as_ptr());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn log_seccomp_filter_failures(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_log_seccomp_filter_failures(self.jail);
|
||||
minijail_log_seccomp_filter_failures(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn use_caps(&mut self, capmask: u64) {
|
||||
unsafe {
|
||||
libminijail::minijail_use_caps(self.jail, capmask);
|
||||
minijail_use_caps(self.jail, capmask);
|
||||
}
|
||||
}
|
||||
pub fn capbset_drop(&mut self, capmask: u64) {
|
||||
unsafe {
|
||||
libminijail::minijail_capbset_drop(self.jail, capmask);
|
||||
minijail_capbset_drop(self.jail, capmask);
|
||||
}
|
||||
}
|
||||
pub fn set_ambient_caps(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_set_ambient_caps(self.jail);
|
||||
minijail_set_ambient_caps(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn reset_signal_mask(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_reset_signal_mask(self.jail);
|
||||
minijail_reset_signal_mask(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn run_as_init(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_run_as_init(self.jail);
|
||||
minijail_run_as_init(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn namespace_pids(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_namespace_pids(self.jail);
|
||||
minijail_namespace_pids(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn namespace_user(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_namespace_user(self.jail);
|
||||
minijail_namespace_user(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn namespace_user_disable_setgroups(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_namespace_user_disable_setgroups(self.jail);
|
||||
minijail_namespace_user_disable_setgroups(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn namespace_vfs(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_namespace_vfs(self.jail);
|
||||
minijail_namespace_vfs(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn new_session_keyring(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_new_session_keyring(self.jail);
|
||||
minijail_new_session_keyring(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn skip_remount_private(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_skip_remount_private(self.jail);
|
||||
minijail_skip_remount_private(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn namespace_ipc(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_namespace_ipc(self.jail);
|
||||
minijail_namespace_ipc(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn namespace_net(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_namespace_net(self.jail);
|
||||
minijail_namespace_net(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn namespace_cgroups(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_namespace_cgroups(self.jail);
|
||||
minijail_namespace_cgroups(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn remount_proc_readonly(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_remount_proc_readonly(self.jail);
|
||||
minijail_remount_proc_readonly(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn set_remount_mode(&mut self, mode: c_ulong) {
|
||||
unsafe { libminijail::minijail_remount_mode(self.jail, mode) }
|
||||
unsafe { minijail_remount_mode(self.jail, mode) }
|
||||
}
|
||||
pub fn uidmap(&mut self, uid_map: &str) -> Result<()> {
|
||||
let map_cstring =
|
||||
CString::new(uid_map).map_err(|_| Error::StrToCString(uid_map.to_owned()))?;
|
||||
unsafe {
|
||||
libminijail::minijail_uidmap(self.jail, map_cstring.as_ptr());
|
||||
minijail_uidmap(self.jail, map_cstring.as_ptr());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -413,20 +407,19 @@ impl Minijail {
|
|||
let map_cstring =
|
||||
CString::new(gid_map).map_err(|_| Error::StrToCString(gid_map.to_owned()))?;
|
||||
unsafe {
|
||||
libminijail::minijail_gidmap(self.jail, map_cstring.as_ptr());
|
||||
minijail_gidmap(self.jail, map_cstring.as_ptr());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn inherit_usergroups(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_inherit_usergroups(self.jail);
|
||||
minijail_inherit_usergroups(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn use_alt_syscall(&mut self, table_name: &str) -> Result<()> {
|
||||
let table_name_string =
|
||||
CString::new(table_name).map_err(|_| Error::StrToCString(table_name.to_owned()))?;
|
||||
let ret =
|
||||
unsafe { libminijail::minijail_use_alt_syscall(self.jail, table_name_string.as_ptr()) };
|
||||
let ret = unsafe { minijail_use_alt_syscall(self.jail, table_name_string.as_ptr()) };
|
||||
if ret < 0 {
|
||||
return Err(Error::SetAltSyscallTable {
|
||||
errno: ret,
|
||||
|
@ -441,7 +434,7 @@ impl Minijail {
|
|||
.to_str()
|
||||
.ok_or(Error::PathToCString(dir.to_owned()))?;
|
||||
let dirname = CString::new(pathstring).map_err(|_| Error::PathToCString(dir.to_owned()))?;
|
||||
let ret = unsafe { libminijail::minijail_enter_chroot(self.jail, dirname.as_ptr()) };
|
||||
let ret = unsafe { minijail_enter_chroot(self.jail, dirname.as_ptr()) };
|
||||
if ret < 0 {
|
||||
return Err(Error::SettingChrootDirectory(ret, dir.to_owned()));
|
||||
}
|
||||
|
@ -453,7 +446,7 @@ impl Minijail {
|
|||
.to_str()
|
||||
.ok_or(Error::PathToCString(dir.to_owned()))?;
|
||||
let dirname = CString::new(pathstring).map_err(|_| Error::PathToCString(dir.to_owned()))?;
|
||||
let ret = unsafe { libminijail::minijail_enter_pivot_root(self.jail, dirname.as_ptr()) };
|
||||
let ret = unsafe { minijail_enter_pivot_root(self.jail, dirname.as_ptr()) };
|
||||
if ret < 0 {
|
||||
return Err(Error::SettingPivotRootDirectory(ret, dir.to_owned()));
|
||||
}
|
||||
|
@ -485,7 +478,7 @@ impl Minijail {
|
|||
CString::new(fstype).map_err(|_| Error::StrToCString(fstype.to_owned()))?;
|
||||
let data_string = CString::new(data).map_err(|_| Error::StrToCString(data.to_owned()))?;
|
||||
let ret = unsafe {
|
||||
libminijail::minijail_mount_with_data(
|
||||
minijail_mount_with_data(
|
||||
self.jail,
|
||||
src_path.as_ptr(),
|
||||
dest_path.as_ptr(),
|
||||
|
@ -508,17 +501,17 @@ impl Minijail {
|
|||
}
|
||||
pub fn mount_dev(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_mount_dev(self.jail);
|
||||
minijail_mount_dev(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn mount_tmp(&mut self) {
|
||||
unsafe {
|
||||
libminijail::minijail_mount_tmp(self.jail);
|
||||
minijail_mount_tmp(self.jail);
|
||||
}
|
||||
}
|
||||
pub fn mount_tmp_size(&mut self, size: usize) {
|
||||
unsafe {
|
||||
libminijail::minijail_mount_tmp_size(self.jail, size);
|
||||
minijail_mount_tmp_size(self.jail, size);
|
||||
}
|
||||
}
|
||||
pub fn mount_bind(&mut self, src: &Path, dest: &Path, writable: bool) -> Result<()> {
|
||||
|
@ -534,7 +527,7 @@ impl Minijail {
|
|||
let dest_path =
|
||||
CString::new(dest_os).map_err(|_| Error::StrToCString(dest_os.to_owned()))?;
|
||||
let ret = unsafe {
|
||||
libminijail::minijail_bind(
|
||||
minijail_bind(
|
||||
self.jail,
|
||||
src_path.as_ptr(),
|
||||
dest_path.as_ptr(),
|
||||
|
@ -571,7 +564,7 @@ impl Minijail {
|
|||
args_array.push(null());
|
||||
|
||||
for fd in inheritable_fds {
|
||||
let ret = unsafe { libminijail::minijail_preserve_fd(self.jail, *fd, *fd) };
|
||||
let ret = unsafe { minijail_preserve_fd(self.jail, *fd, *fd) };
|
||||
if ret < 0 {
|
||||
return Err(Error::PreservingFd(ret));
|
||||
}
|
||||
|
@ -586,9 +579,7 @@ impl Minijail {
|
|||
// These will only be closed when this process exits.
|
||||
for io_fd in &[libc::STDIN_FILENO, libc::STDOUT_FILENO, libc::STDERR_FILENO] {
|
||||
if !inheritable_fds.contains(io_fd) {
|
||||
let ret = unsafe {
|
||||
libminijail::minijail_preserve_fd(self.jail, dev_null.as_raw_fd(), *io_fd)
|
||||
};
|
||||
let ret = unsafe { minijail_preserve_fd(self.jail, dev_null.as_raw_fd(), *io_fd) };
|
||||
if ret < 0 {
|
||||
return Err(Error::PreservingFd(ret));
|
||||
}
|
||||
|
@ -596,15 +587,15 @@ impl Minijail {
|
|||
}
|
||||
|
||||
unsafe {
|
||||
libminijail::minijail_close_open_fds(self.jail);
|
||||
minijail_close_open_fds(self.jail);
|
||||
}
|
||||
|
||||
let mut pid = 0;
|
||||
let ret = unsafe {
|
||||
libminijail::minijail_run_pid_pipes(
|
||||
minijail_run_pid_pipes(
|
||||
self.jail,
|
||||
cmd_cstr.as_ptr(),
|
||||
args_array.as_ptr(),
|
||||
args_array.as_ptr() as *const *mut c_char,
|
||||
&mut pid,
|
||||
null_mut(),
|
||||
null_mut(),
|
||||
|
@ -635,7 +626,7 @@ impl Minijail {
|
|||
|
||||
if let Some(keep_fds) = inheritable_fds {
|
||||
for fd in keep_fds {
|
||||
let ret = libminijail::minijail_preserve_fd(self.jail, *fd, *fd);
|
||||
let ret = minijail_preserve_fd(self.jail, *fd, *fd);
|
||||
if ret < 0 {
|
||||
return Err(Error::PreservingFd(ret));
|
||||
}
|
||||
|
@ -651,17 +642,16 @@ impl Minijail {
|
|||
// These will only be closed when this process exits.
|
||||
for io_fd in &[libc::STDIN_FILENO, libc::STDOUT_FILENO, libc::STDERR_FILENO] {
|
||||
if inheritable_fds.is_none() || !inheritable_fds.unwrap().contains(io_fd) {
|
||||
let ret =
|
||||
libminijail::minijail_preserve_fd(self.jail, dev_null.as_raw_fd(), *io_fd);
|
||||
let ret = minijail_preserve_fd(self.jail, dev_null.as_raw_fd(), *io_fd);
|
||||
if ret < 0 {
|
||||
return Err(Error::PreservingFd(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libminijail::minijail_close_open_fds(self.jail);
|
||||
minijail_close_open_fds(self.jail);
|
||||
|
||||
let ret = libminijail::minijail_fork(self.jail);
|
||||
let ret = minijail_fork(self.jail);
|
||||
if ret < 0 {
|
||||
return Err(Error::ForkingMinijail(ret));
|
||||
}
|
||||
|
@ -675,7 +665,7 @@ impl Drop for Minijail {
|
|||
unsafe {
|
||||
// Destroys the minijail's memory. It is safe to do here because all references to
|
||||
// this object have been dropped.
|
||||
libminijail::minijail_destroy(self.jail);
|
||||
minijail_destroy(self.jail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -701,9 +691,9 @@ mod tests {
|
|||
#[test]
|
||||
fn create_and_free() {
|
||||
unsafe {
|
||||
let j = libminijail::minijail_new();
|
||||
let j = minijail_new();
|
||||
assert_ne!(std::ptr::null_mut(), j);
|
||||
libminijail::minijail_destroy(j);
|
||||
minijail_destroy(j);
|
||||
}
|
||||
|
||||
let j = Minijail::new().unwrap();
|
||||
|
|
Loading…
Reference in a new issue