// Copyright 2020 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.

//! Encapsulates the logic used to setup sandboxes for TEE applications.

use std::os::unix::io::RawFd;
use std::path::Path;

use libc::pid_t;
use minijail::{self, Minijail};

#[derive(thiserror::Error, Debug)]
pub enum Error {
    #[error("failed to setup jail: {0}")]
    Jail(minijail::Error),
    #[error("failed to fork jail process: {0}")]
    ForkingJail(minijail::Error),
    #[error("failed to bind '{0}' to '{1}': {2}")]
    Bind(String, String, minijail::Error),
    #[error("failed to pivot root: {0}")]
    PivotRoot(minijail::Error),
    #[error("failed to parse seccomp policy: {0}")]
    SeccompPolicy(minijail::Error),
    #[error("failed to set max open files: {0}")]
    SettingMaxOpenFiles(minijail::Error),
    #[error("failed to wait on jailed process to complete: {0}")]
    Wait(minijail::Error),
}

/// The result of an operation in this crate.
pub type Result<T> = std::result::Result<T, Error>;

const NEW_ROOT: &str = "/mnt/empty";

pub trait Sandbox {
    /// Execute `cmd` with the specified arguments `args`. The specified file
    /// descriptors are connected to stdio for the child process.
    fn run(&mut self, cmd: &Path, args: &[&str], keep_fds: &[(RawFd, RawFd)]) -> Result<pid_t>;

    fn run_raw(&mut self, cmd: RawFd, args: &[&str], keep_fds: &[(RawFd, RawFd)]) -> Result<pid_t>;

    /// Wait until the child process completes. Non-zero return codes are
    /// returned as an error.
    fn wait_for_completion(&mut self) -> Result<()>;
}

/// An abstraction for the TEE application sandbox.
pub struct MinijailSandbox(minijail::Minijail);

impl MinijailSandbox {
    /// Setup default sandbox / namespaces
    pub fn new(seccomp_bpf_file: Option<&Path>) -> Result<Self> {
        // All child jails run in a new user namespace without any users mapped,
        // they run as nobody unless otherwise configured.
        let mut j = Minijail::new().map_err(Error::Jail)?;

        j.namespace_pids();

        // TODO() determine why uid sandboxing doesn't work.
        //j.namespace_user();
        //j.namespace_user_disable_setgroups();

        j.change_user("nobody").unwrap();
        j.change_group("nobody").unwrap();

        j.use_caps(0);
        j.namespace_vfs();
        j.namespace_net();
        j.no_new_privs();

        if let Some(path) = seccomp_bpf_file {
            j.parse_seccomp_program(&path)
                .map_err(Error::SeccompPolicy)?;
            j.use_seccomp_filter();
        }

        let new_root = Path::new(NEW_ROOT);
        // The initramfs cannot be unmounted so bind mount /mnt/empty as read only and chroot.
        j.mount_bind(new_root, Path::new("/"), false)
            .map_err(|err| Error::Bind(NEW_ROOT.to_string(), NEW_ROOT.to_string(), err))?;
        j.enter_chroot(new_root).map_err(Error::PivotRoot)?;

        let limit = 1024u64;
        j.set_rlimit(libc::RLIMIT_NOFILE as i32, limit, limit)
            .map_err(Error::SettingMaxOpenFiles)?;

        Ok(MinijailSandbox(j))
    }

    /// A version of the sandbox for use with tests because it doesn't require
    /// elevated privilege. It is also used for developer tools.
    pub fn passthrough() -> Result<Self> {
        let j = Minijail::new().map_err(Error::Jail)?;
        Ok(MinijailSandbox(j))
    }
}

impl Sandbox for MinijailSandbox {
    fn run(&mut self, cmd: &Path, args: &[&str], keep_fds: &[(RawFd, RawFd)]) -> Result<pid_t> {
        let pid = match self
            .0
            .run_remap(cmd, keep_fds, args)
            .map_err(Error::ForkingJail)?
        {
            0 => {
                unsafe { libc::exit(0) };
            }
            p => p,
        };

        Ok(pid)
    }

    fn run_raw(&mut self, cmd: RawFd, args: &[&str], keep_fds: &[(RawFd, RawFd)]) -> Result<pid_t> {
        let pid = match self
            .0
            .run_fd_remap(&cmd, keep_fds, args)
            .map_err(Error::ForkingJail)?
        {
            0 => {
                unsafe { libc::exit(0) };
            }
            p => p,
        };

        Ok(pid)
    }

    fn wait_for_completion(&mut self) -> Result<()> {
        self.0.wait().map_err(Error::Wait)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use std::io::{Read, Write};
    use std::os::unix::io::AsRawFd;

    use sys_util::pipe;

    use crate::transport::{CROS_CONNECTION_ERR_FD, CROS_CONNECTION_R_FD, CROS_CONNECTION_W_FD};

    fn do_test(s: &mut dyn Sandbox) {
        const STDOUT_TEST: &str = "stdout test";
        const STDERR_TEST: &str = "stderr test";

        let (r_stdin, mut w_stdin) = pipe(true).unwrap();
        let (mut r_stdout, w_stdout) = pipe(true).unwrap();
        let (mut r_stderr, w_stderr) = pipe(true).unwrap();

        let keep_fds: [(RawFd, RawFd); 3] = [
            (r_stdin.as_raw_fd(), CROS_CONNECTION_R_FD),
            (w_stdout.as_raw_fd(), CROS_CONNECTION_W_FD),
            (w_stderr.as_raw_fd(), CROS_CONNECTION_ERR_FD),
        ];

        println!("Starting sandboxed process.");
        s.run(Path::new("/bin/sh"), &["/bin/sh"], &keep_fds)
            .unwrap();
        std::mem::drop(r_stdin);
        std::mem::drop(w_stdout);
        std::mem::drop(w_stderr);

        println!("Writing to stdin.");
        // The sleep was added to possibly resolve https://crbug.com/1171078.
        write!(
            &mut w_stdin,
            "echo -n '{}'; sleep 0.05; echo -n '{}' 1>&2; exit;",
            STDOUT_TEST, STDERR_TEST
        )
        .unwrap();
        w_stdin.flush().unwrap();
        std::mem::drop(w_stdin);

        println!("Reading stdout.");
        let mut stdout_result = String::new();
        r_stdout.read_to_string(&mut stdout_result).unwrap();

        println!("Reading stderr.");
        let mut stderr_result = String::new();
        r_stderr.read_to_string(&mut stderr_result).unwrap();

        println!("Waiting for sandboxed process.");
        let result = s.wait_for_completion();

        println!("Validating result.");
        if result.is_err() {
            eprintln!("Got error code: {:?}", result)
        }

        assert_eq!(
            (stdout_result, stderr_result),
            (STDOUT_TEST.to_string(), STDERR_TEST.to_string())
        );

        result.unwrap();
    }

    #[test]
    #[ignore] // privileged operation.
    fn sandbox() {
        let mut s = MinijailSandbox::new(None).unwrap();
        do_test(&mut s);
    }

    #[test]
    fn sandbox_unpriviledged() {
        let mut s = MinijailSandbox::passthrough().unwrap();
        do_test(&mut s);
    }
}
