]> git.saurik.com Git - apple/libsystem.git/blob - init.c
Libsystem-1292.100.5.tar.gz
[apple/libsystem.git] / init.c
1 /*
2 * Copyright (c) 2007, 2008, 2011-2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <TargetConditionals.h> // for TARGET_OS_*
30
31 #include <stddef.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <corecrypto/cc_priv.h>
35 #include <libc_private.h>
36 #include <pthread.h>
37 #include <pthread/private.h>
38 #if !TARGET_OS_DRIVERKIT
39 #include <dlfcn.h>
40 #include <os/variant_private.h>
41 #endif
42 #include <fcntl.h>
43 #include <errno.h>
44 #include <sys/kdebug.h>
45 #include <_libkernel_init.h> // Must be after voucher_private.h
46 #include <malloc_implementation.h>
47
48 #include <mach-o/dyld_priv.h>
49
50 // system library initialisers
51 extern void mach_init(void); // from libsystem_kernel.dylib
52 extern void __libplatform_init(void *future_use, const char *envp[], const char *apple[], const struct ProgramVars *vars);
53 extern void __pthread_init(const struct _libpthread_functions *libpthread_funcs, const char *envp[], const char *apple[], const struct ProgramVars *vars); // from libsystem_pthread.dylib
54 extern void __malloc_init(const char *apple[]); // from libsystem_malloc.dylib
55 extern void __keymgr_initializer(void); // from libkeymgr.dylib
56 extern void _dyld_initializer(void); // from libdyld.dylib
57 extern void libdispatch_init(void); // from libdispatch.dylib
58 extern void _libxpc_initializer(void); // from libxpc.dylib
59 extern void _libsecinit_initializer(void); // from libsecinit.dylib
60 extern void _libtrace_init(void); // from libsystem_trace.dylib
61 extern void _container_init(const char *apple[]); // from libsystem_containermanager.dylib
62 extern void __libdarwin_init(void); // from libsystem_darwin.dylib
63
64
65 // clear qos tsd (from pthread)
66 extern void _pthread_clear_qos_tsd(mach_port_t) __attribute__((weak_import));
67
68 // system library atfork handlers
69 extern void _pthread_atfork_prepare(void);
70 extern void _pthread_atfork_parent(void);
71 extern void _pthread_atfork_child(void);
72 extern void _pthread_atfork_prepare_handlers();
73 extern void _pthread_atfork_parent_handlers(void);
74 extern void _pthread_atfork_child_handlers(void);
75 extern void _pthread_exit_if_canceled(int);
76
77 extern void dispatch_atfork_prepare(void);
78 extern void dispatch_atfork_parent(void);
79 extern void dispatch_atfork_child(void);
80
81 extern void _libtrace_fork_child(void);
82
83 extern void _malloc_fork_prepare(void);
84 extern void _malloc_fork_parent(void);
85 extern void _malloc_fork_child(void);
86
87 extern void _mach_fork_child(void);
88 extern void _notify_fork_child(void);
89 extern void _dyld_atfork_prepare(void);
90 extern void _dyld_atfork_parent(void);
91 extern void _dyld_fork_child(void);
92 extern void xpc_atfork_prepare(void);
93 extern void xpc_atfork_parent(void);
94 extern void xpc_atfork_child(void);
95 extern void _libSC_info_fork_prepare(void);
96 extern void _libSC_info_fork_parent(void);
97 extern void _libSC_info_fork_child(void);
98 extern void _asl_fork_child(void);
99
100 #if defined(HAVE_SYSTEM_CORESERVICES)
101 // libsystem_coreservices.dylib
102 extern void _libcoreservices_fork_child(void);
103 extern char *_dirhelper(int, char *, size_t);
104 #endif
105
106 // advance decls for below;
107 void libSystem_atfork_prepare(void);
108 void libSystem_atfork_parent(void);
109 void libSystem_atfork_child(void);
110
111 #if SUPPORT_ASAN
112 const char *__asan_default_options(void);
113 #endif
114
115 static inline void
116 _libSystem_ktrace4(uint32_t code, uint64_t a, uint64_t b, uint64_t c, uint64_t d)
117 {
118 if (__builtin_expect(*(volatile uint32_t *)_COMM_PAGE_KDEBUG_ENABLE == 0, 1)) return;
119 kdebug_trace(code, a, b, c, d);
120 }
121 #define _libSystem_ktrace3(code, a, b, c) _libSystem_ktrace4(code, a, b, c, 0)
122 #define _libSystem_ktrace2(code, a, b) _libSystem_ktrace4(code, a, b, 0, 0)
123 #define _libSystem_ktrace1(code, a) _libSystem_ktrace4(code, a, 0, 0, 0)
124 #define _libSystem_ktrace0(code) _libSystem_ktrace4(code, 0, 0, 0, 0)
125
126 /*
127 * these define stable Ariadne tracepoints. If initializers are removed, or
128 * added, then old tracepoints MUST NOT be recycled.
129 */
130 enum {
131 ARIADNE_LIFECYCLE_libsystem_init = ARIADNEDBG_CODE(220, 4),
132 };
133
134 /*
135 * These represent the initializer "name"
136 *
137 * They happen to match the order of the initializers at some point in time,
138 * but there's no guarantee made that traecepoints will appear in numerical
139 * order. As initializers come and go, new codes shall be allocated,
140 * and no slots reused.
141 */
142 enum init_func {
143 INIT_SYSTEM = 0,
144 INIT_KERNEL = 1,
145 INIT_PLATFORM = 2,
146 INIT_PTHREAD = 3,
147 INIT_LIBC = 4,
148 INIT_MALLOC = 5,
149 INIT_KEYMGR = 6,
150 INIT_DYLD = 7,
151 INIT_LIBDISPATCH = 8,
152 INIT_LIBXPC = 9,
153 INIT_LIBTRACE = 10,
154 INIT_SECINIT = 11,
155 INIT_CONTAINERMGR = 12,
156 INIT_DARWIN = 13,
157 };
158
159 #define _libSystem_ktrace_init_func(what) \
160 _libSystem_ktrace1(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_NONE, INIT_##what)
161
162 // libsyscall_initializer() initializes all of libSystem.dylib
163 // <rdar://problem/4892197>
164 __attribute__((constructor))
165 static void
166 libSystem_initializer(int argc,
167 const char* argv[],
168 const char* envp[],
169 const char* apple[],
170 const struct ProgramVars* vars)
171 {
172 static const struct _libkernel_functions libkernel_funcs = {
173 .version = 4,
174 // V1 functions
175 #if !TARGET_OS_DRIVERKIT
176 .dlsym = dlsym,
177 #endif
178 .malloc = malloc,
179 .free = free,
180 .realloc = realloc,
181 ._pthread_exit_if_canceled = _pthread_exit_if_canceled,
182 // V2 functions (removed)
183 // V3 functions
184 .pthread_clear_qos_tsd = _pthread_clear_qos_tsd,
185 // V4 functions
186 .pthread_current_stack_contains_np = pthread_current_stack_contains_np,
187 };
188
189 static const struct _libpthread_functions libpthread_funcs = {
190 .version = 2,
191 .exit = exit,
192 .malloc = malloc,
193 .free = free,
194 };
195
196 static const struct _libc_functions libc_funcs = {
197 .version = 1,
198 .atfork_prepare = libSystem_atfork_prepare,
199 .atfork_parent = libSystem_atfork_parent,
200 .atfork_child = libSystem_atfork_child,
201 #if defined(HAVE_SYSTEM_CORESERVICES)
202 .dirhelper = _dirhelper,
203 #endif
204 };
205
206 _libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_START);
207
208 __libkernel_init(&libkernel_funcs, envp, apple, vars);
209 _libSystem_ktrace_init_func(KERNEL);
210
211 __libplatform_init(NULL, envp, apple, vars);
212 _libSystem_ktrace_init_func(PLATFORM);
213
214 __pthread_init(&libpthread_funcs, envp, apple, vars);
215 _libSystem_ktrace_init_func(PTHREAD);
216
217 _libc_initializer(&libc_funcs, envp, apple, vars);
218 _libSystem_ktrace_init_func(LIBC);
219
220 // TODO: Move __malloc_init before __libc_init after breaking malloc's upward link to Libc
221 // Note that __malloc_init() will also initialize ASAN when it is present
222 __malloc_init(apple);
223 _libSystem_ktrace_init_func(MALLOC);
224
225 #if TARGET_OS_OSX
226 /* <rdar://problem/9664631> */
227 __keymgr_initializer();
228 _libSystem_ktrace_init_func(KEYMGR);
229 #endif
230
231 _dyld_initializer();
232 _libSystem_ktrace_init_func(DYLD);
233
234 libdispatch_init();
235 _libSystem_ktrace_init_func(LIBDISPATCH);
236
237 #if !TARGET_OS_DRIVERKIT
238 _libxpc_initializer();
239 _libSystem_ktrace_init_func(LIBXPC);
240
241 #if SUPPORT_ASAN
242 setenv("DT_BYPASS_LEAKS_CHECK", "1", 1);
243 #endif
244 #endif // !TARGET_OS_DRIVERKIT
245
246 // must be initialized after dispatch
247 _libtrace_init();
248 _libSystem_ktrace_init_func(LIBTRACE);
249
250 #if !TARGET_OS_DRIVERKIT
251 #if defined(HAVE_SYSTEM_SECINIT)
252 _libsecinit_initializer();
253 _libSystem_ktrace_init_func(SECINIT);
254 #endif
255
256 #if defined(HAVE_SYSTEM_CONTAINERMANAGER)
257 _container_init(apple);
258 _libSystem_ktrace_init_func(CONTAINERMGR);
259 #endif
260
261 __libdarwin_init();
262 _libSystem_ktrace_init_func(DARWIN);
263 #endif // !TARGET_OS_DRIVERKIT
264
265 const struct _malloc_late_init mli = {
266 .version = 1,
267 #if !TARGET_OS_DRIVERKIT
268 .dlopen = dlopen,
269 .dlsym = dlsym,
270 // this must come after _libxpc_initializer()
271 .internal_diagnostics = os_variant_has_internal_diagnostics("com.apple.libsystem"),
272 #endif
273 };
274
275 __malloc_late_init(&mli);
276
277 #if !TARGET_OS_IPHONE
278 /* <rdar://problem/22139800> - Preserve the old behavior of apple[] for
279 * programs that haven't linked against newer SDK.
280 */
281 #define APPLE0_PREFIX "executable_path="
282 if (dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_11){
283 if (strncmp(apple[0], APPLE0_PREFIX, strlen(APPLE0_PREFIX)) == 0){
284 apple[0] = apple[0] + strlen(APPLE0_PREFIX);
285 }
286 }
287 #endif
288
289 #if TARGET_OS_OSX && !defined(__i386__)
290 bool enable_system_version_compat = false;
291 bool enable_ios_version_compat = false;
292 char *system_version_compat_override = getenv("SYSTEM_VERSION_COMPAT");
293 if (system_version_compat_override != NULL) {
294 long override = strtol(system_version_compat_override, NULL, 0);
295 if (override == 1) {
296 enable_system_version_compat = true;
297 } else if (override == 2) {
298 enable_ios_version_compat = true;
299 }
300 } else if (dyld_get_active_platform() == PLATFORM_MACCATALYST) {
301 if (!dyld_program_sdk_at_least(dyld_platform_version_iOS_14_0)) {
302 enable_system_version_compat = true;
303 }
304 } else if (dyld_get_active_platform() == PLATFORM_IOS) {
305 enable_ios_version_compat = true;
306 } else if (!dyld_program_sdk_at_least(dyld_platform_version_macOS_10_16)) {
307 enable_system_version_compat = true;
308 }
309
310 if (enable_system_version_compat || enable_ios_version_compat) {
311 struct _libkernel_late_init_config config = {
312 .version = 2,
313 .enable_system_version_compat = enable_system_version_compat,
314 .enable_ios_version_compat = enable_ios_version_compat,
315 };
316 __libkernel_init_late(&config);
317 }
318 #endif // TARGET_OS_OSX && !defined(__i386__)
319
320 _libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_END);
321
322 /* <rdar://problem/11588042>
323 * C99 standard has the following in section 7.5(3):
324 * "The value of errno is zero at program startup, but is never set
325 * to zero by any library function."
326 */
327 errno = 0;
328 }
329
330 /*
331 * libSystem_atfork_{prepare,parent,child}() are called by libc during fork(2).
332 */
333 void
334 libSystem_atfork_prepare(void)
335 {
336 // first call client prepare handlers registered with pthread_atfork()
337 _pthread_atfork_prepare_handlers();
338
339 // second call hardwired fork prepare handlers for Libsystem components
340 // in the _reverse_ order of library initalization above
341 #if !TARGET_OS_DRIVERKIT
342 _libSC_info_fork_prepare();
343 xpc_atfork_prepare();
344 #endif // !TARGET_OS_DRIVERKIT
345 dispatch_atfork_prepare();
346 _dyld_atfork_prepare();
347 cc_atfork_prepare();
348 _malloc_fork_prepare();
349 _pthread_atfork_prepare();
350 }
351
352 void
353 libSystem_atfork_parent(void)
354 {
355 // first call hardwired fork parent handlers for Libsystem components
356 // in the order of library initalization above
357 _pthread_atfork_parent();
358 _malloc_fork_parent();
359 cc_atfork_parent();
360 _dyld_atfork_parent();
361 dispatch_atfork_parent();
362 #if !TARGET_OS_DRIVERKIT
363 xpc_atfork_parent();
364 _libSC_info_fork_parent();
365 #endif // !TARGET_OS_DRIVERKIT
366
367 // second call client parent handlers registered with pthread_atfork()
368 _pthread_atfork_parent_handlers();
369 }
370
371 void
372 libSystem_atfork_child(void)
373 {
374 // first call hardwired fork child handlers for Libsystem components
375 // in the order of library initalization above
376 _mach_fork_child();
377 _pthread_atfork_child();
378 _malloc_fork_child();
379 cc_atfork_child();
380 _libc_fork_child(); // _arc4_fork_child calls malloc
381 _dyld_fork_child();
382 dispatch_atfork_child();
383 #if !TARGET_OS_DRIVERKIT
384 #if defined(HAVE_SYSTEM_CORESERVICES)
385 _libcoreservices_fork_child();
386 #endif
387 _asl_fork_child();
388 _notify_fork_child();
389 xpc_atfork_child();
390 #endif // !TARGET_OS_DRIVERKIT
391 _libtrace_fork_child();
392 #if !TARGET_OS_DRIVERKIT
393 _libSC_info_fork_child();
394 #endif // !TARGET_OS_DRIVERKIT
395
396 // second call client parent handlers registered with pthread_atfork()
397 _pthread_atfork_child_handlers();
398 }
399
400 #if SUPPORT_ASAN
401
402 // Prevents use of coloring terminal signals in report. These
403 // hinder readability when writing to files or the system log.
404 #define ASAN_OPT_NO_COLOR "color=never"
405
406 // Disables ASan's signal handlers. It's better to let the system catch
407 // these kinds of crashes.
408 #define ASAN_OPT_NO_SIGNAL_HANDLERS ":handle_segv=0:handle_sigbus=0:handle_sigill=0:handle_sigfpe=0"
409
410 // Disables using the out-of-process symbolizer (atos) but still allows
411 // in-process symbolization via `dladdr()`. This gives useful function names
412 // (unless they are redacted) which can be helpful in the event we can't
413 // symbolize offline. Out-of-process symbolization isn't useful because
414 // the dSYMs are usually not present on the device.
415 #define ASAN_OPT_NO_OOP_SYMBOLIZER ":external_symbolizer_path="
416
417 // Don't try to log to a file. It's difficult to find a location for the file
418 // that is writable so just write to stderr.
419 #define ASAN_OPT_FILE_LOG ":log_path=stderr:log_exe_name=0"
420
421 // Print the module map when finding an issue. This is necessary for offline
422 // symbolication.
423 #define ASAN_OPT_MODULE_MAP ":print_module_map=2"
424
425 // Disable ODR violation checking.
426 // <rdar://problem/71021707> Investigate enabling ODR checking for ASan in BATS and in the `_asan` variant
427 #define ASAN_OPT_NO_ODR_VIOLATION ":detect_odr_violation=0"
428
429 // Start ASan in deactivated mode. This reduces memory overhead until
430 // instrumented code is loaded. This prevents catching bugs if no instrumented
431 // code is loaded.
432 #define ASAN_OPT_START_DEACTIVATED ":start_deactivated=1"
433
434 // Do not crash when an error is found. This always works for errors caught via
435 // ASan's interceptors. This won't work for errors caught in ASan
436 // instrumentation unless the code is compiled with
437 // `-fsanitize-recover=address`. If this option is being used then the ASan
438 // reports can only be found by looking at the system log.
439 #define ASAN_OPT_NO_HALT_ON_ERROR ":halt_on_error=0"
440
441 // Crash when an error is found.
442 #define ASAN_OPT_HALT_ON_ERROR ":halt_on_error=1"
443
444 // ASan options common to all supported variants
445 #define COMMON_ASAN_OPTIONS \
446 ASAN_OPT_NO_COLOR \
447 ASAN_OPT_NO_SIGNAL_HANDLERS \
448 ASAN_OPT_NO_OOP_SYMBOLIZER \
449 ASAN_OPT_FILE_LOG \
450 ASAN_OPT_MODULE_MAP \
451 ASAN_OPT_NO_ODR_VIOLATION
452
453 #if defined(CURRENT_VARIANT_normal) || defined(CURRENT_VARIANT_debug) || defined (CURRENT_VARIANT_no_asan)
454
455 // In the normal variant ASan will be running in all userspace processes ("whole userspace ASan").
456 // This mode exists to support "ASan in BATS".
457 //
458 // Supporting ASan in the debug variant preserves existing behavior.
459 //
460 // The no_asan variant does not load the ASan runtime. However, the runtime
461 // might still be loaded if a program or its dependencies are instrumented.
462 // There is nothing we can do to prevent this so we should set the appropriate
463 // ASan options (same as normal variant) if it does happen. We try to do this
464 // here but this currently doesn't work due to rdar://problem/72212914.
465 //
466 // These variants use the following extra options:
467 //
468 // ASAN_OPT_NO_HALT_ON_ERROR - Try to avoid crash loops and increase the
469 // chances of booting successfully.
470 // ASAN_OPT_START_DEACTIVATED - Try to reduce memory overhead.
471
472 # define DEFAULT_ASAN_OPTIONS \
473 COMMON_ASAN_OPTIONS \
474 ASAN_OPT_START_DEACTIVATED \
475 ASAN_OPT_NO_HALT_ON_ERROR
476
477 #elif defined(CURRENT_VARIANT_asan)
478
479 // The `_asan` variant is used to support running proceses with
480 // `DYLD_IMAGE_SUFFIX=_asan`. This mode is typically used to target select parts of the OS.
481 //
482 // It uses the following extra options:
483 //
484 // ASAN_OPT_HALT_ON_ERROR - Crashing is better than just writing the error to the system log
485 // if the system can handle this. This workflow is
486 // more tolerant (e.g. `launchctl debug`) to crashing
487 // than the "whole userspace ASan" workflow.
488
489 # define DEFAULT_ASAN_OPTIONS \
490 COMMON_ASAN_OPTIONS \
491 ASAN_OPT_HALT_ON_ERROR
492
493 #else
494 # error Supporting ASan is not supported in the current variant
495 #endif
496
497 char dynamic_asan_opts[1024] = {0};
498 const char *__asan_default_options(void) {
499 int fd = open("/System/Library/Preferences/com.apple.asan.options", O_RDONLY);
500 if (fd != -1) {
501 ssize_t remaining_size = sizeof(dynamic_asan_opts) - 1;
502 char *p = dynamic_asan_opts;
503 ssize_t read_bytes = 0;
504 do {
505 read_bytes = read(fd, p, remaining_size);
506 remaining_size -= read_bytes;
507 } while (read_bytes > 0);
508 close(fd);
509
510 if (dynamic_asan_opts[0]) {
511 return dynamic_asan_opts;
512 }
513 }
514
515 return DEFAULT_ASAN_OPTIONS;
516 }
517
518 #undef ASAN_OPT_NO_COLOR
519 #undef ASAN_OPT_NO_SIGNAL_HANDLERS
520 #undef ASAN_OPT_NO_OOP_SYMBOLIZER
521 #undef ASAN_OPT_FILE_LOG
522 #undef ASAN_OPT_MODULE_MAP
523 #undef ASAN_OPT_NO_ODR_VIOLATION
524 #undef ASAN_OPT_START_DEACTIVATED
525 #undef ASAN_OPT_NO_HALT_ON_ERROR
526 #undef ASAN_OPT_HALT_ON_ERROR
527
528 #undef COMMON_ASAN_OPTIONS
529 #undef DEFAULT_ASAN_OPTIONS
530
531 #endif
532
533 /*
534 * Old crt1.o glue used to call through mach_init_routine which was used to initialize libSystem.
535 * LibSystem now auto-initializes but mach_init_routine is left for binary compatibility.
536 */
537 static void mach_init_old(void) {}
538 void (*mach_init_routine)(void) = &mach_init_old;
539
540 /*
541 * This __crashreporter_info__ symbol is for all non-dylib parts of libSystem.
542 */
543 const char *__crashreporter_info__;
544 asm (".desc __crashreporter_info__, 0x10");