diff options
Diffstat (limited to 'sandbox/linux/suid/sandbox.c')
-rw-r--r-- | sandbox/linux/suid/sandbox.c | 35 |
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()) |