Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(497)

Side by Side Diff: content/zygote/zygote_main_linux.cc

Issue 10736017: Share the zygote's fopen overrides with nacl_helper. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/content_browser.gypi ('k') | sandbox/linux/services/libc_urandom_override.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <dlfcn.h> 5 #include <dlfcn.h>
6 #include <fcntl.h> 6 #include <fcntl.h>
7 #include <pthread.h> 7 #include <pthread.h>
8 #include <stdio.h> 8 #include <stdio.h>
9 #include <sys/socket.h> 9 #include <sys/socket.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
(...skipping 18 matching lines...) Expand all
29 #include "content/common/font_config_ipc_linux.h" 29 #include "content/common/font_config_ipc_linux.h"
30 #include "content/common/pepper_plugin_registry.h" 30 #include "content/common/pepper_plugin_registry.h"
31 #include "content/common/sandbox_methods_linux.h" 31 #include "content/common/sandbox_methods_linux.h"
32 #include "content/common/seccomp_sandbox.h" 32 #include "content/common/seccomp_sandbox.h"
33 #include "content/common/zygote_commands_linux.h" 33 #include "content/common/zygote_commands_linux.h"
34 #include "content/public/common/content_switches.h" 34 #include "content/public/common/content_switches.h"
35 #include "content/public/common/main_function_params.h" 35 #include "content/public/common/main_function_params.h"
36 #include "content/public/common/sandbox_linux.h" 36 #include "content/public/common/sandbox_linux.h"
37 #include "content/public/common/zygote_fork_delegate_linux.h" 37 #include "content/public/common/zygote_fork_delegate_linux.h"
38 #include "content/zygote/zygote_linux.h" 38 #include "content/zygote/zygote_linux.h"
39 #include "sandbox/linux/services/libc_urandom_override.h"
39 #include "skia/ext/SkFontHost_fontconfig_control.h" 40 #include "skia/ext/SkFontHost_fontconfig_control.h"
40 #include "unicode/timezone.h" 41 #include "unicode/timezone.h"
41 42
42 #if defined(OS_LINUX) 43 #if defined(OS_LINUX)
43 #include <sys/epoll.h> 44 #include <sys/epoll.h>
44 #include <sys/prctl.h> 45 #include <sys/prctl.h>
45 #include <sys/signal.h> 46 #include <sys/signal.h>
46 #else 47 #else
47 #include <signal.h> 48 #include <signal.h>
48 #endif 49 #endif
49 50
50 namespace content { 51 namespace content {
51 52
52 // See http://code.google.com/p/chromium/wiki/LinuxZygote 53 // See http://code.google.com/p/chromium/wiki/LinuxZygote
53 54
54 static const char kUrandomDevPath[] = "/dev/urandom";
55
56 // The SUID sandbox sets this environment variable to a file descriptor 55 // The SUID sandbox sets this environment variable to a file descriptor
57 // over which we can signal that we have completed our startup and can be 56 // over which we can signal that we have completed our startup and can be
58 // chrooted. 57 // chrooted.
59 static const char kSUIDSandboxVar[] = "SBX_D"; 58 static const char kSUIDSandboxVar[] = "SBX_D";
60 59
61 // With SELinux we can carve out a precise sandbox, so we don't have to play 60 // With SELinux we can carve out a precise sandbox, so we don't have to play
62 // with intercepting libc calls. 61 // with intercepting libc calls.
63 #if !defined(CHROMIUM_SELINUX) 62 #if !defined(CHROMIUM_SELINUX)
64 63
65 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, 64 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 // Our first attempt involved some assembly to patch the GOT of the current 133 // Our first attempt involved some assembly to patch the GOT of the current
135 // module. This worked, but was platform specific and doesn't catch the case 134 // module. This worked, but was platform specific and doesn't catch the case
136 // where a library makes a call rather than current module. 135 // where a library makes a call rather than current module.
137 // 136 //
138 // We also considered patching the function in place, but this would again by 137 // We also considered patching the function in place, but this would again by
139 // platform specific and the above technique seems to work well enough. 138 // platform specific and the above technique seems to work well enough.
140 139
141 typedef struct tm* (*LocaltimeFunction)(const time_t* timep); 140 typedef struct tm* (*LocaltimeFunction)(const time_t* timep);
142 typedef struct tm* (*LocaltimeRFunction)(const time_t* timep, 141 typedef struct tm* (*LocaltimeRFunction)(const time_t* timep,
143 struct tm* result); 142 struct tm* result);
144 typedef FILE* (*FopenFunction)(const char* path, const char* mode);
145 typedef int (*XstatFunction)(int version, const char *path, struct stat *buf);
146 typedef int (*Xstat64Function)(int version, const char *path,
147 struct stat64 *buf);
148 143
149 static pthread_once_t g_libc_localtime_funcs_guard = PTHREAD_ONCE_INIT; 144 static pthread_once_t g_libc_localtime_funcs_guard = PTHREAD_ONCE_INIT;
150 static LocaltimeFunction g_libc_localtime; 145 static LocaltimeFunction g_libc_localtime;
151 static LocaltimeFunction g_libc_localtime64; 146 static LocaltimeFunction g_libc_localtime64;
152 static LocaltimeRFunction g_libc_localtime_r; 147 static LocaltimeRFunction g_libc_localtime_r;
153 static LocaltimeRFunction g_libc_localtime64_r; 148 static LocaltimeRFunction g_libc_localtime64_r;
154 149
155 // http://crbug.com/123263, see below.
156 #if !defined(ADDRESS_SANITIZER)
157 static pthread_once_t g_libc_file_io_funcs_guard = PTHREAD_ONCE_INIT;
158 static FopenFunction g_libc_fopen;
159 static FopenFunction g_libc_fopen64;
160 static XstatFunction g_libc_xstat;
161 static Xstat64Function g_libc_xstat64;
162 #endif
163
164 static void InitLibcLocaltimeFunctions() { 150 static void InitLibcLocaltimeFunctions() {
165 g_libc_localtime = reinterpret_cast<LocaltimeFunction>( 151 g_libc_localtime = reinterpret_cast<LocaltimeFunction>(
166 dlsym(RTLD_NEXT, "localtime")); 152 dlsym(RTLD_NEXT, "localtime"));
167 g_libc_localtime64 = reinterpret_cast<LocaltimeFunction>( 153 g_libc_localtime64 = reinterpret_cast<LocaltimeFunction>(
168 dlsym(RTLD_NEXT, "localtime64")); 154 dlsym(RTLD_NEXT, "localtime64"));
169 g_libc_localtime_r = reinterpret_cast<LocaltimeRFunction>( 155 g_libc_localtime_r = reinterpret_cast<LocaltimeRFunction>(
170 dlsym(RTLD_NEXT, "localtime_r")); 156 dlsym(RTLD_NEXT, "localtime_r"));
171 g_libc_localtime64_r = reinterpret_cast<LocaltimeRFunction>( 157 g_libc_localtime64_r = reinterpret_cast<LocaltimeRFunction>(
172 dlsym(RTLD_NEXT, "localtime64_r")); 158 dlsym(RTLD_NEXT, "localtime64_r"));
173 159
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 if (g_am_zygote_or_renderer) { 245 if (g_am_zygote_or_renderer) {
260 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); 246 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0);
261 return result; 247 return result;
262 } else { 248 } else {
263 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, 249 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
264 InitLibcLocaltimeFunctions)); 250 InitLibcLocaltimeFunctions));
265 return g_libc_localtime64_r(timep, result); 251 return g_libc_localtime64_r(timep, result);
266 } 252 }
267 } 253 }
268 254
269 // TODO(sergeyu): Currently this code doesn't work properly under ASAN
270 // - it crashes content_unittests. Make sure it works properly and
271 // enable it here. http://crbug.com/123263
272 #if !defined(ADDRESS_SANITIZER)
273
274 static void InitLibcFileIOFunctions() {
275 g_libc_fopen = reinterpret_cast<FopenFunction>(
276 dlsym(RTLD_NEXT, "fopen"));
277 g_libc_fopen64 = reinterpret_cast<FopenFunction>(
278 dlsym(RTLD_NEXT, "fopen64"));
279
280 if (!g_libc_fopen) {
281 LOG(FATAL) << "Failed to get fopen() from libc.";
282 } else if (!g_libc_fopen64) {
283 #if !defined(OS_OPENBSD) && !defined(OS_FREEBSD)
284 LOG(WARNING) << "Failed to get fopen64() from libc. Using fopen() instead.";
285 #endif // !defined(OS_OPENBSD) && !defined(OS_FREEBSD)
286 g_libc_fopen64 = g_libc_fopen;
287 }
288
289 // TODO(sergeyu): This works only on systems with glibc. Fix it to
290 // work properly on other systems if necessary.
291 g_libc_xstat = reinterpret_cast<XstatFunction>(
292 dlsym(RTLD_NEXT, "__xstat"));
293 g_libc_xstat64 = reinterpret_cast<Xstat64Function>(
294 dlsym(RTLD_NEXT, "__xstat64"));
295
296 if (!g_libc_xstat) {
297 LOG(FATAL) << "Failed to get __xstat() from libc.";
298 }
299 if (!g_libc_xstat64) {
300 LOG(WARNING) << "Failed to get __xstat64() from libc.";
301 }
302 }
303
304 // fopen() and fopen64() are intercepted here so that NSS can open
305 // /dev/urandom to seed its random number generator. NSS is used by
306 // remoting in the sendbox.
307
308 // fopen() call may be redirected to fopen64() in stdio.h using
309 // __REDIRECT(), which sets asm name for fopen() to "fopen64". This
310 // means that we cannot override fopen() directly here. Instead the
311 // the code below defines fopen_override() function with asm name
312 // "fopen", so that all references to fopen() will resolve to this
313 // function.
314 __attribute__ ((__visibility__("default")))
315 FILE* fopen_override(const char* path, const char* mode) __asm__ ("fopen");
316
317 __attribute__ ((__visibility__("default")))
318 FILE* fopen_override(const char* path, const char* mode) {
319 if (g_am_zygote_or_renderer && strcmp(path, kUrandomDevPath) == 0) {
320 int fd = HANDLE_EINTR(dup(base::GetUrandomFD()));
321 if (fd < 0) {
322 PLOG(ERROR) << "dup() failed.";
323 return NULL;
324 }
325 return fdopen(fd, mode);
326 } else {
327 CHECK_EQ(0, pthread_once(&g_libc_file_io_funcs_guard,
328 InitLibcFileIOFunctions));
329 return g_libc_fopen(path, mode);
330 }
331 }
332
333 __attribute__ ((__visibility__("default")))
334 FILE* fopen64(const char* path, const char* mode) {
335 if (g_am_zygote_or_renderer && strcmp(path, kUrandomDevPath) == 0) {
336 int fd = HANDLE_EINTR(dup(base::GetUrandomFD()));
337 if (fd < 0) {
338 PLOG(ERROR) << "dup() failed.";
339 return NULL;
340 }
341 return fdopen(fd, mode);
342 } else {
343 CHECK_EQ(0, pthread_once(&g_libc_file_io_funcs_guard,
344 InitLibcFileIOFunctions));
345 return g_libc_fopen64(path, mode);
346 }
347 }
348
349 // stat() is subject to the same problem as fopen(), so we have to use
350 // the same trick to override it.
351 __attribute__ ((__visibility__("default")))
352 int xstat_override(int version,
353 const char *path,
354 struct stat *buf) __asm__ ("__xstat");
355
356 __attribute__ ((__visibility__("default")))
357 int xstat_override(int version, const char *path, struct stat *buf) {
358 if (g_am_zygote_or_renderer && strcmp(path, kUrandomDevPath) == 0) {
359 int result = __fxstat(version, base::GetUrandomFD(), buf);
360 return result;
361 } else {
362 CHECK_EQ(0, pthread_once(&g_libc_file_io_funcs_guard,
363 InitLibcFileIOFunctions));
364 return g_libc_xstat(version, path, buf);
365 }
366 }
367
368 __attribute__ ((__visibility__("default")))
369 int xstat64_override(int version,
370 const char *path,
371 struct stat64 *buf) __asm__ ("__xstat64");
372
373 __attribute__ ((__visibility__("default")))
374 int xstat64_override(int version, const char *path, struct stat64 *buf) {
375 if (g_am_zygote_or_renderer && strcmp(path, kUrandomDevPath) == 0) {
376 int result = __fxstat64(version, base::GetUrandomFD(), buf);
377 return result;
378 } else {
379 CHECK_EQ(0, pthread_once(&g_libc_file_io_funcs_guard,
380 InitLibcFileIOFunctions));
381 CHECK(g_libc_xstat64);
382 return g_libc_xstat64(version, path, buf);
383 }
384 }
385
386 #endif // !ADDRESS_SANITIZER
387
388 #endif // !CHROMIUM_SELINUX 255 #endif // !CHROMIUM_SELINUX
389 256
390 // This function triggers the static and lazy construction of objects that need 257 // This function triggers the static and lazy construction of objects that need
391 // to be created before imposing the sandbox. 258 // to be created before imposing the sandbox.
392 static void PreSandboxInit() { 259 static void PreSandboxInit() {
393 base::RandUint64(); 260 base::RandUint64();
394 261
395 base::SysInfo::MaxSharedMemorySize(); 262 base::SysInfo::MaxSharedMemorySize();
396 263
397 // ICU DateFormat class (used in base/time_format.cc) needs to get the 264 // ICU DateFormat class (used in base/time_format.cc) needs to get the
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 new FontConfigIPC(Zygote::kMagicSandboxIPCDescriptor)); 482 new FontConfigIPC(Zygote::kMagicSandboxIPCDescriptor));
616 return true; 483 return true;
617 } 484 }
618 485
619 #endif // CHROMIUM_SELINUX 486 #endif // CHROMIUM_SELINUX
620 487
621 bool ZygoteMain(const MainFunctionParams& params, 488 bool ZygoteMain(const MainFunctionParams& params,
622 ZygoteForkDelegate* forkdelegate) { 489 ZygoteForkDelegate* forkdelegate) {
623 #if !defined(CHROMIUM_SELINUX) 490 #if !defined(CHROMIUM_SELINUX)
624 g_am_zygote_or_renderer = true; 491 g_am_zygote_or_renderer = true;
492 sandbox::InitLibcUrandomOverrides();
625 #endif 493 #endif
626 494
627 int proc_fd_for_seccomp = -1; 495 int proc_fd_for_seccomp = -1;
628 #if defined(SECCOMP_SANDBOX) 496 #if defined(SECCOMP_SANDBOX)
629 if (SeccompSandboxEnabled()) { 497 if (SeccompSandboxEnabled()) {
630 // The seccomp sandbox needs access to files in /proc, which might be denied 498 // The seccomp sandbox needs access to files in /proc, which might be denied
631 // after one of the other sandboxes have been started. So, obtain a suitable 499 // after one of the other sandboxes have been started. So, obtain a suitable
632 // file handle in advance. 500 // file handle in advance.
633 proc_fd_for_seccomp = open("/proc", O_DIRECTORY | O_RDONLY); 501 proc_fd_for_seccomp = open("/proc", O_DIRECTORY | O_RDONLY);
634 if (proc_fd_for_seccomp < 0) { 502 if (proc_fd_for_seccomp < 0) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 } 560 }
693 } 561 }
694 #endif // SECCOMP_SANDBOX 562 #endif // SECCOMP_SANDBOX
695 563
696 Zygote zygote(sandbox_flags, forkdelegate, proc_fd_for_seccomp); 564 Zygote zygote(sandbox_flags, forkdelegate, proc_fd_for_seccomp);
697 // This function call can return multiple times, once per fork(). 565 // This function call can return multiple times, once per fork().
698 return zygote.ProcessRequests(); 566 return zygote.ProcessRequests();
699 } 567 }
700 568
701 } // namespace content 569 } // namespace content
OLDNEW
« no previous file with comments | « content/content_browser.gypi ('k') | sandbox/linux/services/libc_urandom_override.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698