// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use libc::pid_t;
use minijail_sys::*;
use std::ffi::CString;
use std::fmt::{self, Display};
use std::fs;
use std::io;
use std::os::raw::{c_char, c_ulong, c_ushort};
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
use std::path::{Path, PathBuf};
use std::ptr::{null, null_mut};

#[derive(Debug)]
pub enum Error {
    // minijail failed to accept bind mount.
    BindMount {
        errno: i32,
        src: PathBuf,
        dst: PathBuf,
    },
    // minijail failed to accept mount.
    Mount {
        errno: i32,
        src: PathBuf,
        dest: PathBuf,
        fstype: String,
        flags: usize,
        data: String,
    },
    /// Failure to count the number of threads in /proc/self/tasks.
    CheckingMultiThreaded(io::Error),
    /// minjail_new failed, this is an allocation failure.
    CreatingMinijail,
    /// minijail_fork failed with the given error code.
    ForkingMinijail(i32),
    /// Attempt to `fork` while already multithreaded.
    ForkingWhileMultiThreaded,
    /// The seccomp policy path doesn't exist.
    SeccompPath(PathBuf),
    /// The string passed in didn't parse to a valid CString.
    StrToCString(String),
    /// The path passed in didn't parse to a valid CString.
    PathToCString(PathBuf),
    /// Failed to call dup2 to set stdin, stdout, or stderr to /dev/null.
    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.
    SetRlimit { errno: i32, kind: libc::c_int },
    /// chroot failed with the provided errno.
    SettingChrootDirectory(i32, PathBuf),
    /// pivot_root failed with the provided errno.
    SettingPivotRootDirectory(i32, PathBuf),
    /// There is an entry in /proc/self/fd that isn't a valid PID.
    ReadFdDirEntry(io::Error),
    /// /proc/self/fd failed to open.
    ReadFdDir(io::Error),
    /// An entry in /proc/self/fd is not an integer
    ProcFd(String),
    /// Minijail refused to preserve an FD in the inherit list of `fork()`.
    PreservingFd(i32),
    /// Program size is too large
    ProgramTooLarge,
    /// Alignment of file should be divisible by the alignment of sock_filter.
    WrongProgramAlignment,
    /// File size should be non-zero and a multiple of sock_filter
    WrongProgramSize,

    /// The command was not found.
    NoCommand,
    /// The command could not be run.
    NoAccess,
    /// Process was killed by SIGSYS indicating a seccomp violation.
    SeccompViolation(i32),
    /// Process was killed by a signal other than SIGSYS.
    Killed(u8),
    /// Process finished returning a non-zero code.
    ReturnCode(u8),
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::Error::*;

        match self {
            BindMount { src, dst, errno } => write!(
                f,
                "failed to accept bind mount {} -> {}: {}",
                src.display(),
                dst.display(),
                io::Error::from_raw_os_error(*errno),
            ),
            Mount {
                errno,
                src,
                dest,
                fstype,
                flags,
                data,
            } => write!(
                f,
                "failed to accept mount {} -> {} of type {:?} with flags 0x{:x} \
                 and data {:?}: {}",
                src.display(),
                dest.display(),
                fstype,
                flags,
                data,
                io::Error::from_raw_os_error(*errno),
            ),
            CheckingMultiThreaded(e) => write!(
                f,
                "Failed to count the number of threads from /proc/self/tasks {}",
                e
            ),
            CreatingMinijail => write!(f, "minjail_new failed due to an allocation failure"),
            ForkingMinijail(e) => write!(f, "minijail_fork failed with error {}", e),
            ForkingWhileMultiThreaded => write!(f, "Attempt to call fork() while multithreaded"),
            SeccompPath(p) => write!(f, "missing seccomp policy path: {}", p.display()),
            StrToCString(s) => write!(f, "failed to convert string into CString: {}", s),
            PathToCString(s) => write!(f, "failed to convert path into CString: {}", s.display()),
            DupDevNull(errno) => write!(
                f,
                "failed to call dup2 to set stdin, stdout, or stderr to /dev/null: {}",
                io::Error::from_raw_os_error(*errno),
            ),
            OpenDevNull(e) => write!(
                f,
                "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 {}: {}",
                name,
                io::Error::from_raw_os_error(*errno),
            ),
            SetRlimit { errno, kind } => write!(f, "failed to set rlimit {}: {}", kind, errno),
            SettingChrootDirectory(errno, p) => write!(
                f,
                "failed to set chroot {}: {}",
                p.display(),
                io::Error::from_raw_os_error(*errno),
            ),
            SettingPivotRootDirectory(errno, p) => write!(
                f,
                "failed to set pivot root {}: {}",
                p.display(),
                io::Error::from_raw_os_error(*errno),
            ),
            ReadFdDirEntry(e) => write!(f, "failed to read an entry in /proc/self/fd: {}", e),
            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)"),
            WrongProgramAlignment => write!(
                f,
                "the alignment of bpf file was not a multiple of that of sock_filter"
            ),
            WrongProgramSize => write!(f, "bpf file was empty or not a multiple of sock_filter"),
            NoCommand => write!(f, "command was not found"),
            NoAccess => write!(f, "unable to execute command"),
            SeccompViolation(s) => write!(f, "seccomp violation syscall #{}", s),
            Killed(s) => write!(f, "killed with signal number {}", s),
            ReturnCode(e) => write!(f, "exited with code {}", e),
        }
    }
}

impl std::error::Error for Error {}

pub type Result<T> = std::result::Result<T, Error>;

/// Configuration to jail a process based on wrapping libminijail.
///
/// Intentionally leave out everything related to `minijail_run`.  Forking is
/// hard to reason about w.r.t. memory and resource safety.  It is better to avoid
/// forking from rust code.  Leave forking to the library user, who can make
/// an informed decision about when to fork to minimize risk.
/// # Examples
/// * Load seccomp policy - like "minijail0 -n -S myfilter.policy"
///
/// ```
/// # use minijail::Minijail;
/// # fn seccomp_filter_test() -> Result<(), ()> {
///       let mut j = Minijail::new().map_err(|_| ())?;
///       j.no_new_privs();
///       j.parse_seccomp_filters("my_filter.policy").map_err(|_| ())?;
///       j.use_seccomp_filter();
///       unsafe { // `fork` will close all the programs FDs.
///           j.fork(None).map_err(|_| ())?;
///       }
/// #     Ok(())
/// # }
/// ```
///
/// * Keep stdin, stdout, and stderr open after jailing.
///
/// ```
/// # use minijail::Minijail;
/// # use std::os::unix::io::RawFd;
/// # fn seccomp_filter_test() -> Result<(), ()> {
///       let j = Minijail::new().map_err(|_| ())?;
///       let preserve_fds: Vec<RawFd> = vec![0, 1, 2];
///       unsafe { // `fork` will close all the programs FDs.
///           j.fork(Some(&preserve_fds)).map_err(|_| ())?;
///       }
/// #     Ok(())
/// # }
/// ```
/// # Errors
/// The `fork` function might not return an error if it fails after forking. A
/// partial jail is not recoverable and will instead result in killing the
/// process.
pub struct Minijail {
    jail: *mut minijail,
}

#[link(name = "c")]
extern "C" {
    fn __libc_current_sigrtmax() -> libc::c_int;
}

fn translate_wait_error(ret: libc::c_int) -> Result<()> {
    if ret == 0 {
        return Ok(());
    }
    if ret == MINIJAIL_ERR_NO_COMMAND as libc::c_int {
        return Err(Error::NoCommand);
    }
    if ret == MINIJAIL_ERR_NO_ACCESS as libc::c_int {
        return Err(Error::NoAccess);
    }
    let sig_base: libc::c_int = MINIJAIL_ERR_SIG_BASE as libc::c_int;
    let sig_max_code: libc::c_int = unsafe { __libc_current_sigrtmax() } + sig_base;
    if ret > sig_base && ret <= sig_max_code {
        return Err(Error::Killed(
            (ret - MINIJAIL_ERR_SIG_BASE as libc::c_int) as u8,
        ));
    }
    if ret > 0 && ret <= 0xff {
        return Err(Error::ReturnCode(ret as u8));
    }
    unreachable!();
}

impl Minijail {
    /// Creates a new jail configuration.
    pub fn new() -> Result<Minijail> {
        let j = unsafe {
            // libminijail actually owns the minijail structure. It will live until we call
            // minijail_destroy.
            minijail_new()
        };
        if j.is_null() {
            return Err(Error::CreatingMinijail);
        }
        Ok(Minijail { jail: j })
    }

    /// Clones self to a new `Minijail`. Useful because `fork` can only be called once on a
    /// `Minijail`.
    pub fn try_clone(&self) -> Result<Minijail> {
        let jail_out = Minijail::new()?;
        unsafe {
            // Safe to clone one minijail to the other as minijail_clone doesn't modify the source
            // jail(`self`) and leaves a valid minijail in the destination(`jail_out`).
            let ret = minijail_copy_jail(self.jail, jail_out.jail);
            if ret < 0 {
                return Err(Error::ReturnCode(ret as u8));
            }
        }

        Ok(jail_out)
    }

    // The following functions are safe because they only set values in the
    // struct already owned by minijail.  The struct's lifetime is tied to
    // `struct Minijail` so it is guaranteed to be valid

    pub fn change_uid(&mut self, uid: libc::uid_t) {
        unsafe {
            minijail_change_uid(self.jail, uid);
        }
    }
    pub fn change_gid(&mut self, gid: libc::gid_t) {
        unsafe {
            minijail_change_gid(self.jail, gid);
        }
    }
    pub fn change_user(&mut self, user: &str) -> Result<()> {
        let user_cstring = CString::new(user).map_err(|_| Error::StrToCString(user.to_owned()))?;
        unsafe {
            minijail_change_user(self.jail, user_cstring.as_ptr());
        }
        Ok(())
    }
    pub fn change_group(&mut self, group: &str) -> Result<()> {
        let group_cstring =
            CString::new(group).map_err(|_| Error::StrToCString(group.to_owned()))?;
        unsafe {
            minijail_change_group(self.jail, group_cstring.as_ptr());
        }
        Ok(())
    }
    pub fn set_supplementary_gids(&mut self, ids: &[libc::gid_t]) {
        unsafe {
            minijail_set_supplementary_gids(self.jail, ids.len(), ids.as_ptr());
        }
    }
    pub fn keep_supplementary_gids(&mut self) {
        unsafe {
            minijail_keep_supplementary_gids(self.jail);
        }
    }
    // rlim_t is defined in minijail-sys to be u64 on all platforms, to avoid
    // issues on 32-bit platforms. It's also useful to us here to avoid
    // libc::rlim64_t, which is not defined at all on Android.
    pub fn set_rlimit(&mut self, kind: libc::c_int, cur: rlim_t, max: rlim_t) -> Result<()> {
        let errno = unsafe { minijail_rlimit(self.jail, kind, cur, max) };
        if errno == 0 {
            Ok(())
        } else {
            Err(Error::SetRlimit { errno, kind })
        }
    }
    pub fn use_seccomp(&mut self) {
        unsafe {
            minijail_use_seccomp(self.jail);
        }
    }
    pub fn no_new_privs(&mut self) {
        unsafe {
            minijail_no_new_privs(self.jail);
        }
    }
    pub fn use_seccomp_filter(&mut self) {
        unsafe {
            minijail_use_seccomp_filter(self.jail);
        }
    }
    pub fn set_seccomp_filter_tsync(&mut self) {
        unsafe {
            minijail_set_seccomp_filter_tsync(self.jail);
        }
    }
    pub fn parse_seccomp_program<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
        if !path.as_ref().is_file() {
            return Err(Error::SeccompPath(path.as_ref().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);
        }
        if buffer.as_ptr() as usize % std::mem::align_of::<sock_filter>() != 0 {
            return Err(Error::WrongProgramAlignment);
        }

        // Safe cast because we checked that the buffer address is divisible by the alignment of
        // sock_filter.
        #[allow(clippy::cast_ptr_alignment)]
        let header = sock_fprog {
            len: count as c_ushort,
            filter: buffer.as_ptr() as *mut sock_filter,
        };
        unsafe {
            minijail_set_seccomp_filters(self.jail, &header);
        }
        Ok(())
    }
    pub fn parse_seccomp_filters<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
        if !path.as_ref().is_file() {
            return Err(Error::SeccompPath(path.as_ref().to_owned()));
        }

        let pathstring = path
            .as_ref()
            .as_os_str()
            .to_str()
            .ok_or_else(|| Error::PathToCString(path.as_ref().to_owned()))?;
        let filename =
            CString::new(pathstring).map_err(|_| Error::PathToCString(path.as_ref().to_owned()))?;
        unsafe {
            minijail_parse_seccomp_filters(self.jail, filename.as_ptr());
        }
        Ok(())
    }
    pub fn log_seccomp_filter_failures(&mut self) {
        unsafe {
            minijail_log_seccomp_filter_failures(self.jail);
        }
    }
    pub fn use_caps(&mut self, capmask: u64) {
        unsafe {
            minijail_use_caps(self.jail, capmask);
        }
    }
    pub fn capbset_drop(&mut self, capmask: u64) {
        unsafe {
            minijail_capbset_drop(self.jail, capmask);
        }
    }
    pub fn set_ambient_caps(&mut self) {
        unsafe {
            minijail_set_ambient_caps(self.jail);
        }
    }
    pub fn reset_signal_mask(&mut self) {
        unsafe {
            minijail_reset_signal_mask(self.jail);
        }
    }
    pub fn run_as_init(&mut self) {
        unsafe {
            minijail_run_as_init(self.jail);
        }
    }
    pub fn namespace_pids(&mut self) {
        unsafe {
            minijail_namespace_pids(self.jail);
        }
    }
    pub fn namespace_user(&mut self) {
        unsafe {
            minijail_namespace_user(self.jail);
        }
    }
    pub fn namespace_user_disable_setgroups(&mut self) {
        unsafe {
            minijail_namespace_user_disable_setgroups(self.jail);
        }
    }
    pub fn namespace_vfs(&mut self) {
        unsafe {
            minijail_namespace_vfs(self.jail);
        }
    }
    pub fn new_session_keyring(&mut self) {
        unsafe {
            minijail_new_session_keyring(self.jail);
        }
    }
    pub fn skip_remount_private(&mut self) {
        unsafe {
            minijail_skip_remount_private(self.jail);
        }
    }
    pub fn namespace_ipc(&mut self) {
        unsafe {
            minijail_namespace_ipc(self.jail);
        }
    }
    pub fn namespace_net(&mut self) {
        unsafe {
            minijail_namespace_net(self.jail);
        }
    }
    pub fn namespace_cgroups(&mut self) {
        unsafe {
            minijail_namespace_cgroups(self.jail);
        }
    }
    pub fn remount_proc_readonly(&mut self) {
        unsafe {
            minijail_remount_proc_readonly(self.jail);
        }
    }
    pub fn set_remount_mode(&mut self, mode: c_ulong) {
        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 {
            minijail_uidmap(self.jail, map_cstring.as_ptr());
        }
        Ok(())
    }
    pub fn gidmap(&mut self, gid_map: &str) -> Result<()> {
        let map_cstring =
            CString::new(gid_map).map_err(|_| Error::StrToCString(gid_map.to_owned()))?;
        unsafe {
            minijail_gidmap(self.jail, map_cstring.as_ptr());
        }
        Ok(())
    }
    pub fn inherit_usergroups(&mut self) {
        unsafe {
            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 { minijail_use_alt_syscall(self.jail, table_name_string.as_ptr()) };
        if ret < 0 {
            return Err(Error::SetAltSyscallTable {
                errno: ret,
                name: table_name.to_owned(),
            });
        }
        Ok(())
    }
    pub fn enter_chroot<P: AsRef<Path>>(&mut self, dir: P) -> Result<()> {
        let pathstring = dir
            .as_ref()
            .as_os_str()
            .to_str()
            .ok_or_else(|| Error::PathToCString(dir.as_ref().to_owned()))?;
        let dirname =
            CString::new(pathstring).map_err(|_| Error::PathToCString(dir.as_ref().to_owned()))?;
        let ret = unsafe { minijail_enter_chroot(self.jail, dirname.as_ptr()) };
        if ret < 0 {
            return Err(Error::SettingChrootDirectory(ret, dir.as_ref().to_owned()));
        }
        Ok(())
    }
    pub fn enter_pivot_root<P: AsRef<Path>>(&mut self, dir: P) -> Result<()> {
        let pathstring = dir
            .as_ref()
            .as_os_str()
            .to_str()
            .ok_or_else(|| Error::PathToCString(dir.as_ref().to_owned()))?;
        let dirname =
            CString::new(pathstring).map_err(|_| Error::PathToCString(dir.as_ref().to_owned()))?;
        let ret = unsafe { minijail_enter_pivot_root(self.jail, dirname.as_ptr()) };
        if ret < 0 {
            return Err(Error::SettingPivotRootDirectory(
                ret,
                dir.as_ref().to_owned(),
            ));
        }
        Ok(())
    }
    pub fn mount<P1: AsRef<Path>, P2: AsRef<Path>>(
        &mut self,
        src: P1,
        dest: P2,
        fstype: &str,
        flags: usize,
    ) -> Result<()> {
        self.mount_with_data(src, dest, fstype, flags, "")
    }
    pub fn mount_with_data<P1: AsRef<Path>, P2: AsRef<Path>>(
        &mut self,
        src: P1,
        dest: P2,
        fstype: &str,
        flags: usize,
        data: &str,
    ) -> Result<()> {
        let src_os = src
            .as_ref()
            .as_os_str()
            .to_str()
            .ok_or_else(|| Error::PathToCString(src.as_ref().to_owned()))?;
        let src_path = CString::new(src_os).map_err(|_| Error::StrToCString(src_os.to_owned()))?;
        let dest_os = dest
            .as_ref()
            .as_os_str()
            .to_str()
            .ok_or_else(|| Error::PathToCString(dest.as_ref().to_owned()))?;
        let dest_path =
            CString::new(dest_os).map_err(|_| Error::StrToCString(dest_os.to_owned()))?;
        let fstype_string =
            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 {
            minijail_mount_with_data(
                self.jail,
                src_path.as_ptr(),
                dest_path.as_ptr(),
                fstype_string.as_ptr(),
                flags as _,
                data_string.as_ptr(),
            )
        };
        if ret < 0 {
            return Err(Error::Mount {
                errno: ret,
                src: src.as_ref().to_owned(),
                dest: dest.as_ref().to_owned(),
                fstype: fstype.to_owned(),
                flags,
                data: data.to_owned(),
            });
        }
        Ok(())
    }
    pub fn mount_dev(&mut self) {
        unsafe {
            minijail_mount_dev(self.jail);
        }
    }
    pub fn mount_tmp(&mut self) {
        unsafe {
            minijail_mount_tmp(self.jail);
        }
    }
    pub fn mount_tmp_size(&mut self, size: usize) {
        unsafe {
            minijail_mount_tmp_size(self.jail, size);
        }
    }
    pub fn mount_bind<P1: AsRef<Path>, P2: AsRef<Path>>(
        &mut self,
        src: P1,
        dest: P2,
        writable: bool,
    ) -> Result<()> {
        let src_os = src
            .as_ref()
            .as_os_str()
            .to_str()
            .ok_or_else(|| Error::PathToCString(src.as_ref().to_owned()))?;
        let src_path = CString::new(src_os).map_err(|_| Error::StrToCString(src_os.to_owned()))?;
        let dest_os = dest
            .as_ref()
            .as_os_str()
            .to_str()
            .ok_or_else(|| Error::PathToCString(dest.as_ref().to_owned()))?;
        let dest_path =
            CString::new(dest_os).map_err(|_| Error::StrToCString(dest_os.to_owned()))?;
        let ret = unsafe {
            minijail_bind(
                self.jail,
                src_path.as_ptr(),
                dest_path.as_ptr(),
                writable as _,
            )
        };
        if ret < 0 {
            return Err(Error::BindMount {
                errno: ret,
                src: src.as_ref().to_owned(),
                dst: dest.as_ref().to_owned(),
            });
        }
        Ok(())
    }

    /// Forks and execs a child and puts it in the previously configured minijail.
    /// FDs 0, 1, and 2 are overwritten with /dev/null FDs unless they are included in the
    /// inheritable_fds list. This function may abort in the child on error because a partially
    /// entered jail isn't recoverable.
    pub fn run<P: AsRef<Path>, S: AsRef<str>>(
        &self,
        cmd: P,
        inheritable_fds: &[RawFd],
        args: &[S],
    ) -> Result<pid_t> {
        self.run_remap(
            cmd,
            &inheritable_fds
                .iter()
                .map(|&a| (a, a))
                .collect::<Vec<(RawFd, RawFd)>>(),
            args,
        )
    }

    /// Behaves the same as `run()` except `inheritable_fds` is a list of fd
    /// mappings rather than just a list of fds to preserve.
    pub fn run_remap<P: AsRef<Path>, S: AsRef<str>>(
        &self,
        cmd: P,
        inheritable_fds: &[(RawFd, RawFd)],
        args: &[S],
    ) -> Result<pid_t> {
        let cmd_os = cmd
            .as_ref()
            .to_str()
            .ok_or_else(|| Error::PathToCString(cmd.as_ref().to_owned()))?;
        let cmd_cstr = CString::new(cmd_os).map_err(|_| Error::StrToCString(cmd_os.to_owned()))?;

        // Converts each incoming `args` string to a `CString`, and then puts each `CString` pointer
        // into a null terminated array, suitable for use as an argv parameter to `execve`.
        let mut args_cstr = Vec::with_capacity(args.len());
        let mut args_array = Vec::with_capacity(args.len());
        for arg in args {
            let arg_cstr = CString::new(arg.as_ref())
                .map_err(|_| Error::StrToCString(arg.as_ref().to_owned()))?;
            args_array.push(arg_cstr.as_ptr());
            args_cstr.push(arg_cstr);
        }
        args_array.push(null());

        for (src_fd, dst_fd) in inheritable_fds {
            let ret = unsafe { minijail_preserve_fd(self.jail, *src_fd, *dst_fd) };
            if ret < 0 {
                return Err(Error::PreservingFd(ret));
            }
        }

        let dev_null = fs::OpenOptions::new()
            .read(true)
            .write(true)
            .open("/dev/null")
            .map_err(Error::OpenDevNull)?;
        // Set stdin, stdout, and stderr to /dev/null unless they are in the inherit list.
        // 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.iter().any(|(_, fd)| *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));
                }
            }
        }

        unsafe {
            minijail_close_open_fds(self.jail);
        }

        let mut pid = 0;
        let ret = unsafe {
            minijail_run_pid_pipes(
                self.jail,
                cmd_cstr.as_ptr(),
                args_array.as_ptr() as *const *mut c_char,
                &mut pid,
                null_mut(),
                null_mut(),
                null_mut(),
            )
        };
        if ret < 0 {
            return Err(Error::ForkingMinijail(ret));
        }
        Ok(pid)
    }

    /// Forks a child and puts it in the previously configured minijail.
    ///
    /// # Safety
    /// `fork` is unsafe because it closes all open FD for this process.  That
    /// could cause a lot of trouble if not handled carefully.  FDs 0, 1, and 2
    /// are overwritten with /dev/null FDs unless they are included in the
    /// inheritable_fds list.
    ///
    /// Also, any Rust objects that own fds may try to close them after the fork. If they belong
    /// to a fd number that was mapped to, the mapped fd will be closed instead.
    ///
    /// This Function may abort in the child on error because a partially
    /// entered jail isn't recoverable.
    pub unsafe fn fork(&self, inheritable_fds: Option<&[RawFd]>) -> Result<pid_t> {
        let m: Vec<(RawFd, RawFd)> = inheritable_fds
            .unwrap_or(&[])
            .iter()
            .map(|&a| (a, a))
            .collect();
        self.fork_remap(&m)
    }

    /// Behaves the same as `fork()` except `inheritable_fds` is a list of fd
    /// mappings rather than just a list of fds to preserve.
    ///
    /// # Safety
    /// See `fork`.
    pub unsafe fn fork_remap(&self, inheritable_fds: &[(RawFd, RawFd)]) -> Result<pid_t> {
        if !is_single_threaded().map_err(Error::CheckingMultiThreaded)? {
            // This test will fail during `cargo test` because the test harness always spawns a test
            // thread. We will make an exception for that case because the tests for this module
            // should always be run in a serial fashion using `--test-threads=1`.
            #[cfg(not(test))]
            return Err(Error::ForkingWhileMultiThreaded);
        }

        for (src_fd, dst_fd) in inheritable_fds {
            let ret = minijail_preserve_fd(self.jail, *src_fd, *dst_fd);
            if ret < 0 {
                return Err(Error::PreservingFd(ret));
            }
        }

        let dev_null = fs::OpenOptions::new()
            .read(true)
            .write(true)
            .open("/dev/null")
            .map_err(Error::OpenDevNull)?;
        // Set stdin, stdout, and stderr to /dev/null unless they are in the inherit list.
        // 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.iter().any(|(_, fd)| *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));
                }
            }
        }

        minijail_close_open_fds(self.jail);

        let ret = minijail_fork(self.jail);
        if ret < 0 {
            return Err(Error::ForkingMinijail(ret));
        }
        if ret == 0 {
            // Safe because dev_null was remapped.
            dev_null.into_raw_fd();
        }
        Ok(ret as pid_t)
    }

    pub fn wait(&self) -> Result<()> {
        let ret: libc::c_int;
        // This is safe because it does not modify the struct.
        unsafe {
            ret = minijail_wait(self.jail);
        }
        translate_wait_error(ret)
    }

    /// Send a SIGTERM to the child process and wait for its return code.
    pub fn kill(&self) -> Result<()> {
        let ret = unsafe {
            // The kill does not change any internal state.
            minijail_kill(self.jail)
        };
        // minijail_kill waits for the process, so also translate the returned wait error.
        translate_wait_error(ret)
    }
}

impl Drop for Minijail {
    /// Frees the Minijail created in Minijail::new.
    fn drop(&mut self) {
        unsafe {
            // Destroys the minijail's memory.  It is safe to do here because all references to
            // this object have been dropped.
            minijail_destroy(self.jail);
        }
    }
}

// Count the number of files in the directory specified by `path`.
fn count_dir_entries<P: AsRef<Path>>(path: P) -> io::Result<usize> {
    Ok(fs::read_dir(path)?.count())
}

// Return true if the current thread is the only thread in the process.
fn is_single_threaded() -> io::Result<bool> {
    match count_dir_entries("/proc/self/task") {
        Ok(1) => Ok(true),
        Ok(_) => Ok(false),
        Err(e) => Err(e),
    }
}

#[cfg(test)]
mod tests {
    use std::process::exit;

    use super::*;

    const SHELL: &str = "/bin/sh";
    const EMPTY_STRING_SLICE: &[&str] = &[];

    #[test]
    fn create_and_free() {
        unsafe {
            let j = minijail_new();
            assert_ne!(std::ptr::null_mut(), j);
            minijail_destroy(j);
        }

        let j = Minijail::new().unwrap();
        drop(j);
    }

    #[test]
    // Test that setting a seccomp filter with no-new-privs works as non-root.
    // This is equivalent to minijail0 -n -S <seccomp_policy>
    fn seccomp_no_new_privs() {
        let mut j = Minijail::new().unwrap();
        j.no_new_privs();
        j.parse_seccomp_filters("src/test_filter.policy").unwrap();
        j.use_seccomp_filter();
        if unsafe { j.fork(None).unwrap() } == 0 {
            exit(0);
        }
    }

    #[test]
    // Test that open FDs get closed and that FDs in the inherit list are left open.
    fn close_fds() {
        unsafe {
            // Using libc to open/close FDs for testing.
            const FILE_PATH: &[u8] = b"/dev/null\0";
            let j = Minijail::new().unwrap();
            let first = libc::open(FILE_PATH.as_ptr() as *const c_char, libc::O_RDONLY);
            assert!(first >= 0);
            let second = libc::open(FILE_PATH.as_ptr() as *const c_char, libc::O_RDONLY);
            assert!(second >= 0);
            let fds: Vec<RawFd> = vec![0, 1, 2, first];
            if j.fork(Some(&fds)).unwrap() == 0 {
                assert!(libc::close(second) < 0); // Should fail as second should be closed already.
                assert_eq!(libc::close(first), 0); // Should succeed as first should be untouched.
                exit(0);
            }
        }
    }

    macro_rules! expect_result {
        ($call:expr, $expected:pat) => {
            let got = $call;
            match got {
                $expected => {}
                _ => {
                    panic!("got {:?} expected {:?}", got, stringify!($expected));
                }
            }
        };
    }

    #[test]
    fn wait_success() {
        let j = Minijail::new().unwrap();
        j.run("/bin/true", &[1, 2], &EMPTY_STRING_SLICE).unwrap();
        expect_result!(j.wait(), Ok(()));
    }

    #[test]
    fn wait_killed() {
        let j = Minijail::new().unwrap();
        j.run(
            SHELL,
            &[1, 2],
            &[SHELL, "-c", "kill -9 $$ &\n/usr/bin/sleep 5"],
        )
        .unwrap();
        expect_result!(j.wait(), Err(Error::Killed(9)));
    }

    #[test]
    fn wait_returncode() {
        let j = Minijail::new().unwrap();
        j.run("/bin/false", &[1, 2], &EMPTY_STRING_SLICE).unwrap();
        expect_result!(j.wait(), Err(Error::ReturnCode(1)));
    }

    #[test]
    fn wait_noaccess() {
        let j = Minijail::new().unwrap();
        j.run("/dev/null", &[1, 2], &EMPTY_STRING_SLICE).unwrap();
        expect_result!(j.wait(), Err(Error::NoAccess));
    }

    #[test]
    fn wait_nocommand() {
        let j = Minijail::new().unwrap();
        j.run("/bin/does not exist", &[1, 2], &EMPTY_STRING_SLICE)
            .unwrap();
        expect_result!(j.wait(), Err(Error::NoCommand));
    }

    #[test]
    fn kill_success() {
        let j = Minijail::new().unwrap();
        j.run(
            Path::new("usr/bin/sleep"),
            &[1, 2],
            &["/usr/bin/sleep", "5"],
        )
        .unwrap();
        const EXPECTED_SIGNAL: u8 = libc::SIGTERM as u8;
        expect_result!(j.kill(), Err(Error::Killed(EXPECTED_SIGNAL)));
    }

    #[test]
    #[ignore] // privileged operation.
    fn chroot() {
        let mut j = Minijail::new().unwrap();
        j.enter_chroot(".").unwrap();
        if unsafe { j.fork(None).unwrap() } == 0 {
            exit(0);
        }
    }

    #[test]
    #[ignore] // privileged operation.
    fn namespace_vfs() {
        let mut j = Minijail::new().unwrap();
        j.namespace_vfs();
        if unsafe { j.fork(None).unwrap() } == 0 {
            exit(0);
        }
    }

    #[test]
    fn run() {
        let j = Minijail::new().unwrap();
        j.run("/bin/true", &[], &EMPTY_STRING_SLICE).unwrap();
    }

    #[test]
    fn run_clone() {
        let j = Minijail::new().unwrap();
        let b = j.try_clone().unwrap();
        // Pass the same FDs to both clones and make sure they don't conflict.
        j.run("/bin/true", &[1, 2], &EMPTY_STRING_SLICE).unwrap();
        b.run("/bin/true", &[1, 2], &EMPTY_STRING_SLICE).unwrap();
    }

    #[test]
    fn run_string_vec() {
        let j = Minijail::new().unwrap();
        let args = vec!["ignored".to_string()];
        j.run(Path::new("/bin/true"), &[], &args).unwrap();
    }
}
