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

Side by Side Diff: content/browser/renderer_host/sandbox_ipc_linux.cc

Issue 255693002: Make SandboxIPCProcess a thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Change LOG(ERROR) to VLOG(1). Created 6 years, 7 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/renderer_host/sandbox_ipc_linux.h" 5 #include "content/browser/renderer_host/sandbox_ipc_linux.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <fontconfig/fontconfig.h> 8 #include <fontconfig/fontconfig.h>
9 #include <sys/poll.h> 9 #include <sys/poll.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 // default: 120 // default:
121 // Don't add any languages in that case that we don't recognise the 121 // Don't add any languages in that case that we don't recognise the
122 // constant. 122 // constant.
123 } 123 }
124 } 124 }
125 125
126 } // namespace 126 } // namespace
127 127
128 namespace content { 128 namespace content {
129 129
130 SandboxIPCProcess::SandboxIPCProcess(int lifeline_fd, 130 SandboxIPCHandler::SandboxIPCHandler(int browser_socket,
131 int browser_socket,
132 std::string sandbox_cmd) 131 std::string sandbox_cmd)
133 : lifeline_fd_(lifeline_fd), browser_socket_(browser_socket) { 132 : browser_socket_(browser_socket) {
134 if (!sandbox_cmd.empty()) { 133 if (!sandbox_cmd.empty()) {
135 sandbox_cmd_.push_back(sandbox_cmd); 134 sandbox_cmd_.push_back(sandbox_cmd);
136 sandbox_cmd_.push_back(base::kFindInodeSwitch); 135 sandbox_cmd_.push_back(base::kFindInodeSwitch);
137 } 136 }
138 137
139 // FontConfig doesn't provide a standard property to control subpixel 138 // FontConfig doesn't provide a standard property to control subpixel
140 // positioning, so we pass the current setting through to WebKit. 139 // positioning, so we pass the current setting through to WebKit.
141 WebFontInfo::setSubpixelPositioning( 140 WebFontInfo::setSubpixelPositioning(
142 gfx::GetDefaultWebkitSubpixelPositioning()); 141 gfx::GetDefaultWebkitSubpixelPositioning());
143
144 CommandLine& command_line = *CommandLine::ForCurrentProcess();
145 command_line.AppendSwitchASCII(switches::kProcessType,
146 switches::kSandboxIPCProcess);
147
148 // Update the process title. The argv was already cached by the call to
149 // SetProcessTitleFromCommandLine in content_main_runner.cc, so we can pass
150 // NULL here (we don't have the original argv at this point).
151 SetProcessTitleFromCommandLine(NULL);
152 } 142 }
153 143
154 void SandboxIPCProcess::Run() { 144 void SandboxIPCHandler::Run() {
155 struct pollfd pfds[2]; 145 struct pollfd pfds[1];
156 pfds[0].fd = lifeline_fd_; 146 pfds[0].fd = browser_socket_;
157 pfds[0].events = POLLIN; 147 pfds[0].events = POLLIN;
158 pfds[1].fd = browser_socket_;
159 pfds[1].events = POLLIN;
160 148
161 int failed_polls = 0; 149 int failed_polls = 0;
162 for (;;) { 150 for (;;) {
163 const int r = HANDLE_EINTR(poll(pfds, 2, -1 /* no timeout */)); 151 const int r =
152 HANDLE_EINTR(poll(pfds, arraysize(pfds), -1 /* no timeout */));
164 // '0' is not a possible return value with no timeout. 153 // '0' is not a possible return value with no timeout.
165 DCHECK_NE(0, r); 154 DCHECK_NE(0, r);
166 if (r < 0) { 155 if (r < 0) {
167 PLOG(WARNING) << "poll"; 156 PLOG(WARNING) << "poll";
168 if (failed_polls++ == 3) { 157 if (failed_polls++ == 3) {
169 LOG(FATAL) << "poll(2) failing. RenderSandboxHostLinux aborting."; 158 LOG(FATAL) << "poll(2) failing. SandboxIPCHandler aborting.";
170 return; 159 return;
171 } 160 }
172 continue; 161 continue;
173 } 162 }
174 163
175 failed_polls = 0; 164 failed_polls = 0;
176 165
177 if (pfds[0].revents) { 166 // If poll(2) reports an error condition in the fd,
178 // our parent died so we should too. 167 // we assume the zygote is gone and we return.
179 _exit(0); 168 if (pfds[0].revents & POLLERR) {
jln (very slow on Chromium) 2014/04/30 20:25:44 I think you are guaranteed (POLLHUP | POLLERR) her
169 VLOG(1) << "poll: Error condition in one or more fds.";
170 return;
180 } 171 }
181 172
182 if (pfds[1].revents) { 173 if (pfds[0].revents & POLLIN) {
183 HandleRequestFromRenderer(browser_socket_); 174 HandleRequestFromRenderer(browser_socket_);
184 } 175 }
185 } 176 }
186 } 177 }
187 178
188 void SandboxIPCProcess::HandleRequestFromRenderer(int fd) { 179 void SandboxIPCHandler::HandleRequestFromRenderer(int fd) {
189 std::vector<int> fds; 180 std::vector<int> fds;
190 181
191 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength 182 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength
192 // bytes long (this is the largest message type). 183 // bytes long (this is the largest message type).
193 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC 184 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC
194 // error for a maximum length message. 185 // error for a maximum length message.
195 char buf[FontConfigIPC::kMaxFontFamilyLength + 128]; 186 char buf[FontConfigIPC::kMaxFontFamilyLength + 128];
196 187
197 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds); 188 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds);
198 if (len == -1) { 189 if (len == -1) {
(...skipping 28 matching lines...) Expand all
227 } else if (kind == LinuxSandbox::METHOD_MATCH_WITH_FALLBACK) { 218 } else if (kind == LinuxSandbox::METHOD_MATCH_WITH_FALLBACK) {
228 HandleMatchWithFallback(fd, pickle, iter, fds); 219 HandleMatchWithFallback(fd, pickle, iter, fds);
229 } 220 }
230 221
231 error: 222 error:
232 for (std::vector<int>::const_iterator i = fds.begin(); i != fds.end(); ++i) { 223 for (std::vector<int>::const_iterator i = fds.begin(); i != fds.end(); ++i) {
233 close(*i); 224 close(*i);
234 } 225 }
235 } 226 }
236 227
237 int SandboxIPCProcess::FindOrAddPath(const SkString& path) { 228 int SandboxIPCHandler::FindOrAddPath(const SkString& path) {
238 int count = paths_.count(); 229 int count = paths_.count();
239 for (int i = 0; i < count; ++i) { 230 for (int i = 0; i < count; ++i) {
240 if (path == *paths_[i]) 231 if (path == *paths_[i])
241 return i; 232 return i;
242 } 233 }
243 *paths_.append() = new SkString(path); 234 *paths_.append() = new SkString(path);
244 return count; 235 return count;
245 } 236 }
246 237
247 void SandboxIPCProcess::HandleFontMatchRequest(int fd, 238 void SandboxIPCHandler::HandleFontMatchRequest(int fd,
248 const Pickle& pickle, 239 const Pickle& pickle,
249 PickleIterator iter, 240 PickleIterator iter,
250 std::vector<int>& fds) { 241 std::vector<int>& fds) {
251 uint32_t requested_style; 242 uint32_t requested_style;
252 std::string family; 243 std::string family;
253 if (!pickle.ReadString(&iter, &family) || 244 if (!pickle.ReadString(&iter, &family) ||
254 !pickle.ReadUInt32(&iter, &requested_style)) 245 !pickle.ReadUInt32(&iter, &requested_style))
255 return; 246 return;
256 247
257 SkFontConfigInterface::FontIdentity result_identity; 248 SkFontConfigInterface::FontIdentity result_identity;
(...skipping 18 matching lines...) Expand all
276 result_identity.fID = static_cast<uint32_t>(index); 267 result_identity.fID = static_cast<uint32_t>(index);
277 268
278 reply.WriteBool(true); 269 reply.WriteBool(true);
279 skia::WriteSkString(&reply, result_family); 270 skia::WriteSkString(&reply, result_family);
280 skia::WriteSkFontIdentity(&reply, result_identity); 271 skia::WriteSkFontIdentity(&reply, result_identity);
281 reply.WriteUInt32(result_style); 272 reply.WriteUInt32(result_style);
282 } 273 }
283 SendRendererReply(fds, reply, -1); 274 SendRendererReply(fds, reply, -1);
284 } 275 }
285 276
286 void SandboxIPCProcess::HandleFontOpenRequest(int fd, 277 void SandboxIPCHandler::HandleFontOpenRequest(int fd,
287 const Pickle& pickle, 278 const Pickle& pickle,
288 PickleIterator iter, 279 PickleIterator iter,
289 std::vector<int>& fds) { 280 std::vector<int>& fds) {
290 uint32_t index; 281 uint32_t index;
291 if (!pickle.ReadUInt32(&iter, &index)) 282 if (!pickle.ReadUInt32(&iter, &index))
292 return; 283 return;
293 if (index >= static_cast<uint32_t>(paths_.count())) 284 if (index >= static_cast<uint32_t>(paths_.count()))
294 return; 285 return;
295 const int result_fd = open(paths_[index]->c_str(), O_RDONLY); 286 const int result_fd = open(paths_[index]->c_str(), O_RDONLY);
296 287
297 Pickle reply; 288 Pickle reply;
298 if (result_fd == -1) { 289 if (result_fd == -1) {
299 reply.WriteBool(false); 290 reply.WriteBool(false);
300 } else { 291 } else {
301 reply.WriteBool(true); 292 reply.WriteBool(true);
302 } 293 }
303 294
304 // The receiver will have its own access to the file, so we will close it 295 // The receiver will have its own access to the file, so we will close it
305 // after this send. 296 // after this send.
306 SendRendererReply(fds, reply, result_fd); 297 SendRendererReply(fds, reply, result_fd);
307 298
308 if (result_fd >= 0) { 299 if (result_fd >= 0) {
309 int err = IGNORE_EINTR(close(result_fd)); 300 int err = IGNORE_EINTR(close(result_fd));
310 DCHECK(!err); 301 DCHECK(!err);
311 } 302 }
312 } 303 }
313 304
314 void SandboxIPCProcess::HandleGetFontFamilyForChar(int fd, 305 void SandboxIPCHandler::HandleGetFontFamilyForChar(int fd,
315 const Pickle& pickle, 306 const Pickle& pickle,
316 PickleIterator iter, 307 PickleIterator iter,
317 std::vector<int>& fds) { 308 std::vector<int>& fds) {
318 // The other side of this call is 309 // The other side of this call is
319 // chrome/renderer/renderer_sandbox_support_linux.cc 310 // content/common/child_process_sandbox_support_impl_linux.cc
320 311
321 EnsureWebKitInitialized(); 312 EnsureWebKitInitialized();
322 WebUChar32 c; 313 WebUChar32 c;
323 if (!pickle.ReadInt(&iter, &c)) 314 if (!pickle.ReadInt(&iter, &c))
324 return; 315 return;
325 316
326 std::string preferred_locale; 317 std::string preferred_locale;
327 if (!pickle.ReadString(&iter, &preferred_locale)) 318 if (!pickle.ReadString(&iter, &preferred_locale))
328 return; 319 return;
329 320
330 blink::WebFontFamily family; 321 blink::WebFontFamily family;
331 WebFontInfo::familyForChar(c, preferred_locale.c_str(), &family); 322 WebFontInfo::familyForChar(c, preferred_locale.c_str(), &family);
332 323
333 Pickle reply; 324 Pickle reply;
334 if (family.name.data()) { 325 if (family.name.data()) {
335 reply.WriteString(family.name.data()); 326 reply.WriteString(family.name.data());
336 } else { 327 } else {
337 reply.WriteString(std::string()); 328 reply.WriteString(std::string());
338 } 329 }
339 reply.WriteBool(family.isBold); 330 reply.WriteBool(family.isBold);
340 reply.WriteBool(family.isItalic); 331 reply.WriteBool(family.isItalic);
341 SendRendererReply(fds, reply, -1); 332 SendRendererReply(fds, reply, -1);
342 } 333 }
343 334
344 void SandboxIPCProcess::HandleGetStyleForStrike(int fd, 335 void SandboxIPCHandler::HandleGetStyleForStrike(int fd,
345 const Pickle& pickle, 336 const Pickle& pickle,
346 PickleIterator iter, 337 PickleIterator iter,
347 std::vector<int>& fds) { 338 std::vector<int>& fds) {
348 std::string family; 339 std::string family;
349 int sizeAndStyle; 340 int sizeAndStyle;
350 341
351 if (!pickle.ReadString(&iter, &family) || 342 if (!pickle.ReadString(&iter, &family) ||
352 !pickle.ReadInt(&iter, &sizeAndStyle)) { 343 !pickle.ReadInt(&iter, &sizeAndStyle)) {
353 return; 344 return;
354 } 345 }
355 346
356 EnsureWebKitInitialized(); 347 EnsureWebKitInitialized();
357 blink::WebFontRenderStyle style; 348 blink::WebFontRenderStyle style;
358 WebFontInfo::renderStyleForStrike(family.c_str(), sizeAndStyle, &style); 349 WebFontInfo::renderStyleForStrike(family.c_str(), sizeAndStyle, &style);
359 350
360 Pickle reply; 351 Pickle reply;
361 reply.WriteInt(style.useBitmaps); 352 reply.WriteInt(style.useBitmaps);
362 reply.WriteInt(style.useAutoHint); 353 reply.WriteInt(style.useAutoHint);
363 reply.WriteInt(style.useHinting); 354 reply.WriteInt(style.useHinting);
364 reply.WriteInt(style.hintStyle); 355 reply.WriteInt(style.hintStyle);
365 reply.WriteInt(style.useAntiAlias); 356 reply.WriteInt(style.useAntiAlias);
366 reply.WriteInt(style.useSubpixelRendering); 357 reply.WriteInt(style.useSubpixelRendering);
367 reply.WriteInt(style.useSubpixelPositioning); 358 reply.WriteInt(style.useSubpixelPositioning);
368 359
369 SendRendererReply(fds, reply, -1); 360 SendRendererReply(fds, reply, -1);
370 } 361 }
371 362
372 void SandboxIPCProcess::HandleLocaltime(int fd, 363 void SandboxIPCHandler::HandleLocaltime(int fd,
373 const Pickle& pickle, 364 const Pickle& pickle,
374 PickleIterator iter, 365 PickleIterator iter,
375 std::vector<int>& fds) { 366 std::vector<int>& fds) {
376 // The other side of this call is in zygote_main_linux.cc 367 // The other side of this call is in zygote_main_linux.cc
377 368
378 std::string time_string; 369 std::string time_string;
379 if (!pickle.ReadString(&iter, &time_string) || 370 if (!pickle.ReadString(&iter, &time_string) ||
380 time_string.size() != sizeof(time_t)) { 371 time_string.size() != sizeof(time_t)) {
381 return; 372 return;
382 } 373 }
(...skipping 11 matching lines...) Expand all
394 sizeof(struct tm)); 385 sizeof(struct tm));
395 time_zone_string = expanded_time->tm_zone; 386 time_zone_string = expanded_time->tm_zone;
396 } 387 }
397 388
398 Pickle reply; 389 Pickle reply;
399 reply.WriteString(result_string); 390 reply.WriteString(result_string);
400 reply.WriteString(time_zone_string); 391 reply.WriteString(time_zone_string);
401 SendRendererReply(fds, reply, -1); 392 SendRendererReply(fds, reply, -1);
402 } 393 }
403 394
404 void SandboxIPCProcess::HandleGetChildWithInode(int fd, 395 void SandboxIPCHandler::HandleGetChildWithInode(int fd,
405 const Pickle& pickle, 396 const Pickle& pickle,
406 PickleIterator iter, 397 PickleIterator iter,
407 std::vector<int>& fds) { 398 std::vector<int>& fds) {
408 // The other side of this call is in zygote_main_linux.cc 399 // The other side of this call is in zygote_main_linux.cc
409 if (sandbox_cmd_.empty()) { 400 if (sandbox_cmd_.empty()) {
410 LOG(ERROR) << "Not in the sandbox, this should not be called"; 401 LOG(ERROR) << "Not in the sandbox, this should not be called";
411 return; 402 return;
412 } 403 }
413 404
414 uint64_t inode; 405 uint64_t inode;
(...skipping 13 matching lines...) Expand all
428 // Even though the pid is invalid, we still need to reply to the zygote 419 // Even though the pid is invalid, we still need to reply to the zygote
429 // and not just return here. 420 // and not just return here.
430 LOG(ERROR) << "Could not get pid"; 421 LOG(ERROR) << "Could not get pid";
431 } 422 }
432 423
433 Pickle reply; 424 Pickle reply;
434 reply.WriteInt(pid); 425 reply.WriteInt(pid);
435 SendRendererReply(fds, reply, -1); 426 SendRendererReply(fds, reply, -1);
436 } 427 }
437 428
438 void SandboxIPCProcess::HandleMakeSharedMemorySegment(int fd, 429 void SandboxIPCHandler::HandleMakeSharedMemorySegment(int fd,
439 const Pickle& pickle, 430 const Pickle& pickle,
440 PickleIterator iter, 431 PickleIterator iter,
441 std::vector<int>& fds) { 432 std::vector<int>& fds) {
442 base::SharedMemoryCreateOptions options; 433 base::SharedMemoryCreateOptions options;
443 uint32_t size; 434 uint32_t size;
444 if (!pickle.ReadUInt32(&iter, &size)) 435 if (!pickle.ReadUInt32(&iter, &size))
445 return; 436 return;
446 options.size = size; 437 options.size = size;
447 if (!pickle.ReadBool(&iter, &options.executable)) 438 if (!pickle.ReadBool(&iter, &options.executable))
448 return; 439 return;
449 int shm_fd = -1; 440 int shm_fd = -1;
450 base::SharedMemory shm; 441 base::SharedMemory shm;
451 if (shm.Create(options)) 442 if (shm.Create(options))
452 shm_fd = shm.handle().fd; 443 shm_fd = shm.handle().fd;
453 Pickle reply; 444 Pickle reply;
454 SendRendererReply(fds, reply, shm_fd); 445 SendRendererReply(fds, reply, shm_fd);
455 } 446 }
456 447
457 void SandboxIPCProcess::HandleMatchWithFallback(int fd, 448 void SandboxIPCHandler::HandleMatchWithFallback(int fd,
458 const Pickle& pickle, 449 const Pickle& pickle,
459 PickleIterator iter, 450 PickleIterator iter,
460 std::vector<int>& fds) { 451 std::vector<int>& fds) {
461 // Unlike the other calls, for which we are an indirection in front of 452 // Unlike the other calls, for which we are an indirection in front of
462 // WebKit or Skia, this call is always made via this sandbox helper 453 // WebKit or Skia, this call is always made via this sandbox helper
463 // process. Therefore the fontconfig code goes in here directly. 454 // process. Therefore the fontconfig code goes in here directly.
464 455
465 std::string face; 456 std::string face;
466 bool is_bold, is_italic; 457 bool is_bold, is_italic;
467 uint32 charset, fallback_family; 458 uint32 charset, fallback_family;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 597
607 Pickle reply; 598 Pickle reply;
608 SendRendererReply(fds, reply, font_fd); 599 SendRendererReply(fds, reply, font_fd);
609 600
610 if (font_fd >= 0) { 601 if (font_fd >= 0) {
611 if (IGNORE_EINTR(close(font_fd)) < 0) 602 if (IGNORE_EINTR(close(font_fd)) < 0)
612 PLOG(ERROR) << "close"; 603 PLOG(ERROR) << "close";
613 } 604 }
614 } 605 }
615 606
616 void SandboxIPCProcess::SendRendererReply(const std::vector<int>& fds, 607 void SandboxIPCHandler::SendRendererReply(const std::vector<int>& fds,
617 const Pickle& reply, 608 const Pickle& reply,
618 int reply_fd) { 609 int reply_fd) {
619 struct msghdr msg; 610 struct msghdr msg;
620 memset(&msg, 0, sizeof(msg)); 611 memset(&msg, 0, sizeof(msg));
621 struct iovec iov = {const_cast<void*>(reply.data()), reply.size()}; 612 struct iovec iov = {const_cast<void*>(reply.data()), reply.size()};
622 msg.msg_iov = &iov; 613 msg.msg_iov = &iov;
623 msg.msg_iovlen = 1; 614 msg.msg_iovlen = 1;
624 615
625 char control_buffer[CMSG_SPACE(sizeof(int))]; 616 char control_buffer[CMSG_SPACE(sizeof(int))];
626 617
(...skipping 14 matching lines...) Expand all
641 cmsg->cmsg_type = SCM_RIGHTS; 632 cmsg->cmsg_type = SCM_RIGHTS;
642 cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 633 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
643 memcpy(CMSG_DATA(cmsg), &reply_fd, sizeof(reply_fd)); 634 memcpy(CMSG_DATA(cmsg), &reply_fd, sizeof(reply_fd));
644 msg.msg_controllen = cmsg->cmsg_len; 635 msg.msg_controllen = cmsg->cmsg_len;
645 } 636 }
646 637
647 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0) 638 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0)
648 PLOG(ERROR) << "sendmsg"; 639 PLOG(ERROR) << "sendmsg";
649 } 640 }
650 641
651 SandboxIPCProcess::~SandboxIPCProcess() { 642 SandboxIPCHandler::~SandboxIPCHandler() {
652 paths_.deleteAll(); 643 paths_.deleteAll();
653 if (webkit_platform_support_) 644 if (webkit_platform_support_)
654 blink::shutdownWithoutV8(); 645 blink::shutdownWithoutV8();
655 } 646 }
656 647
657 void SandboxIPCProcess::EnsureWebKitInitialized() { 648 void SandboxIPCHandler::EnsureWebKitInitialized() {
658 if (webkit_platform_support_) 649 if (webkit_platform_support_)
659 return; 650 return;
660 webkit_platform_support_.reset(new BlinkPlatformImpl); 651 webkit_platform_support_.reset(new BlinkPlatformImpl);
661 blink::initializeWithoutV8(webkit_platform_support_.get()); 652 blink::initializeWithoutV8(webkit_platform_support_.get());
662 } 653 }
663 654
664 } // namespace content 655 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/sandbox_ipc_linux.h ('k') | content/browser/zygote_host/zygote_host_impl_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698