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

Side by Side Diff: chrome/browser/zygote_host_linux.cc

Issue 467058: Linux: Adjust /proc/pid/oom_adj to sacrifice plugin and renderer processes to... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years 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
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/zygote_host_linux.h" 5 #include "chrome/browser/zygote_host_linux.h"
6 6
7 #include <sys/socket.h> 7 #include <sys/socket.h>
8 #include <sys/stat.h> 8 #include <sys/stat.h>
9 #include <sys/types.h> 9 #include <sys/types.h>
10 #include <unistd.h> 10 #include <unistd.h>
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 setenv(saved_envvar, value, 1 /* overwrite */); 42 setenv(saved_envvar, value, 1 /* overwrite */);
43 else 43 else
44 unsetenv(saved_envvar); 44 unsetenv(saved_envvar);
45 45
46 free(saved_envvar); 46 free(saved_envvar);
47 } 47 }
48 } 48 }
49 49
50 ZygoteHost::ZygoteHost() 50 ZygoteHost::ZygoteHost()
51 : pid_(-1), 51 : pid_(-1),
52 init_(false) { 52 init_(false),
53 using_suid_sandbox_(false) {
53 } 54 }
54 55
55 ZygoteHost::~ZygoteHost() { 56 ZygoteHost::~ZygoteHost() {
56 if (init_) 57 if (init_)
57 close(control_fd_); 58 close(control_fd_);
58 } 59 }
59 60
60 void ZygoteHost::Init(const std::string& sandbox_cmd) { 61 void ZygoteHost::Init(const std::string& sandbox_cmd) {
61 DCHECK(!init_); 62 DCHECK(!init_);
62 init_ = true; 63 init_ = true;
(...skipping 30 matching lines...) Expand all
93 if (browser_command_line.HasSwitch(switches::kEnableLogging)) { 94 if (browser_command_line.HasSwitch(switches::kEnableLogging)) {
94 // Append with value to support --enable-logging=stderr. 95 // Append with value to support --enable-logging=stderr.
95 cmd_line.AppendSwitchWithValue(switches::kEnableLogging, 96 cmd_line.AppendSwitchWithValue(switches::kEnableLogging,
96 browser_command_line.GetSwitchValueASCII( 97 browser_command_line.GetSwitchValueASCII(
97 switches::kEnableLogging)); 98 switches::kEnableLogging));
98 } 99 }
99 if (browser_command_line.HasSwitch(switches::kEnableSeccompSandbox)) { 100 if (browser_command_line.HasSwitch(switches::kEnableSeccompSandbox)) {
100 cmd_line.AppendSwitch(switches::kEnableSeccompSandbox); 101 cmd_line.AppendSwitch(switches::kEnableSeccompSandbox);
101 } 102 }
102 103
103 const char* sandbox_binary = sandbox_cmd.c_str(); 104 sandbox_binary_ = sandbox_cmd.c_str();
104 struct stat st; 105 struct stat st;
105 106
106 bool using_suid_sandbox = false; 107 if (!sandbox_cmd.empty() && stat(sandbox_binary_.c_str(), &st) == 0) {
107 if (!sandbox_cmd.empty() && stat(sandbox_binary, &st) == 0) { 108 if (access(sandbox_binary_.c_str(), X_OK) == 0 &&
108 if (access(sandbox_binary, X_OK) == 0 &&
109 (st.st_uid == 0) && 109 (st.st_uid == 0) &&
110 (st.st_mode & S_ISUID) && 110 (st.st_mode & S_ISUID) &&
111 (st.st_mode & S_IXOTH)) { 111 (st.st_mode & S_IXOTH)) {
112 using_suid_sandbox = true; 112 using_suid_sandbox_ = true;
113 cmd_line.PrependWrapper(ASCIIToWide(sandbox_binary)); 113 cmd_line.PrependWrapper(ASCIIToWide(sandbox_binary_.c_str()));
114 114
115 SaveSUIDUnsafeEnvironmentVariables(); 115 SaveSUIDUnsafeEnvironmentVariables();
116 } else { 116 } else {
117 LOG(FATAL) << "The SUID sandbox helper binary was found, but is not " 117 LOG(FATAL) << "The SUID sandbox helper binary was found, but is not "
118 "configured correctly. Rather than run without sandboxing " 118 "configured correctly. Rather than run without sandboxing "
119 "I'm aborting now. You need to make sure that " 119 "I'm aborting now. You need to make sure that "
120 << sandbox_binary << " is mode 4755 and owned by root."; 120 << sandbox_binary_ << " is mode 4755 and owned by root.";
121 } 121 }
122 } 122 }
123 123
124 // Start up the sandbox host process and get the file descriptor for the 124 // Start up the sandbox host process and get the file descriptor for the
125 // renderers to talk to it. 125 // renderers to talk to it.
126 const int sfd = Singleton<RenderSandboxHostLinux>()->GetRendererSocket(); 126 const int sfd = Singleton<RenderSandboxHostLinux>()->GetRendererSocket();
127 fds_to_map.push_back(std::make_pair(sfd, 5)); 127 fds_to_map.push_back(std::make_pair(sfd, 5));
128 128
129 int dummy_fd = -1; 129 int dummy_fd = -1;
130 if (using_suid_sandbox) { 130 if (using_suid_sandbox_) {
131 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0); 131 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0);
132 CHECK(dummy_fd >= 0); 132 CHECK(dummy_fd >= 0);
133 fds_to_map.push_back(std::make_pair(dummy_fd, 7)); 133 fds_to_map.push_back(std::make_pair(dummy_fd, 7));
134 } 134 }
135 135
136 base::ProcessHandle process; 136 base::ProcessHandle process;
137 base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process); 137 base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process);
138 CHECK(process != -1) << "Failed to launch zygote process"; 138 CHECK(process != -1) << "Failed to launch zygote process";
139 139
140 if (using_suid_sandbox) { 140 if (using_suid_sandbox_) {
141 // In the SUID sandbox, the real zygote is forked from the sandbox. 141 // In the SUID sandbox, the real zygote is forked from the sandbox.
142 // We need to look for it. 142 // We need to look for it.
143 // But first, wait for the zygote to tell us it's running. 143 // But first, wait for the zygote to tell us it's running.
144 // The sending code is in chrome/browser/zygote_main_linux.cc. 144 // The sending code is in chrome/browser/zygote_main_linux.cc.
145 std::vector<int> fds_vec; 145 std::vector<int> fds_vec;
146 const int kExpectedLength = sizeof(kZygoteMagic); 146 const int kExpectedLength = sizeof(kZygoteMagic);
147 char buf[kExpectedLength]; 147 char buf[kExpectedLength];
148 const ssize_t len = base::RecvMsg(fds[0], buf, sizeof(buf), &fds_vec); 148 const ssize_t len = base::RecvMsg(fds[0], buf, sizeof(buf), &fds_vec);
149 CHECK(len == kExpectedLength) << "Incorrect zygote magic length"; 149 CHECK(len == kExpectedLength) << "Incorrect zygote magic length";
150 CHECK(0 == strcmp(buf, kZygoteMagic)) << "Incorrect zygote magic"; 150 CHECK(0 == strcmp(buf, kZygoteMagic)) << "Incorrect zygote magic";
151 151
152 std::string inode_output; 152 std::string inode_output;
153 ino_t inode = 0; 153 ino_t inode = 0;
154 // Figure out the inode for |dummy_fd|, close |dummy_fd| on our end, 154 // Figure out the inode for |dummy_fd|, close |dummy_fd| on our end,
155 // and find the zygote process holding |dummy_fd|. 155 // and find the zygote process holding |dummy_fd|.
156 if (base::FileDescriptorGetInode(&inode, dummy_fd)) { 156 if (base::FileDescriptorGetInode(&inode, dummy_fd)) {
157 close(dummy_fd); 157 close(dummy_fd);
158 std::vector<std::string> get_inode_cmdline; 158 std::vector<std::string> get_inode_cmdline;
159 get_inode_cmdline.push_back(sandbox_binary); 159 get_inode_cmdline.push_back(sandbox_binary_);
160 get_inode_cmdline.push_back(base::kFindInodeSwitch); 160 get_inode_cmdline.push_back(base::kFindInodeSwitch);
161 get_inode_cmdline.push_back(Int64ToString(inode)); 161 get_inode_cmdline.push_back(Int64ToString(inode));
162 CommandLine get_inode_cmd(get_inode_cmdline); 162 CommandLine get_inode_cmd(get_inode_cmdline);
163 if (base::GetAppOutput(get_inode_cmd, &inode_output)) { 163 if (base::GetAppOutput(get_inode_cmd, &inode_output)) {
164 StringToInt(inode_output, &pid_); 164 StringToInt(inode_output, &pid_);
165 } 165 }
166 } 166 }
167 CHECK(pid_ > 0) << "Did not find zygote process"; 167 CHECK(pid_ > 0) << "Did not find zygote process";
168 168
169 if (process != pid_) { 169 if (process != pid_) {
(...skipping 30 matching lines...) Expand all
200 fds.push_back(i->second); 200 fds.push_back(i->second);
201 } 201 }
202 202
203 if (!base::SendMsg(control_fd_, pickle.data(), pickle.size(), fds)) 203 if (!base::SendMsg(control_fd_, pickle.data(), pickle.size(), fds))
204 return base::kNullProcessHandle; 204 return base::kNullProcessHandle;
205 205
206 pid_t pid; 206 pid_t pid;
207 if (HANDLE_EINTR(read(control_fd_, &pid, sizeof(pid))) != sizeof(pid)) 207 if (HANDLE_EINTR(read(control_fd_, &pid, sizeof(pid))) != sizeof(pid))
208 return base::kNullProcessHandle; 208 return base::kNullProcessHandle;
209 209
210 const int kRendererScore = 5;
211 if (using_suid_sandbox_) {
212 base::ProcessHandle sandbox_helper_process;
213 base::file_handle_mapping_vector dummy_map;
214 std::vector<std::string> adj_oom_score_cmdline;
215
216 adj_oom_score_cmdline.push_back(sandbox_binary_);
217 adj_oom_score_cmdline.push_back(base::kAdjustOOMScoreSwitch);
218 adj_oom_score_cmdline.push_back(Int64ToString(pid));
219 adj_oom_score_cmdline.push_back(IntToString(kRendererScore));
220 CommandLine adj_oom_score_cmd(adj_oom_score_cmdline);
221 if (base::LaunchApp(adj_oom_score_cmdline, dummy_map, false,
222 &sandbox_helper_process)) {
223 ProcessWatcher::EnsureProcessGetsReaped(sandbox_helper_process);
224 }
225 } else {
226 base::AdjustOOMScore(pid, kRendererScore);
227 }
228
210 return pid; 229 return pid;
211 } 230 }
212 231
213 void ZygoteHost::EnsureProcessTerminated(pid_t process) { 232 void ZygoteHost::EnsureProcessTerminated(pid_t process) {
214 DCHECK(init_); 233 DCHECK(init_);
215 Pickle pickle; 234 Pickle pickle;
216 235
217 pickle.WriteInt(kCmdReap); 236 pickle.WriteInt(kCmdReap);
218 pickle.WriteInt(process); 237 pickle.WriteInt(process);
219 238
(...skipping 28 matching lines...) Expand all
248 !read_pickle.ReadBool(&iter, &tmp_child_exited)) { 267 !read_pickle.ReadBool(&iter, &tmp_child_exited)) {
249 LOG(WARNING) << "Error parsing DidProcessCrash response from zygote."; 268 LOG(WARNING) << "Error parsing DidProcessCrash response from zygote.";
250 return false; 269 return false;
251 } 270 }
252 271
253 if (child_exited) 272 if (child_exited)
254 *child_exited = tmp_child_exited; 273 *child_exited = tmp_child_exited;
255 274
256 return did_crash; 275 return did_crash;
257 } 276 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698