diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-15 18:15:08 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-15 18:15:08 +0000 |
commit | abe3ad93b1996ad1b1aff121dbce6be533e579c3 (patch) | |
tree | 635542dd62d6b7df4c05a3c39f2c737730e23376 /skia/ext/SkFontHost_fontconfig_ipc.cpp | |
parent | 89d156b666af4d4f4c83579be31e9092155bbaf7 (diff) | |
download | chromium_src-abe3ad93b1996ad1b1aff121dbce6be533e579c3.zip chromium_src-abe3ad93b1996ad1b1aff121dbce6be533e579c3.tar.gz chromium_src-abe3ad93b1996ad1b1aff121dbce6be533e579c3.tar.bz2 |
Linux: Add support for chrooted renderers.
http://code.google.com/p/chromium/wiki/LinuxSandboxIPC
Without filesystem access from the renderers, we need another way of
dealing with fontconfig and font loading.
This add support for:
* An "SBX_D" environment variable in the renderers which is used to
signal the end of dynamic linking so that the chroot can be
enforced.
* A sandbox_host process, running outside the sandbox, to deal with
fontconfig requests from the renderers. See the wiki page for
the reasoning behind making it a separate process.
* A new, custom SkFontHost for Skia. Because this is Chrome
specific, it will live outside the upstream Skia tree. This
FontHost can be configured either to drive fontconfig directly
(for the browser process and for any unsandboxed renderers) or to
use an IPC system. Since the same SkFontHost has to be linked into
both the browser and renderer (they are the same binary), this
switch has to be made at run time.
Sandbox IPC calls are rare (a couple of dozen at page load time) and
add about 50us of overhead for each call.
(Reland of r17575 which was reverted in r17577)
http://codereview.chromium.org/112074
BUG=8081
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18405 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/ext/SkFontHost_fontconfig_ipc.cpp')
-rw-r--r-- | skia/ext/SkFontHost_fontconfig_ipc.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/skia/ext/SkFontHost_fontconfig_ipc.cpp b/skia/ext/SkFontHost_fontconfig_ipc.cpp new file mode 100644 index 0000000..1705aed --- /dev/null +++ b/skia/ext/SkFontHost_fontconfig_ipc.cpp @@ -0,0 +1,144 @@ +/* libs/graphics/ports/SkFontHost_fontconfig_direct.cpp +** +** Copyright 2009, Google Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +// http://code.google.com/p/chromium/wiki/LinuxSandboxIPC + +#include "SkFontHost_fontconfig_ipc.h" + +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/uio.h> + +#include "base/pickle.h" +#include "base/unix_domain_socket_posix.h" + +FontConfigIPC::FontConfigIPC(int fd) + : fd_(fd) { +} + +FontConfigIPC::~FontConfigIPC() { + close(fd_); +} + +static ssize_t SyncIPC(int fd, uint8_t* reply, unsigned reply_len, int* result_fd, + const Pickle& request) { + int fds[2]; + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) == -1) + return false; + + std::vector<int> fd_vector; + fd_vector.push_back(fds[1]); + if (!base::SendMsg(fd, request.data(), request.size(), fd_vector)) { + close(fds[0]); + close(fds[1]); + return -1; + } + close(fds[1]); + + fd_vector.clear(); + const ssize_t r = base::RecvMsg(fds[0], reply, reply_len, &fd_vector); + close(fds[0]); + if (r == -1) + return -1; + + if ((fd_vector.size() > 0 && result_fd == NULL) || fd_vector.size() > 1) { + for (std::vector<int>::const_iterator + i = fd_vector.begin(); i != fd_vector.end(); ++i) { + close(*i); + } + + return -1; + } + + if (result_fd) { + if (fd_vector.size() == 0) { + *result_fd = -1; + } else { + *result_fd = fd_vector[0]; + } + } + + return r; +} + +bool FontConfigIPC::Match(std::string* result_family, + unsigned* result_fileid, + bool fileid_valid, unsigned fileid, + const std::string& family, int is_bold, + int is_italic) { + Pickle request; + request.WriteInt(METHOD_MATCH); + request.WriteBool(fileid_valid); + if (fileid_valid) + request.WriteUInt32(fileid); + request.WriteBool(is_bold); + request.WriteBool(is_italic); + request.WriteString(family); + + uint8_t reply_buf[512]; + const ssize_t r = SyncIPC(fd_, reply_buf, sizeof(reply_buf), NULL, request); + if (r == -1) + return false; + + Pickle reply(reinterpret_cast<char*>(reply_buf), r); + void* iter = NULL; + bool result; + if (!reply.ReadBool(&iter, &result)) + return false; + if (!result) + return false; + + uint32_t reply_fileid; + std::string reply_family; + if (!reply.ReadUInt32(&iter, &reply_fileid) || + !reply.ReadString(&iter, &reply_family)) { + return false; + } + + *result_fileid = reply_fileid; + if (result_family) + *result_family = reply_family; + + return true; +} + +int FontConfigIPC::Open(unsigned fileid) { + Pickle request; + request.WriteInt(METHOD_OPEN); + request.WriteUInt32(fileid); + + int result_fd = -1; + uint8_t reply_buf[256]; + const ssize_t r = SyncIPC(fd_, reply_buf, sizeof(reply_buf), &result_fd, request); + + if (r == -1) + return -1; + + Pickle reply(reinterpret_cast<char*>(reply_buf), r); + bool result; + void* iter = NULL; + if (!reply.ReadBool(&iter, &result) || + !result) { + if (result_fd) + close(result_fd); + return -1; + } + + return result_fd; +} |