about summary refs log tree commit diff
path: root/elf/dl-tunables.c
Commit message (Collapse)AuthorAgeFilesLines
* i386: Add <startup.h> [BZ #21913]H.J. Lu2017-08-081-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On Linux/i386, there are 3 ways to make a system call: 1. call *%gs:SYSINFO_OFFSET. This requires TLS initialization. 2. call *_dl_sysinfo. This requires relocation of _dl_sysinfo. 3. int $0x80. This is slower than #2 and #3, but works everywhere. When an object file is compiled with PIC, #1 is prefered since it is faster than #3 and doesn't require relocation of _dl_sysinfo. For dynamic executables, ld.so initializes TLS. However, for static executables, before TLS is initialized by __libc_setup_tls, #3 should be used for system calls. This patch adds <startup.h> which defines _startup_fatal and defaults it to __libc_fatal. It replaces __libc_fatal with _startup_fatal in static executables where it is called before __libc_setup_tls is called. This header file is included in all files containing functions which are called before __libc_setup_tls is called. On Linux/i386, when PIE is enabled by default, _startup_fatal is turned into ABORT_INSTRUCTION and I386_USE_SYSENTER is defined to 0 so that "int $0x80" is used for system calls before __libc_setup_tls is called. Tested on i686 and x86-64. Without this patch, all statically-linked tests will fail on i686 when the compiler defaults to -fPIE. [BZ #21913] * csu/libc-tls.c: Include <startup.h> first. (__libc_setup_tls): Call _startup_fatal instead of __libc_fatal. * elf/dl-tunables.c: Include <startup.h> first. * include/libc-symbols.h (BUILD_PIE_DEFAULT): New. * sysdeps/generic/startup.h: New file. * sysdeps/unix/sysv/linux/i386/startup.h: Likewise. * sysdeps/unix/sysv/linux/i386/brk.c [BUILD_PIE_DEFAULT != 0] (I386_USE_SYSENTER): New. Defined to 0.
* tunables: Use direct syscall for access (BZ#21744)Adhemerval Zanella2017-07-241-0/+2
| | | | | | | | | | | | | | | | | | | | | | | The function maybe_enable_malloc_check, which is called by __tunables_init, calls __access_noerrno. It isn't problem when symbol is is in ld.so, which has a special version of __access_noerrno without stack protector. But when glibc is built with stack protector, maybe_enable_malloc_check in libc.a can't call the regular version of __access_noerrno with stack protector. This patch changes how Linux defines the __access_noerrno to be an inline call instead and thus preventing defining different build rules for ld/static and shared. H.J. Lu <hongjiu.lu@intel.com> Adhemerval Zanella <adhemerval.zanella@linaro.org> [BZ #21744] * elf/dl-tunables.c: Include not-errno.h header. * include/unistd.h (__access_noerrno): Remove definition. * sysdeps/unix/sysv/linux/access.c (__access_noerrno): Likewise. * sysdeps/generic/not-errno.h: New file. * sysdeps/unix/sysv/linux/not-errno.h: Likewise.
* tunables, aarch64: New tunable to override cpuSiddhesh Poyarekar2017-06-301-20/+4
| | | | | | | | | | | | | | | | | | | | Add a new tunable (glibc.tune.cpu) to override CPU identification on aarch64. This is useful in two cases: one where it is desirable to pretend to be another CPU for purposes of testing or because routines written for that CPU are beneficial for specific workloads and second where the underlying kernel does not support emulation of MRS to get the MIDR of the CPU. * elf/dl-tunables.h (tunable_is_name): Move from... * elf/dl-tunables.c (is_name): ... here. (parse_tunables, __tunables_init): Adjust. * manual/tunables.texi: Document glibc.tune.cpu. * sysdeps/aarch64/dl-tunables.list: New file. * sysdeps/unix/sysv/linux/aarch64/cpu-features.c (struct cpu_list): New type. (cpu_list): New list of CPU names and their MIDR. (get_midr_from_mcpu): New function. (init_cpu_features): Override MIDR if necessary.
* ld.so: Consolidate 2 strtouls into _dl_strtoul [BZ #21528]H.J. Lu2017-06-081-68/+1
| | | | | | | | | | | | | | | | | | | | | There are 2 minimal strtoul implementations in ld.so: 1. __strtoul_internal in elf/dl-minimal.c. 2. tunables_strtoul in elf/dl-tunables.c. This patch adds _dl_strtoul to replace them. Tested builds with and without --enable-tunables. [BZ #21528] * elf/dl-minimal.c (__strtoul_internal): Removed. (strtoul): Likewise. * elf/dl-misc.c (_dl_strtoul): New function. * elf/dl-tunables.c (tunables_strtoul): Removed. (tunable_initialize): Replace tunables_strtoul with _dl_strtoul. * elf/rtld.c (process_envvars): Likewise. * sysdeps/unix/sysv/linux/dl-librecon.h (_dl_osversion_init): Likewise. * sysdeps/generic/ldsodefs.h (_dl_strtoul): New prototype.
* tunables: Clean up hooks to get and set tunablesSiddhesh Poyarekar2017-06-071-21/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The TUNABLE_SET_VALUE and family of macros (and my later attempt to add a TUNABLE_GET) never quite went together very well because the overall interface was not clearly defined. This patch is an attempt to do just that. This patch consolidates the API to two simple sets of macros, TUNABLE_GET* and TUNABLE_SET*. If TUNABLE_NAMESPACE is defined, TUNABLE_GET takes just the tunable name, type and a (optionally NULL) callback function to get the value of the tunable. The callback function, if non-NULL, is called if the tunable was externally set (i.e. via GLIBC_TUNABLES or any future mechanism). For example: val = TUNABLE_GET (check, int32_t, check_callback) returns the value of the glibc.malloc.check tunable (assuming TUNABLE_NAMESPACE is set to malloc) as an int32_t into VAL after calling check_callback. Likewise, TUNABLE_SET can be used to set the value of the tunable, although this is currently possible only in the dynamic linker before it relocates itself. For example: TUNABLE_SET (check, int32_t, 2) will set glibc.malloc.check to 2. Of course, this is not possible since we set (or read) glibc.malloc.check long after it is relocated. To access or set a tunable outside of TUNABLE_NAMESPACE, use the TUNABLE_GET_FULL and TUNABLE_SET_FULL macros, which have the following prototype: TUNABLE_GET_FULL (glibc, tune, hwcap_mask, uint64_t, NULL) TUNABLE_SET_FULL (glibc, tune, hwcap_mask, uint64_t, 0xffff) In future the tunable list may get split into mutable and immutable tunables where mutable tunables can be modified by the library and userspace after relocation as well and TUNABLE_SET will be more useful than it currently is. However whenever we actually do that split, we will have to ensure that the mutable tunables are protected with locks. * elf/Versions (__tunable_set_val): Rename to __tunable_get_val. * elf/dl-tunables.c: Likewise. (do_tunable_update_val): New function. (__tunable_set_val): New function. (__tunable_get_val): Call CB only if the tunable was externally initialized. (tunables_strtoul): Replace strval with initialized. * elf/dl-tunables.h (strval): Replace with a bool initialized. (TUNABLE_ENUM_NAME, TUNABLE_ENUM_NAME1): Adjust names to prevent collision. (__tunable_set_val): New function. (TUNABLE_GET, TUNABLE_GET_FULL): New macros. (TUNABLE_SET, TUNABLE_SET_FULL): Likewise. (TUNABLE_SET_VAL): Remove. (TUNABLE_SET_VAL_WITH_CALLBACK): Likewise. * README.tunables: Document the new macros. * malloc/arena.c (ptmalloc_init): Adjust.
* Make __tunables_init hidden and avoid PLTH.J. Lu2017-05-251-0/+2
| | | | | | | | | | | | | Since __tunables_init is internal to ld.so, we should mark it hidden to avoid PLT. We should also avoid PLT when calling __tunable_set_val within ld.so. 2017-05-25 Siddhesh Poyarekar <siddhesh@sourceware.org> H.J. Lu <hongjiu.lu@intel.com> * elf/dl-tunables.c (__tunable_set_val): Make a hidden alias. * elf/dl-tunables.h (__tunables_init): Mark it hidden in rtld. (__tunable_set_val): Likewise.
* tunables: Add support for tunables of uint64_t typeSiddhesh Poyarekar2017-05-171-54/+40
| | | | | | | | | | | | | | | | | | | | | | | | | Recognize the uint64_t type in addition to the current int32_t and size_t. This allows addition of tunables of uint64_t types. In addition to adding the uint64_t type, this patch also consolidates validation and reading of integer types in tunables. One notable change is that of overflow computation in tunables_strtoul. The function was lifted from __internal_strtoul, but it does not need the boundary condition check (i.e. result == ULONG_MAX) since it does not need to set errno. As a result the check can be simplified, which I have now done. * elf/dl-tunable-types.h (tunable_type_code_t): New type TUNABLE_TYPE_UINT_64. * elf/dl-tunables.c (tunables_strtoul): Return uint64_t. Simplify computation of overflow. (tunable_set_val_if_valid_range_signed, tunable_set_val_if_valid_range_unsigned): Remove and replace with this... (TUNABLE_SET_VAL_IF_VALID_RANGE): ... New macro. (tunable_initialize): Adjust. Add uint64_t support. (__tunable_set_val): Add uint64_t support. * README.tunables: Document it.
* Narrowing the visibility of libc-internal.h even further.Zack Weinberg2017-03-011-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | posix/wordexp-test.c used libc-internal.h for PTR_ALIGN_DOWN; similar to what was done with libc-diag.h, I have split the definitions of cast_to_integer, ALIGN_UP, ALIGN_DOWN, PTR_ALIGN_UP, and PTR_ALIGN_DOWN to a new header, libc-pointer-arith.h. It then occurred to me that the remaining declarations in libc-internal.h are mostly to do with early initialization, and probably most of the files including it, even in the core code, don't need it anymore. Indeed, only 19 files actually need what remains of libc-internal.h. 23 others need libc-diag.h instead, and 12 need libc-pointer-arith.h instead. No file needs more than one of them, and 16 don't need any of them! So, with this patch, libc-internal.h stops including libc-diag.h as well as losing the pointer arithmetic macros, and all including files are adjusted. * include/libc-pointer-arith.h: New file. Define cast_to_integer, ALIGN_UP, ALIGN_DOWN, PTR_ALIGN_UP, and PTR_ALIGN_DOWN here. * include/libc-internal.h: Definitions of above macros moved from here. Don't include libc-diag.h anymore either. * posix/wordexp-test.c: Include stdint.h and libc-pointer-arith.h. Don't include libc-internal.h. * debug/pcprofile.c, elf/dl-tunables.c, elf/soinit.c, io/openat.c * io/openat64.c, misc/ptrace.c, nptl/pthread_clock_gettime.c * nptl/pthread_clock_settime.c, nptl/pthread_cond_common.c * string/strcoll_l.c, sysdeps/nacl/brk.c * sysdeps/unix/clock_settime.c * sysdeps/unix/sysv/linux/i386/get_clockfreq.c * sysdeps/unix/sysv/linux/ia64/get_clockfreq.c * sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c * sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c: Don't include libc-internal.h. * elf/get-dynamic-info.h, iconv/loop.c * iconvdata/iso-2022-cn-ext.c, locale/weight.h, locale/weightwc.h * misc/reboot.c, nis/nis_table.c, nptl_db/thread_dbP.h * nscd/connections.c, resolv/res_send.c, soft-fp/fmadf4.c * soft-fp/fmasf4.c, soft-fp/fmatf4.c, stdio-common/vfscanf.c * sysdeps/ieee754/dbl-64/e_lgamma_r.c * sysdeps/ieee754/dbl-64/k_rem_pio2.c * sysdeps/ieee754/flt-32/e_lgammaf_r.c * sysdeps/ieee754/flt-32/k_rem_pio2f.c * sysdeps/ieee754/ldbl-128/k_tanl.c * sysdeps/ieee754/ldbl-128ibm/k_tanl.c * sysdeps/ieee754/ldbl-96/e_lgammal_r.c * sysdeps/ieee754/ldbl-96/k_tanl.c, sysdeps/nptl/futex-internal.h: Include libc-diag.h instead of libc-internal.h. * elf/dl-load.c, elf/dl-reloc.c, locale/programs/locarchive.c * nptl/nptl-init.c, string/strcspn.c, string/strspn.c * malloc/malloc.c, sysdeps/i386/nptl/tls.h * sysdeps/nacl/dl-map-segments.h, sysdeps/x86_64/atomic-machine.h * sysdeps/unix/sysv/linux/spawni.c * sysdeps/x86_64/nptl/tls.h: Include libc-pointer-arith.h instead of libc-internal.h. * elf/get-dynamic-info.h, sysdeps/nacl/dl-map-segments.h * sysdeps/x86_64/atomic-machine.h: Add multiple include guard.
* Fix getting tunable values on big-endian (BZ #21109)Siddhesh Poyarekar2017-02-081-0/+2
| | | | | | | The code to set value passed a tunable_val_t, which when cast to int32_t on big-endian gives the wrong value. Instead, use tunable_val_t.numval instead, which can then be safely cast into int32_t.
* tunables: Fix environment variable processing for setuid binaries (bz #21073)Siddhesh Poyarekar2017-02-021-23/+96
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Florian Weimer pointed out that we have three different kinds of environment variables (and hence tunables): 1. Variables that are removed for setxid processes 2. Variables that are ignored in setxid processes but is passed on to child processes 3. Variables that are passed on to child processes all the time Tunables currently only does (2) and (3) when it should be doing (1) for MALLOC_CHECK_. This patch enhances the is_secure flag in tunables to an enum value that can specify which of the above three categories the tunable (and its envvar alias) belongs to. The default is for tunables to be in (1). Hence, all of the malloc tunables barring MALLOC_CHECK_ are explicitly specified to belong to category (2). There were discussions around abolishing category (2) completely but we can do that as a separate exercise in 2.26. Tested on x86_64 to verify that there are no regressions. [BZ #21073] * elf/dl-tunable-types.h (tunable_seclevel_t): New enum. * elf/dl-tunables.c (tunables_strdup): Remove. (get_next_env): Also return the previous envp. (parse_tunables): Erase tunables of category TUNABLES_SECLEVEL_SXID_ERASE. (maybe_enable_malloc_check): Make MALLOC_CHECK_ TUNABLE_SECLEVEL_NONE if /etc/setuid-debug is accessible. (__tunables_init)[TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring]: Update GLIBC_TUNABLES envvar after parsing. [TUNABLES_FRONTEND != TUNABLES_FRONTEND_valstring]: Erase tunable envvars of category TUNABLES_SECLEVEL_SXID_ERASE. * elf/dl-tunables.h (struct _tunable): Change member is_secure to security_level. * elf/dl-tunables.list: Add security_level annotations for all tunables. * scripts/gen-tunables.awk: Recognize and generate enum values for security_level. * elf/tst-env-setuid.c: New test case. * elf/tst-env-setuid-tunables: new test case. * elf/Makefile (tests-static): Add them.
* * elf/dl-tunables.c (tunable_set_val_if_valid_range): Split into ...DJ Delorie2017-01-201-4/+26
| | | | | | (tunable_set_val_if_valid_range_signed) ... this, and ... (tunable_set_val_if_valid_range_unsigned) ... this. (tunable_initialize): Call the correct one of the above based on type.
* Fix environment traversal when an envvar value is emptySiddhesh Poyarekar2017-01-201-2/+2
| | | | | | | | | | | | | | The condition when the value of an envvar is empty (not just '\0'), the loop in tunables_init gets stuck infinitely because envp is not incremented. Fix that by always incrementing envp in the loop. Added test case (tst-empty-env.c) verifies the fix when the source is configured with --enable-hardcoded-path-in-tests, thanks Josh Stone for providing the test case. Verified on x86_64. * elf/dl-tunables (get_next_env): Always advance envp. * stdlib/tst-empty-env.c: New test case. * stdlib/Makefile (tests): Use it.
* tunables: Avoid getenv calls and disable glibc.malloc.check by defaultSiddhesh Poyarekar2017-01-101-77/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Builds with --enable-tunables failed on i686 because a call to getenv got snuck into tunables, which pulled in strncmp. This patch fixes this build failure by making the glibc.malloc.check check even simpler. The previous approach was convoluted where the tunable was disabled using an unsetenv and overwriting the tunable value with colons. The easier way is to simply mark the tunable as insecure by default (i.e. won't be read for AT_SECURE programs) and then enabled only when the /etc/suid-debug file is found. This also ends up removing a bunch of functions that were specially reimplemented (strlen, unsetenv) to avoid calling into string routines. Tested on x86_64 and i686. * elf/dl-tunables.c (tunables_unsetenv): Remove function. (min_strlen): Likewise. (disable_tunable): Likewise. (maybe_disable_malloc_check): Rename to maybe_enable_malloc_check. (maybe_enable_malloc_check): Enable glibc.malloc.check tunable if /etc/suid-debug file exists. (__tunables_init): Update caller. * elf/dl-tunables.list (glibc.malloc.check): Don't mark as secure.
* Update copyright dates with scripts/update-copyrights.Joseph Myers2017-01-011-1/+1
|
* Enhance --enable-tunables to select tunables frontend at build timeSiddhesh Poyarekar2016-12-311-1/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | At the GNU Tools Cauldron 2016, the state of the current tunables patchset was considered OK with the addition of a way to select the frontend to be used for the tunables. That is, to avoid being locked in to one type of frontend initially, it should be possible to build tunables with a different frontend with something as simple as a configure switch. To that effect, this patch enhances the --enable-tunables option to accept more values than just 'yes' or 'no'. The current frontend (and default when enable-tunables is 'yes') is called 'valstring', to select the frontend where a single environment variable is set to a colon-separated value string. More such frontends can be added in future. * Makeconfig (have-tunables): Check for non-negative instead of positive. * configure.ac: Add 'valstring' as a valid value for --enable-tunables. * configure: Regenerate. * elf/Makefile (have-tunables): Check for non-negative instead of positive. (CPPFLAGS-dl-tunables.c): Define TUNABLES_FRONTEND for dl-tunables.c. * elf/dl-tunables.c (GLIBC_TUNABLES): Define only when TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring. (tunables_strdup): Likewise. (disable_tunables): Likewise. (parse_tunables): Likewise. (__tunables_init): Process GLIBC_TUNABLES envvar only when. TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring. * elf/dl-tunables.h (TUNABLES_FRONTEND_valstring): New macro. (TUNABLES_FRONTEND_yes): New macro, define as TUNABLES_FRONTEND_valstring by default. * manual/install.texi: Document new acceptable values for --enable-tunables. * INSTALL: Regenerate.
* Initialize tunable list with the GLIBC_TUNABLES environment variableSiddhesh Poyarekar2016-12-311-1/+128
| | | | | | | | | | | | | | | | | | | | | | Read tunables values from the users using the GLIBC_TUNABLES environment variable. The value of this variable is a colon-separated list of name=value pairs. So a typical string would look like this: GLIBC_TUNABLES=glibc.malloc.mmap_threshold=2048:glibc.malloc.trim_threshold=1024 * config.make.in (have-loop-to-function): Define. * elf/Makefile (CFLAGS-dl-tunables.c): Add -fno-tree-loop-distribute-patterns. * elf/dl-tunables.c: Include libc-internals.h. (GLIBC_TUNABLES): New macro. (tunables_strdup): New function. (parse_tunables): New function. (min_strlen): New function. (__tunables_init): Use the new functions and macro. (disable_tunable): Disable tunable from GLIBC_TUNABLES. * malloc/tst-malloc-usable-tunables.c: New test case. * malloc/tst-malloc-usable-static-tunables.c: New test case. * malloc/Makefile (tests, tests-static): Add tests.
* Add framework for tunablesSiddhesh Poyarekar2016-12-311-0/+320
The tunables framework allows us to uniformly manage and expose global variables inside glibc as switches to users. tunables/README has instructions for glibc developers to add new tunables. Tunables support can be enabled by passing the --enable-tunables configure flag to the configure script. This patch only adds a framework and does not pose any limitations on how tunable values are read from the user. It also adds environment variables used in malloc behaviour tweaking to the tunables framework as a PoC of the compatibility interface. * manual/install.texi: Add --enable-tunables option. * INSTALL: Regenerate. * README.tunables: New file. * Makeconfig (CPPFLAGS): Define TOP_NAMESPACE. (before-compile): Generate dl-tunable-list.h early. * config.h.in: Add HAVE_TUNABLES. * config.make.in: Add have-tunables. * configure.ac: Add --enable-tunables option. * configure: Regenerate. * csu/init-first.c (__libc_init_first): Move __libc_init_secure earlier... * csu/init-first.c (LIBC_START_MAIN):... to here. Include dl-tunables.h, libc-internal.h. (LIBC_START_MAIN) [!SHARED]: Initialize tunables for static binaries. * elf/Makefile (dl-routines): Add dl-tunables. * elf/Versions (ld): Add __tunable_set_val to GLIBC_PRIVATE namespace. * elf/dl-support (_dl_nondynamic_init): Unset MALLOC_CHECK_ only when !HAVE_TUNABLES. * elf/rtld.c (process_envvars): Likewise. * elf/dl-sysdep.c [HAVE_TUNABLES]: Include dl-tunables.h (_dl_sysdep_start): Call __tunables_init. * elf/dl-tunable-types.h: New file. * elf/dl-tunables.c: New file. * elf/dl-tunables.h: New file. * elf/dl-tunables.list: New file. * malloc/tst-malloc-usable-static.c: New test case. * malloc/Makefile (tests-static): Add it. * malloc/arena.c [HAVE_TUNABLES]: Include dl-tunables.h. Define TUNABLE_NAMESPACE. (DL_TUNABLE_CALLBACK (set_mallopt_check)): New function. (DL_TUNABLE_CALLBACK_FNDECL): New macro. Use it to define callback functions. (ptmalloc_init): Set tunable values. * scripts/gen-tunables.awk: New file. * sysdeps/mach/hurd/dl-sysdep.c: Include dl-tunables.h. (_dl_sysdep_start): Call __tunables_init.