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

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

Issue 10399043: zygote: Redirect 64-bit libc localtime and localtime_r routines. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Failure to locate 64-bit counterparts should not be Fatal. Created 8 years, 7 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 <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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 typedef struct tm* (*LocaltimeFunction)(const time_t* timep); 166 typedef struct tm* (*LocaltimeFunction)(const time_t* timep);
167 typedef struct tm* (*LocaltimeRFunction)(const time_t* timep, 167 typedef struct tm* (*LocaltimeRFunction)(const time_t* timep,
168 struct tm* result); 168 struct tm* result);
169 typedef FILE* (*FopenFunction)(const char* path, const char* mode); 169 typedef FILE* (*FopenFunction)(const char* path, const char* mode);
170 typedef int (*XstatFunction)(int version, const char *path, struct stat *buf); 170 typedef int (*XstatFunction)(int version, const char *path, struct stat *buf);
171 typedef int (*Xstat64Function)(int version, const char *path, 171 typedef int (*Xstat64Function)(int version, const char *path,
172 struct stat64 *buf); 172 struct stat64 *buf);
173 173
174 static pthread_once_t g_libc_localtime_funcs_guard = PTHREAD_ONCE_INIT; 174 static pthread_once_t g_libc_localtime_funcs_guard = PTHREAD_ONCE_INIT;
175 static LocaltimeFunction g_libc_localtime; 175 static LocaltimeFunction g_libc_localtime;
176 static LocaltimeFunction g_libc_localtime64;
176 static LocaltimeRFunction g_libc_localtime_r; 177 static LocaltimeRFunction g_libc_localtime_r;
178 static LocaltimeRFunction g_libc_localtime64_r;
177 179
178 static pthread_once_t g_libc_file_io_funcs_guard = PTHREAD_ONCE_INIT; 180 static pthread_once_t g_libc_file_io_funcs_guard = PTHREAD_ONCE_INIT;
179 static FopenFunction g_libc_fopen; 181 static FopenFunction g_libc_fopen;
180 static FopenFunction g_libc_fopen64; 182 static FopenFunction g_libc_fopen64;
181 static XstatFunction g_libc_xstat; 183 static XstatFunction g_libc_xstat;
182 static Xstat64Function g_libc_xstat64; 184 static Xstat64Function g_libc_xstat64;
183 185
184 static void InitLibcLocaltimeFunctions() { 186 static void InitLibcLocaltimeFunctions() {
185 g_libc_localtime = reinterpret_cast<LocaltimeFunction>( 187 g_libc_localtime = reinterpret_cast<LocaltimeFunction>(
186 dlsym(RTLD_NEXT, "localtime")); 188 dlsym(RTLD_NEXT, "localtime"));
189 g_libc_localtime64 = reinterpret_cast<LocaltimeFunction>(
190 dlsym(RTLD_NEXT, "localtime64"));
187 g_libc_localtime_r = reinterpret_cast<LocaltimeRFunction>( 191 g_libc_localtime_r = reinterpret_cast<LocaltimeRFunction>(
188 dlsym(RTLD_NEXT, "localtime_r")); 192 dlsym(RTLD_NEXT, "localtime_r"));
193 g_libc_localtime64_r = reinterpret_cast<LocaltimeRFunction>(
194 dlsym(RTLD_NEXT, "localtime64_r"));
189 195
190 if (!g_libc_localtime || !g_libc_localtime_r) { 196 if (!g_libc_localtime || !g_libc_localtime_r) {
191 // http://code.google.com/p/chromium/issues/detail?id=16800 197 // http://code.google.com/p/chromium/issues/detail?id=16800
192 // 198 //
193 // Nvidia's libGL.so overrides dlsym for an unknown reason and replaces 199 // Nvidia's libGL.so overrides dlsym for an unknown reason and replaces
194 // it with a version which doesn't work. In this case we'll get a NULL 200 // it with a version which doesn't work. In this case we'll get a NULL
195 // result. There's not a lot we can do at this point, so we just bodge it! 201 // result. There's not a lot we can do at this point, so we just bodge it!
196 LOG(ERROR) << "Your system is broken: dlsym doesn't work! This has been " 202 LOG(ERROR) << "Your system is broken: dlsym doesn't work! This has been "
197 "reported to be caused by Nvidia's libGL. You should expect" 203 "reported to be caused by Nvidia's libGL. You should expect"
198 " time related functions to misbehave. " 204 " time related functions to misbehave. "
199 "http://code.google.com/p/chromium/issues/detail?id=16800"; 205 "http://code.google.com/p/chromium/issues/detail?id=16800";
200 } 206 }
201 207
202 if (!g_libc_localtime) 208 if (!g_libc_localtime)
203 g_libc_localtime = gmtime; 209 g_libc_localtime = gmtime;
210 if (!g_libc_localtime64)
211 g_libc_localtime64 = g_libc_localtime;
204 if (!g_libc_localtime_r) 212 if (!g_libc_localtime_r)
205 g_libc_localtime_r = gmtime_r; 213 g_libc_localtime_r = gmtime_r;
214 if (!g_libc_localtime64_r)
215 g_libc_localtime64_r = g_libc_localtime_r;
206 } 216 }
207 217
208 struct tm* localtime(const time_t* timep) { 218 // Define localtime_override() function with asm name "localtime", so that all
219 // references to localtime() will resolve to this function. Notice that we need
220 // to set visibility attribute to "default" to export the symbol, as it is set
221 // to "hidden" by default in chrome per build/common.gypi.
222 __attribute__ ((__visibility__("default")))
223 struct tm* localtime_override(const time_t* timep) __asm__ ("localtime");
224
225 __attribute__ ((__visibility__("default")))
226 struct tm* localtime_override(const time_t* timep) {
209 if (g_am_zygote_or_renderer) { 227 if (g_am_zygote_or_renderer) {
210 static struct tm time_struct; 228 static struct tm time_struct;
211 static char timezone_string[64]; 229 static char timezone_string[64];
212 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, 230 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string,
213 sizeof(timezone_string)); 231 sizeof(timezone_string));
214 return &time_struct; 232 return &time_struct;
215 } else { 233 } else {
216 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, 234 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
217 InitLibcLocaltimeFunctions)); 235 InitLibcLocaltimeFunctions));
218 return g_libc_localtime(timep); 236 return g_libc_localtime(timep);
219 } 237 }
220 } 238 }
221 239
222 struct tm* localtime_r(const time_t* timep, struct tm* result) { 240 // Use same trick to override localtime64(), localtime_r() and localtime64_r().
241 __attribute__ ((__visibility__("default")))
242 struct tm* localtime64_override(const time_t* timep) __asm__ ("localtime64");
243
244 __attribute__ ((__visibility__("default")))
245 struct tm* localtime64_override(const time_t* timep) {
246 if (g_am_zygote_or_renderer) {
247 static struct tm time_struct;
248 static char timezone_string[64];
249 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string,
250 sizeof(timezone_string));
251 return &time_struct;
252 } else {
253 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
254 InitLibcLocaltimeFunctions));
255 return g_libc_localtime64(timep);
256 }
257 }
258
259 __attribute__ ((__visibility__("default")))
260 struct tm* localtime_r_override(const time_t* timep,
261 struct tm* result) __asm__ ("localtime_r");
262
263 __attribute__ ((__visibility__("default")))
264 struct tm* localtime_r_override(const time_t* timep, struct tm* result) {
223 if (g_am_zygote_or_renderer) { 265 if (g_am_zygote_or_renderer) {
224 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); 266 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0);
225 return result; 267 return result;
226 } else { 268 } else {
227 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, 269 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
228 InitLibcLocaltimeFunctions)); 270 InitLibcLocaltimeFunctions));
229 return g_libc_localtime_r(timep, result); 271 return g_libc_localtime_r(timep, result);
230 } 272 }
231 } 273 }
232 274
275 __attribute__ ((__visibility__("default")))
276 struct tm* localtime64_r_override(const time_t* timep,
277 struct tm* result) __asm__ ("localtime64_r");
278
279 __attribute__ ((__visibility__("default")))
280 struct tm* localtime64_r_override(const time_t* timep, struct tm* result) {
281 if (g_am_zygote_or_renderer) {
282 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0);
283 return result;
284 } else {
285 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
286 InitLibcLocaltimeFunctions));
287 return g_libc_localtime64_r(timep, result);
288 }
289 }
290
233 // TODO(sergeyu): Currently this code doesn't work properly under ASAN 291 // TODO(sergeyu): Currently this code doesn't work properly under ASAN
234 // - it crashes content_unittests. Make sure it works properly and 292 // - it crashes content_unittests. Make sure it works properly and
235 // enable it here. http://crbug.com/123263 293 // enable it here. http://crbug.com/123263
236 #if !defined(ADDRESS_SANITIZER) 294 #if !defined(ADDRESS_SANITIZER)
237 295
238 static void InitLibcFileIOFunctions() { 296 static void InitLibcFileIOFunctions() {
239 g_libc_fopen = reinterpret_cast<FopenFunction>( 297 g_libc_fopen = reinterpret_cast<FopenFunction>(
240 dlsym(RTLD_NEXT, "fopen")); 298 dlsym(RTLD_NEXT, "fopen"));
241 g_libc_fopen64 = reinterpret_cast<FopenFunction>( 299 g_libc_fopen64 = reinterpret_cast<FopenFunction>(
242 dlsym(RTLD_NEXT, "fopen64")); 300 dlsym(RTLD_NEXT, "fopen64"));
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 } 592 }
535 } 593 }
536 #endif // SECCOMP_SANDBOX 594 #endif // SECCOMP_SANDBOX
537 595
538 Zygote zygote(sandbox_flags, forkdelegate, proc_fd_for_seccomp); 596 Zygote zygote(sandbox_flags, forkdelegate, proc_fd_for_seccomp);
539 // This function call can return multiple times, once per fork(). 597 // This function call can return multiple times, once per fork().
540 return zygote.ProcessRequests(); 598 return zygote.ProcessRequests();
541 } 599 }
542 600
543 } // namespace content 601 } // namespace content
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