aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Reid <dgreid@google.com>2021-05-13 21:35:58 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-05-13 21:35:58 +0000
commitf58d5792e4f726c41da8bd9a4285b05f2db5f6d1 (patch)
tree832aaffc3276b8ebfc0960c3d4bc4138ad8a6490
parent2b0562127e7287f76d84dcf7a0866951cc4d2ebc (diff)
parentbe7d912d94e0782d296aaf6fdbb314fe97713f5d (diff)
downloadminijail-android12-qpr3-s7-release.tar.gz
Original change: https://android-review.googlesource.com/c/platform/external/minijail/+/1704166 Change-Id: I129fa16327dde76dbfa69da22709432866f1feed
-rw-r--r--libminijail.c20
-rw-r--r--libminijail.h10
-rw-r--r--libminijail_unittest.cc4
-rw-r--r--rust/minijail-sys/libminijail.rs3
-rw-r--r--rust/minijail/src/lib.rs25
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()];