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

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

Issue 10031027: Redirect fopen("/dev/urandom") so that NSS can properly seed it's RNG. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 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 | « no previous file | no next file » | 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 "content/browser/zygote_host_impl_linux.h" 5 #include "content/browser/zygote_host_impl_linux.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <pthread.h> 9 #include <pthread.h>
10 #include <stdio.h>
10 #include <sys/socket.h> 11 #include <sys/socket.h>
11 #include <sys/stat.h> 12 #include <sys/stat.h>
12 #include <sys/types.h> 13 #include <sys/types.h>
13 #include <sys/wait.h> 14 #include <sys/wait.h>
14 #include <unistd.h> 15 #include <unistd.h>
15 16
16 #include "base/basictypes.h" 17 #include "base/basictypes.h"
17 #include "base/command_line.h" 18 #include "base/command_line.h"
18 #include "base/eintr_wrapper.h" 19 #include "base/eintr_wrapper.h"
19 #include "base/file_path.h" 20 #include "base/file_path.h"
20 #include "base/file_util.h" 21 #include "base/file_util.h"
21 #include "base/global_descriptors_posix.h" 22 #include "base/global_descriptors_posix.h"
22 #include "base/hash_tables.h" 23 #include "base/hash_tables.h"
23 #include "base/linux_util.h" 24 #include "base/linux_util.h"
24 #include "base/memory/scoped_ptr.h" 25 #include "base/memory/scoped_ptr.h"
25 #include "base/pickle.h" 26 #include "base/pickle.h"
26 #include "base/process_util.h" 27 #include "base/process_util.h"
27 #include "base/rand_util.h" 28 #include "base/rand_util.h"
29 #include "base/rand_util_c.h"
28 #include "base/sys_info.h" 30 #include "base/sys_info.h"
29 #include "build/build_config.h" 31 #include "build/build_config.h"
30 #include "crypto/nss_util.h" 32 #include "crypto/nss_util.h"
31 #include "content/common/chrome_descriptors.h" 33 #include "content/common/chrome_descriptors.h"
32 #include "content/common/font_config_ipc_linux.h" 34 #include "content/common/font_config_ipc_linux.h"
33 #include "content/common/pepper_plugin_registry.h" 35 #include "content/common/pepper_plugin_registry.h"
34 #include "content/common/sandbox_methods_linux.h" 36 #include "content/common/sandbox_methods_linux.h"
35 #include "content/common/seccomp_sandbox.h" 37 #include "content/common/seccomp_sandbox.h"
36 #include "content/common/set_process_title.h" 38 #include "content/common/set_process_title.h"
37 #include "content/common/unix_domain_socket_posix.h" 39 #include "content/common/unix_domain_socket_posix.h"
(...skipping 19 matching lines...) Expand all
57 #include <selinux/context.h> 59 #include <selinux/context.h>
58 #endif 60 #endif
59 61
60 // http://code.google.com/p/chromium/wiki/LinuxZygote 62 // http://code.google.com/p/chromium/wiki/LinuxZygote
61 63
62 static const int kBrowserDescriptor = 3; 64 static const int kBrowserDescriptor = 3;
63 static const int kMagicSandboxIPCDescriptor = 5; 65 static const int kMagicSandboxIPCDescriptor = 5;
64 static const int kZygoteIdDescriptor = 7; 66 static const int kZygoteIdDescriptor = 7;
65 static bool g_suid_sandbox_active = false; 67 static bool g_suid_sandbox_active = false;
66 68
69 static char kUrandomDevPath[] = "/dev/urandom";
agl 2012/04/10 15:18:13 const
Sergey Ulanov 2012/04/10 17:21:01 Done.
70
67 #if defined(SECCOMP_SANDBOX) 71 #if defined(SECCOMP_SANDBOX)
68 static int g_proc_fd = -1; 72 static int g_proc_fd = -1;
69 #endif 73 #endif
70 74
71 #if defined(CHROMIUM_SELINUX) 75 #if defined(CHROMIUM_SELINUX)
72 static void SELinuxTransitionToTypeOrDie(const char* type) { 76 static void SELinuxTransitionToTypeOrDie(const char* type) {
73 security_context_t security_context; 77 security_context_t security_context;
74 if (getcon(&security_context)) 78 if (getcon(&security_context))
75 LOG(FATAL) << "Cannot get SELinux context"; 79 LOG(FATAL) << "Cannot get SELinux context";
76 80
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 // Our first attempt involved some assembly to patch the GOT of the current 629 // Our first attempt involved some assembly to patch the GOT of the current
626 // module. This worked, but was platform specific and doesn't catch the case 630 // module. This worked, but was platform specific and doesn't catch the case
627 // where a library makes a call rather than current module. 631 // where a library makes a call rather than current module.
628 // 632 //
629 // We also considered patching the function in place, but this would again by 633 // We also considered patching the function in place, but this would again by
630 // platform specific and the above technique seems to work well enough. 634 // platform specific and the above technique seems to work well enough.
631 635
632 typedef struct tm* (*LocaltimeFunction)(const time_t* timep); 636 typedef struct tm* (*LocaltimeFunction)(const time_t* timep);
633 typedef struct tm* (*LocaltimeRFunction)(const time_t* timep, 637 typedef struct tm* (*LocaltimeRFunction)(const time_t* timep,
634 struct tm* result); 638 struct tm* result);
639 typedef FILE* (*FopenFunction)(const char* path, const char* mode);
635 640
636 static pthread_once_t g_libc_localtime_funcs_guard = PTHREAD_ONCE_INIT; 641 static pthread_once_t g_libc_localtime_funcs_guard = PTHREAD_ONCE_INIT;
637 static LocaltimeFunction g_libc_localtime; 642 static LocaltimeFunction g_libc_localtime;
638 static LocaltimeRFunction g_libc_localtime_r; 643 static LocaltimeRFunction g_libc_localtime_r;
639 644
645 static pthread_once_t g_libc_fopen_funcs_guard = PTHREAD_ONCE_INIT;
646 static FopenFunction g_libc_fopen;
647 static FopenFunction g_libc_fopen64;
648
640 static void InitLibcLocaltimeFunctions() { 649 static void InitLibcLocaltimeFunctions() {
641 g_libc_localtime = reinterpret_cast<LocaltimeFunction>( 650 g_libc_localtime = reinterpret_cast<LocaltimeFunction>(
642 dlsym(RTLD_NEXT, "localtime")); 651 dlsym(RTLD_NEXT, "localtime"));
643 g_libc_localtime_r = reinterpret_cast<LocaltimeRFunction>( 652 g_libc_localtime_r = reinterpret_cast<LocaltimeRFunction>(
644 dlsym(RTLD_NEXT, "localtime_r")); 653 dlsym(RTLD_NEXT, "localtime_r"));
645 654
646 if (!g_libc_localtime || !g_libc_localtime_r) { 655 if (!g_libc_localtime || !g_libc_localtime_r) {
647 // http://code.google.com/p/chromium/issues/detail?id=16800 656 // http://code.google.com/p/chromium/issues/detail?id=16800
648 // 657 //
649 // Nvidia's libGL.so overrides dlsym for an unknown reason and replaces 658 // Nvidia's libGL.so overrides dlsym for an unknown reason and replaces
(...skipping 29 matching lines...) Expand all
679 if (g_am_zygote_or_renderer) { 688 if (g_am_zygote_or_renderer) {
680 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); 689 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0);
681 return result; 690 return result;
682 } else { 691 } else {
683 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, 692 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
684 InitLibcLocaltimeFunctions)); 693 InitLibcLocaltimeFunctions));
685 return g_libc_localtime_r(timep, result); 694 return g_libc_localtime_r(timep, result);
686 } 695 }
687 } 696 }
688 697
698 static void InitLibcFopenFunctions() {
699 g_libc_fopen = reinterpret_cast<FopenFunction>(
700 dlsym(RTLD_NEXT, "fopen"));
agl 2012/04/10 15:18:13 nit: indentation here should be four spaces from t
Sergey Ulanov 2012/04/10 17:21:01 Done.
701 g_libc_fopen64 = reinterpret_cast<FopenFunction>(
702 dlsym(RTLD_NEXT, "fopen64"));
703
704 if (!g_libc_fopen || !g_libc_fopen64) {
705 LOG(ERROR) << "Failed to get fopen() from glibc.";
706 }
707 }
708
709 // fopen() and fopen64() are intercepted here so that NSS can open
710 // /dev/urandom to seed it's random number generator. NSS is used by
711 // remoting in the sendbox.
712
713 // fopen() call may be redirected to fopen64() in stdio.h using
714 // __REDIRECT(), which sets asm name for fopen() to "fopen64". This
715 // means that we cannot override fopen() directly here. Instead the
716 // the code below defines fopen_override() function with asm name
717 // "fopen", so that all references to fopen() will resolve to this
718 // function.
719 __attribute__ ((__visibility__("default")))
720 FILE* fopen_override(const char* path, const char* mode) __asm__ ("fopen");
agl 2012/04/10 15:18:13 nit: blank line between these.
Sergey Ulanov 2012/04/10 17:21:01 Done.
721 __attribute__ ((__visibility__("default")))
722 FILE* fopen_override(const char* path, const char* mode) {
723 if (g_am_zygote_or_renderer && strcmp(path, kUrandomDevPath) == 0) {
724 int fd = dup(GetUrandomFD());
agl 2012/04/10 15:18:13 needs to be wrapped with HANDLE_EINTR
Sergey Ulanov 2012/04/10 17:21:01 Done.
725 if (fd < 0) {
726 LOG(ERROR) << "dup() failed.";
agl 2012/04/10 15:18:13 PLOG
Sergey Ulanov 2012/04/10 17:21:01 Done.
727 return NULL;
728 }
729 return fdopen(fd, mode);
730 } else {
731 CHECK_EQ(0, pthread_once(&g_libc_fopen_funcs_guard,
732 InitLibcFopenFunctions));
733 return g_libc_fopen(path, mode);
734 }
735 }
736
737 __attribute__ ((__visibility__("default")))
738 FILE* fopen64(const char* path, const char* mode) {
739 if (g_am_zygote_or_renderer && strcmp(path, kUrandomDevPath) == 0) {
740 int fd = dup(GetUrandomFD());
agl 2012/04/10 15:18:13 needs to be wrapped with HANDLE_EINTR
Sergey Ulanov 2012/04/10 17:21:01 Done.
741 if (fd < 0) {
742 PLOG(ERROR) << "dup() failed.";
743 return NULL;
744 }
745 return fdopen(fd, mode);
746 } else {
747 CHECK_EQ(0, pthread_once(&g_libc_fopen_funcs_guard,
748 InitLibcFopenFunctions));
749 return g_libc_fopen64(path, mode);
750 }
751 }
752
689 #endif // !CHROMIUM_SELINUX 753 #endif // !CHROMIUM_SELINUX
690 754
691 // This function triggers the static and lazy construction of objects that need 755 // This function triggers the static and lazy construction of objects that need
692 // to be created before imposing the sandbox. 756 // to be created before imposing the sandbox.
693 static void PreSandboxInit() { 757 static void PreSandboxInit() {
694 base::RandUint64(); 758 base::RandUint64();
695 759
696 base::SysInfo::MaxSharedMemorySize(); 760 base::SysInfo::MaxSharedMemorySize();
697 761
698 // ICU DateFormat class (used in base/time_format.cc) needs to get the 762 // ICU DateFormat class (used in base/time_format.cc) needs to get the
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 VLOG(1) << "Enabling experimental Seccomp sandbox."; 937 VLOG(1) << "Enabling experimental Seccomp sandbox.";
874 sandbox_flags |= ZygoteHostImpl::kSandboxSeccomp; 938 sandbox_flags |= ZygoteHostImpl::kSandboxSeccomp;
875 } 939 }
876 } 940 }
877 #endif // SECCOMP_SANDBOX 941 #endif // SECCOMP_SANDBOX
878 942
879 Zygote zygote(sandbox_flags, forkdelegate); 943 Zygote zygote(sandbox_flags, forkdelegate);
880 // This function call can return multiple times, once per fork(). 944 // This function call can return multiple times, once per fork().
881 return zygote.ProcessRequests(); 945 return zygote.ProcessRequests();
882 } 946 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698