OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/render_sandbox_host_linux.h" | 5 #include "content/browser/renderer_host/render_sandbox_host_linux.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <fontconfig/fontconfig.h> | 8 #include <fontconfig/fontconfig.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <sys/poll.h> | 10 #include <sys/poll.h> |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "base/pickle.h" | 23 #include "base/pickle.h" |
24 #include "base/posix/eintr_wrapper.h" | 24 #include "base/posix/eintr_wrapper.h" |
25 #include "base/posix/unix_domain_socket_linux.h" | 25 #include "base/posix/unix_domain_socket_linux.h" |
26 #include "base/process_util.h" | 26 #include "base/process_util.h" |
27 #include "base/shared_memory.h" | 27 #include "base/shared_memory.h" |
28 #include "base/string_number_conversions.h" | 28 #include "base/string_number_conversions.h" |
29 #include "base/string_util.h" | 29 #include "base/string_util.h" |
30 #include "content/common/font_config_ipc_linux.h" | 30 #include "content/common/font_config_ipc_linux.h" |
31 #include "content/common/sandbox_linux.h" | 31 #include "content/common/sandbox_linux.h" |
32 #include "content/common/webkitplatformsupport_impl.h" | 32 #include "content/common/webkitplatformsupport_impl.h" |
33 #include "skia/ext/SkFontHost_fontconfig_direct.h" | 33 #include "skia/ext/skia_utils_base.h" |
34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" | 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" |
35 #include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebFontInfo.h" | 35 #include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebFontInfo.h" |
36 #include "third_party/npapi/bindings/npapi_extensions.h" | 36 #include "third_party/npapi/bindings/npapi_extensions.h" |
| 37 #include "third_party/skia/include/ports/SkFontConfigInterface.h" |
37 #include "ui/gfx/font_render_params_linux.h" | 38 #include "ui/gfx/font_render_params_linux.h" |
38 | 39 |
39 using WebKit::WebCString; | 40 using WebKit::WebCString; |
40 using WebKit::WebFontInfo; | 41 using WebKit::WebFontInfo; |
41 using WebKit::WebUChar; | 42 using WebKit::WebUChar; |
42 | 43 |
43 namespace content { | 44 namespace content { |
44 | 45 |
45 // http://code.google.com/p/chromium/wiki/LinuxSandboxIPC | 46 // http://code.google.com/p/chromium/wiki/LinuxSandboxIPC |
46 | 47 |
47 // BEWARE: code in this file run across *processes* (not just threads). | 48 // BEWARE: code in this file run across *processes* (not just threads). |
48 | 49 |
49 // This code runs in a child process | 50 // This code runs in a child process |
50 class SandboxIPCProcess { | 51 class SandboxIPCProcess { |
51 public: | 52 public: |
52 // lifeline_fd: this is the read end of a pipe which the browser process | 53 // lifeline_fd: this is the read end of a pipe which the browser process |
53 // holds the other end of. If the browser process dies, its descriptors are | 54 // holds the other end of. If the browser process dies, its descriptors are |
54 // closed and we will noticed an EOF on the pipe. That's our signal to exit. | 55 // closed and we will noticed an EOF on the pipe. That's our signal to exit. |
55 // browser_socket: the browser's end of the sandbox IPC socketpair. From the | 56 // browser_socket: the browser's end of the sandbox IPC socketpair. From the |
56 // point of view of the renderer, it's talking to the browser but this | 57 // point of view of the renderer, it's talking to the browser but this |
57 // object actually services the requests. | 58 // object actually services the requests. |
58 // sandbox_cmd: the path of the sandbox executable | 59 // sandbox_cmd: the path of the sandbox executable |
59 SandboxIPCProcess(int lifeline_fd, int browser_socket, | 60 SandboxIPCProcess(int lifeline_fd, int browser_socket, |
60 std::string sandbox_cmd) | 61 std::string sandbox_cmd) |
61 : lifeline_fd_(lifeline_fd), | 62 : lifeline_fd_(lifeline_fd), |
62 browser_socket_(browser_socket), | 63 browser_socket_(browser_socket) { |
63 font_config_(new FontConfigDirect()) { | |
64 if (!sandbox_cmd.empty()) { | 64 if (!sandbox_cmd.empty()) { |
65 sandbox_cmd_.push_back(sandbox_cmd); | 65 sandbox_cmd_.push_back(sandbox_cmd); |
66 sandbox_cmd_.push_back(base::kFindInodeSwitch); | 66 sandbox_cmd_.push_back(base::kFindInodeSwitch); |
67 } | 67 } |
68 | 68 |
69 // FontConfig doesn't provide a standard property to control subpixel | 69 // FontConfig doesn't provide a standard property to control subpixel |
70 // positioning, so we pass the current setting through to WebKit. | 70 // positioning, so we pass the current setting through to WebKit. |
71 WebFontInfo::setSubpixelPositioning( | 71 WebFontInfo::setSubpixelPositioning( |
72 gfx::GetDefaultWebkitSubpixelPositioning()); | 72 gfx::GetDefaultWebkitSubpixelPositioning()); |
73 } | 73 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 // --------------------------------------------------------------------------- | 112 // --------------------------------------------------------------------------- |
113 // Requests from the renderer... | 113 // Requests from the renderer... |
114 | 114 |
115 void HandleRequestFromRenderer(int fd) { | 115 void HandleRequestFromRenderer(int fd) { |
116 std::vector<int> fds; | 116 std::vector<int> fds; |
117 | 117 |
118 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength | 118 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength |
119 // bytes long (this is the largest message type). | 119 // bytes long (this is the largest message type). |
120 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC | 120 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC |
121 // error for a maximum length message. | 121 // error for a maximum length message. |
122 char buf[FontConfigInterface::kMaxFontFamilyLength + 128]; | 122 char buf[FontConfigIPC::kMaxFontFamilyLength + 128]; |
123 | 123 |
124 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds); | 124 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds); |
125 if (len == -1) { | 125 if (len == -1) { |
126 // TODO: should send an error reply, or the sender might block forever. | 126 // TODO: should send an error reply, or the sender might block forever. |
127 NOTREACHED() | 127 NOTREACHED() |
128 << "Sandbox host message is larger than kMaxFontFamilyLength"; | 128 << "Sandbox host message is larger than kMaxFontFamilyLength"; |
129 return; | 129 return; |
130 } | 130 } |
131 if (fds.empty()) | 131 if (fds.empty()) |
132 return; | 132 return; |
(...skipping 23 matching lines...) Expand all Loading... |
156 HandleMatchWithFallback(fd, pickle, iter, fds); | 156 HandleMatchWithFallback(fd, pickle, iter, fds); |
157 } | 157 } |
158 | 158 |
159 error: | 159 error: |
160 for (std::vector<int>::const_iterator | 160 for (std::vector<int>::const_iterator |
161 i = fds.begin(); i != fds.end(); ++i) { | 161 i = fds.begin(); i != fds.end(); ++i) { |
162 close(*i); | 162 close(*i); |
163 } | 163 } |
164 } | 164 } |
165 | 165 |
| 166 int FindOrAddPath(const SkString& path) { |
| 167 int count = paths_.count(); |
| 168 for (int i = 0; i < count; ++i) { |
| 169 if (path == *paths_[i]) |
| 170 return i; |
| 171 } |
| 172 *paths_.append() = new SkString(path); |
| 173 return count; |
| 174 } |
| 175 |
166 void HandleFontMatchRequest(int fd, const Pickle& pickle, PickleIterator iter, | 176 void HandleFontMatchRequest(int fd, const Pickle& pickle, PickleIterator iter, |
167 std::vector<int>& fds) { | 177 std::vector<int>& fds) { |
168 bool filefaceid_valid; | 178 uint32_t requested_style; |
169 uint32_t filefaceid = 0; | |
170 | |
171 if (!pickle.ReadBool(&iter, &filefaceid_valid)) | |
172 return; | |
173 if (filefaceid_valid) { | |
174 if (!pickle.ReadUInt32(&iter, &filefaceid)) | |
175 return; | |
176 } | |
177 bool is_bold, is_italic; | |
178 if (!pickle.ReadBool(&iter, &is_bold) || | |
179 !pickle.ReadBool(&iter, &is_italic)) { | |
180 return; | |
181 } | |
182 | |
183 uint32_t characters_bytes; | |
184 if (!pickle.ReadUInt32(&iter, &characters_bytes)) | |
185 return; | |
186 const char* characters = NULL; | |
187 if (characters_bytes > 0) { | |
188 const uint32_t kMaxCharactersBytes = 1 << 10; | |
189 if (characters_bytes % 2 != 0 || // We expect UTF-16. | |
190 characters_bytes > kMaxCharactersBytes || | |
191 !pickle.ReadBytes(&iter, &characters, characters_bytes)) | |
192 return; | |
193 } | |
194 | |
195 std::string family; | 179 std::string family; |
196 if (!pickle.ReadString(&iter, &family)) | 180 if (!pickle.ReadString(&iter, &family) || |
| 181 !pickle.ReadUInt32(&iter, &requested_style)) |
197 return; | 182 return; |
198 | 183 |
199 std::string result_family; | 184 SkFontConfigInterface::FontIdentity result_identity; |
200 unsigned result_filefaceid; | 185 SkString result_family; |
201 const bool r = font_config_->Match( | 186 SkTypeface::Style result_style; |
202 &result_family, &result_filefaceid, filefaceid_valid, filefaceid, | 187 SkFontConfigInterface* fc = |
203 family, characters, characters_bytes, &is_bold, &is_italic); | 188 SkFontConfigInterface::GetSingletonDirectInterface(); |
| 189 const bool r = fc->matchFamilyName( |
| 190 family.c_str(), static_cast<SkTypeface::Style>(requested_style), |
| 191 &result_identity, &result_family, &result_style); |
204 | 192 |
205 Pickle reply; | 193 Pickle reply; |
206 if (!r) { | 194 if (!r) { |
207 reply.WriteBool(false); | 195 reply.WriteBool(false); |
208 } else { | 196 } else { |
| 197 // Stash away the returned path, so we can give it an ID (index) |
| 198 // which will later be given to us in a request to open the file. |
| 199 int index = FindOrAddPath(result_identity.fString); |
| 200 result_identity.fID = static_cast<uint32_t>(index); |
| 201 |
209 reply.WriteBool(true); | 202 reply.WriteBool(true); |
210 reply.WriteUInt32(result_filefaceid); | 203 skia::WriteSkString(&reply, result_family); |
211 reply.WriteString(result_family); | 204 skia::WriteSkFontIdentity(&reply, result_identity); |
212 reply.WriteBool(is_bold); | 205 reply.WriteUInt32(result_style); |
213 reply.WriteBool(is_italic); | |
214 } | 206 } |
215 SendRendererReply(fds, reply, -1); | 207 SendRendererReply(fds, reply, -1); |
216 } | 208 } |
217 | 209 |
218 void HandleFontOpenRequest(int fd, const Pickle& pickle, PickleIterator iter, | 210 void HandleFontOpenRequest(int fd, const Pickle& pickle, PickleIterator iter, |
219 std::vector<int>& fds) { | 211 std::vector<int>& fds) { |
220 uint32_t filefaceid; | 212 uint32_t index; |
221 if (!pickle.ReadUInt32(&iter, &filefaceid)) | 213 if (!pickle.ReadUInt32(&iter, &index)) |
222 return; | 214 return; |
223 const int result_fd = font_config_->Open(filefaceid); | 215 if (index >= static_cast<uint32_t>(paths_.count())) |
| 216 return; |
| 217 const int result_fd = open(paths_[index]->c_str(), O_RDONLY); |
224 | 218 |
225 Pickle reply; | 219 Pickle reply; |
226 if (result_fd == -1) { | 220 if (result_fd == -1) { |
227 reply.WriteBool(false); | 221 reply.WriteBool(false); |
228 } else { | 222 } else { |
229 reply.WriteBool(true); | 223 reply.WriteBool(true); |
230 } | 224 } |
231 | 225 |
232 SendRendererReply(fds, reply, result_fd); | 226 SendRendererReply(fds, reply, result_fd); |
233 | |
234 if (result_fd >= 0) | |
235 close(result_fd); | |
236 } | 227 } |
237 | 228 |
238 void HandleGetFontFamilyForChars(int fd, const Pickle& pickle, | 229 void HandleGetFontFamilyForChars(int fd, const Pickle& pickle, |
239 PickleIterator iter, | 230 PickleIterator iter, |
240 std::vector<int>& fds) { | 231 std::vector<int>& fds) { |
241 // The other side of this call is | 232 // The other side of this call is |
242 // chrome/renderer/renderer_sandbox_support_linux.cc | 233 // chrome/renderer/renderer_sandbox_support_linux.cc |
243 | 234 |
244 int num_chars; | 235 int num_chars; |
245 if (!pickle.ReadInt(&iter, &num_chars)) | 236 if (!pickle.ReadInt(&iter, &num_chars)) |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 } | 643 } |
653 | 644 |
654 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0) | 645 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0) |
655 PLOG(ERROR) << "sendmsg"; | 646 PLOG(ERROR) << "sendmsg"; |
656 } | 647 } |
657 | 648 |
658 // --------------------------------------------------------------------------- | 649 // --------------------------------------------------------------------------- |
659 | 650 |
660 const int lifeline_fd_; | 651 const int lifeline_fd_; |
661 const int browser_socket_; | 652 const int browser_socket_; |
662 scoped_ptr<FontConfigDirect> font_config_; | |
663 std::vector<std::string> sandbox_cmd_; | 653 std::vector<std::string> sandbox_cmd_; |
664 scoped_ptr<WebKitPlatformSupportImpl> webkit_platform_support_; | 654 scoped_ptr<WebKitPlatformSupportImpl> webkit_platform_support_; |
| 655 SkTDArray<SkString*> paths_; |
665 }; | 656 }; |
666 | 657 |
667 SandboxIPCProcess::~SandboxIPCProcess() { | 658 SandboxIPCProcess::~SandboxIPCProcess() { |
| 659 paths_.deleteAll(); |
668 if (webkit_platform_support_.get()) | 660 if (webkit_platform_support_.get()) |
669 WebKit::shutdown(); | 661 WebKit::shutdown(); |
670 } | 662 } |
671 | 663 |
672 void SandboxIPCProcess::EnsureWebKitInitialized() { | 664 void SandboxIPCProcess::EnsureWebKitInitialized() { |
673 if (webkit_platform_support_.get()) | 665 if (webkit_platform_support_.get()) |
674 return; | 666 return; |
675 webkit_platform_support_.reset(new WebKitPlatformSupportImpl); | 667 webkit_platform_support_.reset(new WebKitPlatformSupportImpl); |
676 WebKit::initializeWithoutV8(webkit_platform_support_.get()); | 668 WebKit::initializeWithoutV8(webkit_platform_support_.get()); |
677 } | 669 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 RenderSandboxHostLinux::~RenderSandboxHostLinux() { | 727 RenderSandboxHostLinux::~RenderSandboxHostLinux() { |
736 if (initialized_) { | 728 if (initialized_) { |
737 if (HANDLE_EINTR(close(renderer_socket_)) < 0) | 729 if (HANDLE_EINTR(close(renderer_socket_)) < 0) |
738 PLOG(ERROR) << "close"; | 730 PLOG(ERROR) << "close"; |
739 if (HANDLE_EINTR(close(childs_lifeline_fd_)) < 0) | 731 if (HANDLE_EINTR(close(childs_lifeline_fd_)) < 0) |
740 PLOG(ERROR) << "close"; | 732 PLOG(ERROR) << "close"; |
741 } | 733 } |
742 } | 734 } |
743 | 735 |
744 } // namespace content | 736 } // namespace content |
OLD | NEW |