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/skia_utils_base.h" | 33 #include "skia/ext/SkFontHost_fontconfig_direct.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" | |
38 #include "ui/gfx/font_render_params_linux.h" | 37 #include "ui/gfx/font_render_params_linux.h" |
39 | 38 |
40 using WebKit::WebCString; | 39 using WebKit::WebCString; |
41 using WebKit::WebFontInfo; | 40 using WebKit::WebFontInfo; |
42 using WebKit::WebUChar; | 41 using WebKit::WebUChar; |
43 | 42 |
44 namespace content { | 43 namespace content { |
45 | 44 |
46 // http://code.google.com/p/chromium/wiki/LinuxSandboxIPC | 45 // http://code.google.com/p/chromium/wiki/LinuxSandboxIPC |
47 | 46 |
48 // BEWARE: code in this file run across *processes* (not just threads). | 47 // BEWARE: code in this file run across *processes* (not just threads). |
49 | 48 |
50 // This code runs in a child process | 49 // This code runs in a child process |
51 class SandboxIPCProcess { | 50 class SandboxIPCProcess { |
52 public: | 51 public: |
53 // lifeline_fd: this is the read end of a pipe which the browser process | 52 // lifeline_fd: this is the read end of a pipe which the browser process |
54 // holds the other end of. If the browser process dies, its descriptors are | 53 // holds the other end of. If the browser process dies, its descriptors are |
55 // closed and we will noticed an EOF on the pipe. That's our signal to exit. | 54 // closed and we will noticed an EOF on the pipe. That's our signal to exit. |
56 // browser_socket: the browser's end of the sandbox IPC socketpair. From the | 55 // browser_socket: the browser's end of the sandbox IPC socketpair. From the |
57 // point of view of the renderer, it's talking to the browser but this | 56 // point of view of the renderer, it's talking to the browser but this |
58 // object actually services the requests. | 57 // object actually services the requests. |
59 // sandbox_cmd: the path of the sandbox executable | 58 // sandbox_cmd: the path of the sandbox executable |
60 SandboxIPCProcess(int lifeline_fd, int browser_socket, | 59 SandboxIPCProcess(int lifeline_fd, int browser_socket, |
61 std::string sandbox_cmd) | 60 std::string sandbox_cmd) |
62 : lifeline_fd_(lifeline_fd), | 61 : lifeline_fd_(lifeline_fd), |
63 browser_socket_(browser_socket) { | 62 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[FontConfigIPC::kMaxFontFamilyLength + 128]; | 122 char buf[FontConfigInterface::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 | |
176 void HandleFontMatchRequest(int fd, const Pickle& pickle, PickleIterator iter, | 166 void HandleFontMatchRequest(int fd, const Pickle& pickle, PickleIterator iter, |
177 std::vector<int>& fds) { | 167 std::vector<int>& fds) { |
178 uint32_t requested_style; | 168 bool filefaceid_valid; |
| 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 |
179 std::string family; | 195 std::string family; |
180 if (!pickle.ReadString(&iter, &family) || | 196 if (!pickle.ReadString(&iter, &family)) |
181 !pickle.ReadUInt32(&iter, &requested_style)) | |
182 return; | 197 return; |
183 | 198 |
184 SkFontConfigInterface::FontIdentity result_identity; | 199 std::string result_family; |
185 SkString result_family; | 200 unsigned result_filefaceid; |
186 SkTypeface::Style result_style; | 201 const bool r = font_config_->Match( |
187 SkFontConfigInterface* fc = | 202 &result_family, &result_filefaceid, filefaceid_valid, filefaceid, |
188 SkFontConfigInterface::GetSingletonDirectInterface(); | 203 family, characters, characters_bytes, &is_bold, &is_italic); |
189 const bool r = fc->matchFamilyName( | |
190 family.c_str(), static_cast<SkTypeface::Style>(requested_style), | |
191 &result_identity, &result_family, &result_style); | |
192 | 204 |
193 Pickle reply; | 205 Pickle reply; |
194 if (!r) { | 206 if (!r) { |
195 reply.WriteBool(false); | 207 reply.WriteBool(false); |
196 } else { | 208 } 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 | |
202 reply.WriteBool(true); | 209 reply.WriteBool(true); |
203 skia::WriteSkString(&reply, result_family); | 210 reply.WriteUInt32(result_filefaceid); |
204 skia::WriteSkFontIdentity(&reply, result_identity); | 211 reply.WriteString(result_family); |
205 reply.WriteUInt32(result_style); | 212 reply.WriteBool(is_bold); |
| 213 reply.WriteBool(is_italic); |
206 } | 214 } |
207 SendRendererReply(fds, reply, -1); | 215 SendRendererReply(fds, reply, -1); |
208 } | 216 } |
209 | 217 |
210 void HandleFontOpenRequest(int fd, const Pickle& pickle, PickleIterator iter, | 218 void HandleFontOpenRequest(int fd, const Pickle& pickle, PickleIterator iter, |
211 std::vector<int>& fds) { | 219 std::vector<int>& fds) { |
212 uint32_t index; | 220 uint32_t filefaceid; |
213 if (!pickle.ReadUInt32(&iter, &index)) | 221 if (!pickle.ReadUInt32(&iter, &filefaceid)) |
214 return; | 222 return; |
215 if (index >= static_cast<uint32_t>(paths_.count())) | 223 const int result_fd = font_config_->Open(filefaceid); |
216 return; | |
217 const int result_fd = open(paths_[index]->c_str(), O_RDONLY); | |
218 | 224 |
219 Pickle reply; | 225 Pickle reply; |
220 if (result_fd == -1) { | 226 if (result_fd == -1) { |
221 reply.WriteBool(false); | 227 reply.WriteBool(false); |
222 } else { | 228 } else { |
223 reply.WriteBool(true); | 229 reply.WriteBool(true); |
224 } | 230 } |
225 | 231 |
226 SendRendererReply(fds, reply, result_fd); | 232 SendRendererReply(fds, reply, result_fd); |
| 233 |
| 234 if (result_fd >= 0) |
| 235 close(result_fd); |
227 } | 236 } |
228 | 237 |
229 void HandleGetFontFamilyForChars(int fd, const Pickle& pickle, | 238 void HandleGetFontFamilyForChars(int fd, const Pickle& pickle, |
230 PickleIterator iter, | 239 PickleIterator iter, |
231 std::vector<int>& fds) { | 240 std::vector<int>& fds) { |
232 // The other side of this call is | 241 // The other side of this call is |
233 // chrome/renderer/renderer_sandbox_support_linux.cc | 242 // chrome/renderer/renderer_sandbox_support_linux.cc |
234 | 243 |
235 int num_chars; | 244 int num_chars; |
236 if (!pickle.ReadInt(&iter, &num_chars)) | 245 if (!pickle.ReadInt(&iter, &num_chars)) |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 } | 652 } |
644 | 653 |
645 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0) | 654 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0) |
646 PLOG(ERROR) << "sendmsg"; | 655 PLOG(ERROR) << "sendmsg"; |
647 } | 656 } |
648 | 657 |
649 // --------------------------------------------------------------------------- | 658 // --------------------------------------------------------------------------- |
650 | 659 |
651 const int lifeline_fd_; | 660 const int lifeline_fd_; |
652 const int browser_socket_; | 661 const int browser_socket_; |
| 662 scoped_ptr<FontConfigDirect> font_config_; |
653 std::vector<std::string> sandbox_cmd_; | 663 std::vector<std::string> sandbox_cmd_; |
654 scoped_ptr<WebKitPlatformSupportImpl> webkit_platform_support_; | 664 scoped_ptr<WebKitPlatformSupportImpl> webkit_platform_support_; |
655 SkTDArray<SkString*> paths_; | |
656 }; | 665 }; |
657 | 666 |
658 SandboxIPCProcess::~SandboxIPCProcess() { | 667 SandboxIPCProcess::~SandboxIPCProcess() { |
659 paths_.deleteAll(); | |
660 if (webkit_platform_support_.get()) | 668 if (webkit_platform_support_.get()) |
661 WebKit::shutdown(); | 669 WebKit::shutdown(); |
662 } | 670 } |
663 | 671 |
664 void SandboxIPCProcess::EnsureWebKitInitialized() { | 672 void SandboxIPCProcess::EnsureWebKitInitialized() { |
665 if (webkit_platform_support_.get()) | 673 if (webkit_platform_support_.get()) |
666 return; | 674 return; |
667 webkit_platform_support_.reset(new WebKitPlatformSupportImpl); | 675 webkit_platform_support_.reset(new WebKitPlatformSupportImpl); |
668 WebKit::initializeWithoutV8(webkit_platform_support_.get()); | 676 WebKit::initializeWithoutV8(webkit_platform_support_.get()); |
669 } | 677 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 RenderSandboxHostLinux::~RenderSandboxHostLinux() { | 735 RenderSandboxHostLinux::~RenderSandboxHostLinux() { |
728 if (initialized_) { | 736 if (initialized_) { |
729 if (HANDLE_EINTR(close(renderer_socket_)) < 0) | 737 if (HANDLE_EINTR(close(renderer_socket_)) < 0) |
730 PLOG(ERROR) << "close"; | 738 PLOG(ERROR) << "close"; |
731 if (HANDLE_EINTR(close(childs_lifeline_fd_)) < 0) | 739 if (HANDLE_EINTR(close(childs_lifeline_fd_)) < 0) |
732 PLOG(ERROR) << "close"; | 740 PLOG(ERROR) << "close"; |
733 } | 741 } |
734 } | 742 } |
735 | 743 |
736 } // namespace content | 744 } // namespace content |
OLD | NEW |