Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: sandbox/linux/suid/client/setuid_sandbox_client.cc

Issue 10807059: Refactor the setuid sandbox client code to its own class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <sys/types.h>
6 #include <sys/wait.h>
7
8 #include "base/eintr_wrapper.h"
9 #include "base/environment.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/string_number_conversions.h"
13
14 #include "sandbox/linux/suid/common/sandbox.h"
15 #include "sandbox/linux/suid/common/suid_unsafe_environment_variables.h"
16 #include "setuid_sandbox_client.h"
17
18 namespace {
19
20 // Set an environment variable that reflects the API version we expect from the
21 // setuid sandbox. Old versions of the sandbox will ignore this.
22 void SetSandboxAPIEnvironmentVariable(base::Environment* env) {
23 env->SetVar(sandbox::kSandboxEnvironmentApiRequest,
24 base::IntToString(sandbox::kSUIDSandboxApiNumber));
25 }
26
27 // Wrapper around a shared C function.
28 // Returns the "saved" environment variable name corresponding to |envvar|
29 // in a new string or NULL.
30 std::string* CreateSavedVariableName(const char* envvar) {
31 char* const saved_env_var = SandboxSavedEnvironmentVariable(envvar);
32 if (!saved_env_var)
33 return NULL;
34 std::string* saved_env_var_copy = new std::string(saved_env_var);
35 // SandboxSavedEnvironmentVariable is the C function that we wrap and uses
36 // malloc() to allocate memory.
37 free(saved_env_var);
38 return saved_env_var_copy;
39 }
40
41 // The ELF loader will clear many environment variables so we save them to
42 // different names here so that the SUID sandbox can resolve them for the
43 // renderer.
44 void SaveSUIDUnsafeEnvironmentVariables(base::Environment* env) {
45 for (unsigned i = 0; kSUIDUnsafeEnvironmentVariables[i]; ++i) {
46 const char* const env_var = kSUIDUnsafeEnvironmentVariables[i];
47 // Get the saved environment variable corresponding to envvar.
48 scoped_ptr<std::string> saved_env_var(CreateSavedVariableName(env_var));
49 if (saved_env_var == NULL)
50 continue;
51
52 std::string value;
53 if (env->GetVar(env_var, &value))
54 env->SetVar(saved_env_var->c_str(), value);
55 else
56 env->UnSetVar(saved_env_var->c_str());
57 }
58 }
59
60 int GetHelperApi(base::Environment* env) {
61 std::string api_string;
62 int api_number = 0; // Assume API version 0 if no environment was found.
63 if (env->GetVar(sandbox::kSandboxEnvironmentApiProvides, &api_string) &&
64 !base::StringToInt(api_string, &api_number)) {
65 // It's an error if we could not convert the API number.
66 api_number = -1;
67 }
68 return api_number;
69 }
70
71 // Convert |var_name| from the environment |env| to an int.
72 // Return -1 if the variable does not exist or the value cannot be converted.
73 int EnvToInt(base::Environment* env, const char* var_name) {
74 std::string var_string;
75 int var_value = -1;
76 if (env->GetVar(var_name, &var_string) &&
77 !base::StringToInt(var_string, &var_value)) {
78 var_value = -1;
79 }
80 return var_value;
81 }
82
83 pid_t GetHelperPID(base::Environment* env) {
84 return EnvToInt(env, sandbox::kSandboxHelperPidEnvironmentVarName);
85 }
86
87 // Get the IPC file descriptor used to communicate with the setuid helper.
88 int GetIPCDescriptor(base::Environment* env) {
89 return EnvToInt(env, sandbox::kSandboxDescriptorEnvironmentVarName);
90 }
91
92 } // namespace
93
94 namespace sandbox {
95
96 SetuidSandboxClient* SetuidSandboxClient::Create() {
97 base::Environment* environment(base::Environment::Create());
98 SetuidSandboxClient* sandbox_client(new(SetuidSandboxClient));
99
100 CHECK(environment);
101 sandbox_client->env_ = environment;
102 return sandbox_client;
103 }
104
105 SetuidSandboxClient::SetuidSandboxClient() {
106 env_ = NULL;
107 }
108
109 SetuidSandboxClient::~SetuidSandboxClient() {
110 delete env_;
111 }
112
113 bool SetuidSandboxClient::IsSuidSandboxChild() const {
114 return GetIPCDescriptor(env_) >= 0;
115 }
116
117 bool SetuidSandboxClient::IsSuidSandboxUpToDate() const {
118 return GetHelperApi(env_) == kSUIDSandboxApiNumber;
119 }
120
121 bool SetuidSandboxClient::IsInNewPIDNamespace() const {
122 return env_->HasVar(kSandboxPIDNSEnvironmentVarName);
123 }
124
125 bool SetuidSandboxClient::IsInNewNETNamespace() const {
126 return env_->HasVar(kSandboxNETNSEnvironmentVarName);
127 }
128
129 bool SetuidSandboxClient::ChrootMe() {
130 int fd = GetIPCDescriptor(env_);
131
132 if (fd < 0) {
133 LOG(ERROR) << "Failed to obtain the sandbox IPC descriptor";
134 return false;
135 }
136
137 if (HANDLE_EINTR(write(fd, &kMsgChrootMe, 1)) != 1) {
138 LOG(ERROR) << "Failed to write to chroot pipe: " << errno;
Jorge Lucangeli Obes 2012/07/23 20:23:50 PLOG(ERROR)?
jln (very slow on Chromium) 2012/07/23 21:32:15 Done.
139 return false;
140 }
141
142 // We need to reap the chroot helper process in any event.
143 pid_t helper_pid = GetHelperPID(env_);
144 // If helper_pid is -1 we wait for any child.
145 if (waitpid(helper_pid, NULL, 0) < 0) {
146 LOG(ERROR) << "Failed to wait for setuid helper to die " << errno;
Jorge Lucangeli Obes 2012/07/23 20:23:50 PLOG
jln (very slow on Chromium) 2012/07/23 21:32:15 Done.
147 return false;
148 }
149
150 char reply;
151 if (HANDLE_EINTR(read(fd, &reply, 1)) != 1) {
152 LOG(ERROR) << "Failed to read from chroot pipe: " << errno;
Jorge Lucangeli Obes 2012/07/23 20:23:50 PLOG
jln (very slow on Chromium) 2012/07/23 21:32:15 Done.
153 return false;
154 }
155
156 if (reply != kMsgChrootSuccessful) {
157 LOG(ERROR) << "Error code reply from chroot helper";
158 return false;
159 }
160 return true;
161 }
162
163 void SetuidSandboxClient::SetupLaunchEnvironment() {
164 SaveSUIDUnsafeEnvironmentVariables(env_);
165 SetSandboxAPIEnvironmentVariable(env_);
166 }
167
168 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698