| 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 "third_party/skia/include/ports/SkFontConfigInterface.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 "ui/gfx/font_render_params_linux.h" | 37 #include "ui/gfx/font_render_params_linux.h" |
| 38 | 38 |
| 39 using WebKit::WebCString; | 39 using WebKit::WebCString; |
| 40 using WebKit::WebFontInfo; | 40 using WebKit::WebFontInfo; |
| 41 using WebKit::WebUChar; | 41 using WebKit::WebUChar; |
| 42 | 42 |
| 43 namespace content { | 43 namespace content { |
| 44 | 44 |
| 45 // http://code.google.com/p/chromium/wiki/LinuxSandboxIPC | 45 // http://code.google.com/p/chromium/wiki/LinuxSandboxIPC |
| 46 | 46 |
| 47 // BEWARE: code in this file run across *processes* (not just threads). | 47 // BEWARE: code in this file run across *processes* (not just threads). |
| 48 | 48 |
| 49 // This code runs in a child process | 49 // This code runs in a child process |
| 50 class SandboxIPCProcess { | 50 class SandboxIPCProcess { |
| 51 public: | 51 public: |
| 52 // 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 |
| 53 // 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 |
| 54 // 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. |
| 55 // 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 |
| 56 // 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 |
| 57 // object actually services the requests. | 57 // object actually services the requests. |
| 58 // sandbox_cmd: the path of the sandbox executable | 58 // sandbox_cmd: the path of the sandbox executable |
| 59 SandboxIPCProcess(int lifeline_fd, int browser_socket, | 59 SandboxIPCProcess(int lifeline_fd, int browser_socket, |
| 60 std::string sandbox_cmd) | 60 std::string sandbox_cmd) |
| 61 : lifeline_fd_(lifeline_fd), | 61 : lifeline_fd_(lifeline_fd), |
| 62 browser_socket_(browser_socket), | 62 browser_socket_(browser_socket) { |
| 63 font_config_(new FontConfigDirect()) { | |
| 64 if (!sandbox_cmd.empty()) { | 63 if (!sandbox_cmd.empty()) { |
| 65 sandbox_cmd_.push_back(sandbox_cmd); | 64 sandbox_cmd_.push_back(sandbox_cmd); |
| 66 sandbox_cmd_.push_back(base::kFindInodeSwitch); | 65 sandbox_cmd_.push_back(base::kFindInodeSwitch); |
| 67 } | 66 } |
| 68 | 67 |
| 69 // FontConfig doesn't provide a standard property to control subpixel | 68 // FontConfig doesn't provide a standard property to control subpixel |
| 70 // positioning, so we pass the current setting through to WebKit. | 69 // positioning, so we pass the current setting through to WebKit. |
| 71 WebFontInfo::setSubpixelPositioning( | 70 WebFontInfo::setSubpixelPositioning( |
| 72 gfx::GetDefaultWebkitSubpixelPositioning()); | 71 gfx::GetDefaultWebkitSubpixelPositioning()); |
| 73 } | 72 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 // --------------------------------------------------------------------------- | 111 // --------------------------------------------------------------------------- |
| 113 // Requests from the renderer... | 112 // Requests from the renderer... |
| 114 | 113 |
| 115 void HandleRequestFromRenderer(int fd) { | 114 void HandleRequestFromRenderer(int fd) { |
| 116 std::vector<int> fds; | 115 std::vector<int> fds; |
| 117 | 116 |
| 118 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength | 117 // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength |
| 119 // bytes long (this is the largest message type). | 118 // bytes long (this is the largest message type). |
| 120 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC | 119 // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC |
| 121 // error for a maximum length message. | 120 // error for a maximum length message. |
| 122 char buf[FontConfigInterface::kMaxFontFamilyLength + 128]; | 121 char buf[FontConfigIPC::kMaxFontFamilyLength + 128]; |
| 123 | 122 |
| 124 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds); | 123 const ssize_t len = UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds); |
| 125 if (len == -1) { | 124 if (len == -1) { |
| 126 // TODO: should send an error reply, or the sender might block forever. | 125 // TODO: should send an error reply, or the sender might block forever. |
| 127 NOTREACHED() | 126 NOTREACHED() |
| 128 << "Sandbox host message is larger than kMaxFontFamilyLength"; | 127 << "Sandbox host message is larger than kMaxFontFamilyLength"; |
| 129 return; | 128 return; |
| 130 } | 129 } |
| 131 if (fds.empty()) | 130 if (fds.empty()) |
| 132 return; | 131 return; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 158 | 157 |
| 159 error: | 158 error: |
| 160 for (std::vector<int>::const_iterator | 159 for (std::vector<int>::const_iterator |
| 161 i = fds.begin(); i != fds.end(); ++i) { | 160 i = fds.begin(); i != fds.end(); ++i) { |
| 162 close(*i); | 161 close(*i); |
| 163 } | 162 } |
| 164 } | 163 } |
| 165 | 164 |
| 166 void HandleFontMatchRequest(int fd, const Pickle& pickle, PickleIterator iter, | 165 void HandleFontMatchRequest(int fd, const Pickle& pickle, PickleIterator iter, |
| 167 std::vector<int>& fds) { | 166 std::vector<int>& fds) { |
| 168 bool filefaceid_valid; | 167 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; | 168 std::string family; |
| 196 if (!pickle.ReadString(&iter, &family)) | 169 if (!pickle.ReadString(&iter, &family) || |
| 170 !pickle.ReadUInt32(&iter, &requested_style)) |
| 197 return; | 171 return; |
| 198 | 172 |
| 199 std::string result_family; | 173 SkFontConfigInterface::FontIdentity result_identity; |
| 200 unsigned result_filefaceid; | 174 SkString result_family; |
| 201 const bool r = font_config_->Match( | 175 SkTypeface::Style result_style; |
| 202 &result_family, &result_filefaceid, filefaceid_valid, filefaceid, | 176 SkFontConfigInterface* fc = |
| 203 family, characters, characters_bytes, &is_bold, &is_italic); | 177 SkFontConfigInterface::GetSingletonDirectInterface(); |
| 178 const bool r = fc->matchFamilyName( |
| 179 family.c_str(), (SkTypeface::Style)requested_style, |
| 180 &result_identity, &result_family, &result_style); |
| 204 | 181 |
| 205 Pickle reply; | 182 Pickle reply; |
| 206 if (!r) { | 183 if (!r) { |
| 207 reply.WriteBool(false); | 184 reply.WriteBool(false); |
| 208 } else { | 185 } else { |
| 209 reply.WriteBool(true); | 186 reply.WriteBool(true); |
| 210 reply.WriteUInt32(result_filefaceid); | 187 reply.WriteString(std::string(result_family.c_str())); |
| 211 reply.WriteString(result_family); | 188 reply.WriteString(std::string(result_identity.fString.c_str())); |
| 212 reply.WriteBool(is_bold); | 189 reply.WriteUInt32((uint32_t)result_identity.fIntPtr); |
| 213 reply.WriteBool(is_italic); | 190 reply.WriteUInt32(result_style); |
| 214 } | 191 } |
| 215 SendRendererReply(fds, reply, -1); | 192 SendRendererReply(fds, reply, -1); |
| 216 } | 193 } |
| 217 | 194 |
| 218 void HandleFontOpenRequest(int fd, const Pickle& pickle, PickleIterator iter, | 195 void HandleFontOpenRequest(int fd, const Pickle& pickle, PickleIterator iter, |
| 219 std::vector<int>& fds) { | 196 std::vector<int>& fds) { |
| 220 uint32_t filefaceid; | 197 std::string path; |
| 221 if (!pickle.ReadUInt32(&iter, &filefaceid)) | 198 if (!pickle.ReadString(&iter, &path)) |
| 222 return; | 199 return; |
| 223 const int result_fd = font_config_->Open(filefaceid); | 200 const int result_fd = open(path.c_str(), O_RDONLY); |
| 224 | 201 |
| 225 Pickle reply; | 202 Pickle reply; |
| 226 if (result_fd == -1) { | 203 if (result_fd == -1) { |
| 227 reply.WriteBool(false); | 204 reply.WriteBool(false); |
| 228 } else { | 205 } else { |
| 229 reply.WriteBool(true); | 206 reply.WriteBool(true); |
| 230 } | 207 } |
| 231 | 208 |
| 232 SendRendererReply(fds, reply, result_fd); | 209 SendRendererReply(fds, reply, result_fd); |
| 233 | |
| 234 if (result_fd >= 0) | |
| 235 close(result_fd); | |
| 236 } | 210 } |
| 237 | 211 |
| 238 void HandleGetFontFamilyForChars(int fd, const Pickle& pickle, | 212 void HandleGetFontFamilyForChars(int fd, const Pickle& pickle, |
| 239 PickleIterator iter, | 213 PickleIterator iter, |
| 240 std::vector<int>& fds) { | 214 std::vector<int>& fds) { |
| 241 // The other side of this call is | 215 // The other side of this call is |
| 242 // chrome/renderer/renderer_sandbox_support_linux.cc | 216 // chrome/renderer/renderer_sandbox_support_linux.cc |
| 243 | 217 |
| 244 int num_chars; | 218 int num_chars; |
| 245 if (!pickle.ReadInt(&iter, &num_chars)) | 219 if (!pickle.ReadInt(&iter, &num_chars)) |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 } | 626 } |
| 653 | 627 |
| 654 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0) | 628 if (HANDLE_EINTR(sendmsg(fds[0], &msg, MSG_DONTWAIT)) < 0) |
| 655 PLOG(ERROR) << "sendmsg"; | 629 PLOG(ERROR) << "sendmsg"; |
| 656 } | 630 } |
| 657 | 631 |
| 658 // --------------------------------------------------------------------------- | 632 // --------------------------------------------------------------------------- |
| 659 | 633 |
| 660 const int lifeline_fd_; | 634 const int lifeline_fd_; |
| 661 const int browser_socket_; | 635 const int browser_socket_; |
| 662 scoped_ptr<FontConfigDirect> font_config_; | |
| 663 std::vector<std::string> sandbox_cmd_; | 636 std::vector<std::string> sandbox_cmd_; |
| 664 scoped_ptr<WebKitPlatformSupportImpl> webkit_platform_support_; | 637 scoped_ptr<WebKitPlatformSupportImpl> webkit_platform_support_; |
| 665 }; | 638 }; |
| 666 | 639 |
| 667 SandboxIPCProcess::~SandboxIPCProcess() { | 640 SandboxIPCProcess::~SandboxIPCProcess() { |
| 668 if (webkit_platform_support_.get()) | 641 if (webkit_platform_support_.get()) |
| 669 WebKit::shutdown(); | 642 WebKit::shutdown(); |
| 670 } | 643 } |
| 671 | 644 |
| 672 void SandboxIPCProcess::EnsureWebKitInitialized() { | 645 void SandboxIPCProcess::EnsureWebKitInitialized() { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 RenderSandboxHostLinux::~RenderSandboxHostLinux() { | 708 RenderSandboxHostLinux::~RenderSandboxHostLinux() { |
| 736 if (initialized_) { | 709 if (initialized_) { |
| 737 if (HANDLE_EINTR(close(renderer_socket_)) < 0) | 710 if (HANDLE_EINTR(close(renderer_socket_)) < 0) |
| 738 PLOG(ERROR) << "close"; | 711 PLOG(ERROR) << "close"; |
| 739 if (HANDLE_EINTR(close(childs_lifeline_fd_)) < 0) | 712 if (HANDLE_EINTR(close(childs_lifeline_fd_)) < 0) |
| 740 PLOG(ERROR) << "close"; | 713 PLOG(ERROR) << "close"; |
| 741 } | 714 } |
| 742 } | 715 } |
| 743 | 716 |
| 744 } // namespace content | 717 } // namespace content |
| OLD | NEW |