diff options
author | Victor Hsieh <victorhsieh@google.com> | 2021-04-16 22:44:12 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-04-16 22:44:12 +0000 |
commit | 91879f033c28d9780eae3831968368c147cbf1a0 (patch) | |
tree | 2599f8acad9ba3c1dab43a2352313c1126f714cf | |
parent | dcb0854a69f48d6e5e71ecd7571845aa8c78face (diff) | |
parent | 43046804aad712ad752641ec4c756f9c418e1fad (diff) | |
download | minijail-91879f033c28d9780eae3831968368c147cbf1a0.tar.gz |
Add kill function am: ab5fdce629 am: 12df15ecef am: a68a03fd31 am: 43046804aa
Original change: https://android-review.googlesource.com/c/platform/external/minijail/+/1675957
Change-Id: I1862f8fcde6774feba7d4cf6c32bf8b095d7454f
-rw-r--r-- | rust/minijail/src/lib.rs | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/rust/minijail/src/lib.rs b/rust/minijail/src/lib.rs index 7805721..b052dc6 100644 --- a/rust/minijail/src/lib.rs +++ b/rust/minijail/src/lib.rs @@ -230,6 +230,29 @@ 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> { @@ -745,26 +768,17 @@ impl Minijail { unsafe { ret = minijail_wait(self.jail); } - 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!(); + 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) } } @@ -901,6 +915,19 @@ mod tests { } #[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(); |