summaryrefslogtreecommitdiffstats
path: root/sandbox/linux/suid/sandbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/linux/suid/sandbox.c')
-rw-r--r--sandbox/linux/suid/sandbox.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/sandbox/linux/suid/sandbox.c b/sandbox/linux/suid/sandbox.c
index c16045a..c061a85 100644
--- a/sandbox/linux/suid/sandbox.c
+++ b/sandbox/linux/suid/sandbox.c
@@ -11,6 +11,8 @@
#include <sched.h>
#include <signal.h>
#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -21,8 +23,8 @@
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
-#include <stdbool.h>
+#include "linux_util.h"
#include "suid_unsafe_environment_variables.h"
#if !defined(CLONE_NEWPID)
@@ -37,7 +39,7 @@ static const char kMsgChrootMe = 'C';
static const char kMsgChrootSuccessful = 'O';
static void FatalError(const char *msg, ...)
- __attribute__((noreturn, format(printf,1,2)));
+ __attribute__((noreturn, format(printf, 1, 2)));
static void FatalError(const char *msg, ...) {
va_list ap;
@@ -109,7 +111,7 @@ static int CloneChrootHelperProcess() {
if (pid == 0) {
// We share our files structure with an untrusted process. As a security in
// depth measure, we make sure that we can't open anything by mistake.
- // TODO: drop CAP_SYS_RESOURCE / use SECURE_NOROOT
+ // TODO(agl): drop CAP_SYS_RESOURCE / use SECURE_NOROOT
const struct rlimit nofile = {0, 0};
if (setrlimit(RLIMIT_NOFILE, &nofile))
@@ -258,7 +260,6 @@ static bool DropRoot() {
}
static bool SetupChildEnvironment() {
-
unsigned i;
// ld.so may have cleared several environment variables because we are SUID.
@@ -291,6 +292,32 @@ int main(int argc, char **argv) {
return 1;
}
+ // In the SUID sandbox, if we succeed in calling MoveToNewPIDNamespace()
+ // below, then the zygote and all the renderers are in an alternate PID
+ // namespace and do not know their real PIDs. As such, they report the wrong
+ // PIDs to the task manager.
+ //
+ // To fix this, when the zygote spawns a new renderer, it gives the renderer
+ // a dummy socket, which has a unique inode number. Then it asks the sandbox
+ // host to find the PID of the process holding that fd by searching /proc.
+ //
+ // Since the zygote and renderers are all spawned by this setuid executable,
+ // their entries in /proc are owned by root and only readable by root. In
+ // order to search /proc for the fd we want, this setuid executable has to
+ // double as a helper and perform the search. The code block below does this
+ // when you call it with --find-inode INODE_NUMBER.
+ if (argc == 3 && (0 == strcmp(argv[1], kFindInodeSwitch))) {
+ pid_t pid;
+ char *endptr;
+ ino_t inode = strtoull(argv[2], &endptr, 10);
+ if (inode == ULLONG_MAX || *endptr)
+ return 1;
+ if (!FindProcessHoldingSocket(&pid, inode))
+ return 1;
+ printf("%d\n", pid);
+ return 0;
+ }
+
if (!MoveToNewPIDNamespace())
return 1;
if (!SpawnChrootHelper())