diff options
author | Dylan Reid <dgreid@chromium.org> | 2017-06-26 18:24:36 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-06-28 00:59:00 -0700 |
commit | fa8c6802b6a392a3dbc6300fabb47eeebf219ed6 (patch) | |
tree | 114002ed8b014339c69c25f72b421e6937835bcc /io_jail/src | |
parent | b4af07af9c54e7b5b2f2e55369b9ac74025a6853 (diff) | |
download | crosvm-fa8c6802b6a392a3dbc6300fabb47eeebf219ed6.tar crosvm-fa8c6802b6a392a3dbc6300fabb47eeebf219ed6.tar.gz crosvm-fa8c6802b6a392a3dbc6300fabb47eeebf219ed6.tar.bz2 crosvm-fa8c6802b6a392a3dbc6300fabb47eeebf219ed6.tar.lz crosvm-fa8c6802b6a392a3dbc6300fabb47eeebf219ed6.tar.xz crosvm-fa8c6802b6a392a3dbc6300fabb47eeebf219ed6.tar.zst crosvm-fa8c6802b6a392a3dbc6300fabb47eeebf219ed6.zip |
io_jail: Overwrite standard I/O FDs
The FDs for stdin, stdout, and stderr shouldn't be left empty. Just closing these FDs causes the next open() call from the jailed process to reuse the 0, 1, or 2 FD. This confuses basic infrastructure like println!. Change-Id: I40ea471b4a011f2be5132e1a0ff50656ae2ec14a Signed-off-by: Dylan Reid <dgreid@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/549659
Diffstat (limited to 'io_jail/src')
-rw-r--r-- | io_jail/src/lib.rs | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/io_jail/src/lib.rs b/io_jail/src/lib.rs index 0c9af8b..04b8070 100644 --- a/io_jail/src/lib.rs +++ b/io_jail/src/lib.rs @@ -12,16 +12,20 @@ mod libminijail; use std::ffi::CString; use std::fs; -use std::os::unix::io::RawFd; +use std::os::unix::io::{AsRawFd, RawFd}; use std::path::Path; use std::str::FromStr; -#[derive(Clone, Copy, Debug)] +#[derive(Debug)] pub enum Error { /// minjail_new failed, this is an allocation failure. CreatingMinijail, /// The path or name string passed in didn't parse to a valid CString. InvalidCString, + /// 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(std::io::Error), /// Setting the specified alt-syscall table failed with errno. Is the table in the kernel? SetAltSyscallTable(i32), /// chroot failed with the provided errno. @@ -207,8 +211,10 @@ impl Minijail { /// Enters the previously configured minijail. /// `enter` is unsafe because it closes all open FD for this process. That - /// could cause a lot of trouble if not handled carefully. - /// This Function aborts on error because a partially entered jail isn't + /// 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. + /// This Function may abort on error because a partially entered jail isn't /// recoverable. pub unsafe fn enter(&self, inheritable_fds: Option<&[RawFd]>) -> Result<()> { if let Some(keep_fds) = inheritable_fds { @@ -241,6 +247,17 @@ impl Minijail { // return an error but won't break anything. libc::close(fd); } + // Set stdin, stdout, and stderr to /dev/null unless they are in the inherit list. + // These will only be closed when this process exits. + let dev_null = fs::File::open("/dev/null").map_err(Error::OpenDevNull)?; + for io_fd in &[libc::STDIN_FILENO, libc::STDOUT_FILENO, libc::STDERR_FILENO] { + if !inheritable_fds.contains(io_fd) { + let ret = libc::dup2(dev_null.as_raw_fd(), *io_fd); + if ret < 0 { + return Err(Error::DupDevNull(*libc::__errno_location())); + } + } + } Ok(()) } } |