diff options
Diffstat (limited to 'sandbox/linux/suid/client/setuid_sandbox_host.cc')
-rw-r--r-- | sandbox/linux/suid/client/setuid_sandbox_host.cc | 195 |
1 files changed, 0 insertions, 195 deletions
diff --git a/sandbox/linux/suid/client/setuid_sandbox_host.cc b/sandbox/linux/suid/client/setuid_sandbox_host.cc deleted file mode 100644 index 71171ebd4f..0000000000 --- a/sandbox/linux/suid/client/setuid_sandbox_host.cc +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "sandbox/linux/suid/client/setuid_sandbox_host.h" - -#include <fcntl.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <string> -#include <utility> - -#include "base/command_line.h" -#include "base/environment.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/path_service.h" -#include "base/posix/eintr_wrapper.h" -#include "base/process/launch.h" -#include "base/process/process_metrics.h" -#include "base/strings/string_number_conversions.h" -#include "sandbox/linux/suid/common/sandbox.h" -#include "sandbox/linux/suid/common/suid_unsafe_environment_variables.h" - -namespace { - -// Set an environment variable that reflects the API version we expect from the -// setuid sandbox. Old versions of the sandbox will ignore this. -void SetSandboxAPIEnvironmentVariable(base::Environment* env) { - env->SetVar(sandbox::kSandboxEnvironmentApiRequest, - base::IntToString(sandbox::kSUIDSandboxApiNumber)); -} - -// Unset environment variables that are expected to be set by the setuid -// sandbox. This is to allow nesting of one instance of the SUID sandbox -// inside another. -void UnsetExpectedEnvironmentVariables(base::EnvironmentMap* env_map) { - DCHECK(env_map); - const base::NativeEnvironmentString environment_vars[] = { - sandbox::kSandboxDescriptorEnvironmentVarName, - sandbox::kSandboxHelperPidEnvironmentVarName, - sandbox::kSandboxEnvironmentApiProvides, - sandbox::kSandboxPIDNSEnvironmentVarName, - sandbox::kSandboxNETNSEnvironmentVarName, - }; - - for (size_t i = 0; i < arraysize(environment_vars); ++i) { - // Setting values in EnvironmentMap to an empty-string will make - // sure that they get unset from the environment via AlterEnvironment(). - (*env_map)[environment_vars[i]] = base::NativeEnvironmentString(); - } -} - -// Wrapper around a shared C function. -// Returns the "saved" environment variable name corresponding to |envvar| -// in a new string or NULL. -std::string* CreateSavedVariableName(const char* env_var) { - char* const saved_env_var = SandboxSavedEnvironmentVariable(env_var); - if (!saved_env_var) - return NULL; - std::string* saved_env_var_copy = new std::string(saved_env_var); - // SandboxSavedEnvironmentVariable is the C function that we wrap and uses - // malloc() to allocate memory. - free(saved_env_var); - return saved_env_var_copy; -} - -// The ELF loader will clear many environment variables so we save them to -// different names here so that the SUID sandbox can resolve them for the -// renderer. -void SaveSUIDUnsafeEnvironmentVariables(base::Environment* env) { - for (unsigned i = 0; kSUIDUnsafeEnvironmentVariables[i]; ++i) { - const char* env_var = kSUIDUnsafeEnvironmentVariables[i]; - // Get the saved environment variable corresponding to envvar. - scoped_ptr<std::string> saved_env_var(CreateSavedVariableName(env_var)); - if (saved_env_var == NULL) - continue; - - std::string value; - if (env->GetVar(env_var, &value)) - env->SetVar(saved_env_var->c_str(), value); - else - env->UnSetVar(saved_env_var->c_str()); - } -} - -const char* GetDevelSandboxPath() { - return getenv("CHROME_DEVEL_SANDBOX"); -} - -} // namespace - -namespace sandbox { - -SetuidSandboxHost* SetuidSandboxHost::Create() { - base::Environment* environment(base::Environment::Create()); - CHECK(environment); - return new SetuidSandboxHost(environment); -} - -SetuidSandboxHost::SetuidSandboxHost(base::Environment* env) : env_(env) { -} - -SetuidSandboxHost::~SetuidSandboxHost() { -} - -// Check if CHROME_DEVEL_SANDBOX is set but empty. This currently disables -// the setuid sandbox. TODO(jln): fix this (crbug.com/245376). -bool SetuidSandboxHost::IsDisabledViaEnvironment() { - const char* devel_sandbox_path = GetDevelSandboxPath(); - if (devel_sandbox_path && '\0' == *devel_sandbox_path) { - return true; - } - return false; -} - -base::FilePath SetuidSandboxHost::GetSandboxBinaryPath() { - base::FilePath sandbox_binary; - base::FilePath exe_dir; - if (PathService::Get(base::DIR_EXE, &exe_dir)) { - base::FilePath sandbox_candidate = exe_dir.AppendASCII("chrome-sandbox"); - if (base::PathExists(sandbox_candidate)) - sandbox_binary = sandbox_candidate; - } - - // In user-managed builds, including development builds, an environment - // variable is required to enable the sandbox. See - // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment - struct stat st; - if (sandbox_binary.empty() && stat(base::kProcSelfExe, &st) == 0 && - st.st_uid == getuid()) { - const char* devel_sandbox_path = GetDevelSandboxPath(); - if (devel_sandbox_path) { - sandbox_binary = base::FilePath(devel_sandbox_path); - } - } - - return sandbox_binary; -} - -void SetuidSandboxHost::PrependWrapper(base::CommandLine* cmd_line) { - std::string sandbox_binary(GetSandboxBinaryPath().value()); - struct stat st; - if (sandbox_binary.empty() || stat(sandbox_binary.c_str(), &st) != 0) { - LOG(FATAL) << "The SUID sandbox helper binary is missing: " - << sandbox_binary << " Aborting now. See " - "https://code.google.com/p/chromium/wiki/" - "LinuxSUIDSandboxDevelopment."; - } - - if (access(sandbox_binary.c_str(), X_OK) != 0 || (st.st_uid != 0) || - ((st.st_mode & S_ISUID) == 0) || ((st.st_mode & S_IXOTH)) == 0) { - LOG(FATAL) << "The SUID sandbox helper binary was found, but is not " - "configured correctly. Rather than run without sandboxing " - "I'm aborting now. You need to make sure that " - << sandbox_binary << " is owned by root and has mode 4755."; - } - - cmd_line->PrependWrapper(sandbox_binary); -} - -void SetuidSandboxHost::SetupLaunchOptions( - base::LaunchOptions* options, - base::FileHandleMappingVector* fds_to_remap, - base::ScopedFD* dummy_fd) { - DCHECK(options); - DCHECK(fds_to_remap); - - // Launching a setuid binary requires PR_SET_NO_NEW_PRIVS to not be used. - options->allow_new_privs = true; - UnsetExpectedEnvironmentVariables(&options->environ); - - // Set dummy_fd to the reading end of a closed pipe. - int pipe_fds[2]; - PCHECK(0 == pipe(pipe_fds)); - PCHECK(0 == IGNORE_EINTR(close(pipe_fds[1]))); - dummy_fd->reset(pipe_fds[0]); - - // We no longer need a dummy socket for discovering the child's PID, - // but the sandbox is still hard-coded to expect a file descriptor at - // kZygoteIdFd. Fixing this requires a sandbox API change. :( - fds_to_remap->push_back(std::make_pair(dummy_fd->get(), kZygoteIdFd)); -} - -void SetuidSandboxHost::SetupLaunchEnvironment() { - SaveSUIDUnsafeEnvironmentVariables(env_.get()); - SetSandboxAPIEnvironmentVariable(env_.get()); -} - -} // namespace sandbox |