| OLD | NEW |
| 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/zygote/zygote_main.h" | 5 #include "content/zygote/zygote_main.h" |
| 6 | 6 |
| 7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <pthread.h> | 10 #include <pthread.h> |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 if (!g_libc_localtime) | 174 if (!g_libc_localtime) |
| 175 g_libc_localtime = gmtime; | 175 g_libc_localtime = gmtime; |
| 176 if (!g_libc_localtime64) | 176 if (!g_libc_localtime64) |
| 177 g_libc_localtime64 = g_libc_localtime; | 177 g_libc_localtime64 = g_libc_localtime; |
| 178 if (!g_libc_localtime_r) | 178 if (!g_libc_localtime_r) |
| 179 g_libc_localtime_r = gmtime_r; | 179 g_libc_localtime_r = gmtime_r; |
| 180 if (!g_libc_localtime64_r) | 180 if (!g_libc_localtime64_r) |
| 181 g_libc_localtime64_r = g_libc_localtime_r; | 181 g_libc_localtime64_r = g_libc_localtime_r; |
| 182 } | 182 } |
| 183 | 183 |
| 184 #if defined(MEMORY_SANITIZER) | |
| 185 void msan_unpoison_string(const char *s) { | |
| 186 if (!s) return; | |
| 187 // Can't call strlen() on an uninitialized string. Instead, unpoison byte by | |
| 188 // byte until the string is over. | |
| 189 do { | |
| 190 __msan_unpoison(s, sizeof(*s)); | |
| 191 } while(*(s++)); | |
| 192 } | |
| 193 #endif | |
| 194 | |
| 195 // Define localtime_override() function with asm name "localtime", so that all | 184 // Define localtime_override() function with asm name "localtime", so that all |
| 196 // references to localtime() will resolve to this function. Notice that we need | 185 // references to localtime() will resolve to this function. Notice that we need |
| 197 // to set visibility attribute to "default" to export the symbol, as it is set | 186 // to set visibility attribute to "default" to export the symbol, as it is set |
| 198 // to "hidden" by default in chrome per build/common.gypi. | 187 // to "hidden" by default in chrome per build/common.gypi. |
| 199 __attribute__ ((__visibility__("default"))) | 188 __attribute__ ((__visibility__("default"))) |
| 200 struct tm* localtime_override(const time_t* timep) __asm__ ("localtime"); | 189 struct tm* localtime_override(const time_t* timep) __asm__ ("localtime"); |
| 201 | 190 |
| 202 __attribute__ ((__visibility__("default"))) | 191 __attribute__ ((__visibility__("default"))) |
| 203 struct tm* localtime_override(const time_t* timep) { | 192 struct tm* localtime_override(const time_t* timep) { |
| 204 if (g_am_zygote_or_renderer) { | 193 if (g_am_zygote_or_renderer) { |
| 205 static struct tm time_struct; | 194 static struct tm time_struct; |
| 206 static char timezone_string[64]; | 195 static char timezone_string[64]; |
| 207 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, | 196 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, |
| 208 sizeof(timezone_string)); | 197 sizeof(timezone_string)); |
| 209 return &time_struct; | 198 return &time_struct; |
| 210 } else { | 199 } else { |
| 211 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | 200 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, |
| 212 InitLibcLocaltimeFunctions)); | 201 InitLibcLocaltimeFunctions)); |
| 213 struct tm* res = g_libc_localtime(timep); | 202 struct tm* res = g_libc_localtime(timep); |
| 214 #if defined(MEMORY_SANITIZER) | 203 #if defined(MEMORY_SANITIZER) |
| 215 if (res) __msan_unpoison(res, sizeof(*res)); | 204 if (res) __msan_unpoison(res, sizeof(*res)); |
| 216 if (res->tm_zone) msan_unpoison_string(res->tm_zone); | 205 if (res->tm_zone) __msan_unpoison_string(res->tm_zone); |
| 217 #endif | 206 #endif |
| 218 return res; | 207 return res; |
| 219 } | 208 } |
| 220 } | 209 } |
| 221 | 210 |
| 222 // Use same trick to override localtime64(), localtime_r() and localtime64_r(). | 211 // Use same trick to override localtime64(), localtime_r() and localtime64_r(). |
| 223 __attribute__ ((__visibility__("default"))) | 212 __attribute__ ((__visibility__("default"))) |
| 224 struct tm* localtime64_override(const time_t* timep) __asm__ ("localtime64"); | 213 struct tm* localtime64_override(const time_t* timep) __asm__ ("localtime64"); |
| 225 | 214 |
| 226 __attribute__ ((__visibility__("default"))) | 215 __attribute__ ((__visibility__("default"))) |
| 227 struct tm* localtime64_override(const time_t* timep) { | 216 struct tm* localtime64_override(const time_t* timep) { |
| 228 if (g_am_zygote_or_renderer) { | 217 if (g_am_zygote_or_renderer) { |
| 229 static struct tm time_struct; | 218 static struct tm time_struct; |
| 230 static char timezone_string[64]; | 219 static char timezone_string[64]; |
| 231 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, | 220 ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, |
| 232 sizeof(timezone_string)); | 221 sizeof(timezone_string)); |
| 233 return &time_struct; | 222 return &time_struct; |
| 234 } else { | 223 } else { |
| 235 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | 224 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, |
| 236 InitLibcLocaltimeFunctions)); | 225 InitLibcLocaltimeFunctions)); |
| 237 struct tm* res = g_libc_localtime64(timep); | 226 struct tm* res = g_libc_localtime64(timep); |
| 238 #if defined(MEMORY_SANITIZER) | 227 #if defined(MEMORY_SANITIZER) |
| 239 if (res) __msan_unpoison(res, sizeof(*res)); | 228 if (res) __msan_unpoison(res, sizeof(*res)); |
| 240 if (res->tm_zone) msan_unpoison_string(res->tm_zone); | 229 if (res->tm_zone) __msan_unpoison_string(res->tm_zone); |
| 241 #endif | 230 #endif |
| 242 return res; | 231 return res; |
| 243 } | 232 } |
| 244 } | 233 } |
| 245 | 234 |
| 246 __attribute__ ((__visibility__("default"))) | 235 __attribute__ ((__visibility__("default"))) |
| 247 struct tm* localtime_r_override(const time_t* timep, | 236 struct tm* localtime_r_override(const time_t* timep, |
| 248 struct tm* result) __asm__ ("localtime_r"); | 237 struct tm* result) __asm__ ("localtime_r"); |
| 249 | 238 |
| 250 __attribute__ ((__visibility__("default"))) | 239 __attribute__ ((__visibility__("default"))) |
| 251 struct tm* localtime_r_override(const time_t* timep, struct tm* result) { | 240 struct tm* localtime_r_override(const time_t* timep, struct tm* result) { |
| 252 if (g_am_zygote_or_renderer) { | 241 if (g_am_zygote_or_renderer) { |
| 253 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); | 242 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); |
| 254 return result; | 243 return result; |
| 255 } else { | 244 } else { |
| 256 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | 245 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, |
| 257 InitLibcLocaltimeFunctions)); | 246 InitLibcLocaltimeFunctions)); |
| 258 struct tm* res = g_libc_localtime_r(timep, result); | 247 struct tm* res = g_libc_localtime_r(timep, result); |
| 259 #if defined(MEMORY_SANITIZER) | 248 #if defined(MEMORY_SANITIZER) |
| 260 if (res) __msan_unpoison(res, sizeof(*res)); | 249 if (res) __msan_unpoison(res, sizeof(*res)); |
| 261 if (res->tm_zone) msan_unpoison_string(res->tm_zone); | 250 if (res->tm_zone) __msan_unpoison_string(res->tm_zone); |
| 262 #endif | 251 #endif |
| 263 return res; | 252 return res; |
| 264 } | 253 } |
| 265 } | 254 } |
| 266 | 255 |
| 267 __attribute__ ((__visibility__("default"))) | 256 __attribute__ ((__visibility__("default"))) |
| 268 struct tm* localtime64_r_override(const time_t* timep, | 257 struct tm* localtime64_r_override(const time_t* timep, |
| 269 struct tm* result) __asm__ ("localtime64_r"); | 258 struct tm* result) __asm__ ("localtime64_r"); |
| 270 | 259 |
| 271 __attribute__ ((__visibility__("default"))) | 260 __attribute__ ((__visibility__("default"))) |
| 272 struct tm* localtime64_r_override(const time_t* timep, struct tm* result) { | 261 struct tm* localtime64_r_override(const time_t* timep, struct tm* result) { |
| 273 if (g_am_zygote_or_renderer) { | 262 if (g_am_zygote_or_renderer) { |
| 274 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); | 263 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); |
| 275 return result; | 264 return result; |
| 276 } else { | 265 } else { |
| 277 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | 266 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, |
| 278 InitLibcLocaltimeFunctions)); | 267 InitLibcLocaltimeFunctions)); |
| 279 struct tm* res = g_libc_localtime64_r(timep, result); | 268 struct tm* res = g_libc_localtime64_r(timep, result); |
| 280 #if defined(MEMORY_SANITIZER) | 269 #if defined(MEMORY_SANITIZER) |
| 281 if (res) __msan_unpoison(res, sizeof(*res)); | 270 if (res) __msan_unpoison(res, sizeof(*res)); |
| 282 if (res->tm_zone) msan_unpoison_string(res->tm_zone); | 271 if (res->tm_zone) __msan_unpoison_string(res->tm_zone); |
| 283 #endif | 272 #endif |
| 284 return res; | 273 return res; |
| 285 } | 274 } |
| 286 } | 275 } |
| 287 | 276 |
| 288 #if defined(ENABLE_PLUGINS) | 277 #if defined(ENABLE_PLUGINS) |
| 289 // Loads the (native) libraries but does not initialize them (i.e., does not | 278 // Loads the (native) libraries but does not initialize them (i.e., does not |
| 290 // call PPP_InitializeModule). This is needed by the zygote on Linux to get | 279 // call PPP_InitializeModule). This is needed by the zygote on Linux to get |
| 291 // access to the plugins before entering the sandbox. | 280 // access to the plugins before entering the sandbox. |
| 292 void PreloadPepperPlugins() { | 281 void PreloadPepperPlugins() { |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 int sandbox_flags = linux_sandbox->GetStatus(); | 466 int sandbox_flags = linux_sandbox->GetStatus(); |
| 478 bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID; | 467 bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID; |
| 479 CHECK_EQ(must_enable_setuid_sandbox, setuid_sandbox_engaged); | 468 CHECK_EQ(must_enable_setuid_sandbox, setuid_sandbox_engaged); |
| 480 | 469 |
| 481 Zygote zygote(sandbox_flags, fork_delegates.Pass()); | 470 Zygote zygote(sandbox_flags, fork_delegates.Pass()); |
| 482 // This function call can return multiple times, once per fork(). | 471 // This function call can return multiple times, once per fork(). |
| 483 return zygote.ProcessRequests(); | 472 return zygote.ProcessRequests(); |
| 484 } | 473 } |
| 485 | 474 |
| 486 } // namespace content | 475 } // namespace content |
| OLD | NEW |