aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Hsieh <victorhsieh@google.com>2021-04-16 21:29:40 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-04-16 21:29:40 +0000
commit12df15ecef7cc6e0ae5756aa81e1ee6abf0a6a67 (patch)
tree2599f8acad9ba3c1dab43a2352313c1126f714cf
parentda98682f0162939e9d1dad8643f9033b81ea4996 (diff)
parentab5fdce6297f841389f8e80010b1b247bee78b96 (diff)
downloadminijail-12df15ecef7cc6e0ae5756aa81e1ee6abf0a6a67.tar.gz
Add kill function am: ab5fdce629
Original change: https://android-review.googlesource.com/c/platform/external/minijail/+/1675957 Change-Id: Iff0fd076c51f47a8a907e682fca85758a4ba15a2
-rw-r--r--rust/minijail/src/lib.rs67
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();