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

Side by Side Diff: content/browser/zygote_main_linux.cc

Issue 9447084: Refactor Pickle Read methods to use higher performance PickleIterator. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: compile (racing with incoming CLs) Created 8 years, 9 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 "content/browser/zygote_host_impl_linux.h" 5 #include "content/browser/zygote_host_impl_linux.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <pthread.h> 9 #include <pthread.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 _exit(0); 162 _exit(0);
163 return false; 163 return false;
164 } 164 }
165 165
166 if (len == -1) { 166 if (len == -1) {
167 PLOG(ERROR) << "Error reading message from browser"; 167 PLOG(ERROR) << "Error reading message from browser";
168 return false; 168 return false;
169 } 169 }
170 170
171 Pickle pickle(buf, len); 171 Pickle pickle(buf, len);
172 void* iter = NULL; 172 PickleIterator iter(pickle);
173 173
174 int kind; 174 int kind;
175 if (pickle.ReadInt(&iter, &kind)) { 175 if (pickle.ReadInt(&iter, &kind)) {
176 switch (kind) { 176 switch (kind) {
177 case ZygoteHostImpl::kCmdFork: 177 case ZygoteHostImpl::kCmdFork:
178 // This function call can return multiple times, once per fork(). 178 // This function call can return multiple times, once per fork().
179 return HandleForkRequest(fd, pickle, iter, fds); 179 return HandleForkRequest(fd, pickle, iter, fds);
180 180
181 case ZygoteHostImpl::kCmdReap: 181 case ZygoteHostImpl::kCmdReap:
182 if (!fds.empty()) 182 if (!fds.empty())
(...skipping 14 matching lines...) Expand all
197 } 197 }
198 } 198 }
199 199
200 LOG(WARNING) << "Error parsing message from browser"; 200 LOG(WARNING) << "Error parsing message from browser";
201 for (std::vector<int>::const_iterator 201 for (std::vector<int>::const_iterator
202 i = fds.begin(); i != fds.end(); ++i) 202 i = fds.begin(); i != fds.end(); ++i)
203 close(*i); 203 close(*i);
204 return false; 204 return false;
205 } 205 }
206 206
207 void HandleReapRequest(int fd, const Pickle& pickle, void* iter) { 207 void HandleReapRequest(int fd, const Pickle& pickle, PickleIterator iter) {
208 base::ProcessId child; 208 base::ProcessId child;
209 base::ProcessId actual_child; 209 base::ProcessId actual_child;
210 210
211 if (!pickle.ReadInt(&iter, &child)) { 211 if (!pickle.ReadInt(&iter, &child)) {
212 LOG(WARNING) << "Error parsing reap request from browser"; 212 LOG(WARNING) << "Error parsing reap request from browser";
213 return; 213 return;
214 } 214 }
215 215
216 if (g_suid_sandbox_active) { 216 if (g_suid_sandbox_active) {
217 actual_child = real_pids_to_sandbox_pids[child]; 217 actual_child = real_pids_to_sandbox_pids[child];
218 if (!actual_child) 218 if (!actual_child)
219 return; 219 return;
220 real_pids_to_sandbox_pids.erase(child); 220 real_pids_to_sandbox_pids.erase(child);
221 } else { 221 } else {
222 actual_child = child; 222 actual_child = child;
223 } 223 }
224 224
225 base::EnsureProcessTerminated(actual_child); 225 base::EnsureProcessTerminated(actual_child);
226 } 226 }
227 227
228 void HandleGetTerminationStatus(int fd, const Pickle& pickle, void* iter) { 228 void HandleGetTerminationStatus(int fd,
229 const Pickle& pickle,
230 PickleIterator iter) {
229 base::ProcessHandle child; 231 base::ProcessHandle child;
230 232
231 if (!pickle.ReadInt(&iter, &child)) { 233 if (!pickle.ReadInt(&iter, &child)) {
232 LOG(WARNING) << "Error parsing GetTerminationStatus request " 234 LOG(WARNING) << "Error parsing GetTerminationStatus request "
233 << "from browser"; 235 << "from browser";
234 return; 236 return;
235 } 237 }
236 238
237 base::TerminationStatus status; 239 base::TerminationStatus status;
238 int exit_code; 240 int exit_code;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 342
341 const ssize_t r = UnixDomainSocket::SendRecvMsg( 343 const ssize_t r = UnixDomainSocket::SendRecvMsg(
342 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, 344 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL,
343 request); 345 request);
344 if (r == -1) { 346 if (r == -1) {
345 LOG(ERROR) << "Failed to get child process's real PID"; 347 LOG(ERROR) << "Failed to get child process's real PID";
346 goto error; 348 goto error;
347 } 349 }
348 350
349 Pickle reply(reinterpret_cast<char*>(reply_buf), r); 351 Pickle reply(reinterpret_cast<char*>(reply_buf), r);
350 void* iter = NULL; 352 PickleIterator iter(reply);
351 if (!reply.ReadInt(&iter, &real_pid)) 353 if (!reply.ReadInt(&iter, &real_pid))
352 goto error; 354 goto error;
353 if (real_pid <= 0) { 355 if (real_pid <= 0) {
354 // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already? 356 // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already?
355 LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed"; 357 LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed";
356 goto error; 358 goto error;
357 } 359 }
358 real_pids_to_sandbox_pids[real_pid] = pid; 360 real_pids_to_sandbox_pids[real_pid] = pid;
359 } 361 }
360 if (use_helper) { 362 if (use_helper) {
(...skipping 25 matching lines...) Expand all
386 close(pipe_fds[0]); 388 close(pipe_fds[0]);
387 if (pipe_fds[1] >= 0) 389 if (pipe_fds[1] >= 0)
388 close(pipe_fds[1]); 390 close(pipe_fds[1]);
389 return -1; 391 return -1;
390 } 392 }
391 393
392 // Unpacks process type and arguments from |pickle| and forks a new process. 394 // Unpacks process type and arguments from |pickle| and forks a new process.
393 // Returns -1 on error, otherwise returns twice, returning 0 to the child 395 // Returns -1 on error, otherwise returns twice, returning 0 to the child
394 // process and the child process ID to the parent process, like fork(). 396 // process and the child process ID to the parent process, like fork().
395 base::ProcessId ReadArgsAndFork(const Pickle& pickle, 397 base::ProcessId ReadArgsAndFork(const Pickle& pickle,
396 void* iter, 398 PickleIterator iter,
397 std::vector<int>& fds, 399 std::vector<int>& fds,
398 std::string* uma_name, 400 std::string* uma_name,
399 int* uma_sample, 401 int* uma_sample,
400 int* uma_boundary_value) { 402 int* uma_boundary_value) {
401 std::vector<std::string> args; 403 std::vector<std::string> args;
402 int argc = 0; 404 int argc = 0;
403 int numfds = 0; 405 int numfds = 0;
404 base::GlobalDescriptors::Mapping mapping; 406 base::GlobalDescriptors::Mapping mapping;
405 std::string process_type; 407 std::string process_type;
406 std::string channel_id; 408 std::string channel_id;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 << " numfds " << numfds << " child_pid " << child_pid; 481 << " numfds " << numfds << " child_pid " << child_pid;
480 } 482 }
481 return child_pid; 483 return child_pid;
482 } 484 }
483 485
484 // Handle a 'fork' request from the browser: this means that the browser 486 // Handle a 'fork' request from the browser: this means that the browser
485 // wishes to start a new renderer. Returns true if we are in a new process, 487 // wishes to start a new renderer. Returns true if we are in a new process,
486 // otherwise writes the child_pid back to the browser via |fd|. Writes a 488 // otherwise writes the child_pid back to the browser via |fd|. Writes a
487 // child_pid of -1 on error. 489 // child_pid of -1 on error.
488 bool HandleForkRequest(int fd, const Pickle& pickle, 490 bool HandleForkRequest(int fd, const Pickle& pickle,
489 void* iter, std::vector<int>& fds) { 491 PickleIterator iter, std::vector<int>& fds) {
490 std::string uma_name; 492 std::string uma_name;
491 int uma_sample; 493 int uma_sample;
492 int uma_boundary_value; 494 int uma_boundary_value;
493 base::ProcessId child_pid = ReadArgsAndFork(pickle, iter, fds, 495 base::ProcessId child_pid = ReadArgsAndFork(pickle, iter, fds,
494 &uma_name, &uma_sample, 496 &uma_name, &uma_sample,
495 &uma_boundary_value); 497 &uma_boundary_value);
496 if (child_pid == 0) 498 if (child_pid == 0)
497 return true; 499 return true;
498 for (std::vector<int>::const_iterator 500 for (std::vector<int>::const_iterator
499 i = fds.begin(); i != fds.end(); ++i) 501 i = fds.begin(); i != fds.end(); ++i)
(...skipping 14 matching lines...) Expand all
514 if (!uma_name.empty()) { 516 if (!uma_name.empty()) {
515 reply_pickle.WriteInt(uma_sample); 517 reply_pickle.WriteInt(uma_sample);
516 reply_pickle.WriteInt(uma_boundary_value); 518 reply_pickle.WriteInt(uma_boundary_value);
517 } 519 }
518 if (HANDLE_EINTR(write(fd, reply_pickle.data(), reply_pickle.size())) != 520 if (HANDLE_EINTR(write(fd, reply_pickle.data(), reply_pickle.size())) !=
519 static_cast<ssize_t> (reply_pickle.size())) 521 static_cast<ssize_t> (reply_pickle.size()))
520 PLOG(ERROR) << "write"; 522 PLOG(ERROR) << "write";
521 return false; 523 return false;
522 } 524 }
523 525
524 bool HandleGetSandboxStatus(int fd, const Pickle& pickle, void* iter) { 526 bool HandleGetSandboxStatus(int fd,
527 const Pickle& pickle,
528 PickleIterator iter) {
525 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_)) != 529 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_)) !=
526 sizeof(sandbox_flags_))) { 530 sizeof(sandbox_flags_))) {
527 PLOG(ERROR) << "write"; 531 PLOG(ERROR) << "write";
528 } 532 }
529 533
530 return false; 534 return false;
531 } 535 }
532 536
533 // In the SUID sandbox, we try to use a new PID namespace. Thus the PIDs 537 // In the SUID sandbox, we try to use a new PID namespace. Thus the PIDs
534 // fork() returns are not the real PIDs, so we need to map the Real PIDS 538 // fork() returns are not the real PIDs, so we need to map the Real PIDS
(...skipping 25 matching lines...) Expand all
560 564
561 uint8_t reply_buf[512]; 565 uint8_t reply_buf[512];
562 const ssize_t r = UnixDomainSocket::SendRecvMsg( 566 const ssize_t r = UnixDomainSocket::SendRecvMsg(
563 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, request); 567 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, request);
564 if (r == -1) { 568 if (r == -1) {
565 memset(output, 0, sizeof(struct tm)); 569 memset(output, 0, sizeof(struct tm));
566 return; 570 return;
567 } 571 }
568 572
569 Pickle reply(reinterpret_cast<char*>(reply_buf), r); 573 Pickle reply(reinterpret_cast<char*>(reply_buf), r);
570 void* iter = NULL; 574 PickleIterator iter(reply);
571 std::string result, timezone; 575 std::string result, timezone;
572 if (!reply.ReadString(&iter, &result) || 576 if (!reply.ReadString(&iter, &result) ||
573 !reply.ReadString(&iter, &timezone) || 577 !reply.ReadString(&iter, &timezone) ||
574 result.size() != sizeof(struct tm)) { 578 result.size() != sizeof(struct tm)) {
575 memset(output, 0, sizeof(struct tm)); 579 memset(output, 0, sizeof(struct tm));
576 return; 580 return;
577 } 581 }
578 582
579 memcpy(output, result.data(), sizeof(struct tm)); 583 memcpy(output, result.data(), sizeof(struct tm));
580 if (timezone_out_len) { 584 if (timezone_out_len) {
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 VLOG(1) << "Enabling experimental Seccomp sandbox."; 873 VLOG(1) << "Enabling experimental Seccomp sandbox.";
870 sandbox_flags |= ZygoteHostImpl::kSandboxSeccomp; 874 sandbox_flags |= ZygoteHostImpl::kSandboxSeccomp;
871 } 875 }
872 } 876 }
873 #endif // SECCOMP_SANDBOX 877 #endif // SECCOMP_SANDBOX
874 878
875 Zygote zygote(sandbox_flags, forkdelegate); 879 Zygote zygote(sandbox_flags, forkdelegate);
876 // This function call can return multiple times, once per fork(). 880 // This function call can return multiple times, once per fork().
877 return zygote.ProcessRequests(); 881 return zygote.ProcessRequests();
878 } 882 }
OLDNEW
« no previous file with comments | « content/browser/zygote_host_impl_linux.cc ('k') | content/common/child_process_sandbox_support_impl_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698