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

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: jar feedback 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 PickleReader 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, PickleReader 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, const Pickle& pickle, PickleReader ite r) {
229 base::ProcessHandle child; 229 base::ProcessHandle child;
230 230
231 if (!pickle.ReadInt(&iter, &child)) { 231 if (!pickle.ReadInt(&iter, &child)) {
232 LOG(WARNING) << "Error parsing GetTerminationStatus request " 232 LOG(WARNING) << "Error parsing GetTerminationStatus request "
233 << "from browser"; 233 << "from browser";
234 return; 234 return;
235 } 235 }
236 236
237 base::TerminationStatus status; 237 base::TerminationStatus status;
238 int exit_code; 238 int exit_code;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 340
341 const ssize_t r = UnixDomainSocket::SendRecvMsg( 341 const ssize_t r = UnixDomainSocket::SendRecvMsg(
342 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, 342 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL,
343 request); 343 request);
344 if (r == -1) { 344 if (r == -1) {
345 LOG(ERROR) << "Failed to get child process's real PID"; 345 LOG(ERROR) << "Failed to get child process's real PID";
346 goto error; 346 goto error;
347 } 347 }
348 348
349 Pickle reply(reinterpret_cast<char*>(reply_buf), r); 349 Pickle reply(reinterpret_cast<char*>(reply_buf), r);
350 void* iter = NULL; 350 PickleReader iter(reply);
351 if (!reply.ReadInt(&iter, &real_pid)) 351 if (!reply.ReadInt(&iter, &real_pid))
352 goto error; 352 goto error;
353 if (real_pid <= 0) { 353 if (real_pid <= 0) {
354 // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already? 354 // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already?
355 LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed"; 355 LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed";
356 goto error; 356 goto error;
357 } 357 }
358 real_pids_to_sandbox_pids[real_pid] = pid; 358 real_pids_to_sandbox_pids[real_pid] = pid;
359 } 359 }
360 if (use_helper) { 360 if (use_helper) {
(...skipping 25 matching lines...) Expand all
386 close(pipe_fds[0]); 386 close(pipe_fds[0]);
387 if (pipe_fds[1] >= 0) 387 if (pipe_fds[1] >= 0)
388 close(pipe_fds[1]); 388 close(pipe_fds[1]);
389 return -1; 389 return -1;
390 } 390 }
391 391
392 // Unpacks process type and arguments from |pickle| and forks a new process. 392 // 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 393 // 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(). 394 // process and the child process ID to the parent process, like fork().
395 base::ProcessId ReadArgsAndFork(const Pickle& pickle, 395 base::ProcessId ReadArgsAndFork(const Pickle& pickle,
396 void* iter, 396 PickleReader iter,
397 std::vector<int>& fds, 397 std::vector<int>& fds,
398 std::string* uma_name, 398 std::string* uma_name,
399 int* uma_sample, 399 int* uma_sample,
400 int* uma_boundary_value) { 400 int* uma_boundary_value) {
401 std::vector<std::string> args; 401 std::vector<std::string> args;
402 int argc = 0; 402 int argc = 0;
403 int numfds = 0; 403 int numfds = 0;
404 base::GlobalDescriptors::Mapping mapping; 404 base::GlobalDescriptors::Mapping mapping;
405 std::string process_type; 405 std::string process_type;
406 std::string channel_id; 406 std::string channel_id;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 << " numfds " << numfds << " child_pid " << child_pid; 479 << " numfds " << numfds << " child_pid " << child_pid;
480 } 480 }
481 return child_pid; 481 return child_pid;
482 } 482 }
483 483
484 // Handle a 'fork' request from the browser: this means that the browser 484 // 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, 485 // 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 486 // otherwise writes the child_pid back to the browser via |fd|. Writes a
487 // child_pid of -1 on error. 487 // child_pid of -1 on error.
488 bool HandleForkRequest(int fd, const Pickle& pickle, 488 bool HandleForkRequest(int fd, const Pickle& pickle,
489 void* iter, std::vector<int>& fds) { 489 PickleReader iter, std::vector<int>& fds) {
490 std::string uma_name; 490 std::string uma_name;
491 int uma_sample; 491 int uma_sample;
492 int uma_boundary_value; 492 int uma_boundary_value;
493 base::ProcessId child_pid = ReadArgsAndFork(pickle, iter, fds, 493 base::ProcessId child_pid = ReadArgsAndFork(pickle, iter, fds,
494 &uma_name, &uma_sample, 494 &uma_name, &uma_sample,
495 &uma_boundary_value); 495 &uma_boundary_value);
496 if (child_pid == 0) 496 if (child_pid == 0)
497 return true; 497 return true;
498 for (std::vector<int>::const_iterator 498 for (std::vector<int>::const_iterator
499 i = fds.begin(); i != fds.end(); ++i) 499 i = fds.begin(); i != fds.end(); ++i)
(...skipping 14 matching lines...) Expand all
514 if (!uma_name.empty()) { 514 if (!uma_name.empty()) {
515 reply_pickle.WriteInt(uma_sample); 515 reply_pickle.WriteInt(uma_sample);
516 reply_pickle.WriteInt(uma_boundary_value); 516 reply_pickle.WriteInt(uma_boundary_value);
517 } 517 }
518 if (HANDLE_EINTR(write(fd, reply_pickle.data(), reply_pickle.size())) != 518 if (HANDLE_EINTR(write(fd, reply_pickle.data(), reply_pickle.size())) !=
519 static_cast<ssize_t> (reply_pickle.size())) 519 static_cast<ssize_t> (reply_pickle.size()))
520 PLOG(ERROR) << "write"; 520 PLOG(ERROR) << "write";
521 return false; 521 return false;
522 } 522 }
523 523
524 bool HandleGetSandboxStatus(int fd, const Pickle& pickle, void* iter) { 524 bool HandleGetSandboxStatus(int fd, const Pickle& pickle, PickleReader iter) {
525 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_)) != 525 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_)) !=
526 sizeof(sandbox_flags_))) { 526 sizeof(sandbox_flags_))) {
527 PLOG(ERROR) << "write"; 527 PLOG(ERROR) << "write";
528 } 528 }
529 529
530 return false; 530 return false;
531 } 531 }
532 532
533 // In the SUID sandbox, we try to use a new PID namespace. Thus the PIDs 533 // 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 534 // fork() returns are not the real PIDs, so we need to map the Real PIDS
(...skipping 25 matching lines...) Expand all
560 560
561 uint8_t reply_buf[512]; 561 uint8_t reply_buf[512];
562 const ssize_t r = UnixDomainSocket::SendRecvMsg( 562 const ssize_t r = UnixDomainSocket::SendRecvMsg(
563 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, request); 563 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, request);
564 if (r == -1) { 564 if (r == -1) {
565 memset(output, 0, sizeof(struct tm)); 565 memset(output, 0, sizeof(struct tm));
566 return; 566 return;
567 } 567 }
568 568
569 Pickle reply(reinterpret_cast<char*>(reply_buf), r); 569 Pickle reply(reinterpret_cast<char*>(reply_buf), r);
570 void* iter = NULL; 570 PickleReader iter(reply);
571 std::string result, timezone; 571 std::string result, timezone;
572 if (!reply.ReadString(&iter, &result) || 572 if (!reply.ReadString(&iter, &result) ||
573 !reply.ReadString(&iter, &timezone) || 573 !reply.ReadString(&iter, &timezone) ||
574 result.size() != sizeof(struct tm)) { 574 result.size() != sizeof(struct tm)) {
575 memset(output, 0, sizeof(struct tm)); 575 memset(output, 0, sizeof(struct tm));
576 return; 576 return;
577 } 577 }
578 578
579 memcpy(output, result.data(), sizeof(struct tm)); 579 memcpy(output, result.data(), sizeof(struct tm));
580 if (timezone_out_len) { 580 if (timezone_out_len) {
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 VLOG(1) << "Enabling experimental Seccomp sandbox."; 869 VLOG(1) << "Enabling experimental Seccomp sandbox.";
870 sandbox_flags |= ZygoteHostImpl::kSandboxSeccomp; 870 sandbox_flags |= ZygoteHostImpl::kSandboxSeccomp;
871 } 871 }
872 } 872 }
873 #endif // SECCOMP_SANDBOX 873 #endif // SECCOMP_SANDBOX
874 874
875 Zygote zygote(sandbox_flags, forkdelegate); 875 Zygote zygote(sandbox_flags, forkdelegate);
876 // This function call can return multiple times, once per fork(). 876 // This function call can return multiple times, once per fork().
877 return zygote.ProcessRequests(); 877 return zygote.ProcessRequests();
878 } 878 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698