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

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

Issue 286903021: Make SandboxIPCProcess a thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Close FDs in ::~SandboxIPCHandler(). 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // default: 122 // default:
123 // Don't add any languages in that case that we don't recognise the 123 // Don't add any languages in that case that we don't recognise the
124 // constant. 124 // constant.
125 } 125 }
126 } 126 }
127 127
128 } // namespace 128 } // namespace
129 129
130 namespace content { 130 namespace content {
131 131
132 SandboxIPCProcess::SandboxIPCProcess(int lifeline_fd, int browser_socket) 132 SandboxIPCHandler::SandboxIPCHandler(int lifeline_fd, int browser_socket)
133 : lifeline_fd_(lifeline_fd), browser_socket_(browser_socket) { 133 : lifeline_fd_(lifeline_fd), browser_socket_(browser_socket) {
134 // FontConfig doesn't provide a standard property to control subpixel 134 // FontConfig doesn't provide a standard property to control subpixel
135 // positioning, so we pass the current setting through to WebKit. 135 // positioning, so we pass the current setting through to WebKit.
136 WebFontInfo::setSubpixelPositioning( 136 WebFontInfo::setSubpixelPositioning(
137 gfx::GetDefaultWebkitSubpixelPositioning()); 137 gfx::GetDefaultWebkitSubpixelPositioning());
138
139 CommandLine& command_line = *CommandLine::ForCurrentProcess();
140 command_line.AppendSwitchASCII(switches::kProcessType,
141 switches::kSandboxIPCProcess);
142
143 // Update the process title. The argv was already cached by the call to
144 // SetProcessTitleFromCommandLine in content_main_runner.cc, so we can pass
145 // NULL here (we don't have the original argv at this point).
146 SetProcessTitleFromCommandLine(NULL);
147 } 138 }
148 139
149 void SandboxIPCProcess::Run() { 140 void SandboxIPCHandler::Run() {
150 struct pollfd pfds[2]; 141 struct pollfd pfds[2];
151 pfds[0].fd = lifeline_fd_; 142 pfds[0].fd = lifeline_fd_;
152 pfds[0].events = POLLIN; 143 pfds[0].events = POLLIN;
153 pfds[1].fd = browser_socket_; 144 pfds[1].fd = browser_socket_;
154 pfds[1].events = POLLIN; 145 pfds[1].events = POLLIN;
155 146
156 int failed_polls = 0; 147 int failed_polls = 0;
157 for (;;) { 148 for (;;) {
158 const int r = HANDLE_EINTR(poll(pfds, 2, -1 /* no timeout */)); 149 const int r =
150 HANDLE_EINTR(poll(pfds, arraysize(pfds), -1 /* no timeout */));
159 // '0' is not a possible return value with no timeout. 151 // '0' is not a possible return value with no timeout.
160 DCHECK_NE(0, r); 152 DCHECK_NE(0, r);
161 if (r < 0) { 153 if (r < 0) {
162 PLOG(WARNING) << "poll"; 154 PLOG(WARNING) << "poll";
163 if (failed_polls++ == 3) { 155 if (failed_polls++ == 3) {
164 LOG(FATAL) << "poll(2) failing. RenderSandboxHostLinux aborting."; 156 LOG(FATAL) << "poll(2) failing. SandboxIPCHandler aborting.";
165 return; 157 return;
166 } 158 }
167 continue; 159 continue;
168 } 160 }
169 161
170 failed_polls = 0; 162 failed_polls = 0;
171 163
172 // The browser process will close the other end of this pipe on shutdown, 164 // The browser process will close the other end of this pipe on shutdown,
173 // so we should exit. 165 // so we should exit.
174 if (pfds[0].revents) { 166 if (pfds[0].revents) {
175 break; 167 break;
176 } 168 }
177 169
178 if (pfds[1].revents) { 170 // If poll(2) reports an error condition in this fd,
171 // we assume the zygote is gone and we exit the loop.
172 if (pfds[1].revents & (POLLERR | POLLHUP)) {
173 break;
174 }
175
176 if (pfds[1].revents & POLLIN) {
179 HandleRequestFromRenderer(browser_socket_); 177 HandleRequestFromRenderer(browser_socket_);
180 } 178 }
181 } 179 }
182 180
183 VLOG(1) << "SandboxIPCProcess stopping."; 181 VLOG(1) << "SandboxIPCHandler stopping.";
184 } 182 }
185 183
186 void SandboxIPCProcess::HandleRequestFromRenderer(int fd) { 184 void SandboxIPCHandler::HandleRequestFromRenderer(int fd) {
187 ScopedVector<base::ScopedFD> fds; 185 ScopedVector<base::ScopedFD> fds;
188 186
189 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength 187 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength
190 // bytes long (this is the largest message type). 188 // bytes long (this is the largest message type).
191 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC 189 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC
192 // error for a maximum length message. 190 // error for a maximum length message.
193 char buf[FontConfigIPC::kMaxFontFamilyLength + 128]; 191 char buf[FontConfigIPC::kMaxFontFamilyLength + 128];
194 192
195 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds); 193 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds);
196 if (len == -1) { 194 if (len == -1) {
(...skipping 21 matching lines...) Expand all
218 HandleLocaltime(fd, pickle, iter, fds.get()); 216 HandleLocaltime(fd, pickle, iter, fds.get());
219 } else if (kind == LinuxSandbox::METHOD_GET_STYLE_FOR_STRIKE) { 217 } else if (kind == LinuxSandbox::METHOD_GET_STYLE_FOR_STRIKE) {
220 HandleGetStyleForStrike(fd, pickle, iter, fds.get()); 218 HandleGetStyleForStrike(fd, pickle, iter, fds.get());
221 } else if (kind == LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT) { 219 } else if (kind == LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT) {
222 HandleMakeSharedMemorySegment(fd, pickle, iter, fds.get()); 220 HandleMakeSharedMemorySegment(fd, pickle, iter, fds.get());
223 } else if (kind == LinuxSandbox::METHOD_MATCH_WITH_FALLBACK) { 221 } else if (kind == LinuxSandbox::METHOD_MATCH_WITH_FALLBACK) {
224 HandleMatchWithFallback(fd, pickle, iter, fds.get()); 222 HandleMatchWithFallback(fd, pickle, iter, fds.get());
225 } 223 }
226 } 224 }
227 225
228 int SandboxIPCProcess::FindOrAddPath(const SkString& path) { 226 int SandboxIPCHandler::FindOrAddPath(const SkString& path) {
229 int count = paths_.count(); 227 int count = paths_.count();
230 for (int i = 0; i < count; ++i) { 228 for (int i = 0; i < count; ++i) {
231 if (path == *paths_[i]) 229 if (path == *paths_[i])
232 return i; 230 return i;
233 } 231 }
234 *paths_.append() = new SkString(path); 232 *paths_.append() = new SkString(path);
235 return count; 233 return count;
236 } 234 }
237 235
238 void SandboxIPCProcess::HandleFontMatchRequest( 236 void SandboxIPCHandler::HandleFontMatchRequest(
239 int fd, 237 int fd,
240 const Pickle& pickle, 238 const Pickle& pickle,
241 PickleIterator iter, 239 PickleIterator iter,
242 const std::vector<base::ScopedFD*>& fds) { 240 const std::vector<base::ScopedFD*>& fds) {
243 uint32_t requested_style; 241 uint32_t requested_style;
244 std::string family; 242 std::string family;
245 if (!pickle.ReadString(&iter, &family) || 243 if (!pickle.ReadString(&iter, &family) ||
246 !pickle.ReadUInt32(&iter, &requested_style)) 244 !pickle.ReadUInt32(&iter, &requested_style))
247 return; 245 return;
248 246
(...skipping 19 matching lines...) Expand all
268 result_identity.fID = static_cast<uint32_t>(index); 266 result_identity.fID = static_cast<uint32_t>(index);
269 267
270 reply.WriteBool(true); 268 reply.WriteBool(true);
271 skia::WriteSkString(&reply, result_family); 269 skia::WriteSkString(&reply, result_family);
272 skia::WriteSkFontIdentity(&reply, result_identity); 270 skia::WriteSkFontIdentity(&reply, result_identity);
273 reply.WriteUInt32(result_style); 271 reply.WriteUInt32(result_style);
274 } 272 }
275 SendRendererReply(fds, reply, -1); 273 SendRendererReply(fds, reply, -1);
276 } 274 }
277 275
278 void SandboxIPCProcess::HandleFontOpenRequest( 276 void SandboxIPCHandler::HandleFontOpenRequest(
279 int fd, 277 int fd,
280 const Pickle& pickle, 278 const Pickle& pickle,
281 PickleIterator iter, 279 PickleIterator iter,
282 const std::vector<base::ScopedFD*>& fds) { 280 const std::vector<base::ScopedFD*>& fds) {
283 uint32_t index; 281 uint32_t index;
284 if (!pickle.ReadUInt32(&iter, &index)) 282 if (!pickle.ReadUInt32(&iter, &index))
285 return; 283 return;
286 if (index >= static_cast<uint32_t>(paths_.count())) 284 if (index >= static_cast<uint32_t>(paths_.count()))
287 return; 285 return;
288 const int result_fd = open(paths_[index]->c_str(), O_RDONLY); 286 const int result_fd = open(paths_[index]->c_str(), O_RDONLY);
289 287
290 Pickle reply; 288 Pickle reply;
291 if (result_fd == -1) { 289 if (result_fd == -1) {
292 reply.WriteBool(false); 290 reply.WriteBool(false);
293 } else { 291 } else {
294 reply.WriteBool(true); 292 reply.WriteBool(true);
295 } 293 }
296 294
297 // 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
298 // after this send. 296 // after this send.
299 SendRendererReply(fds, reply, result_fd); 297 SendRendererReply(fds, reply, result_fd);
300 298
301 if (result_fd >= 0) { 299 if (result_fd >= 0) {
302 int err = IGNORE_EINTR(close(result_fd)); 300 int err = IGNORE_EINTR(close(result_fd));
303 DCHECK(!err); 301 DCHECK(!err);
304 } 302 }
305 } 303 }
306 304
307 void SandboxIPCProcess::HandleGetFontFamilyForChar( 305 void SandboxIPCHandler::HandleGetFontFamilyForChar(
308 int fd, 306 int fd,
309 const Pickle& pickle, 307 const Pickle& pickle,
310 PickleIterator iter, 308 PickleIterator iter,
311 const std::vector<base::ScopedFD*>& fds) { 309 const std::vector<base::ScopedFD*>& fds) {
312 // The other side of this call is 310 // The other side of this call is
313 // chrome/renderer/renderer_sandbox_support_linux.cc 311 // content/common/child_process_sandbox_support_impl_linux.cc
314 312
315 EnsureWebKitInitialized(); 313 EnsureWebKitInitialized();
316 WebUChar32 c; 314 WebUChar32 c;
317 if (!pickle.ReadInt(&iter, &c)) 315 if (!pickle.ReadInt(&iter, &c))
318 return; 316 return;
319 317
320 std::string preferred_locale; 318 std::string preferred_locale;
321 if (!pickle.ReadString(&iter, &preferred_locale)) 319 if (!pickle.ReadString(&iter, &preferred_locale))
322 return; 320 return;
323 321
324 blink::WebFontFamily family; 322 blink::WebFontFamily family;
325 WebFontInfo::familyForChar(c, preferred_locale.c_str(), &family); 323 WebFontInfo::familyForChar(c, preferred_locale.c_str(), &family);
326 324
327 Pickle reply; 325 Pickle reply;
328 if (family.name.data()) { 326 if (family.name.data()) {
329 reply.WriteString(family.name.data()); 327 reply.WriteString(family.name.data());
330 } else { 328 } else {
331 reply.WriteString(std::string()); 329 reply.WriteString(std::string());
332 } 330 }
333 reply.WriteBool(family.isBold); 331 reply.WriteBool(family.isBold);
334 reply.WriteBool(family.isItalic); 332 reply.WriteBool(family.isItalic);
335 SendRendererReply(fds, reply, -1); 333 SendRendererReply(fds, reply, -1);
336 } 334 }
337 335
338 void SandboxIPCProcess::HandleGetStyleForStrike( 336 void SandboxIPCHandler::HandleGetStyleForStrike(
339 int fd, 337 int fd,
340 const Pickle& pickle, 338 const Pickle& pickle,
341 PickleIterator iter, 339 PickleIterator iter,
342 const std::vector<base::ScopedFD*>& fds) { 340 const std::vector<base::ScopedFD*>& fds) {
343 std::string family; 341 std::string family;
344 int sizeAndStyle; 342 int sizeAndStyle;
345 343
346 if (!pickle.ReadString(&iter, &family) || 344 if (!pickle.ReadString(&iter, &family) ||
347 !pickle.ReadInt(&iter, &sizeAndStyle)) { 345 !pickle.ReadInt(&iter, &sizeAndStyle)) {
348 return; 346 return;
349 } 347 }
350 348
351 EnsureWebKitInitialized(); 349 EnsureWebKitInitialized();
352 blink::WebFontRenderStyle style; 350 blink::WebFontRenderStyle style;
353 WebFontInfo::renderStyleForStrike(family.c_str(), sizeAndStyle, &style); 351 WebFontInfo::renderStyleForStrike(family.c_str(), sizeAndStyle, &style);
354 352
355 Pickle reply; 353 Pickle reply;
356 reply.WriteInt(style.useBitmaps); 354 reply.WriteInt(style.useBitmaps);
357 reply.WriteInt(style.useAutoHint); 355 reply.WriteInt(style.useAutoHint);
358 reply.WriteInt(style.useHinting); 356 reply.WriteInt(style.useHinting);
359 reply.WriteInt(style.hintStyle); 357 reply.WriteInt(style.hintStyle);
360 reply.WriteInt(style.useAntiAlias); 358 reply.WriteInt(style.useAntiAlias);
361 reply.WriteInt(style.useSubpixelRendering); 359 reply.WriteInt(style.useSubpixelRendering);
362 reply.WriteInt(style.useSubpixelPositioning); 360 reply.WriteInt(style.useSubpixelPositioning);
363 361
364 SendRendererReply(fds, reply, -1); 362 SendRendererReply(fds, reply, -1);
365 } 363 }
366 364
367 void SandboxIPCProcess::HandleLocaltime( 365 void SandboxIPCHandler::HandleLocaltime(
368 int fd, 366 int fd,
369 const Pickle& pickle, 367 const Pickle& pickle,
370 PickleIterator iter, 368 PickleIterator iter,
371 const std::vector<base::ScopedFD*>& fds) { 369 const std::vector<base::ScopedFD*>& fds) {
372 // The other side of this call is in zygote_main_linux.cc 370 // The other side of this call is in zygote_main_linux.cc
373 371
374 std::string time_string; 372 std::string time_string;
375 if (!pickle.ReadString(&iter, &time_string) || 373 if (!pickle.ReadString(&iter, &time_string) ||
376 time_string.size() != sizeof(time_t)) { 374 time_string.size() != sizeof(time_t)) {
377 return; 375 return;
(...skipping 12 matching lines...) Expand all
390 sizeof(struct tm)); 388 sizeof(struct tm));
391 time_zone_string = expanded_time->tm_zone; 389 time_zone_string = expanded_time->tm_zone;
392 } 390 }
393 391
394 Pickle reply; 392 Pickle reply;
395 reply.WriteString(result_string); 393 reply.WriteString(result_string);
396 reply.WriteString(time_zone_string); 394 reply.WriteString(time_zone_string);
397 SendRendererReply(fds, reply, -1); 395 SendRendererReply(fds, reply, -1);
398 } 396 }
399 397
400 void SandboxIPCProcess::HandleMakeSharedMemorySegment( 398 void SandboxIPCHandler::HandleMakeSharedMemorySegment(
401 int fd, 399 int fd,
402 const Pickle& pickle, 400 const Pickle& pickle,
403 PickleIterator iter, 401 PickleIterator iter,
404 const std::vector<base::ScopedFD*>& fds) { 402 const std::vector<base::ScopedFD*>& fds) {
405 base::SharedMemoryCreateOptions options; 403 base::SharedMemoryCreateOptions options;
406 uint32_t size; 404 uint32_t size;
407 if (!pickle.ReadUInt32(&iter, &size)) 405 if (!pickle.ReadUInt32(&iter, &size))
408 return; 406 return;
409 options.size = size; 407 options.size = size;
410 if (!pickle.ReadBool(&iter, &options.executable)) 408 if (!pickle.ReadBool(&iter, &options.executable))
411 return; 409 return;
412 int shm_fd = -1; 410 int shm_fd = -1;
413 base::SharedMemory shm; 411 base::SharedMemory shm;
414 if (shm.Create(options)) 412 if (shm.Create(options))
415 shm_fd = shm.handle().fd; 413 shm_fd = shm.handle().fd;
416 Pickle reply; 414 Pickle reply;
417 SendRendererReply(fds, reply, shm_fd); 415 SendRendererReply(fds, reply, shm_fd);
418 } 416 }
419 417
420 void SandboxIPCProcess::HandleMatchWithFallback( 418 void SandboxIPCHandler::HandleMatchWithFallback(
421 int fd, 419 int fd,
422 const Pickle& pickle, 420 const Pickle& pickle,
423 PickleIterator iter, 421 PickleIterator iter,
424 const std::vector<base::ScopedFD*>& fds) { 422 const std::vector<base::ScopedFD*>& fds) {
425 // Unlike the other calls, for which we are an indirection in front of 423 // Unlike the other calls, for which we are an indirection in front of
426 // WebKit or Skia, this call is always made via this sandbox helper 424 // WebKit or Skia, this call is always made via this sandbox helper
427 // process. Therefore the fontconfig code goes in here directly. 425 // process. Therefore the fontconfig code goes in here directly.
428 426
429 std::string face; 427 std::string face;
430 bool is_bold, is_italic; 428 bool is_bold, is_italic;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 568
571 Pickle reply; 569 Pickle reply;
572 SendRendererReply(fds, reply, font_fd); 570 SendRendererReply(fds, reply, font_fd);
573 571
574 if (font_fd >= 0) { 572 if (font_fd >= 0) {
575 if (IGNORE_EINTR(close(font_fd)) < 0) 573 if (IGNORE_EINTR(close(font_fd)) < 0)
576 PLOG(ERROR) << "close"; 574 PLOG(ERROR) << "close";
577 } 575 }
578 } 576 }
579 577
580 void SandboxIPCProcess::SendRendererReply( 578 void SandboxIPCHandler::SendRendererReply(
581 const std::vector<base::ScopedFD*>& fds, 579 const std::vector<base::ScopedFD*>& fds,
582 const Pickle& reply, 580 const Pickle& reply,
583 int reply_fd) { 581 int reply_fd) {
584 struct msghdr msg; 582 struct msghdr msg;
585 memset(&msg, 0, sizeof(msg)); 583 memset(&msg, 0, sizeof(msg));
586 struct iovec iov = {const_cast<void*>(reply.data()), reply.size()}; 584 struct iovec iov = {const_cast<void*>(reply.data()), reply.size()};
587 msg.msg_iov = &iov; 585 msg.msg_iov = &iov;
588 msg.msg_iovlen = 1; 586 msg.msg_iovlen = 1;
589 587
590 char control_buffer[CMSG_SPACE(sizeof(int))]; 588 char control_buffer[CMSG_SPACE(sizeof(int))];
(...skipping 15 matching lines...) Expand all
606 cmsg->cmsg_type = SCM_RIGHTS; 604 cmsg->cmsg_type = SCM_RIGHTS;
607 cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 605 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
608 memcpy(CMSG_DATA(cmsg), &reply_fd, sizeof(reply_fd)); 606 memcpy(CMSG_DATA(cmsg), &reply_fd, sizeof(reply_fd));
609 msg.msg_controllen = cmsg->cmsg_len; 607 msg.msg_controllen = cmsg->cmsg_len;
610 } 608 }
611 609
612 if (HANDLE_EINTR(sendmsg(fds[0]->get(), &msg, MSG_DONTWAIT)) < 0) 610 if (HANDLE_EINTR(sendmsg(fds[0]->get(), &msg, MSG_DONTWAIT)) < 0)
613 PLOG(ERROR) << "sendmsg"; 611 PLOG(ERROR) << "sendmsg";
614 } 612 }
615 613
616 SandboxIPCProcess::~SandboxIPCProcess() { 614 SandboxIPCHandler::~SandboxIPCHandler() {
617 paths_.deleteAll(); 615 paths_.deleteAll();
618 if (webkit_platform_support_) 616 if (webkit_platform_support_)
619 blink::shutdownWithoutV8(); 617 blink::shutdownWithoutV8();
618
619 if (IGNORE_EINTR(close(lifeline_fd_)) < 0)
620 PLOG(ERROR) << "close";
621 if (IGNORE_EINTR(close(browser_socket_)) < 0)
622 PLOG(ERROR) << "close";
620 } 623 }
621 624
622 void SandboxIPCProcess::EnsureWebKitInitialized() { 625 void SandboxIPCHandler::EnsureWebKitInitialized() {
623 if (webkit_platform_support_) 626 if (webkit_platform_support_)
624 return; 627 return;
625 webkit_platform_support_.reset(new BlinkPlatformImpl); 628 webkit_platform_support_.reset(new BlinkPlatformImpl);
626 blink::initializeWithoutV8(webkit_platform_support_.get()); 629 blink::initializeWithoutV8(webkit_platform_support_.get());
627 } 630 }
628 631
629 } // namespace content 632 } // 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