| OLD | NEW |
| 1 // Copyright (c) 2011 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 <unistd.h> | 10 #include <unistd.h> |
| 11 #include <sys/uio.h> | 11 #include <sys/uio.h> |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 if (len == -1) { | 117 if (len == -1) { |
| 118 // TODO: should send an error reply, or the sender might block forever. | 118 // TODO: should send an error reply, or the sender might block forever. |
| 119 NOTREACHED() | 119 NOTREACHED() |
| 120 << "Sandbox host message is larger than kMaxFontFamilyLength"; | 120 << "Sandbox host message is larger than kMaxFontFamilyLength"; |
| 121 return; | 121 return; |
| 122 } | 122 } |
| 123 if (fds.empty()) | 123 if (fds.empty()) |
| 124 return; | 124 return; |
| 125 | 125 |
| 126 Pickle pickle(buf, len); | 126 Pickle pickle(buf, len); |
| 127 void* iter = NULL; | 127 PickleIterator iter(pickle); |
| 128 | 128 |
| 129 int kind; | 129 int kind; |
| 130 if (!pickle.ReadInt(&iter, &kind)) | 130 if (!pickle.ReadInt(&iter, &kind)) |
| 131 goto error; | 131 goto error; |
| 132 | 132 |
| 133 if (kind == FontConfigIPC::METHOD_MATCH) { | 133 if (kind == FontConfigIPC::METHOD_MATCH) { |
| 134 HandleFontMatchRequest(fd, pickle, iter, fds); | 134 HandleFontMatchRequest(fd, pickle, iter, fds); |
| 135 } else if (kind == FontConfigIPC::METHOD_OPEN) { | 135 } else if (kind == FontConfigIPC::METHOD_OPEN) { |
| 136 HandleFontOpenRequest(fd, pickle, iter, fds); | 136 HandleFontOpenRequest(fd, pickle, iter, fds); |
| 137 } else if (kind == LinuxSandbox::METHOD_GET_FONT_FAMILY_FOR_CHARS) { | 137 } else if (kind == LinuxSandbox::METHOD_GET_FONT_FAMILY_FOR_CHARS) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 148 HandleMatchWithFallback(fd, pickle, iter, fds); | 148 HandleMatchWithFallback(fd, pickle, iter, fds); |
| 149 } | 149 } |
| 150 | 150 |
| 151 error: | 151 error: |
| 152 for (std::vector<int>::const_iterator | 152 for (std::vector<int>::const_iterator |
| 153 i = fds.begin(); i != fds.end(); ++i) { | 153 i = fds.begin(); i != fds.end(); ++i) { |
| 154 close(*i); | 154 close(*i); |
| 155 } | 155 } |
| 156 } | 156 } |
| 157 | 157 |
| 158 void HandleFontMatchRequest(int fd, const Pickle& pickle, void* iter, | 158 void HandleFontMatchRequest(int fd, const Pickle& pickle, PickleIterator iter, |
| 159 std::vector<int>& fds) { | 159 std::vector<int>& fds) { |
| 160 bool filefaceid_valid; | 160 bool filefaceid_valid; |
| 161 uint32_t filefaceid; | 161 uint32_t filefaceid; |
| 162 | 162 |
| 163 if (!pickle.ReadBool(&iter, &filefaceid_valid)) | 163 if (!pickle.ReadBool(&iter, &filefaceid_valid)) |
| 164 return; | 164 return; |
| 165 if (filefaceid_valid) { | 165 if (filefaceid_valid) { |
| 166 if (!pickle.ReadUInt32(&iter, &filefaceid)) | 166 if (!pickle.ReadUInt32(&iter, &filefaceid)) |
| 167 return; | 167 return; |
| 168 } | 168 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 } else { | 200 } else { |
| 201 reply.WriteBool(true); | 201 reply.WriteBool(true); |
| 202 reply.WriteUInt32(result_filefaceid); | 202 reply.WriteUInt32(result_filefaceid); |
| 203 reply.WriteString(result_family); | 203 reply.WriteString(result_family); |
| 204 reply.WriteBool(is_bold); | 204 reply.WriteBool(is_bold); |
| 205 reply.WriteBool(is_italic); | 205 reply.WriteBool(is_italic); |
| 206 } | 206 } |
| 207 SendRendererReply(fds, reply, -1); | 207 SendRendererReply(fds, reply, -1); |
| 208 } | 208 } |
| 209 | 209 |
| 210 void HandleFontOpenRequest(int fd, const Pickle& pickle, void* iter, | 210 void HandleFontOpenRequest(int fd, const Pickle& pickle, PickleIterator iter, |
| 211 std::vector<int>& fds) { | 211 std::vector<int>& fds) { |
| 212 uint32_t filefaceid; | 212 uint32_t filefaceid; |
| 213 if (!pickle.ReadUInt32(&iter, &filefaceid)) | 213 if (!pickle.ReadUInt32(&iter, &filefaceid)) |
| 214 return; | 214 return; |
| 215 const int result_fd = font_config_->Open(filefaceid); | 215 const int result_fd = font_config_->Open(filefaceid); |
| 216 | 216 |
| 217 Pickle reply; | 217 Pickle reply; |
| 218 if (result_fd == -1) { | 218 if (result_fd == -1) { |
| 219 reply.WriteBool(false); | 219 reply.WriteBool(false); |
| 220 } else { | 220 } else { |
| 221 reply.WriteBool(true); | 221 reply.WriteBool(true); |
| 222 } | 222 } |
| 223 | 223 |
| 224 SendRendererReply(fds, reply, result_fd); | 224 SendRendererReply(fds, reply, result_fd); |
| 225 | 225 |
| 226 if (result_fd >= 0) | 226 if (result_fd >= 0) |
| 227 close(result_fd); | 227 close(result_fd); |
| 228 } | 228 } |
| 229 | 229 |
| 230 void HandleGetFontFamilyForChars(int fd, const Pickle& pickle, void* iter, | 230 void HandleGetFontFamilyForChars(int fd, const Pickle& pickle, |
| 231 PickleIterator iter, |
| 231 std::vector<int>& fds) { | 232 std::vector<int>& fds) { |
| 232 // The other side of this call is | 233 // The other side of this call is |
| 233 // chrome/renderer/renderer_sandbox_support_linux.cc | 234 // chrome/renderer/renderer_sandbox_support_linux.cc |
| 234 | 235 |
| 235 int num_chars; | 236 int num_chars; |
| 236 if (!pickle.ReadInt(&iter, &num_chars)) | 237 if (!pickle.ReadInt(&iter, &num_chars)) |
| 237 return; | 238 return; |
| 238 | 239 |
| 239 // We don't want a corrupt renderer asking too much of us, it might | 240 // We don't want a corrupt renderer asking too much of us, it might |
| 240 // overflow later in the code. | 241 // overflow later in the code. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 271 if (family.name.data()) { | 272 if (family.name.data()) { |
| 272 reply.WriteString(family.name.data()); | 273 reply.WriteString(family.name.data()); |
| 273 } else { | 274 } else { |
| 274 reply.WriteString(""); | 275 reply.WriteString(""); |
| 275 } | 276 } |
| 276 reply.WriteBool(family.isBold); | 277 reply.WriteBool(family.isBold); |
| 277 reply.WriteBool(family.isItalic); | 278 reply.WriteBool(family.isItalic); |
| 278 SendRendererReply(fds, reply, -1); | 279 SendRendererReply(fds, reply, -1); |
| 279 } | 280 } |
| 280 | 281 |
| 281 void HandleGetStyleForStrike(int fd, const Pickle& pickle, void* iter, | 282 void HandleGetStyleForStrike(int fd, const Pickle& pickle, |
| 283 PickleIterator iter, |
| 282 std::vector<int>& fds) { | 284 std::vector<int>& fds) { |
| 283 std::string family; | 285 std::string family; |
| 284 int sizeAndStyle; | 286 int sizeAndStyle; |
| 285 | 287 |
| 286 if (!pickle.ReadString(&iter, &family) || | 288 if (!pickle.ReadString(&iter, &family) || |
| 287 !pickle.ReadInt(&iter, &sizeAndStyle)) { | 289 !pickle.ReadInt(&iter, &sizeAndStyle)) { |
| 288 return; | 290 return; |
| 289 } | 291 } |
| 290 | 292 |
| 291 EnsureWebKitInitialized(); | 293 EnsureWebKitInitialized(); |
| 292 WebKit::WebFontRenderStyle style; | 294 WebKit::WebFontRenderStyle style; |
| 293 WebFontInfo::renderStyleForStrike(family.c_str(), sizeAndStyle, &style); | 295 WebFontInfo::renderStyleForStrike(family.c_str(), sizeAndStyle, &style); |
| 294 | 296 |
| 295 Pickle reply; | 297 Pickle reply; |
| 296 reply.WriteInt(style.useBitmaps); | 298 reply.WriteInt(style.useBitmaps); |
| 297 reply.WriteInt(style.useAutoHint); | 299 reply.WriteInt(style.useAutoHint); |
| 298 reply.WriteInt(style.useHinting); | 300 reply.WriteInt(style.useHinting); |
| 299 reply.WriteInt(style.hintStyle); | 301 reply.WriteInt(style.hintStyle); |
| 300 reply.WriteInt(style.useAntiAlias); | 302 reply.WriteInt(style.useAntiAlias); |
| 301 reply.WriteInt(style.useSubpixel); | 303 reply.WriteInt(style.useSubpixel); |
| 302 | 304 |
| 303 SendRendererReply(fds, reply, -1); | 305 SendRendererReply(fds, reply, -1); |
| 304 } | 306 } |
| 305 | 307 |
| 306 void HandleLocaltime(int fd, const Pickle& pickle, void* iter, | 308 void HandleLocaltime(int fd, const Pickle& pickle, PickleIterator iter, |
| 307 std::vector<int>& fds) { | 309 std::vector<int>& fds) { |
| 308 // The other side of this call is in zygote_main_linux.cc | 310 // The other side of this call is in zygote_main_linux.cc |
| 309 | 311 |
| 310 std::string time_string; | 312 std::string time_string; |
| 311 if (!pickle.ReadString(&iter, &time_string) || | 313 if (!pickle.ReadString(&iter, &time_string) || |
| 312 time_string.size() != sizeof(time_t)) { | 314 time_string.size() != sizeof(time_t)) { |
| 313 return; | 315 return; |
| 314 } | 316 } |
| 315 | 317 |
| 316 time_t time; | 318 time_t time; |
| 317 memcpy(&time, time_string.data(), sizeof(time)); | 319 memcpy(&time, time_string.data(), sizeof(time)); |
| 318 // We use localtime here because we need the tm_zone field to be filled | 320 // We use localtime here because we need the tm_zone field to be filled |
| 319 // out. Since we are a single-threaded process, this is safe. | 321 // out. Since we are a single-threaded process, this is safe. |
| 320 const struct tm* expanded_time = localtime(&time); | 322 const struct tm* expanded_time = localtime(&time); |
| 321 | 323 |
| 322 std::string result_string; | 324 std::string result_string; |
| 323 const char* time_zone_string = ""; | 325 const char* time_zone_string = ""; |
| 324 if (expanded_time != NULL) { | 326 if (expanded_time != NULL) { |
| 325 result_string = std::string(reinterpret_cast<const char*>(expanded_time), | 327 result_string = std::string(reinterpret_cast<const char*>(expanded_time), |
| 326 sizeof(struct tm)); | 328 sizeof(struct tm)); |
| 327 time_zone_string = expanded_time->tm_zone; | 329 time_zone_string = expanded_time->tm_zone; |
| 328 } | 330 } |
| 329 | 331 |
| 330 Pickle reply; | 332 Pickle reply; |
| 331 reply.WriteString(result_string); | 333 reply.WriteString(result_string); |
| 332 reply.WriteString(time_zone_string); | 334 reply.WriteString(time_zone_string); |
| 333 SendRendererReply(fds, reply, -1); | 335 SendRendererReply(fds, reply, -1); |
| 334 } | 336 } |
| 335 | 337 |
| 336 void HandleGetChildWithInode(int fd, const Pickle& pickle, void* iter, | 338 void HandleGetChildWithInode(int fd, const Pickle& pickle, |
| 339 PickleIterator iter, |
| 337 std::vector<int>& fds) { | 340 std::vector<int>& fds) { |
| 338 // The other side of this call is in zygote_main_linux.cc | 341 // The other side of this call is in zygote_main_linux.cc |
| 339 if (sandbox_cmd_.empty()) { | 342 if (sandbox_cmd_.empty()) { |
| 340 LOG(ERROR) << "Not in the sandbox, this should not be called"; | 343 LOG(ERROR) << "Not in the sandbox, this should not be called"; |
| 341 return; | 344 return; |
| 342 } | 345 } |
| 343 | 346 |
| 344 uint64_t inode; | 347 uint64_t inode; |
| 345 if (!pickle.ReadUInt64(&iter, &inode)) | 348 if (!pickle.ReadUInt64(&iter, &inode)) |
| 346 return; | 349 return; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 358 // Even though the pid is invalid, we still need to reply to the zygote | 361 // Even though the pid is invalid, we still need to reply to the zygote |
| 359 // and not just return here. | 362 // and not just return here. |
| 360 LOG(ERROR) << "Could not get pid"; | 363 LOG(ERROR) << "Could not get pid"; |
| 361 } | 364 } |
| 362 | 365 |
| 363 Pickle reply; | 366 Pickle reply; |
| 364 reply.WriteInt(pid); | 367 reply.WriteInt(pid); |
| 365 SendRendererReply(fds, reply, -1); | 368 SendRendererReply(fds, reply, -1); |
| 366 } | 369 } |
| 367 | 370 |
| 368 void HandleMakeSharedMemorySegment(int fd, const Pickle& pickle, void* iter, | 371 void HandleMakeSharedMemorySegment(int fd, const Pickle& pickle, |
| 372 PickleIterator iter, |
| 369 std::vector<int>& fds) { | 373 std::vector<int>& fds) { |
| 370 base::SharedMemoryCreateOptions options; | 374 base::SharedMemoryCreateOptions options; |
| 371 if (!pickle.ReadUInt32(&iter, &options.size)) | 375 if (!pickle.ReadUInt32(&iter, &options.size)) |
| 372 return; | 376 return; |
| 373 if (!pickle.ReadBool(&iter, &options.executable)) | 377 if (!pickle.ReadBool(&iter, &options.executable)) |
| 374 return; | 378 return; |
| 375 int shm_fd = -1; | 379 int shm_fd = -1; |
| 376 base::SharedMemory shm; | 380 base::SharedMemory shm; |
| 377 if (shm.Create(options)) | 381 if (shm.Create(options)) |
| 378 shm_fd = shm.handle().fd; | 382 shm_fd = shm.handle().fd; |
| 379 Pickle reply; | 383 Pickle reply; |
| 380 SendRendererReply(fds, reply, shm_fd); | 384 SendRendererReply(fds, reply, shm_fd); |
| 381 } | 385 } |
| 382 | 386 |
| 383 void HandleMatchWithFallback(int fd, const Pickle& pickle, void* iter, | 387 void HandleMatchWithFallback(int fd, const Pickle& pickle, |
| 388 PickleIterator iter, |
| 384 std::vector<int>& fds) { | 389 std::vector<int>& fds) { |
| 385 // Unlike the other calls, for which we are an indirection in front of | 390 // Unlike the other calls, for which we are an indirection in front of |
| 386 // WebKit or Skia, this call is always made via this sandbox helper | 391 // WebKit or Skia, this call is always made via this sandbox helper |
| 387 // process. Therefore the fontconfig code goes in here directly. | 392 // process. Therefore the fontconfig code goes in here directly. |
| 388 | 393 |
| 389 std::string face; | 394 std::string face; |
| 390 bool is_bold, is_italic; | 395 bool is_bold, is_italic; |
| 391 uint32 charset; | 396 uint32 charset; |
| 392 | 397 |
| 393 if (!pickle.ReadString(&iter, &face) || | 398 if (!pickle.ReadString(&iter, &face) || |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 } | 722 } |
| 718 | 723 |
| 719 RenderSandboxHostLinux::~RenderSandboxHostLinux() { | 724 RenderSandboxHostLinux::~RenderSandboxHostLinux() { |
| 720 if (initialized_) { | 725 if (initialized_) { |
| 721 if (HANDLE_EINTR(close(renderer_socket_)) < 0) | 726 if (HANDLE_EINTR(close(renderer_socket_)) < 0) |
| 722 PLOG(ERROR) << "close"; | 727 PLOG(ERROR) << "close"; |
| 723 if (HANDLE_EINTR(close(childs_lifeline_fd_)) < 0) | 728 if (HANDLE_EINTR(close(childs_lifeline_fd_)) < 0) |
| 724 PLOG(ERROR) << "close"; | 729 PLOG(ERROR) << "close"; |
| 725 } | 730 } |
| 726 } | 731 } |
| OLD | NEW |