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

Side by Side Diff: sandbox/linux/services/libc_urandom_override.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 | « sandbox/linux/services/libc_urandom_override.h ('k') | sandbox/sandbox_linux.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "sandbox/linux/services/libc_urandom_override.h"
6
7 #include <dlfcn.h>
8 #include <pthread.h>
9 #include <stdio.h>
10 #include <sys/stat.h>
11
12 #include "base/eintr_wrapper.h"
13 #include "base/logging.h"
14 #include "base/rand_util.h"
15
16 // Note: this file is used by the zygote and nacl_helper.
17
18 namespace sandbox {
19
20 // With SELinux we can carve out a precise sandbox, so we don't have to play
21 // with intercepting libc calls.
22 #if !defined(CHROMIUM_SELINUX)
23
24 static bool g_override_urandom = false;
25
26 void InitLibcUrandomOverrides() {
27 // Make sure /dev/urandom is open.
28 base::GetUrandomFD();
29 g_override_urandom = true;
30 }
31
32 // TODO(sergeyu): Currently this code doesn't work properly under ASAN
33 // - it crashes content_unittests. Make sure it works properly and
34 // enable it here. http://crbug.com/123263
35 #if !defined(ADDRESS_SANITIZER)
36
37 static const char kUrandomDevPath[] = "/dev/urandom";
38
39 typedef FILE* (*FopenFunction)(const char* path, const char* mode);
40 typedef int (*XstatFunction)(int version, const char *path, struct stat *buf);
41 typedef int (*Xstat64Function)(int version, const char *path,
42 struct stat64 *buf);
43
44 static pthread_once_t g_libc_file_io_funcs_guard = PTHREAD_ONCE_INIT;
45 static FopenFunction g_libc_fopen;
46 static FopenFunction g_libc_fopen64;
47 static XstatFunction g_libc_xstat;
48 static Xstat64Function g_libc_xstat64;
49
50 static void InitLibcFileIOFunctions() {
51 g_libc_fopen = reinterpret_cast<FopenFunction>(
52 dlsym(RTLD_NEXT, "fopen"));
53 g_libc_fopen64 = reinterpret_cast<FopenFunction>(
54 dlsym(RTLD_NEXT, "fopen64"));
55
56 if (!g_libc_fopen) {
57 LOG(FATAL) << "Failed to get fopen() from libc.";
58 } else if (!g_libc_fopen64) {
59 #if !defined(OS_OPENBSD) && !defined(OS_FREEBSD)
60 LOG(WARNING) << "Failed to get fopen64() from libc. Using fopen() instead.";
61 #endif // !defined(OS_OPENBSD) && !defined(OS_FREEBSD)
62 g_libc_fopen64 = g_libc_fopen;
63 }
64
65 // TODO(sergeyu): This works only on systems with glibc. Fix it to
66 // work properly on other systems if necessary.
67 g_libc_xstat = reinterpret_cast<XstatFunction>(
68 dlsym(RTLD_NEXT, "__xstat"));
69 g_libc_xstat64 = reinterpret_cast<Xstat64Function>(
70 dlsym(RTLD_NEXT, "__xstat64"));
71
72 if (!g_libc_xstat) {
73 LOG(FATAL) << "Failed to get __xstat() from libc.";
74 }
75 if (!g_libc_xstat64) {
76 LOG(WARNING) << "Failed to get __xstat64() from libc.";
77 }
78 }
79
80 // fopen() and fopen64() are intercepted here so that NSS can open
81 // /dev/urandom to seed its random number generator. NSS is used by
82 // remoting in the sendbox.
83
84 // fopen() call may be redirected to fopen64() in stdio.h using
85 // __REDIRECT(), which sets asm name for fopen() to "fopen64". This
86 // means that we cannot override fopen() directly here. Instead the
87 // the code below defines fopen_override() function with asm name
88 // "fopen", so that all references to fopen() will resolve to this
89 // function.
90 __attribute__ ((__visibility__("default")))
91 FILE* fopen_override(const char* path, const char* mode) __asm__ ("fopen");
92
93 __attribute__ ((__visibility__("default")))
94 FILE* fopen_override(const char* path, const char* mode) {
95 if (g_override_urandom && strcmp(path, kUrandomDevPath) == 0) {
96 int fd = HANDLE_EINTR(dup(base::GetUrandomFD()));
97 if (fd < 0) {
98 PLOG(ERROR) << "dup() failed.";
99 return NULL;
100 }
101 return fdopen(fd, mode);
102 } else {
103 CHECK_EQ(0, pthread_once(&g_libc_file_io_funcs_guard,
104 InitLibcFileIOFunctions));
105 return g_libc_fopen(path, mode);
106 }
107 }
108
109 __attribute__ ((__visibility__("default")))
110 FILE* fopen64(const char* path, const char* mode) {
111 if (g_override_urandom && strcmp(path, kUrandomDevPath) == 0) {
112 int fd = HANDLE_EINTR(dup(base::GetUrandomFD()));
113 if (fd < 0) {
114 PLOG(ERROR) << "dup() failed.";
115 return NULL;
116 }
117 return fdopen(fd, mode);
118 } else {
119 CHECK_EQ(0, pthread_once(&g_libc_file_io_funcs_guard,
120 InitLibcFileIOFunctions));
121 return g_libc_fopen64(path, mode);
122 }
123 }
124
125 // stat() is subject to the same problem as fopen(), so we have to use
126 // the same trick to override it.
127 __attribute__ ((__visibility__("default")))
128 int xstat_override(int version,
129 const char *path,
130 struct stat *buf) __asm__ ("__xstat");
131
132 __attribute__ ((__visibility__("default")))
133 int xstat_override(int version, const char *path, struct stat *buf) {
134 if (g_override_urandom && strcmp(path, kUrandomDevPath) == 0) {
135 int result = __fxstat(version, base::GetUrandomFD(), buf);
136 return result;
137 } else {
138 CHECK_EQ(0, pthread_once(&g_libc_file_io_funcs_guard,
139 InitLibcFileIOFunctions));
140 return g_libc_xstat(version, path, buf);
141 }
142 }
143
144 __attribute__ ((__visibility__("default")))
145 int xstat64_override(int version,
146 const char *path,
147 struct stat64 *buf) __asm__ ("__xstat64");
148
149 __attribute__ ((__visibility__("default")))
150 int xstat64_override(int version, const char *path, struct stat64 *buf) {
151 if (g_override_urandom && strcmp(path, kUrandomDevPath) == 0) {
152 int result = __fxstat64(version, base::GetUrandomFD(), buf);
153 return result;
154 } else {
155 CHECK_EQ(0, pthread_once(&g_libc_file_io_funcs_guard,
156 InitLibcFileIOFunctions));
157 CHECK(g_libc_xstat64);
158 return g_libc_xstat64(version, path, buf);
159 }
160 }
161
162 #endif // !ADDRESS_SANITIZER
163
164 #endif // !CHROMIUM_SELINUX
165
166 } // namespace content
OLDNEW
« no previous file with comments | « sandbox/linux/services/libc_urandom_override.h ('k') | sandbox/sandbox_linux.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698