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 |