diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-24 15:19:01 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-24 15:19:01 +0000 |
commit | a8ad46902facb0bbacb80deb5dbae9af15f48f2e (patch) | |
tree | f57122a5aaccd5530a8a97d71787e0ce044b7bfa /sandbox | |
parent | 34fb7a75707023ab174735edb21afd609423efb3 (diff) | |
download | chromium_src-a8ad46902facb0bbacb80deb5dbae9af15f48f2e.zip chromium_src-a8ad46902facb0bbacb80deb5dbae9af15f48f2e.tar.gz chromium_src-a8ad46902facb0bbacb80deb5dbae9af15f48f2e.tar.bz2 |
Add NEWNS and NEWNET to the SUID sandbox.
This patch attempts to fork off the sandboxed process with the
additional NEWNS and NEWNET flags. If these flags aren't supported at
runtime then the code will degrade to the current behaviour.
NEWNS starts children in a new mount namespace so that they cannot
affect the parent's mounts. (This is a little bit useless every little
helps.)
NEWNET starts children in a new network space, initially with no
network devices and this stops sandboxed processes from talking to the
network. Additionally, children exist in their own namespaces for UNIX
domain sockets and the abstract namespace.
http://codereview.chromium.org/2108020/show
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48040 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/linux/suid/sandbox.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/sandbox/linux/suid/sandbox.c b/sandbox/linux/suid/sandbox.c index 7389f03..be6176a 100644 --- a/sandbox/linux/suid/sandbox.c +++ b/sandbox/linux/suid/sandbox.c @@ -33,6 +33,12 @@ #if !defined(CLONE_NEWPID) #define CLONE_NEWPID 0x20000000 #endif +#if !defined(CLONE_NEWNET) +#define CLONE_NEWNET 0x40000000 +#endif +#if !defined(CLONE_NEWNS) +#define CLONE_NEWNS 0x00020000 +#endif #if !defined(BTRFS_SUPER_MAGIC) #define BTRFS_SUPER_MAGIC 0x9123683E @@ -260,23 +266,32 @@ static bool SpawnChrootHelper() { return true; } -static bool MoveToNewPIDNamespace() { - const pid_t pid = syscall( - __NR_clone, CLONE_NEWPID | SIGCHLD, 0, 0, 0); +static bool MoveToNewNamespaces() { + // These are the sets of flags which we'll try, in order. + const int kCloneExtraFlags[] = { + CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWNS, + CLONE_NEWPID | CLONE_NEWNET, + CLONE_NEWPID, + }; - if (pid == -1) { - if (errno == EINVAL) { - // System doesn't support NEWPID. We carry on anyway. - return true; - } + for (size_t i = 0; + i < sizeof(kCloneExtraFlags) / sizeof(kCloneExtraFlags[0]); + i++) { + pid_t pid = syscall(__NR_clone, SIGCHLD | kCloneExtraFlags[i], 0, 0, 0); - perror("Failed to move to new PID namespace"); - return false; - } + if (pid > 0) + _exit(0); - if (pid) - _exit(0); + if (pid == 0) + break; + + if (errno != EINVAL) { + perror("Failed to move to new PID namespace"); + return false; + } + } + // If the system doesn't support NEWPID then we carry on anyway. return true; } @@ -349,7 +364,7 @@ int main(int argc, char **argv) { return 1; } - // In the SUID sandbox, if we succeed in calling MoveToNewPIDNamespace() + // In the SUID sandbox, if we succeed in calling MoveToNewNamespaces() // 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. @@ -389,7 +404,7 @@ int main(int argc, char **argv) { return AdjustOOMScore(pid, score); } - if (!MoveToNewPIDNamespace()) + if (!MoveToNewNamespaces()) return 1; if (!SpawnChrootHelper()) return 1; |