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

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

Issue 240563002: Extract SandboxIPCProcess into its own file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Set upstream correctly. Created 6 years, 8 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
(Empty)
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
jln (very slow on Chromium) 2014/04/17 00:28:37 No (c), just "Copyright 2014"
jln (very slow on Chromium) 2014/04/17 00:28:37 This file should be sandbox_ipc_linux.cc
Jorge Lucangeli Obes 2014/04/23 00:38:57 Done.
Jorge Lucangeli Obes 2014/04/23 00:38:57 Done.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/sandbox_ipc.h"
6
7 #include <fcntl.h>
8 #include <fontconfig/fontconfig.h>
9 #include <sys/poll.h>
10 #include <sys/socket.h>
11 #include <sys/stat.h>
12
13 #include "base/command_line.h"
14 #include "base/linux_util.h"
15 #include "base/memory/shared_memory.h"
16 #include "base/posix/eintr_wrapper.h"
17 #include "base/posix/unix_domain_socket_linux.h"
18 #include "base/process/launch.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "content/common/font_config_ipc_linux.h"
21 #include "content/common/sandbox_linux/sandbox_linux.h"
22 #include "content/common/set_process_title.h"
23 #include "content/public/common/content_switches.h"
24 #include "ppapi/c/trusted/ppb_browser_font_trusted.h"
25 #include "third_party/WebKit/public/platform/linux/WebFontInfo.h"
26 #include "third_party/WebKit/public/web/WebKit.h"
27 #include "third_party/npapi/bindings/npapi_extensions.h"
28 #include "third_party/skia/include/ports/SkFontConfigInterface.h"
29 #include "ui/gfx/font_render_params_linux.h"
30
31 using blink::WebCString;
32 using blink::WebFontInfo;
33 using blink::WebUChar;
34 using blink::WebUChar32;
35
36 namespace {
37
38 // MSCharSetToFontconfig translates a Microsoft charset identifier to a
39 // fontconfig language set by appending to |langset|.
40 static void MSCharSetToFontconfig(FcLangSet* langset, unsigned fdwCharSet) {
41 // We have need to translate raw fdwCharSet values into terms that
42 // fontconfig can understand. (See the description of fdwCharSet in the MSDN
43 // documentation for CreateFont:
44 // http://msdn.microsoft.com/en-us/library/dd183499(VS.85).aspx )
45 //
46 // Although the argument is /called/ 'charset', the actual values conflate
47 // character sets (which are sets of Unicode code points) and character
48 // encodings (which are algorithms for turning a series of bits into a
49 // series of code points.) Sometimes the values will name a language,
50 // sometimes they'll name an encoding. In the latter case I'm assuming that
51 // they mean the set of code points in the domain of that encoding.
52 //
53 // fontconfig deals with ISO 639-1 language codes:
54 // http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
55 //
56 // So, for each of the documented fdwCharSet values I've had to take a
57 // guess at the set of ISO 639-1 languages intended.
58
59 switch (fdwCharSet) {
60 case NPCharsetAnsi:
61 // These values I don't really know what to do with, so I'm going to map
62 // them to English also.
63 case NPCharsetDefault:
64 case NPCharsetMac:
65 case NPCharsetOEM:
66 case NPCharsetSymbol:
67 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("en"));
68 break;
69 case NPCharsetBaltic:
70 // The three baltic languages.
71 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("et"));
72 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("lv"));
73 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("lt"));
74 break;
75 // TODO(jungshik): Would we be better off mapping Big5 to zh-tw
76 // and GB2312 to zh-cn? Fontconfig has 4 separate orthography
77 // files (zh-{cn,tw,hk,mo}.
78 case NPCharsetChineseBIG5:
79 case NPCharsetGB2312:
80 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("zh"));
81 break;
82 case NPCharsetEastEurope:
83 // A scattering of eastern European languages.
84 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("pl"));
85 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("cs"));
86 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("sk"));
87 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("hu"));
88 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("hr"));
89 break;
90 case NPCharsetGreek:
91 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("el"));
92 break;
93 case NPCharsetHangul:
94 case NPCharsetJohab:
95 // Korean
96 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ko"));
97 break;
98 case NPCharsetRussian:
99 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ru"));
100 break;
101 case NPCharsetShiftJIS:
102 // Japanese
103 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ja"));
104 break;
105 case NPCharsetTurkish:
106 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("tr"));
107 break;
108 case NPCharsetVietnamese:
109 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("vi"));
110 break;
111 case NPCharsetArabic:
112 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ar"));
113 break;
114 case NPCharsetHebrew:
115 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("he"));
116 break;
117 case NPCharsetThai:
118 FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("th"));
119 break;
120 // default:
121 // Don't add any languages in that case that we don't recognise the
122 // constant.
123 }
124 }
125
126 }
jln (very slow on Chromium) 2014/04/17 00:28:37 // namespace
Jorge Lucangeli Obes 2014/04/23 00:38:57 Done.
127
128 namespace content {
129
130 SandboxIPCProcess::SandboxIPCProcess(int lifeline_fd,
131 int browser_socket,
132 std::string sandbox_cmd)
133 : lifeline_fd_(lifeline_fd), browser_socket_(browser_socket) {
134 if (!sandbox_cmd.empty()) {
135 sandbox_cmd_.push_back(sandbox_cmd);
136 sandbox_cmd_.push_back(base::kFindInodeSwitch);
137 }
138
139 // FontConfig doesn't provide a standard property to control subpixel
140 // positioning, so we pass the current setting through to WebKit.
141 WebFontInfo::setSubpixelPositioning(
142 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 }
153
154 void SandboxIPCProcess::Run() {
155 struct pollfd pfds[2];
156 pfds[0].fd = lifeline_fd_;
157 pfds[0].events = POLLIN;
158 pfds[1].fd = browser_socket_;
159 pfds[1].events = POLLIN;
160
161 int failed_polls = 0;
162 for (;;) {
163 const int r = HANDLE_EINTR(poll(pfds, 2, -1 /* no timeout */));
164 // '0' is not a possible return value with no timeout.
165 DCHECK_NE(0, r);
166 if (r < 0) {
167 PLOG(WARNING) << "poll";
168 if (failed_polls++ == 3) {
169 LOG(FATAL) << "poll(2) failing. RenderSandboxHostLinux aborting.";
170 return;
171 }
172 continue;
173 }
174
175 failed_polls = 0;
176
177 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_);
184 }
185 }
186 }
187
188 void SandboxIPCProcess::HandleRequestFromRenderer(int fd) {
189 std::vector<int> fds;
190
191 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength
192 // bytes long (this is the largest message type).
193 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC
194 // error for a maximum length message.
195 char buf[FontConfigIPC::kMaxFontFamilyLength + 128];
196
197 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds);
198 if (len == -1) {
199 // TODO: should send an error reply, or the sender might block forever.
200 NOTREACHED() << "Sandbox host message is larger than kMaxFontFamilyLength";
201 return;
202 }
203 if (fds.empty())
204 return;
205
206 Pickle pickle(buf, len);
207 PickleIterator iter(pickle);
208
209 int kind;
210 if (!pickle.ReadInt(&iter, &kind))
211 goto error;
212
213 if (kind == FontConfigIPC::METHOD_MATCH) {
214 HandleFontMatchRequest(fd, pickle, iter, fds);
215 } else if (kind == FontConfigIPC::METHOD_OPEN) {
216 HandleFontOpenRequest(fd, pickle, iter, fds);
217 } else if (kind == LinuxSandbox::METHOD_GET_FONT_FAMILY_FOR_CHAR) {
218 HandleGetFontFamilyForChar(fd, pickle, iter, fds);
219 } else if (kind == LinuxSandbox::METHOD_LOCALTIME) {
220 HandleLocaltime(fd, pickle, iter, fds);
221 } else if (kind == LinuxSandbox::METHOD_GET_CHILD_WITH_INODE) {
222 HandleGetChildWithInode(fd, pickle, iter, fds);
223 } else if (kind == LinuxSandbox::METHOD_GET_STYLE_FOR_STRIKE) {
224 HandleGetStyleForStrike(fd, pickle, iter, fds);
225 } else if (kind == LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT) {
226 HandleMakeSharedMemorySegment(fd, pickle, iter, fds);
227 } else if (kind == LinuxSandbox::METHOD_MATCH_WITH_FALLBACK) {
228 HandleMatchWithFallback(fd, pickle, iter, fds);
229 }
230
231 error:
232 for (std::vector<int>::const_iterator i = fds.begin(); i != fds.end(); ++i) {
233 close(*i);
234 }
235 }
236
237 int SandboxIPCProcess::FindOrAddPath(const SkString& path) {
238 int count = paths_.count();
239 for (int i = 0; i < count; ++i) {
240 if (path == *paths_[i])
241 return i;
242 }
243 *paths_.append() = new SkString(path);
244 return count;
245 }
246
247 void SandboxIPCProcess::HandleFontMatchRequest(int fd,
248 const Pickle& pickle,
249 PickleIterator iter,
250 std::vector<int>& fds) {
251 uint32_t requested_style;
252 std::string family;
253 if (!pickle.ReadString(&iter, &family) ||
254 !pickle.ReadUInt32(&iter, &requested_style))
255 return;
256
257 SkFontConfigInterface::FontIdentity result_identity;
258 SkString result_family;
259 SkTypeface::Style result_style;
260 SkFontConfigInterface* fc =
261 SkFontConfigInterface::GetSingletonDirectInterface();
262 const bool r =
263 fc->matchFamilyName(family.c_str(),
264 static_cast<SkTypeface::Style>(requested_style),
265 &result_identity,
266 &result_family,
267 &result_style);
268
269 Pickle reply;
270 if (!r) {
271 reply.WriteBool(false);
272 } else {
273 // Stash away the returned path, so we can give it an ID (index)
274 // which will later be given to us in a request to open the file.
275 int index = FindOrAddPath(result_identity.fString);
276 result_identity.fID = static_cast<uint32_t>(index);
277
278 reply.WriteBool(true);
279 skia::WriteSkString(&reply, result_family);
280 skia::WriteSkFontIdentity(&reply, result_identity);
281 reply.WriteUInt32(result_style);
282 }
283 SendRendererReply(fds, reply, -1);
284 }
285
286 void SandboxIPCProcess::HandleFontOpenRequest(int fd,
287 const Pickle& pickle,
288 PickleIterator iter,
289 std::vector<int>& fds) {
290 uint32_t index;
291 if (!pickle.ReadUInt32(&iter, &index))
292 return;
293 if (index >= static_cast<uint32_t>(paths_.count()))
294 return;
295 const int result_fd = open(paths_[index]->c_str(), O_RDONLY);
296
297 Pickle reply;
298 if (result_fd == -1) {
299 reply.WriteBool(false);
300 } else {
301 reply.WriteBool(true);
302 }
303
304 // The receiver will have its own access to the file, so we will close it
305 // after this send.
306 SendRendererReply(fds, reply, result_fd);
307
308 if (result_fd >= 0) {
309 int err = IGNORE_EINTR(close(result_fd));
310 DCHECK(!err);
311 }
312 }
313
314 void SandboxIPCProcess::HandleGetFontFamilyForChar(int fd,
315 const Pickle& pickle,
316 PickleIterator iter,
317 std::vector<int>& fds) {
318 // The other side of this call is
319 // chrome/renderer/renderer_sandbox_support_linux.cc
320
321 EnsureWebKitInitialized();
322 WebUChar32 c;
323 if (!pickle.ReadInt(&iter, &c))
324 return;
325
326 std::string preferred_locale;
327 if (!pickle.ReadString(&iter, &preferred_locale))
328 return;
329
330 blink::WebFontFamily family;
331 WebFontInfo::familyForChar(c, preferred_locale.c_str(), &family);
332
333 Pickle reply;
334 if (family.name.data()) {
335 reply.WriteString(family.name.data());
336 } else {
337 reply.WriteString(std::string());
338 }
339 reply.WriteBool(family.isBold);
340 reply.WriteBool(family.isItalic);
341 SendRendererReply(fds, reply, -1);
342 }
343
344 void SandboxIPCProcess::HandleGetStyleForStrike(int fd,
345 const Pickle& pickle,
346 PickleIterator iter,
347 std::vector<int>& fds) {
348 std::string family;
349 int sizeAndStyle;
350
351 if (!pickle.ReadString(&iter, &family) ||
352 !pickle.ReadInt(&iter, &sizeAndStyle)) {
353 return;
354 }
355
356 EnsureWebKitInitialized();
357 blink::WebFontRenderStyle style;
358 WebFontInfo::renderStyleForStrike(family.c_str(), sizeAndStyle, &style);
359
360 Pickle reply;
361 reply.WriteInt(style.useBitmaps);
362 reply.WriteInt(style.useAutoHint);
363 reply.WriteInt(style.useHinting);
364 reply.WriteInt(style.hintStyle);
365 reply.WriteInt(style.useAntiAlias);
366 reply.WriteInt(style.useSubpixelRendering);
367 reply.WriteInt(style.useSubpixelPositioning);
368
369 SendRendererReply(fds, reply, -1);
370 }
371
372 void SandboxIPCProcess::HandleLocaltime(int fd,
373 const Pickle& pickle,
374 PickleIterator iter,
375 std::vector<int>& fds) {
376 // The other side of this call is in zygote_main_linux.cc
377
378 std::string time_string;
379 if (!pickle.ReadString(&iter, &time_string) ||
380 time_string.size() != sizeof(time_t)) {
381 return;
382 }
383
384 time_t time;
385 memcpy(&time, time_string.data(), sizeof(time));
386 // We use localtime here because we need the tm_zone field to be filled
387 // out. Since we are a single-threaded process, this is safe.
388 const struct tm* expanded_time = localtime(&time);
389
390 std::string result_string;
391 const char* time_zone_string = "";
392 if (expanded_time != NULL) {
393 result_string = std::string(reinterpret_cast<const char*>(expanded_time),
394 sizeof(struct tm));
395 time_zone_string = expanded_time->tm_zone;
396 }
397
398 Pickle reply;
399 reply.WriteString(result_string);
400 reply.WriteString(time_zone_string);
401 SendRendererReply(fds, reply, -1);
402 }
403
404 void SandboxIPCProcess::HandleGetChildWithInode(int fd,
405 const Pickle& pickle,
406 PickleIterator iter,
407 std::vector<int>& fds) {
408 // The other side of this call is in zygote_main_linux.cc
409 if (sandbox_cmd_.empty()) {
410 LOG(ERROR) << "Not in the sandbox, this should not be called";
411 return;
412 }
413
414 uint64_t inode;
415 if (!pickle.ReadUInt64(&iter, &inode))
416 return;
417
418 base::ProcessId pid = 0;
419 std::string inode_output;
420
421 std::vector<std::string> sandbox_cmd = sandbox_cmd_;
422 sandbox_cmd.push_back(base::Int64ToString(inode));
423 CommandLine get_inode_cmd(sandbox_cmd);
424 if (base::GetAppOutput(get_inode_cmd, &inode_output))
425 base::StringToInt(inode_output, &pid);
426
427 if (!pid) {
428 // Even though the pid is invalid, we still need to reply to the zygote
429 // and not just return here.
430 LOG(ERROR) << "Could not get pid";
431 }
432
433 Pickle reply;
434 reply.WriteInt(pid);
435 SendRendererReply(fds, reply, -1);
436 }
437
438 void SandboxIPCProcess::HandleMakeSharedMemorySegment(int fd,
439 const Pickle& pickle,
440 PickleIterator iter,
441 std::vector<int>& fds) {
442 base::SharedMemoryCreateOptions options;
443 uint32_t size;
444 if (!pickle.ReadUInt32(&iter, &size))
445 return;
446 options.size = size;
447 if (!pickle.ReadBool(&iter, &options.executable))
448 return;
449 int shm_fd = -1;
450 base::SharedMemory shm;
451 if (shm.Create(options))
452 shm_fd = shm.handle().fd;
453 Pickle reply;
454 SendRendererReply(fds, reply, shm_fd);
455 }
456
457 void SandboxIPCProcess::HandleMatchWithFallback(int fd,
458 const Pickle& pickle,
459 PickleIterator iter,
460 std::vector<int>& fds) {
461 // 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
463 // process. Therefore the fontconfig code goes in here directly.
464
465 std::string face;
466 bool is_bold, is_italic;
467 uint32 charset, fallback_family;
468
469 if (!pickle.ReadString(&iter, &face) || face.empty() ||
470 !pickle.ReadBool(&iter, &is_bold) ||
471 !pickle.ReadBool(&iter, &is_italic) ||
472 !pickle.ReadUInt32(&iter, &charset) ||
473 !pickle.ReadUInt32(&iter, &fallback_family)) {
474 return;
475 }
476
477 FcLangSet* langset = FcLangSetCreate();
478 MSCharSetToFontconfig(langset, charset);
479
480 FcPattern* pattern = FcPatternCreate();
481 // TODO(agl): FC_FAMILy needs to change
482 FcPatternAddString(
483 pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(face.c_str()));
484
485 std::string generic_font_name;
486 switch (fallback_family) {
487 case PP_BROWSERFONT_TRUSTED_FAMILY_SERIF:
488 generic_font_name = "Times New Roman";
489 break;
490 case PP_BROWSERFONT_TRUSTED_FAMILY_SANSSERIF:
491 generic_font_name = "Arial";
492 break;
493 case PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE:
494 generic_font_name = "Courier New";
495 break;
496 }
497 if (!generic_font_name.empty()) {
498 const FcChar8* fc_generic_font_name =
499 reinterpret_cast<const FcChar8*>(generic_font_name.c_str());
500 FcPatternAddString(pattern, FC_FAMILY, fc_generic_font_name);
501 }
502
503 if (is_bold)
504 FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
505 if (is_italic)
506 FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
507 FcPatternAddLangSet(pattern, FC_LANG, langset);
508 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
509 FcConfigSubstitute(NULL, pattern, FcMatchPattern);
510 FcDefaultSubstitute(pattern);
511
512 FcResult result;
513 FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result);
514 int font_fd = -1;
515 int good_enough_index = -1;
516 bool good_enough_index_set = false;
517
518 if (font_set) {
519 for (int i = 0; i < font_set->nfont; ++i) {
520 FcPattern* current = font_set->fonts[i];
521
522 // Older versions of fontconfig have a bug where they cannot select
523 // only scalable fonts so we have to manually filter the results.
524 FcBool is_scalable;
525 if (FcPatternGetBool(current, FC_SCALABLE, 0, &is_scalable) !=
526 FcResultMatch ||
527 !is_scalable) {
528 continue;
529 }
530
531 FcChar8* c_filename;
532 if (FcPatternGetString(current, FC_FILE, 0, &c_filename) !=
533 FcResultMatch) {
534 continue;
535 }
536
537 // We only want to return sfnt (TrueType) based fonts. We don't have a
538 // very good way of detecting this so we'll filter based on the
539 // filename.
540 bool is_sfnt = false;
541 static const char kSFNTExtensions[][5] = {".ttf", ".otc", ".TTF", ".ttc",
542 ""};
543 const size_t filename_len = strlen(reinterpret_cast<char*>(c_filename));
544 for (unsigned j = 0;; j++) {
545 if (kSFNTExtensions[j][0] == 0) {
546 // None of the extensions matched.
547 break;
548 }
549 const size_t ext_len = strlen(kSFNTExtensions[j]);
550 if (filename_len > ext_len &&
551 memcmp(c_filename + filename_len - ext_len,
552 kSFNTExtensions[j],
553 ext_len) == 0) {
554 is_sfnt = true;
555 break;
556 }
557 }
558
559 if (!is_sfnt)
560 continue;
561
562 // This font is good enough to pass muster, but we might be able to do
563 // better with subsequent ones.
564 if (!good_enough_index_set) {
565 good_enough_index = i;
566 good_enough_index_set = true;
567 }
568
569 FcValue matrix;
570 bool have_matrix = FcPatternGet(current, FC_MATRIX, 0, &matrix) == 0;
571
572 if (is_italic && have_matrix) {
573 // we asked for an italic font, but fontconfig is giving us a
574 // non-italic font with a transformation matrix.
575 continue;
576 }
577
578 FcValue embolden;
579 const bool have_embolden =
580 FcPatternGet(current, FC_EMBOLDEN, 0, &embolden) == 0;
581
582 if (is_bold && have_embolden) {
583 // we asked for a bold font, but fontconfig gave us a non-bold font
584 // and asked us to apply fake bolding.
585 continue;
586 }
587
588 font_fd = open(reinterpret_cast<char*>(c_filename), O_RDONLY);
589 if (font_fd >= 0)
590 break;
591 }
592 }
593
594 if (font_fd == -1 && good_enough_index_set) {
595 // We didn't find a font that we liked, so we fallback to something
596 // acceptable.
597 FcPattern* current = font_set->fonts[good_enough_index];
598 FcChar8* c_filename;
599 FcPatternGetString(current, FC_FILE, 0, &c_filename);
600 font_fd = open(reinterpret_cast<char*>(c_filename), O_RDONLY);
601 }
602
603 if (font_set)
604 FcFontSetDestroy(font_set);
605 FcPatternDestroy(pattern);
606
607 Pickle reply;
608 SendRendererReply(fds, reply, font_fd);
609
610 if (font_fd >= 0) {
611 if (IGNORE_EINTR(close(font_fd)) < 0)
612 PLOG(ERROR) << "close";
613 }
614 }
615
616 void SandboxIPCProcess::SendRendererReply(const std::vector<int>& fds,
617 const Pickle& reply,
618 int reply_fd) {
619 struct msghdr msg;
620 memset(&msg, 0, sizeof(msg));
621 struct iovec iov = {const_cast<void*>(reply.data()), reply.size()};
622 msg.msg_iov = &iov;
623 msg.msg_iovlen = 1;
624
625 char control_buffer[CMSG_SPACE(sizeof(int))];
626
627 if (reply_fd != -1) {
628 struct stat st;
629 if (fstat(reply_fd, &st) == 0 && S_ISDIR(st.st_mode)) {
630 LOG(FATAL) << "Tried to send a directory descriptor over sandbox IPC";
631 // We must never send directory descriptors to a sandboxed process
632 // because they can use openat with ".." elements in the path in order
633 // to escape the sandbox and reach the real filesystem.
634 }
635
636 struct cmsghdr* cmsg;
637 msg.msg_control = control_buffer;
638 msg.msg_controllen = sizeof(control_buffer);
639 cmsg = CMSG_FIRSTHDR(&msg);
640 cmsg->cmsg_level = SOL_SOCKET;
641 cmsg->cmsg_type = SCM_RIGHTS;
642 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
643 memcpy(CMSG_DATA(cmsg), &reply_fd, sizeof(reply_fd));
644 msg.msg_controllen = cmsg->cmsg_len;
645 }
646
647 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0)
648 PLOG(ERROR) << "sendmsg";
649 }
650
651 SandboxIPCProcess::~SandboxIPCProcess() {
652 paths_.deleteAll();
653 if (webkit_platform_support_)
654 blink::shutdownWithoutV8();
655 }
656
657 void SandboxIPCProcess::EnsureWebKitInitialized() {
658 if (webkit_platform_support_)
659 return;
660 webkit_platform_support_.reset(new BlinkPlatformImpl);
661 blink::initializeWithoutV8(webkit_platform_support_.get());
662 }
663
664 }
jln (very slow on Chromium) 2014/04/17 00:28:37 // namespace content
Jorge Lucangeli Obes 2014/04/23 00:38:57 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698