diff options
Diffstat (limited to 'libc/elf')
32 files changed, 355 insertions, 58 deletions
diff --git a/libc/elf/Makefile b/libc/elf/Makefile index aaa9534b2..27d249b2f 100644 --- a/libc/elf/Makefile +++ b/libc/elf/Makefile @@ -121,7 +121,8 @@ endif tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1 \ tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 tests-static = tst-tls1-static tst-tls2-static tst-stackguard1-static \ - tst-leaks1-static tst-array1-static tst-array5-static + tst-leaks1-static tst-array1-static tst-array5-static \ + tst-ptrguard1-static ifeq (yes,$(build-shared)) tests-static += tst-tls9-static tst-tls9-static-ENV = \ @@ -145,7 +146,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit1 tst-audit2 tst-audit8 \ tst-stackguard1 tst-addr1 tst-thrlock \ tst-unique1 tst-unique2 tst-unique3 tst-unique4 \ - tst-initorder tst-initorder2 tst-relsort1 tst-null-argv + tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \ + tst-ptrguard1 # reldep9 test-srcs = tst-pathopt selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null) @@ -1016,6 +1018,12 @@ LDFLAGS-order2mod2.so = $(no-as-needed) tst-stackguard1-ARGS = --command "$(host-test-program-cmd) --child" tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child" +tst-ptrguard1-ARGS = --command "$(host-test-program-cmd) --child" +# When built statically, the pointer guard interface uses +# __pointer_chk_guard_local. +CFLAGS-tst-ptrguard1-static.c = -DPTRGUARD_LOCAL +tst-ptrguard1-static-ARGS = --command "$(objpfx)tst-ptrguard1-static --child" + $(objpfx)tst-leaks1: $(libdl) $(objpfx)tst-leaks1-mem: $(objpfx)tst-leaks1.out $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@ diff --git a/libc/elf/cache.c b/libc/elf/cache.c index 9bf261cd2..1a43dd776 100644 --- a/libc/elf/cache.c +++ b/libc/elf/cache.c @@ -105,6 +105,15 @@ print_entry (const char *lib, int flag, unsigned int osversion, case FLAG_ARM_LIBSF: fputs (",soft-float", stdout); break; + case FLAG_MIPS_LIB32_NAN2008: + fputs (",nan2008", stdout); + break; + case FLAG_MIPS64_LIBN32_NAN2008: + fputs (",N32,nan2008", stdout); + break; + case FLAG_MIPS64_LIBN64_NAN2008: + fputs (",64bit,nan2008", stdout); + break; case 0: break; default: diff --git a/libc/elf/dl-deps.c b/libc/elf/dl-deps.c index 6cdb3b8e5..6e7bb962e 100644 --- a/libc/elf/dl-deps.c +++ b/libc/elf/dl-deps.c @@ -595,7 +595,6 @@ Filters not supported with LD_TRACE_PRELINKING")); if (list[i]->l_reserved) { /* Need to allocate new array of relocation dependencies. */ - struct link_map_reldeps *l_reldeps; l_reldeps = malloc (sizeof (*l_reldeps) + map->l_reldepsmax * sizeof (struct link_map *)); diff --git a/libc/elf/dl-libc.c b/libc/elf/dl-libc.c index aba0d1af1..397d89899 100644 --- a/libc/elf/dl-libc.c +++ b/libc/elf/dl-libc.c @@ -286,6 +286,7 @@ libc_freeres_fn (free_mem) /* Free the initfini dependency list. */ if (l->l_free_initfini) free (l->l_initfini); + l->l_initfini = NULL; } if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0 diff --git a/libc/elf/dl-support.c b/libc/elf/dl-support.c index fe5804fe3..5d19b29cc 100644 --- a/libc/elf/dl-support.c +++ b/libc/elf/dl-support.c @@ -170,6 +170,9 @@ size_t _dl_phnum; uint64_t _dl_hwcap __attribute__ ((nocommon)); uint64_t _dl_hwcap2 __attribute__ ((nocommon)); +/* The value of the FPU control word the kernel will preset in hardware. */ +fpu_control_t _dl_fpu_control = _FPU_DEFAULT; + /* This is not initialized to HWCAP_IMPORTANT, matching the definition of _dl_important_hwcaps, below, where no hwcap strings are ever used. This mask is still used to mediate the lookups in the cache @@ -256,6 +259,9 @@ _dl_aux_init (ElfW(auxv_t) *av) case AT_HWCAP2: GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; break; + case AT_FPUCW: + GLRO(dl_fpu_control) = av->a_un.a_val; + break; #ifdef NEED_DL_SYSINFO case AT_SYSINFO: GL(dl_sysinfo) = av->a_un.a_val; diff --git a/libc/elf/elf.h b/libc/elf/elf.h index fe55c928c..a05ea3b64 100644 --- a/libc/elf/elf.h +++ b/libc/elf/elf.h @@ -1383,6 +1383,7 @@ typedef struct #define EF_MIPS_64BIT_WHIRL 16 #define EF_MIPS_ABI2 32 #define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */ #define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */ /* Legal values for MIPS architecture level. */ @@ -2335,6 +2336,117 @@ typedef Elf32_Addr Elf32_Conflict; #define R_AARCH64_NONE 0 /* No relocation. */ #define R_AARCH64_ABS64 257 /* Direct 64 bit. */ #define R_AARCH64_ABS32 258 /* Direct 32 bit. */ +#define R_AARCH64_ABS16 259 /* Direct 16-bit. */ +#define R_AARCH64_PREL64 260 /* PC-relative 64-bit. */ +#define R_AARCH64_PREL32 261 /* PC-relative 32-bit. */ +#define R_AARCH64_PREL16 262 /* PC-relative 16-bit. */ +#define R_AARCH64_MOVW_UABS_G0 263 /* Dir. MOVZ imm. from bits 15:0. */ +#define R_AARCH64_MOVW_UABS_G0_NC 264 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_UABS_G1 265 /* Dir. MOVZ imm. from bits 31:16. */ +#define R_AARCH64_MOVW_UABS_G1_NC 266 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_UABS_G2 267 /* Dir. MOVZ imm. from bits 47:32. */ +#define R_AARCH64_MOVW_UABS_G2_NC 268 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_UABS_G3 269 /* Dir. MOV{K,Z} imm. from 63:48. */ +#define R_AARCH64_MOVW_SABS_G0 270 /* Dir. MOV{N,Z} imm. from 15:0. */ +#define R_AARCH64_MOVW_SABS_G1 271 /* Dir. MOV{N,Z} imm. from 31:16. */ +#define R_AARCH64_MOVW_SABS_G2 272 /* Dir. MOV{N,Z} imm. from 47:32. */ +#define R_AARCH64_LD_PREL_LO19 273 /* PC-rel. LD imm. from bits 20:2. */ +#define R_AARCH64_ADR_PREL_LO21 274 /* PC-rel. ADR imm. from bits 20:0. */ +#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page-rel. ADRP imm. from 32:12. */ +#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check. */ +#define R_AARCH64_ADD_ABS_LO12_NC 277 /* Dir. ADD imm. from bits 11:0. */ +#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */ +#define R_AARCH64_TSTBR14 279 /* PC-rel. TBZ/TBNZ imm. from 15:2. */ +#define R_AARCH64_CONDBR19 280 /* PC-rel. cond. br. imm. from 20:2. */ +#define R_AARCH64_JUMP26 282 /* PC-rel. B imm. from bits 27:2. */ +#define R_AARCH64_CALL26 283 /* Likewise for CALL. */ +#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1. */ +#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2. */ +#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3. */ +#define R_AARCH64_MOVW_PREL_G0 287 /* PC-rel. MOV{N,Z} imm. from 15:0. */ +#define R_AARCH64_MOVW_PREL_G0_NC 288 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_PREL_G1 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */ +#define R_AARCH64_MOVW_PREL_G1_NC 290 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_PREL_G2 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */ +#define R_AARCH64_MOVW_PREL_G2_NC 292 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_PREL_G3 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */ +#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4. */ +#define R_AARCH64_MOVW_GOTOFF_G0 300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */ +#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_GOTOFF_G1 302 /* GOT-rel. o. MOV{N,Z} imm. 31:16. */ +#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_GOTOFF_G2 304 /* GOT-rel. o. MOV{N,Z} imm. 47:32. */ +#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check. */ +#define R_AARCH64_MOVW_GOTOFF_G3 306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */ +#define R_AARCH64_GOTREL64 307 /* GOT-relative 64-bit. */ +#define R_AARCH64_GOTREL32 308 /* GOT-relative 32-bit. */ +#define R_AARCH64_GOT_LD_PREL19 309 /* PC-rel. GOT off. load imm. 20:2. */ +#define R_AARCH64_LD64_GOTOFF_LO15 310 /* GOT-rel. off. LD/ST imm. 14:3. */ +#define R_AARCH64_ADR_GOT_PAGE 311 /* P-page-rel. GOT off. ADRP 32:12. */ +#define R_AARCH64_LD64_GOT_LO12_NC 312 /* Dir. GOT off. LD/ST imm. 11:3. */ +#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */ +#define R_AARCH64_TLSGD_ADR_PREL21 512 /* PC-relative ADR imm. 20:0. */ +#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* page-rel. ADRP imm. 32:12. */ +#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0. */ +#define R_AARCH64_TLSGD_MOVW_G1 515 /* GOT-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* GOT-rel. MOVK imm. 15:0. */ +#define R_AARCH64_TLSLD_ADR_PREL21 517 /* Like 512; local dynamic model. */ +#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Like 513; local dynamic model. */ +#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model. */ +#define R_AARCH64_TLSLD_MOVW_G1 520 /* Like 515; local dynamic model. */ +#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* Like 516; local dynamic model. */ +#define R_AARCH64_TLSLD_LD_PREL19 522 /* TLS PC-rel. load imm. 20:2. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0. */ +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */ +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0. */ +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check. */ +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0. */ +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1. */ +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2. */ +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3. */ +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check. */ +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0. */ +#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12. */ +#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3. */ +#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0. */ +#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check. */ +#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12. */ +#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0. */ +#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check. */ +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0. */ +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */ +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1. */ +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check. */ +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2. */ +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check. */ +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3. */ +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check. */ +#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2. */ +#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0. */ +#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12. */ +#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3. */ +#define R_AARCH64_TLSDESC_ADD_LO12 564 /* Direct ADD imm. from 11:0. */ +#define R_AARCH64_TLSDESC_OFF_G1 565 /* GOT-rel. MOV{N,Z} imm. 31:16. */ +#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck. */ +#define R_AARCH64_TLSDESC_LDR 567 /* Relax LDR. */ +#define R_AARCH64_TLSDESC_ADD 568 /* Relax ADD. */ +#define R_AARCH64_TLSDESC_CALL 569 /* Relax BLR. */ +#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4. */ +#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check. */ +#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */ +#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check. */ #define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */ #define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ #define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ @@ -2343,6 +2455,7 @@ typedef Elf32_Addr Elf32_Conflict; #define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */ #define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */ #define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ +#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ /* ARM relocs. */ diff --git a/libc/elf/ldd.bash.in b/libc/elf/ldd.bash.in index 73e35662d..c4a1a1513 100644 --- a/libc/elf/ldd.bash.in +++ b/libc/elf/ldd.bash.in @@ -44,7 +44,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. exit 0 ;; --h | --he | --hel | --help) - printf $"Usage: ldd [OPTION]... FILE... + echo $"Usage: ldd [OPTION]... FILE... --help print this help and exit --version print version information and exit -d, --data-relocs process data relocations @@ -106,19 +106,18 @@ if test "$unused" = yes; then add_env="$add_env LD_DEBUG=\"$LD_DEBUG${LD_DEBUG:+,}unused\"" fi -# The following use of cat is needed to make ldd work in SELinux -# environments where the executed program might not have permissions -# to write to the console/tty. But only bash 3.x supports the pipefail -# option, and we don't bother to handle the case for older bash versions. -if x=`set -o` && test "$x" != "${x#*pipefail}" && set -o pipefail ; then - try_trace() { - eval $add_env '"$@"' | cat - } -else - try_trace() { - eval $add_env '"$@"' - } -fi +# The following command substitution is needed to make ldd work in SELinux +# environments where the RTLD might not have permission to write to the +# terminal. The extra "x" character prevents the shell from trimming trailing +# newlines from command substitution results. This function is defined as a +# subshell compound list (using "(...)") to prevent parameter assignments from +# affecting the calling shell execution environment. +try_trace() ( + output=$(eval $add_env '"$@"' 2>&1; rc=$?; printf 'x'; exit $rc) + rc=$? + printf '%s' "${output%x}" + return $rc +) case $# in 0) diff --git a/libc/elf/tst-ptrguard1-static.c b/libc/elf/tst-ptrguard1-static.c new file mode 100644 index 000000000..7aff3b7b5 --- /dev/null +++ b/libc/elf/tst-ptrguard1-static.c @@ -0,0 +1 @@ +#include "tst-ptrguard1.c" diff --git a/libc/elf/tst-ptrguard1.c b/libc/elf/tst-ptrguard1.c new file mode 100644 index 000000000..c344a04db --- /dev/null +++ b/libc/elf/tst-ptrguard1.c @@ -0,0 +1,202 @@ +/* Copyright (C) 2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/wait.h> +#include <stackguard-macros.h> +#include <tls.h> +#include <unistd.h> + +#ifndef POINTER_CHK_GUARD +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif + +static const char *command; +static bool child; +static uintptr_t ptr_chk_guard_copy; +static bool ptr_chk_guard_copy_set; +static int fds[2]; + +static void __attribute__ ((constructor)) +con (void) +{ + ptr_chk_guard_copy = POINTER_CHK_GUARD; + ptr_chk_guard_copy_set = true; +} + +static int +uintptr_t_cmp (const void *a, const void *b) +{ + if (*(uintptr_t *) a < *(uintptr_t *) b) + return 1; + if (*(uintptr_t *) a > *(uintptr_t *) b) + return -1; + return 0; +} + +static int +do_test (void) +{ + if (!ptr_chk_guard_copy_set) + { + puts ("constructor has not been run"); + return 1; + } + + if (ptr_chk_guard_copy != POINTER_CHK_GUARD) + { + puts ("POINTER_CHK_GUARD changed between constructor and do_test"); + return 1; + } + + if (child) + { + write (2, &ptr_chk_guard_copy, sizeof (ptr_chk_guard_copy)); + return 0; + } + + if (command == NULL) + { + puts ("missing --command or --child argument"); + return 1; + } + +#define N 16 + uintptr_t child_ptr_chk_guards[N + 1]; + child_ptr_chk_guards[N] = ptr_chk_guard_copy; + int i; + for (i = 0; i < N; ++i) + { + if (pipe (fds) < 0) + { + printf ("couldn't create pipe: %m\n"); + return 1; + } + + pid_t pid = fork (); + if (pid < 0) + { + printf ("fork failed: %m\n"); + return 1; + } + + if (!pid) + { + if (ptr_chk_guard_copy != POINTER_CHK_GUARD) + { + puts ("POINTER_CHK_GUARD changed after fork"); + exit (1); + } + + close (fds[0]); + close (2); + dup2 (fds[1], 2); + close (fds[1]); + + system (command); + exit (0); + } + + close (fds[1]); + + if (TEMP_FAILURE_RETRY (read (fds[0], &child_ptr_chk_guards[i], + sizeof (uintptr_t))) != sizeof (uintptr_t)) + { + puts ("could not read ptr_chk_guard value from child"); + return 1; + } + + close (fds[0]); + + pid_t termpid; + int status; + termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)); + if (termpid == -1) + { + printf ("waitpid failed: %m\n"); + return 1; + } + else if (termpid != pid) + { + printf ("waitpid returned %ld != %ld\n", + (long int) termpid, (long int) pid); + return 1; + } + else if (!WIFEXITED (status) || WEXITSTATUS (status)) + { + puts ("child hasn't exited with exit status 0"); + return 1; + } + } + + qsort (child_ptr_chk_guards, N + 1, sizeof (uintptr_t), uintptr_t_cmp); + + /* The default pointer guard is the same as the default stack guard. + They are only set to default if dl_random is NULL. */ + uintptr_t default_guard = 0; + unsigned char *p = (unsigned char *) &default_guard; + p[sizeof (uintptr_t) - 1] = 255; + p[sizeof (uintptr_t) - 2] = '\n'; + p[0] = 0; + + /* Test if the pointer guard canaries are either randomized, + or equal to the default pointer guard value. + Even with randomized pointer guards it might happen + that the random number generator generates the same + values, but if that happens in more than half from + the 16 runs, something is very wrong. */ + int ndifferences = 0; + int ndefaults = 0; + for (i = 0; i < N; ++i) + { + if (child_ptr_chk_guards[i] != child_ptr_chk_guards[i+1]) + ndifferences++; + else if (child_ptr_chk_guards[i] == default_guard) + ndefaults++; + } + + printf ("differences %d defaults %d\n", ndifferences, ndefaults); + + if (ndifferences < N / 2 && ndefaults < N / 2) + { + puts ("pointer guard values are not randomized enough"); + puts ("nor equal to the default value"); + return 1; + } + + return 0; +} + +#define OPT_COMMAND 10000 +#define OPT_CHILD 10001 +#define CMDLINE_OPTIONS \ + { "command", required_argument, NULL, OPT_COMMAND }, \ + { "child", no_argument, NULL, OPT_CHILD }, +#define CMDLINE_PROCESS \ + case OPT_COMMAND: \ + command = optarg; \ + break; \ + case OPT_CHILD: \ + child = true; \ + break; +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/libc/elf/tst-tls-dlinfo.c b/libc/elf/tst-tls-dlinfo.c index 26c281117..28661b19c 100644 --- a/libc/elf/tst-tls-dlinfo.c +++ b/libc/elf/tst-tls-dlinfo.c @@ -2,8 +2,6 @@ #include <stdio.h> #include <stdlib.h> -#include <tls.h> - #define TEST_FUNCTION do_test () static int diff --git a/libc/elf/tst-tls1.c b/libc/elf/tst-tls1.c index 3b9b10f9a..bec0a2ff2 100644 --- a/libc/elf/tst-tls1.c +++ b/libc/elf/tst-tls1.c @@ -1,8 +1,6 @@ /* glibc test for TLS in ld.so. */ #include <stdio.h> -#include <tls.h> - #include "tls-macros.h" diff --git a/libc/elf/tst-tls10.h b/libc/elf/tst-tls10.h index 2b5709af7..7c8c6a639 100644 --- a/libc/elf/tst-tls10.h +++ b/libc/elf/tst-tls10.h @@ -1,4 +1,3 @@ -#include <tls.h> #include <stdlib.h> struct A diff --git a/libc/elf/tst-tls14.c b/libc/elf/tst-tls14.c index ffd31e97b..6bacb599d 100644 --- a/libc/elf/tst-tls14.c +++ b/libc/elf/tst-tls14.c @@ -4,8 +4,6 @@ #include <stdio.h> #include <stdlib.h> -#include <tls.h> - #define AL 4096 struct foo { diff --git a/libc/elf/tst-tls2.c b/libc/elf/tst-tls2.c index 3d13272c0..d0b6d5140 100644 --- a/libc/elf/tst-tls2.c +++ b/libc/elf/tst-tls2.c @@ -1,8 +1,6 @@ /* glibc test for TLS in ld.so. */ #include <stdio.h> -#include <tls.h> - #include "tls-macros.h" diff --git a/libc/elf/tst-tls3.c b/libc/elf/tst-tls3.c index c5e501eb4..ca96c6a07 100644 --- a/libc/elf/tst-tls3.c +++ b/libc/elf/tst-tls3.c @@ -1,8 +1,6 @@ /* glibc test for TLS in ld.so. */ #include <stdio.h> -#include <tls.h> - #include "tls-macros.h" diff --git a/libc/elf/tst-tls4.c b/libc/elf/tst-tls4.c index 4ae33db24..63170c347 100644 --- a/libc/elf/tst-tls4.c +++ b/libc/elf/tst-tls4.c @@ -2,8 +2,6 @@ #include <stdio.h> #include <stdlib.h> -#include <tls.h> - #define TEST_FUNCTION do_test () static int diff --git a/libc/elf/tst-tls5.c b/libc/elf/tst-tls5.c index 27b18294f..76905c56d 100644 --- a/libc/elf/tst-tls5.c +++ b/libc/elf/tst-tls5.c @@ -2,8 +2,6 @@ #include <stdio.h> #include <stdlib.h> -#include <tls.h> - #define TEST_FUNCTION do_test () static int diff --git a/libc/elf/tst-tls6.c b/libc/elf/tst-tls6.c index 021622d9c..9e6235f1d 100644 --- a/libc/elf/tst-tls6.c +++ b/libc/elf/tst-tls6.c @@ -3,7 +3,6 @@ #include <stdlib.h> #include <link.h> -#include <tls.h> #define TEST_FUNCTION do_test () diff --git a/libc/elf/tst-tls7.c b/libc/elf/tst-tls7.c index 1edc2b635..23a16e448 100644 --- a/libc/elf/tst-tls7.c +++ b/libc/elf/tst-tls7.c @@ -3,7 +3,6 @@ #include <stdlib.h> #include <link.h> -#include <tls.h> #define TEST_FUNCTION do_test () diff --git a/libc/elf/tst-tls8.c b/libc/elf/tst-tls8.c index 36b1baca6..4bf3e3ffb 100644 --- a/libc/elf/tst-tls8.c +++ b/libc/elf/tst-tls8.c @@ -3,7 +3,6 @@ #include <stdlib.h> #include <link.h> -#include <tls.h> #define TEST_FUNCTION do_test () diff --git a/libc/elf/tst-tls9.c b/libc/elf/tst-tls9.c index 12078518f..6306fb565 100644 --- a/libc/elf/tst-tls9.c +++ b/libc/elf/tst-tls9.c @@ -3,7 +3,6 @@ #include <stdlib.h> #include <link.h> -#include <tls.h> #define TEST_FUNCTION do_test () static int diff --git a/libc/elf/tst-tlsmod1.c b/libc/elf/tst-tlsmod1.c index 4d966c947..8d9156791 100644 --- a/libc/elf/tst-tlsmod1.c +++ b/libc/elf/tst-tlsmod1.c @@ -1,7 +1,5 @@ #include <stdio.h> -#include <tls.h> - #include "tls-macros.h" diff --git a/libc/elf/tst-tlsmod13.c b/libc/elf/tst-tlsmod13.c index 76da630a0..7712d8b8c 100644 --- a/libc/elf/tst-tlsmod13.c +++ b/libc/elf/tst-tlsmod13.c @@ -1,5 +1,3 @@ -#include <tls.h> - __thread int a[2] __attribute__ ((tls_model ("initial-exec"))); int diff --git a/libc/elf/tst-tlsmod13a.c b/libc/elf/tst-tlsmod13a.c index d5515d4a1..ca4eaccbf 100644 --- a/libc/elf/tst-tlsmod13a.c +++ b/libc/elf/tst-tlsmod13a.c @@ -1,5 +1,3 @@ -#include <tls.h> - __thread int b[2] __attribute__ ((tls_model ("initial-exec"))); extern int foo (void); diff --git a/libc/elf/tst-tlsmod14a.c b/libc/elf/tst-tlsmod14a.c index 6806d3403..824c06d1f 100644 --- a/libc/elf/tst-tlsmod14a.c +++ b/libc/elf/tst-tlsmod14a.c @@ -1,8 +1,6 @@ #include <stdint.h> #include <stdio.h> -#include <tls.h> - #define AL 4096 struct foo { diff --git a/libc/elf/tst-tlsmod16a.c b/libc/elf/tst-tlsmod16a.c index c16e603c8..4ec6a6c37 100644 --- a/libc/elf/tst-tlsmod16a.c +++ b/libc/elf/tst-tlsmod16a.c @@ -1,3 +1 @@ -#include <tls.h> - int __thread tlsvar; diff --git a/libc/elf/tst-tlsmod16b.c b/libc/elf/tst-tlsmod16b.c index 7268c56bc..1ecba26db 100644 --- a/libc/elf/tst-tlsmod16b.c +++ b/libc/elf/tst-tlsmod16b.c @@ -1,5 +1,3 @@ -#include <tls.h> - extern __thread int tlsvar __attribute__((tls_model("initial-exec"))); void * diff --git a/libc/elf/tst-tlsmod2.c b/libc/elf/tst-tlsmod2.c index 981923313..40eb1407f 100644 --- a/libc/elf/tst-tlsmod2.c +++ b/libc/elf/tst-tlsmod2.c @@ -1,7 +1,5 @@ #include <stdio.h> -#include <tls.h> - #include "tls-macros.h" diff --git a/libc/elf/tst-tlsmod3.c b/libc/elf/tst-tlsmod3.c index 5c456ee2d..6d186c47e 100644 --- a/libc/elf/tst-tlsmod3.c +++ b/libc/elf/tst-tlsmod3.c @@ -1,7 +1,5 @@ #include <stdio.h> -#include <tls.h> - #include "tls-macros.h" extern int in_dso (int n, int *caller_foop); diff --git a/libc/elf/tst-tlsmod4.c b/libc/elf/tst-tlsmod4.c index dd9548661..86889aac7 100644 --- a/libc/elf/tst-tlsmod4.c +++ b/libc/elf/tst-tlsmod4.c @@ -1,7 +1,5 @@ #include <stdio.h> -#include <tls.h> - #include "tls-macros.h" diff --git a/libc/elf/tst-tlsmod5.c b/libc/elf/tst-tlsmod5.c index 00d3a9d92..a97c7e5e0 100644 --- a/libc/elf/tst-tlsmod5.c +++ b/libc/elf/tst-tlsmod5.c @@ -1,5 +1,3 @@ -#include <tls.h> - #include "tls-macros.h" COMMON_INT_DEF(foo); diff --git a/libc/elf/tst-tlsmod6.c b/libc/elf/tst-tlsmod6.c index 244d9ae48..e968596dd 100644 --- a/libc/elf/tst-tlsmod6.c +++ b/libc/elf/tst-tlsmod6.c @@ -1,5 +1,3 @@ -#include <tls.h> - #include "tls-macros.h" COMMON_INT_DEF(bar); |