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

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: Really fix compile. 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 = HANDLE_EINTR(poll(pfds, 2, -1 /* no timeout */));
piman 2014/04/29 01:47:02 Actually, we should only poll 1 fd, not 2.
jln (very slow on Chromium) 2014/04/29 19:45:28 s/2/arraysize(pfds)/
Jorge Lucangeli Obes 2014/04/29 20:51:10 Done.
164 // '0' is not a possible return value with no timeout. 152 // '0' is not a possible return value with no timeout.
165 DCHECK_NE(0, r); 153 DCHECK_NE(0, r);
166 if (r < 0) { 154 if (r < 0) {
167 PLOG(WARNING) << "poll"; 155 PLOG(WARNING) << "poll";
168 if (failed_polls++ == 3) { 156 if (failed_polls++ == 3) {
169 LOG(FATAL) << "poll(2) failing. RenderSandboxHostLinux aborting."; 157 LOG(FATAL) << "poll(2) failing. SandboxIPCHandler aborting.";
170 return; 158 return;
piman 2014/04/29 00:25:46 How do we ever exit the thread?
Jorge Lucangeli Obes 2014/04/29 20:51:10 Done.
171 } 159 }
172 continue; 160 continue;
173 } 161 }
174 162
175 failed_polls = 0; 163 failed_polls = 0;
176 164
177 if (pfds[0].revents) { 165 if (pfds[0].revents) {
178 // our parent died so we should too.
179 _exit(0);
180 }
181
182 if (pfds[1].revents) {
183 HandleRequestFromRenderer(browser_socket_); 166 HandleRequestFromRenderer(browser_socket_);
184 } 167 }
185 } 168 }
186 } 169 }
187 170
188 void SandboxIPCProcess::HandleRequestFromRenderer(int fd) { 171 void SandboxIPCHandler::HandleRequestFromRenderer(int fd) {
189 std::vector<int> fds; 172 std::vector<int> fds;
190 173
191 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength 174 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength
192 // bytes long (this is the largest message type). 175 // bytes long (this is the largest message type).
193 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC 176 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC
194 // error for a maximum length message. 177 // error for a maximum length message.
195 char buf[FontConfigIPC::kMaxFontFamilyLength + 128]; 178 char buf[FontConfigIPC::kMaxFontFamilyLength + 128];
196 179
197 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds); 180 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds);
198 if (len == -1) { 181 if (len == -1) {
(...skipping 28 matching lines...) Expand all
227 } else if (kind == LinuxSandbox::METHOD_MATCH_WITH_FALLBACK) { 210 } else if (kind == LinuxSandbox::METHOD_MATCH_WITH_FALLBACK) {
228 HandleMatchWithFallback(fd, pickle, iter, fds); 211 HandleMatchWithFallback(fd, pickle, iter, fds);
229 } 212 }
230 213
231 error: 214 error:
232 for (std::vector<int>::const_iterator i = fds.begin(); i != fds.end(); ++i) { 215 for (std::vector<int>::const_iterator i = fds.begin(); i != fds.end(); ++i) {
233 close(*i); 216 close(*i);
234 } 217 }
235 } 218 }
236 219
237 int SandboxIPCProcess::FindOrAddPath(const SkString& path) { 220 int SandboxIPCHandler::FindOrAddPath(const SkString& path) {
238 int count = paths_.count(); 221 int count = paths_.count();
239 for (int i = 0; i < count; ++i) { 222 for (int i = 0; i < count; ++i) {
240 if (path == *paths_[i]) 223 if (path == *paths_[i])
241 return i; 224 return i;
242 } 225 }
243 *paths_.append() = new SkString(path); 226 *paths_.append() = new SkString(path);
244 return count; 227 return count;
245 } 228 }
246 229
247 void SandboxIPCProcess::HandleFontMatchRequest(int fd, 230 void SandboxIPCHandler::HandleFontMatchRequest(int fd,
248 const Pickle& pickle, 231 const Pickle& pickle,
249 PickleIterator iter, 232 PickleIterator iter,
250 std::vector<int>& fds) { 233 std::vector<int>& fds) {
251 uint32_t requested_style; 234 uint32_t requested_style;
252 std::string family; 235 std::string family;
253 if (!pickle.ReadString(&iter, &family) || 236 if (!pickle.ReadString(&iter, &family) ||
254 !pickle.ReadUInt32(&iter, &requested_style)) 237 !pickle.ReadUInt32(&iter, &requested_style))
255 return; 238 return;
256 239
257 SkFontConfigInterface::FontIdentity result_identity; 240 SkFontConfigInterface::FontIdentity result_identity;
(...skipping 18 matching lines...) Expand all
276 result_identity.fID = static_cast<uint32_t>(index); 259 result_identity.fID = static_cast<uint32_t>(index);
277 260
278 reply.WriteBool(true); 261 reply.WriteBool(true);
279 skia::WriteSkString(&reply, result_family); 262 skia::WriteSkString(&reply, result_family);
280 skia::WriteSkFontIdentity(&reply, result_identity); 263 skia::WriteSkFontIdentity(&reply, result_identity);
281 reply.WriteUInt32(result_style); 264 reply.WriteUInt32(result_style);
282 } 265 }
283 SendRendererReply(fds, reply, -1); 266 SendRendererReply(fds, reply, -1);
284 } 267 }
285 268
286 void SandboxIPCProcess::HandleFontOpenRequest(int fd, 269 void SandboxIPCHandler::HandleFontOpenRequest(int fd,
287 const Pickle& pickle, 270 const Pickle& pickle,
288 PickleIterator iter, 271 PickleIterator iter,
289 std::vector<int>& fds) { 272 std::vector<int>& fds) {
290 uint32_t index; 273 uint32_t index;
291 if (!pickle.ReadUInt32(&iter, &index)) 274 if (!pickle.ReadUInt32(&iter, &index))
292 return; 275 return;
293 if (index >= static_cast<uint32_t>(paths_.count())) 276 if (index >= static_cast<uint32_t>(paths_.count()))
294 return; 277 return;
295 const int result_fd = open(paths_[index]->c_str(), O_RDONLY); 278 const int result_fd = open(paths_[index]->c_str(), O_RDONLY);
296 279
297 Pickle reply; 280 Pickle reply;
298 if (result_fd == -1) { 281 if (result_fd == -1) {
299 reply.WriteBool(false); 282 reply.WriteBool(false);
300 } else { 283 } else {
301 reply.WriteBool(true); 284 reply.WriteBool(true);
302 } 285 }
303 286
304 // The receiver will have its own access to the file, so we will close it 287 // The receiver will have its own access to the file, so we will close it
305 // after this send. 288 // after this send.
306 SendRendererReply(fds, reply, result_fd); 289 SendRendererReply(fds, reply, result_fd);
307 290
308 if (result_fd >= 0) { 291 if (result_fd >= 0) {
309 int err = IGNORE_EINTR(close(result_fd)); 292 int err = IGNORE_EINTR(close(result_fd));
310 DCHECK(!err); 293 DCHECK(!err);
311 } 294 }
312 } 295 }
313 296
314 void SandboxIPCProcess::HandleGetFontFamilyForChar(int fd, 297 void SandboxIPCHandler::HandleGetFontFamilyForChar(int fd,
315 const Pickle& pickle, 298 const Pickle& pickle,
316 PickleIterator iter, 299 PickleIterator iter,
317 std::vector<int>& fds) { 300 std::vector<int>& fds) {
318 // The other side of this call is 301 // The other side of this call is
319 // chrome/renderer/renderer_sandbox_support_linux.cc 302 // content/common/child_process_sandbox_support_impl_linux.cc
320 303
321 EnsureWebKitInitialized(); 304 EnsureWebKitInitialized();
322 WebUChar32 c; 305 WebUChar32 c;
323 if (!pickle.ReadInt(&iter, &c)) 306 if (!pickle.ReadInt(&iter, &c))
324 return; 307 return;
325 308
326 std::string preferred_locale; 309 std::string preferred_locale;
327 if (!pickle.ReadString(&iter, &preferred_locale)) 310 if (!pickle.ReadString(&iter, &preferred_locale))
328 return; 311 return;
329 312
330 blink::WebFontFamily family; 313 blink::WebFontFamily family;
331 WebFontInfo::familyForChar(c, preferred_locale.c_str(), &family); 314 WebFontInfo::familyForChar(c, preferred_locale.c_str(), &family);
332 315
333 Pickle reply; 316 Pickle reply;
334 if (family.name.data()) { 317 if (family.name.data()) {
335 reply.WriteString(family.name.data()); 318 reply.WriteString(family.name.data());
336 } else { 319 } else {
337 reply.WriteString(std::string()); 320 reply.WriteString(std::string());
338 } 321 }
339 reply.WriteBool(family.isBold); 322 reply.WriteBool(family.isBold);
340 reply.WriteBool(family.isItalic); 323 reply.WriteBool(family.isItalic);
341 SendRendererReply(fds, reply, -1); 324 SendRendererReply(fds, reply, -1);
342 } 325 }
343 326
344 void SandboxIPCProcess::HandleGetStyleForStrike(int fd, 327 void SandboxIPCHandler::HandleGetStyleForStrike(int fd,
345 const Pickle& pickle, 328 const Pickle& pickle,
346 PickleIterator iter, 329 PickleIterator iter,
347 std::vector<int>& fds) { 330 std::vector<int>& fds) {
348 std::string family; 331 std::string family;
349 int sizeAndStyle; 332 int sizeAndStyle;
350 333
351 if (!pickle.ReadString(&iter, &family) || 334 if (!pickle.ReadString(&iter, &family) ||
352 !pickle.ReadInt(&iter, &sizeAndStyle)) { 335 !pickle.ReadInt(&iter, &sizeAndStyle)) {
353 return; 336 return;
354 } 337 }
355 338
356 EnsureWebKitInitialized(); 339 EnsureWebKitInitialized();
357 blink::WebFontRenderStyle style; 340 blink::WebFontRenderStyle style;
358 WebFontInfo::renderStyleForStrike(family.c_str(), sizeAndStyle, &style); 341 WebFontInfo::renderStyleForStrike(family.c_str(), sizeAndStyle, &style);
359 342
360 Pickle reply; 343 Pickle reply;
361 reply.WriteInt(style.useBitmaps); 344 reply.WriteInt(style.useBitmaps);
362 reply.WriteInt(style.useAutoHint); 345 reply.WriteInt(style.useAutoHint);
363 reply.WriteInt(style.useHinting); 346 reply.WriteInt(style.useHinting);
364 reply.WriteInt(style.hintStyle); 347 reply.WriteInt(style.hintStyle);
365 reply.WriteInt(style.useAntiAlias); 348 reply.WriteInt(style.useAntiAlias);
366 reply.WriteInt(style.useSubpixelRendering); 349 reply.WriteInt(style.useSubpixelRendering);
367 reply.WriteInt(style.useSubpixelPositioning); 350 reply.WriteInt(style.useSubpixelPositioning);
368 351
369 SendRendererReply(fds, reply, -1); 352 SendRendererReply(fds, reply, -1);
370 } 353 }
371 354
372 void SandboxIPCProcess::HandleLocaltime(int fd, 355 void SandboxIPCHandler::HandleLocaltime(int fd,
373 const Pickle& pickle, 356 const Pickle& pickle,
374 PickleIterator iter, 357 PickleIterator iter,
375 std::vector<int>& fds) { 358 std::vector<int>& fds) {
376 // The other side of this call is in zygote_main_linux.cc 359 // The other side of this call is in zygote_main_linux.cc
377 360
378 std::string time_string; 361 std::string time_string;
379 if (!pickle.ReadString(&iter, &time_string) || 362 if (!pickle.ReadString(&iter, &time_string) ||
380 time_string.size() != sizeof(time_t)) { 363 time_string.size() != sizeof(time_t)) {
381 return; 364 return;
382 } 365 }
(...skipping 11 matching lines...) Expand all
394 sizeof(struct tm)); 377 sizeof(struct tm));
395 time_zone_string = expanded_time->tm_zone; 378 time_zone_string = expanded_time->tm_zone;
396 } 379 }
397 380
398 Pickle reply; 381 Pickle reply;
399 reply.WriteString(result_string); 382 reply.WriteString(result_string);
400 reply.WriteString(time_zone_string); 383 reply.WriteString(time_zone_string);
401 SendRendererReply(fds, reply, -1); 384 SendRendererReply(fds, reply, -1);
402 } 385 }
403 386
404 void SandboxIPCProcess::HandleGetChildWithInode(int fd, 387 void SandboxIPCHandler::HandleGetChildWithInode(int fd,
405 const Pickle& pickle, 388 const Pickle& pickle,
406 PickleIterator iter, 389 PickleIterator iter,
407 std::vector<int>& fds) { 390 std::vector<int>& fds) {
408 // The other side of this call is in zygote_main_linux.cc 391 // The other side of this call is in zygote_main_linux.cc
409 if (sandbox_cmd_.empty()) { 392 if (sandbox_cmd_.empty()) {
410 LOG(ERROR) << "Not in the sandbox, this should not be called"; 393 LOG(ERROR) << "Not in the sandbox, this should not be called";
411 return; 394 return;
412 } 395 }
413 396
414 uint64_t inode; 397 uint64_t inode;
(...skipping 13 matching lines...) Expand all
428 // Even though the pid is invalid, we still need to reply to the zygote 411 // Even though the pid is invalid, we still need to reply to the zygote
429 // and not just return here. 412 // and not just return here.
430 LOG(ERROR) << "Could not get pid"; 413 LOG(ERROR) << "Could not get pid";
431 } 414 }
432 415
433 Pickle reply; 416 Pickle reply;
434 reply.WriteInt(pid); 417 reply.WriteInt(pid);
435 SendRendererReply(fds, reply, -1); 418 SendRendererReply(fds, reply, -1);
436 } 419 }
437 420
438 void SandboxIPCProcess::HandleMakeSharedMemorySegment(int fd, 421 void SandboxIPCHandler::HandleMakeSharedMemorySegment(int fd,
439 const Pickle& pickle, 422 const Pickle& pickle,
440 PickleIterator iter, 423 PickleIterator iter,
441 std::vector<int>& fds) { 424 std::vector<int>& fds) {
442 base::SharedMemoryCreateOptions options; 425 base::SharedMemoryCreateOptions options;
443 uint32_t size; 426 uint32_t size;
444 if (!pickle.ReadUInt32(&iter, &size)) 427 if (!pickle.ReadUInt32(&iter, &size))
445 return; 428 return;
446 options.size = size; 429 options.size = size;
447 if (!pickle.ReadBool(&iter, &options.executable)) 430 if (!pickle.ReadBool(&iter, &options.executable))
448 return; 431 return;
449 int shm_fd = -1; 432 int shm_fd = -1;
450 base::SharedMemory shm; 433 base::SharedMemory shm;
451 if (shm.Create(options)) 434 if (shm.Create(options))
452 shm_fd = shm.handle().fd; 435 shm_fd = shm.handle().fd;
453 Pickle reply; 436 Pickle reply;
454 SendRendererReply(fds, reply, shm_fd); 437 SendRendererReply(fds, reply, shm_fd);
455 } 438 }
456 439
457 void SandboxIPCProcess::HandleMatchWithFallback(int fd, 440 void SandboxIPCHandler::HandleMatchWithFallback(int fd,
458 const Pickle& pickle, 441 const Pickle& pickle,
459 PickleIterator iter, 442 PickleIterator iter,
460 std::vector<int>& fds) { 443 std::vector<int>& fds) {
461 // Unlike the other calls, for which we are an indirection in front of 444 // 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 445 // WebKit or Skia, this call is always made via this sandbox helper
463 // process. Therefore the fontconfig code goes in here directly. 446 // process. Therefore the fontconfig code goes in here directly.
464 447
465 std::string face; 448 std::string face;
466 bool is_bold, is_italic; 449 bool is_bold, is_italic;
467 uint32 charset, fallback_family; 450 uint32 charset, fallback_family;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 589
607 Pickle reply; 590 Pickle reply;
608 SendRendererReply(fds, reply, font_fd); 591 SendRendererReply(fds, reply, font_fd);
609 592
610 if (font_fd >= 0) { 593 if (font_fd >= 0) {
611 if (IGNORE_EINTR(close(font_fd)) < 0) 594 if (IGNORE_EINTR(close(font_fd)) < 0)
612 PLOG(ERROR) << "close"; 595 PLOG(ERROR) << "close";
613 } 596 }
614 } 597 }
615 598
616 void SandboxIPCProcess::SendRendererReply(const std::vector<int>& fds, 599 void SandboxIPCHandler::SendRendererReply(const std::vector<int>& fds,
617 const Pickle& reply, 600 const Pickle& reply,
618 int reply_fd) { 601 int reply_fd) {
619 struct msghdr msg; 602 struct msghdr msg;
620 memset(&msg, 0, sizeof(msg)); 603 memset(&msg, 0, sizeof(msg));
621 struct iovec iov = {const_cast<void*>(reply.data()), reply.size()}; 604 struct iovec iov = {const_cast<void*>(reply.data()), reply.size()};
622 msg.msg_iov = &iov; 605 msg.msg_iov = &iov;
623 msg.msg_iovlen = 1; 606 msg.msg_iovlen = 1;
624 607
625 char control_buffer[CMSG_SPACE(sizeof(int))]; 608 char control_buffer[CMSG_SPACE(sizeof(int))];
626 609
(...skipping 14 matching lines...) Expand all
641 cmsg->cmsg_type = SCM_RIGHTS; 624 cmsg->cmsg_type = SCM_RIGHTS;
642 cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 625 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
643 memcpy(CMSG_DATA(cmsg), &reply_fd, sizeof(reply_fd)); 626 memcpy(CMSG_DATA(cmsg), &reply_fd, sizeof(reply_fd));
644 msg.msg_controllen = cmsg->cmsg_len; 627 msg.msg_controllen = cmsg->cmsg_len;
645 } 628 }
646 629
647 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0) 630 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0)
648 PLOG(ERROR) << "sendmsg"; 631 PLOG(ERROR) << "sendmsg";
649 } 632 }
650 633
651 SandboxIPCProcess::~SandboxIPCProcess() { 634 SandboxIPCHandler::~SandboxIPCHandler() {
652 paths_.deleteAll(); 635 paths_.deleteAll();
653 if (webkit_platform_support_) 636 if (webkit_platform_support_)
654 blink::shutdownWithoutV8(); 637 blink::shutdownWithoutV8();
655 } 638 }
656 639
657 void SandboxIPCProcess::EnsureWebKitInitialized() { 640 void SandboxIPCHandler::EnsureWebKitInitialized() {
658 if (webkit_platform_support_) 641 if (webkit_platform_support_)
659 return; 642 return;
660 webkit_platform_support_.reset(new BlinkPlatformImpl); 643 webkit_platform_support_.reset(new BlinkPlatformImpl);
661 blink::initializeWithoutV8(webkit_platform_support_.get()); 644 blink::initializeWithoutV8(webkit_platform_support_.get());
662 } 645 }
663 646
664 } // namespace content 647 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698