diff options
author | Dylan Reid <dgreid@google.com> | 2021-05-13 21:35:58 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-05-13 21:35:58 +0000 |
commit | f58d5792e4f726c41da8bd9a4285b05f2db5f6d1 (patch) | |
tree | 832aaffc3276b8ebfc0960c3d4bc4138ad8a6490 | |
parent | 2b0562127e7287f76d84dcf7a0866951cc4d2ebc (diff) | |
parent | be7d912d94e0782d296aaf6fdbb314fe97713f5d (diff) | |
download | minijail-android12-qpr3-s7-release.tar.gz |
Add minijail_copy_jail am: 6dc224fbd5 am: f11bc7ed24 am: be7d912d94android-12.1.0_r9android-12.1.0_r8android-12.1.0_r7android-12.1.0_r22android-12.1.0_r21android-12.1.0_r20android-12.1.0_r19android-12.1.0_r11android-12.1.0_r10android-12.0.0_r32android-12.0.0_r29android-12.0.0_r28android-12.0.0_r27android-12.0.0_r26android-12.0.0_r21android-12.0.0_r20android-12.0.0_r19android-12.0.0_r18android-12.0.0_r16android12L-devandroid12-qpr3-s7-releaseandroid12-qpr3-s6-releaseandroid12-qpr3-s5-releaseandroid12-qpr3-s4-releaseandroid12-qpr3-s3-releaseandroid12-qpr3-s2-releaseandroid12-qpr3-s1-releaseandroid12-qpr3-releaseandroid12-qpr1-releaseandroid12-qpr1-d-s3-releaseandroid12-qpr1-d-s2-releaseandroid12-qpr1-d-s1-releaseandroid12-qpr1-d-releaseandroid12-dev
Original change: https://android-review.googlesource.com/c/platform/external/minijail/+/1704166
Change-Id: I129fa16327dde76dbfa69da22709432866f1feed
-rw-r--r-- | libminijail.c | 20 | ||||
-rw-r--r-- | libminijail.h | 10 | ||||
-rw-r--r-- | libminijail_unittest.cc | 4 | ||||
-rw-r--r-- | rust/minijail-sys/libminijail.rs | 3 | ||||
-rw-r--r-- | rust/minijail/src/lib.rs | 25 |
5 files changed, 62 insertions, 0 deletions
diff --git a/libminijail.c b/libminijail.c index b09a05c..0820dbb 100644 --- a/libminijail.c +++ b/libminijail.c @@ -2518,6 +2518,26 @@ error: return err; } +int API minijail_copy_jail(const struct minijail *from, struct minijail *out) +{ + size_t sz = minijail_size(from); + if (!sz) + return -EINVAL; + + char *buf = malloc(sz); + if (!buf) + return -ENOMEM; + + int err = minijail_marshal(from, buf, sz); + if (err) + goto error; + + err = minijail_unmarshal(out, buf, sz); +error: + free(buf); + return err; +} + static int setup_preload(const struct minijail *j attribute_unused, char ***child_env attribute_unused) { diff --git a/libminijail.h b/libminijail.h index 067fabd..cfd42d2 100644 --- a/libminijail.h +++ b/libminijail.h @@ -484,6 +484,16 @@ int minijail_wait(struct minijail *j); void minijail_destroy(struct minijail *j); /* + * Deep copies the minijail in |from| to |out| providing two identical jails + * that can be used to contain separate children created with minijail_fork(). + * + * Duplicating a jail is invalid after a jail has been passed to + * minijail_fork(). Many minijail_*() calls will yield undefined + * results when called on a jail duplicated post-fork. + */ +int minijail_copy_jail(const struct minijail *from, struct minijail *out); + +/* * minijail_log_to_fd: redirects the module-wide logging to an FD instead of * syslog. * @fd FD to log to. Caller must ensure this is available after diff --git a/libminijail_unittest.cc b/libminijail_unittest.cc index 521982f..78e3cfb 100644 --- a/libminijail_unittest.cc +++ b/libminijail_unittest.cc @@ -221,6 +221,10 @@ TEST_F(MarshalTest, 0xff) { EXPECT_EQ(-EINVAL, minijail_unmarshal(j_, buf_, sizeof(buf_))); } +TEST_F(MarshalTest, copy_empty) { + ASSERT_EQ(0, minijail_copy_jail(m_, j_)); +} + TEST(KillTest, running_process) { const ScopedMinijail j(minijail_new()); char* const argv[] = {"sh", "-c", "sleep 1000", nullptr}; diff --git a/rust/minijail-sys/libminijail.rs b/rust/minijail-sys/libminijail.rs index aa613cb..594a479 100644 --- a/rust/minijail-sys/libminijail.rs +++ b/rust/minijail-sys/libminijail.rs @@ -286,6 +286,9 @@ extern "C" { ) -> ::std::os::raw::c_int; } extern "C" { + pub fn minijail_copy_jail(from: *const minijail, out: *mut minijail) -> ::std::os::raw::c_int; +} +extern "C" { pub fn minijail_add_hook( j: *mut minijail, hook: minijail_hook_t, diff --git a/rust/minijail/src/lib.rs b/rust/minijail/src/lib.rs index ba9c8af..ba59075 100644 --- a/rust/minijail/src/lib.rs +++ b/rust/minijail/src/lib.rs @@ -266,6 +266,22 @@ impl Minijail { 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 @@ -991,6 +1007,15 @@ mod tests { } #[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()]; |