Snap for 5611628 from 9b41e654d3dd9d35d3d353848a7ddf315786b544 to sdk-release
Change-Id: Ia0038ddc1f62fba1ae6dc5834a7fec1c85aa432d
diff --git a/libminijail.c b/libminijail.c
index ee9b9a0..a5e4073 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -163,6 +163,7 @@
int close_open_fds : 1;
int new_session_keyring : 1;
int forward_signals : 1;
+ int setsid : 1;
} flags;
uid_t uid;
gid_t gid;
@@ -237,6 +238,7 @@
j->flags.pid_file = 0;
j->flags.cgroups = 0;
j->flags.forward_signals = 0;
+ j->flags.setsid = 0;
j->remount_mode = 0;
}
@@ -733,6 +735,11 @@
return 0;
}
+int API minijail_create_session(struct minijail *j) {
+ j->flags.setsid = 1;
+ return 0;
+}
+
int API minijail_mount_with_data(struct minijail *j, const char *src,
const char *dest, const char *type,
unsigned long flags, const char *data)
@@ -2930,15 +2937,15 @@
}
/*
- * If any of stdin, stdout, or stderr are TTYs, create a new session.
- * This prevents the jailed process from using the TIOCSTI ioctl
- * to push characters into the parent process terminal's input buffer,
- * therefore escaping the jail.
+ * If any of stdin, stdout, or stderr are TTYs, or setsid flag is
+ * set, create a new session. This prevents the jailed process from
+ * using the TIOCSTI ioctl to push characters into the parent process
+ * terminal's input buffer, therefore escaping the jail.
*
* Since it has just forked, the child will not be a process group
* leader, and this call to setsid() should always succeed.
*/
- if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) ||
+ if (j->flags.setsid || isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) ||
isatty(STDERR_FILENO)) {
if (setsid() < 0) {
pdie("setsid() failed");
diff --git a/libminijail.h b/libminijail.h
index 0853c17..2ea5ad8 100644
--- a/libminijail.h
+++ b/libminijail.h
@@ -160,6 +160,9 @@
*/
int minijail_forward_signals(struct minijail *j);
+/* The jailed child process should call setsid() to create a new session. */
+int minijail_create_session(struct minijail *j);
+
/*
* minijail_enter_chroot: enables chroot() restriction for @j
* @j minijail to apply restriction to
diff --git a/libminijail_unittest.cc b/libminijail_unittest.cc
index 8ba331a..d6896bf 100644
--- a/libminijail_unittest.cc
+++ b/libminijail_unittest.cc
@@ -877,3 +877,47 @@
ASSERT_EQ(-EINVAL, parse_size(&size, "-1G"));
ASSERT_EQ(-EINVAL, parse_size(&size, "; /bin/rm -- "));
}
+
+void TestCreateSession(bool create_session) {
+ int status;
+ int pipe_fds[2];
+ pid_t child_pid;
+ pid_t parent_sid = getsid(0);
+ ssize_t pid_size = sizeof(pid_t);
+
+ ScopedMinijail j(minijail_new());
+ // stdin/stdout/stderr might be attached to TTYs. Close them to avoid creating
+ // a new session because of that.
+ minijail_close_open_fds(j.get());
+
+ if (create_session)
+ minijail_create_session(j.get());
+
+ ASSERT_EQ(pipe(pipe_fds), 0);
+ minijail_preserve_fd(j.get(), pipe_fds[0], pipe_fds[0]);
+
+ child_pid = minijail_fork(j.get());
+ ASSERT_GE(child_pid, 0);
+ if (child_pid == 0) {
+ pid_t sid_in_parent;
+ ASSERT_EQ(read(pipe_fds[0], &sid_in_parent, pid_size), pid_size);
+ if (create_session)
+ ASSERT_NE(sid_in_parent, getsid(0));
+ else
+ ASSERT_EQ(sid_in_parent, getsid(0));
+ exit(0);
+ }
+
+ EXPECT_EQ(write(pipe_fds[1], &parent_sid, pid_size), pid_size);
+ waitpid(child_pid, &status, 0);
+ ASSERT_TRUE(WIFEXITED(status));
+ EXPECT_EQ(WEXITSTATUS(status), 0);
+}
+
+TEST(Test, default_no_new_session) {
+ TestCreateSession(/*create_session=*/false);
+}
+
+TEST(Test, create_new_session) {
+ TestCreateSession(/*create_session=*/true);
+}