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

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: 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) {
Jorge Lucangeli Obes 2012/05/16 02:59:45 Shouldn't you add checks for the *64 versions of t
hshi1 2012/05/16 17:36:16 Done.
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;
204 if (!g_libc_localtime_r) 210 if (!g_libc_localtime_r)
205 g_libc_localtime_r = gmtime_r; 211 g_libc_localtime_r = gmtime_r;
206 } 212 }
207 213
208 struct tm* localtime(const time_t* timep) { 214 __attribute__ ((__visibility__("default")))
Jorge Lucangeli Obes 2012/05/16 02:59:45 Why do we need the visibility annotations?
hshi1 2012/05/16 03:04:09 This is a copy&paste based on the fopen/fopen64 co
hshi1 2012/05/16 17:36:16 It appears to be useless. I would assume that visi
hshi1 2012/05/16 17:44:57 Sorry, I take this back. It appears that the visib
215 struct tm* localtime_override(const time_t* timep) __asm__ ("localtime");
216
217 __attribute__ ((__visibility__("default")))
218 struct tm* localtime_override(const time_t* timep) {
209 if (g_am_zygote_or_renderer) { 219 if (g_am_zygote_or_renderer) {
210 static struct tm time_struct; 220 static struct tm time_struct;
211 static char timezone_string[64]; 221 static char timezone_string[64];
212 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, 222 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string,
213 sizeof(timezone_string)); 223 sizeof(timezone_string));
214 return &time_struct; 224 return &time_struct;
215 } else { 225 } else {
216 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, 226 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
217 InitLibcLocaltimeFunctions)); 227 InitLibcLocaltimeFunctions));
218 return g_libc_localtime(timep); 228 return g_libc_localtime(timep);
219 } 229 }
220 } 230 }
221 231
222 struct tm* localtime_r(const time_t* timep, struct tm* result) { 232 __attribute__ ((__visibility__("default")))
233 struct tm* localtime64_override(const time_t* timep) __asm__ ("localtime64");
234
235 __attribute__ ((__visibility__("default")))
236 struct tm* localtime64_override(const time_t* timep) {
237 if (g_am_zygote_or_renderer) {
238 static struct tm time_struct;
239 static char timezone_string[64];
240 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string,
241 sizeof(timezone_string));
242 return &time_struct;
243 } else {
244 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
245 InitLibcLocaltimeFunctions));
246 return g_libc_localtime64(timep);
247 }
248 }
249
250 __attribute__ ((__visibility__("default")))
251 struct tm* localtime_r_override(const time_t* timep,
252 struct tm* result) __asm__ ("localtime_r");
253
254 __attribute__ ((__visibility__("default")))
255 struct tm* localtime_r_override(const time_t* timep, struct tm* result) {
223 if (g_am_zygote_or_renderer) { 256 if (g_am_zygote_or_renderer) {
224 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); 257 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0);
225 return result; 258 return result;
226 } else { 259 } else {
227 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, 260 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
228 InitLibcLocaltimeFunctions)); 261 InitLibcLocaltimeFunctions));
229 return g_libc_localtime_r(timep, result); 262 return g_libc_localtime_r(timep, result);
230 } 263 }
231 } 264 }
232 265
266 __attribute__ ((__visibility__("default")))
267 struct tm* localtime64_r_override(const time_t* timep,
268 struct tm* result) __asm__ ("localtime64_r");
269
270 __attribute__ ((__visibility__("default")))
271 struct tm* localtime64_r_override(const time_t* timep, struct tm* result) {
272 if (g_am_zygote_or_renderer) {
273 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0);
274 return result;
275 } else {
276 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard,
277 InitLibcLocaltimeFunctions));
278 return g_libc_localtime64_r(timep, result);
279 }
280 }
281
233 // TODO(sergeyu): Currently this code doesn't work properly under ASAN 282 // TODO(sergeyu): Currently this code doesn't work properly under ASAN
234 // - it crashes content_unittests. Make sure it works properly and 283 // - it crashes content_unittests. Make sure it works properly and
235 // enable it here. http://crbug.com/123263 284 // enable it here. http://crbug.com/123263
236 #if !defined(ADDRESS_SANITIZER) 285 #if !defined(ADDRESS_SANITIZER)
237 286
238 static void InitLibcFileIOFunctions() { 287 static void InitLibcFileIOFunctions() {
239 g_libc_fopen = reinterpret_cast<FopenFunction>( 288 g_libc_fopen = reinterpret_cast<FopenFunction>(
240 dlsym(RTLD_NEXT, "fopen")); 289 dlsym(RTLD_NEXT, "fopen"));
241 g_libc_fopen64 = reinterpret_cast<FopenFunction>( 290 g_libc_fopen64 = reinterpret_cast<FopenFunction>(
242 dlsym(RTLD_NEXT, "fopen64")); 291 dlsym(RTLD_NEXT, "fopen64"));
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 } 583 }
535 } 584 }
536 #endif // SECCOMP_SANDBOX 585 #endif // SECCOMP_SANDBOX
537 586
538 Zygote zygote(sandbox_flags, forkdelegate, proc_fd_for_seccomp); 587 Zygote zygote(sandbox_flags, forkdelegate, proc_fd_for_seccomp);
539 // This function call can return multiple times, once per fork(). 588 // This function call can return multiple times, once per fork().
540 return zygote.ProcessRequests(); 589 return zygote.ProcessRequests();
541 } 590 }
542 591
543 } // namespace content 592 } // 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