summary refs log tree commit diff
path: root/io_jail
diff options
context:
space:
mode:
authorMatt Delco <delco@chromium.org>2019-11-13 08:05:55 -0800
committerCommit Bot <commit-bot@chromium.org>2019-11-16 10:29:04 +0000
commit2da61323894c9c12d38fa18ed918987f297ea77d (patch)
treea060c1cb901b4ccd787d6b8e6671de03caf1937b /io_jail
parent8865c5b1951d3dc6dee7e164708b4ccc7f703de1 (diff)
downloadcrosvm-2da61323894c9c12d38fa18ed918987f297ea77d.tar
crosvm-2da61323894c9c12d38fa18ed918987f297ea77d.tar.gz
crosvm-2da61323894c9c12d38fa18ed918987f297ea77d.tar.bz2
crosvm-2da61323894c9c12d38fa18ed918987f297ea77d.tar.lz
crosvm-2da61323894c9c12d38fa18ed918987f297ea77d.tar.xz
crosvm-2da61323894c9c12d38fa18ed918987f297ea77d.tar.zst
crosvm-2da61323894c9c12d38fa18ed918987f297ea77d.zip
io_jail: add additional apis
This change adds additional APIs that are present in the libminijail
header file but not in the rust thunk.  In particular it adds the API
that allows pre-compiled bpf files to be used as a policy file.  The
native API lacks an API to specify a filename (it only provides an API
to provide the contents of the file).

BUG=None
TEST=Local run of build_test to confirm that both .bpf and .policy files
work in a subsequent change.

Change-Id: I15510ffa857b501512f3f9905882545f407bcd78
Signed-off-by: Matt Delco <delco@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1914415
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'io_jail')
-rw-r--r--io_jail/Cargo.toml1
-rw-r--r--io_jail/src/lib.rs33
-rw-r--r--io_jail/src/libminijail.rs9
3 files changed, 42 insertions, 1 deletions
diff --git a/io_jail/Cargo.toml b/io_jail/Cargo.toml
index 5e7ca5d..31f8e6f 100644
--- a/io_jail/Cargo.toml
+++ b/io_jail/Cargo.toml
@@ -6,3 +6,4 @@ edition = "2018"
 
 [dependencies]
 libc = "*"
+net_sys = { path = "../net_sys" }
diff --git a/io_jail/src/lib.rs b/io_jail/src/lib.rs
index 7e66ec5..59d6887 100644
--- a/io_jail/src/lib.rs
+++ b/io_jail/src/lib.rs
@@ -9,10 +9,12 @@
 mod libminijail;
 
 use libc::pid_t;
+use net_sys::{sock_filter, sock_fprog};
 use std::ffi::CString;
 use std::fmt::{self, Display};
 use std::fs;
 use std::io;
+use std::os::raw::c_ushort;
 use std::os::unix::io::{AsRawFd, RawFd};
 use std::path::{Path, PathBuf};
 use std::ptr::{null, null_mut};
@@ -52,6 +54,8 @@ pub enum Error {
     DupDevNull(i32),
     /// Failed to set up /dev/null for FDs 0, 1, or 2.
     OpenDevNull(io::Error),
+    /// Failed to read policy bpf from file.
+    ReadProgram(io::Error),
     /// Setting the specified alt-syscall table failed with errno. Is the table in the kernel?
     SetAltSyscallTable { errno: i32, name: String },
     /// Setting the specified rlimit failed with errno.
@@ -68,6 +72,10 @@ pub enum Error {
     ProcFd(String),
     /// Minijail refused to preserve an FD in the inherit list of `fork()`.
     PreservingFd(i32),
+    /// Program size is too large
+    ProgramTooLarge,
+    /// File size should be non-zero and a multiple of sock_filter
+    WrongProgramSize,
 }
 
 impl Display for Error {
@@ -121,6 +129,7 @@ impl Display for Error {
                 "fail to open /dev/null for setting FDs 0, 1, or 2: {}",
                 e,
             ),
+            ReadProgram(e) => write!(f, "failed to read from bpf file: {}", e),
             SetAltSyscallTable { name, errno } => write!(
                 f,
                 "failed to set alt-syscall table {}: {}",
@@ -144,6 +153,8 @@ impl Display for Error {
             ReadFdDir(e) => write!(f, "failed to open /proc/self/fd: {}", e),
             ProcFd(s) => write!(f, "an entry in /proc/self/fd is not an integer: {}", s),
             PreservingFd(e) => write!(f, "fork failed in minijail_preserve_fd with error {}", e),
+            ProgramTooLarge => write!(f, "bpf program is too large (max 64K instructions)"),
+            WrongProgramSize => write!(f, "bpf file was empty or not a multiple of sock_filter"),
         }
     }
 }
@@ -269,6 +280,28 @@ impl Minijail {
             libminijail::minijail_set_seccomp_filter_tsync(self.jail);
         }
     }
+    pub fn parse_seccomp_program(&mut self, path: &Path) -> Result<()> {
+        if !path.is_file() {
+            return Err(Error::SeccompPath(path.to_owned()));
+        }
+
+        let buffer = fs::read(path).map_err(Error::ReadProgram)?;
+        if buffer.len() % std::mem::size_of::<sock_filter>() != 0 {
+            return Err(Error::WrongProgramSize);
+        }
+        let count = buffer.len() / std::mem::size_of::<sock_filter>();
+        if count > (!0 as u16) as usize {
+            return Err(Error::ProgramTooLarge);
+        }
+        let header = sock_fprog {
+            len: count as c_ushort,
+            filter: buffer.as_ptr() as *mut sock_filter,
+        };
+        unsafe {
+            libminijail::minijail_set_seccomp_filters(self.jail, &header);
+        }
+        Ok(())
+    }
     pub fn parse_seccomp_filters(&mut self, path: &Path) -> Result<()> {
         if !path.is_file() {
             return Err(Error::SeccompPath(path.to_owned()));
diff --git a/io_jail/src/libminijail.rs b/io_jail/src/libminijail.rs
index 227e753..14175dc 100644
--- a/io_jail/src/libminijail.rs
+++ b/io_jail/src/libminijail.rs
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 use libc::{gid_t, pid_t, rlim_t, uid_t};
-use std::os::raw::{c_char, c_int, c_ulong};
+use std::os::raw::{c_char, c_int, c_long, c_ulong};
 
 /// Struct minijail is an opaque type inside libminijail.
 /// See the minijail man page for a description of functions.
@@ -24,6 +24,7 @@ extern "C" {
     pub fn minijail_no_new_privs(j: *mut minijail);
     pub fn minijail_use_seccomp_filter(j: *mut minijail);
     pub fn minijail_set_seccomp_filter_tsync(j: *mut minijail);
+    pub fn minijail_set_seccomp_filters(j: *mut minijail, filter: *const net_sys::sock_fprog);
     pub fn minijail_parse_seccomp_filters(j: *mut minijail, path: *const c_char);
     pub fn minijail_parse_seccomp_filters_from_fd(j: *mut minijail, fd: c_int);
     pub fn minijail_log_seccomp_filter_failures(j: *mut minijail);
@@ -31,16 +32,22 @@ extern "C" {
     pub fn minijail_capbset_drop(j: *mut minijail, capmask: u64);
     pub fn minijail_set_ambient_caps(j: *mut minijail);
     pub fn minijail_reset_signal_mask(j: *mut minijail);
+    pub fn minijail_reset_signal_handlers(j: *mut minijail);
     pub fn minijail_namespace_vfs(j: *mut minijail);
     pub fn minijail_namespace_enter_vfs(j: *mut minijail, ns_path: *const c_char);
     pub fn minijail_new_session_keyring(j: *mut minijail);
+    pub fn minijail_skip_setting_securebits(j: *mut minijail, securebits_skip_mask: u64);
     pub fn minijail_skip_remount_private(j: *mut minijail);
+    pub fn minijail_remount_mode(j: *mut minijail, mode: c_long);
     pub fn minijail_namespace_ipc(j: *mut minijail);
+    pub fn minijail_namespace_uts(j: *mut minijail);
+    pub fn minijail_namespace_set_hostname(j: *mut minijail, name: *const c_char) -> c_int;
     pub fn minijail_namespace_net(j: *mut minijail);
     pub fn minijail_namespace_enter_net(j: *mut minijail, ns_path: *const c_char);
     pub fn minijail_namespace_cgroups(j: *mut minijail);
     pub fn minijail_close_open_fds(j: *mut minijail);
     pub fn minijail_namespace_pids(j: *mut minijail);
+    pub fn minijail_namespace_pids_rw_proc(j: *mut minijail);
     pub fn minijail_namespace_user(j: *mut minijail);
     pub fn minijail_namespace_user_disable_setgroups(j: *mut minijail);
     pub fn minijail_uidmap(j: *mut minijail, uidmap: *const c_char) -> c_int;