From c6f206fa055c3d6fada2943ef77c84e560aacee2 Mon Sep 17 00:00:00 2001 From: GNU Libc Maintainers Date: Tue, 5 May 2020 19:12:38 +0100 Subject: [PATCH] git-updates GIT update of https://sourceware.org/git/glibc.git/release/2.30/master from glibc-2.30 GIT update of https://sourceware.org/git/glibc.git/release/2.30/master from glibc-2.30 Gbp-Pq: Name git-updates.diff --- ChangeLog | 211 ++++++++ NEWS | 48 ++ bits/utmp.h | 104 +++- configure | 25 +- configure.ac | 11 +- debug/tst-backtrace5.c | 12 + elf/dl-tunables.list | 5 + libio/oldstdfiles.c | 5 + localedata/locales/bo_CN | 1 + localedata/locales/ug_CN | 1 + localedata/locales/zh_CN | 1 + login/Makefile | 6 +- login/getutent_r.c | 108 +--- login/getutid_r.c | 7 +- login/getutline_r.c | 2 +- login/getutmp.c | 12 - login/getutmpx.c | 13 - login/login.c | 4 - login/logout.c | 10 - login/logwtmp.c | 10 - login/programs/utmpdump.c | 46 +- login/tst-pututxline-cache.c | 193 +++++++ login/tst-pututxline-lockfail.c | 176 ++++++ login/tst-updwtmpx.c | 112 ++++ login/tst-utmp.c | 25 - login/updwtmp.c | 2 +- login/utmp-private.h | 29 +- login/utmp_file.c | 511 +++++++++--------- login/utmpname.c | 3 +- malloc/Makefile | 6 +- malloc/arena.c | 2 + malloc/malloc.c | 31 +- malloc/malloc.h | 3 +- malloc/tst-mallocfork2.c | 39 +- malloc/tst-mxfast.c | 50 ++ malloc/tst-pvalloc-fortify.c | 48 ++ misc/sys/cdefs.h | 8 - posix/glob.c | 25 +- stdlib/Makefile | 3 +- stdlib/tst-system.c | 124 ++++- string/string.h | 3 +- string/test-strstr.c | 41 +- support/shell-container.c | 40 +- sysdeps/alpha/fpu/libm-test-ulps | 16 +- sysdeps/arm/be/nofpu/Implies | 1 + sysdeps/arm/le/nofpu/Implies | 1 + sysdeps/generic/not-cancel.h | 2 + sysdeps/generic/utmp-equal.h | 34 +- sysdeps/gnu/bits/utmp.h | 126 ----- sysdeps/gnu/bits/utmpx.h | 12 +- sysdeps/hppa/dl-fptr.c | 26 +- sysdeps/hppa/dl-machine.h | 36 +- sysdeps/hppa/dl-runtime.c | 58 ++ sysdeps/hppa/dl-trampoline.S | 74 ++- sysdeps/hppa/fpu/libm-test-ulps | 88 +-- sysdeps/i386/sysdep.h | 5 +- sysdeps/ieee754/ldbl-96/Makefile | 5 +- sysdeps/ieee754/ldbl-96/e_rem_pio2l.c | 12 + sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c | 41 ++ sysdeps/posix/system.c | 18 +- sysdeps/powerpc/powerpc32/backtrace.c | 2 + sysdeps/powerpc/powerpc64/backtrace.c | 2 + sysdeps/s390/dl-procinfo.c | 4 +- sysdeps/s390/dl-procinfo.h | 2 +- sysdeps/s390/strstr-arch13.S | 2 +- sysdeps/unix/getlogin_r.c | 7 +- sysdeps/unix/sysv/linux/Makefile | 4 +- sysdeps/unix/sysv/linux/Versions | 1 + sysdeps/unix/{ => sysv/linux}/alpha/getegid.S | 0 sysdeps/unix/{ => sysv/linux}/alpha/geteuid.S | 0 sysdeps/unix/{ => sysv/linux}/alpha/getppid.S | 0 sysdeps/unix/sysv/linux/bits/statx.h | 12 +- sysdeps/unix/sysv/linux/hppa/atomic-machine.h | 28 + sysdeps/unix/sysv/linux/hppa/clone.S | 9 +- sysdeps/unix/sysv/linux/microblaze/sysdep.h | 91 ++-- sysdeps/unix/sysv/linux/mips/Makefile | 21 +- sysdeps/unix/sysv/linux/mips/configure | 41 ++ sysdeps/unix/sysv/linux/mips/configure.ac | 32 ++ .../sysv/linux/mips/mips32/mips-syscall5.S | 6 +- .../sysv/linux/mips/mips32/mips-syscall6.S | 6 +- .../sysv/linux/mips/mips32/mips-syscall7.S | 7 +- .../linux/mips/mips32/mips16/mips16-syscall.h | 64 ++- .../mips/mips32/mips16/mips16-syscall0.c | 4 +- .../mips/mips32/mips16/mips16-syscall1.c | 6 +- .../mips/mips32/mips16/mips16-syscall2.c | 6 +- .../mips/mips32/mips16/mips16-syscall3.c | 6 +- .../mips/mips32/mips16/mips16-syscall4.c | 6 +- sysdeps/unix/sysv/linux/mips/mips32/sysdep.h | 147 ++--- .../unix/sysv/linux/mips/mips64/n32/sysdep.h | 123 +++-- .../unix/sysv/linux/mips/mips64/n64/sysdep.h | 121 +++-- sysdeps/unix/sysv/linux/mips/mips64/syscall.S | 2 +- sysdeps/unix/sysv/linux/not-cancel.h | 4 + sysdeps/unix/sysv/linux/pread64_nocancel.c | 32 ++ sysdeps/unix/sysv/linux/riscv/sysdep.h | 84 ++- sysdeps/unix/sysv/linux/riscv/vfork.S | 5 +- sysdeps/unix/sysv/linux/s390/bits/utmp.h | 3 +- sysdeps/unix/sysv/linux/s390/bits/utmpx.h | 12 +- sysdeps/unix/sysv/linux/sparc/Makefile | 8 +- .../unix/sysv/linux/sparc/sparc32/sigaction.c | 26 +- .../sysv/linux/sparc/sparc32/sigreturn_stub.S | 34 ++ .../unix/sysv/linux/sparc/sparc64/sigaction.c | 14 +- .../sysv/linux/sparc/sparc64/sigreturn_stub.S | 29 + sysdeps/unix/sysv/linux/test-errno-linux.c | 5 +- .../unix/sysv/linux/x86_64/64/dl-librecon.h | 3 +- time/Makefile | 2 + 105 files changed, 2519 insertions(+), 1175 deletions(-) create mode 100644 login/tst-pututxline-cache.c create mode 100644 login/tst-pututxline-lockfail.c create mode 100644 login/tst-updwtmpx.c create mode 100644 malloc/tst-mxfast.c create mode 100644 malloc/tst-pvalloc-fortify.c create mode 100644 sysdeps/arm/be/nofpu/Implies create mode 100644 sysdeps/arm/le/nofpu/Implies delete mode 100644 sysdeps/gnu/bits/utmp.h create mode 100644 sysdeps/hppa/dl-runtime.c create mode 100644 sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c rename sysdeps/unix/{ => sysv/linux}/alpha/getegid.S (100%) rename sysdeps/unix/{ => sysv/linux}/alpha/geteuid.S (100%) rename sysdeps/unix/{ => sysv/linux}/alpha/getppid.S (100%) create mode 100644 sysdeps/unix/sysv/linux/pread64_nocancel.c create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S diff --git a/ChangeLog b/ChangeLog index cdb9e1488..bc2f4aae6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,214 @@ +2019-08-15 Florian Weimer + + [BZ #24899] + * sysdeps/gnu/bits/utmpx.h (struct utmpx): Add + __attribute_nonstring__ to ut_line, ut_id, ut_user, ut_host. + * sysdeps/unix/sysv/linux/s390/bits/utmpx.h (struct utmpx): + Likewise. + * sysdeps/gnu/bits/utmp.h (struct utmp): Add + __attribute_nonstring__ to ut_id. + * sysdeps/unix/sysv/linux/s390/bits/utmpx.h (struct utmp): + Likewise. + +2019-08-28 Florian Weimer + + [BZ #24902] + * login/Makefile (tests): Add tst-pututxline-lockfail. + (tst-pututxline-lockfail): Link with -lpthread. + * login/utmp_file.c (internal_getut_r): Remove buffer argument. + (__libc_getutid_r): Adjust. + (__libc_pututline): Likewise. Check for file_offset == -1. + * login/tst-pututxline-lockfail.c: New file. + +2019-08-15 Florian Weimer + + [BZ #24880] + * login/utmp_file.c (file_locking_failed): Use struct flock64. + (file_locking_unlock): Likewise. + +2019-08-15 Florian Weimer + + [BZ #24879] + login: Disarm timer after utmp lock acquisition. + * login/utmp_file.c (struct file_locking): Remove. + (try_file_lock): Adjust. + (file_lock_restore): Remove function. + (__libc_getutent_r): . + (internal_getut_r): Likewise. + (__libc_getutline_r): Likewise. + (__libc_pututline): Likewise. + (__libc_updwtmp): Likewise. + +2019-08-15 Florian Weimer + + * login/utmp_file.c (__libc_updwtmp): Unlock the right file + descriptor. + * login/Makefile (tests): Add tst-updwtmpx. + * login/tst-updwtmpx.c: New file. + +2019-08-13 Florian Weimer + + * login/utmp_file.c (LOCK_FILE, LOCKING_FAILED, UNLOCK_FILE): + Remove macros. + (struct file_locking): New. + (try_file_lock, file_unlock, file_lock_restore): New functions. + (__libc_getutent_r): Use the new functions. + (internal_getut_r): Likewise. + (__libc_getutline_r): Likewise. + (__libc_pututline): Likewise. + (__libc_updwtmp): Likewise. + +2019-08-13 Florian Weimer + + * login/getutid_r.c (__getutid_r): _HAVE_UT_ID and _HAVE_UT_TYPE + are always true. + * login/getutmp.c (getutmp): _HAVE_UT_TYPE, _HAVE_UT_PID, + _HAVE_UT_ID, _HAVE_UT_HOST, _HAVE_UT_TV are always true. + * login/getutmpx.c (getutmpx): Likewise. + * login/login.c (login): _HAVE_UT_TYPE, _HAVE_UT_PID are always + true. + * login/logout.c (logout): _HAVE_UT_TYPE, _HAVE_UT_HOST, + _HAVE_UT_TV are always true. + * login/logwtmp.c (logwtmp): _HAVE_UT_PID, _HAVE_UT_TYPE, + _HAVE_UT_HOST, _HAVE_UT_TV are always true. + * login/tst-utmp.c: _HAVE_UT_TYPE, _HAVE_UT_TV are always true. + * login/utmp_file.c (__libc_setutent): _HAVE_UT_TYPE, _HAVE_UT_ID + are always true. + (internal_getut_r): _HAVE_UT_TYPE is always true. + (__libc_pututline): Likewise. + * login/programs/utmpdump.c (print_entry): Assume that + _HAVE_UT_TYPE, _HAVE_UT_PID, _HAVE_UT_ID, _HAVE_UT_HOST, + _HAVE_UT_TV are always true. + * sysdeps/generic/utmp-equal.h (__utmp_equal): _HAVE_UT_TYPE, + _HAVE_UT_ID are always true. + * sysdeps/gnu/bits/utmp.h: Move to ... + * bits/utmp.h: ... here, replacing the old file. + +2019-08-05 Florian Weimer + + [BZ #23518] + * login/uptmp-private.h (struct ufuncs): Remove definition. + (__libc_utmp_file_functions, __libc_utmp_unknown_functions) + (__libc_utmp_jump_table): Remove declarations. + (__libc_setutent, __libc_getutent_r, __libc_getutid_r) + (__libc_getutline_r, __libc_pututline, __libc_endutent) + (__libc_updwtmp): Declare. + * login/getutent_r.c (__libc_utmp_unknown_functions) + (__libc_utmp_jump_table, setutent_unknown, getutent_r_unknown) + (getutid_r_unknown, getutline_r_unknown, pututline_unknown) + (endutent_unknown): Remove definitions. + (__setutent): Call __libc_setutent. + (__getutent_r): Call __libc_getutent_r. + (__pututline): Call __libc_pututline. + (__endutent): Call __libc_endutent. + * login/getutid_r.c (__getutid_r): Call __libc_getutid_r. + * login/getutline_r.c (__getutline_r): Call __libc_getutline_r. + * login/updwtmp.c (__updwtmp): Call __libc_updwtmp. + * login/utmp_file.c (__libc_utmp_file_functions): Remove definition + (__libc_setutent): Rename from stetutent_file. Drop static. + (maybe_setutent): New function. + (__libc_getutent_r): Rename from getutent_r_file. Drop static. + Check for initialization. + (__libc_getutid_r): Rename from getutid_r_file. Drop static. + Check for initialization. + (__libc_getutline_r): Rename from getutline_r_file. Drop static. + Check for initialization. + (__libc_pututline): Rename from pututline_file. Drop static. + Check for initialization. + (__libc_endutent): Rename from endutent_file. Drop static. Check + for initialization. + (__libc_updwtmp): Rename from updwtmp_file. Drop static. + * login/utmpname.c (__utmpname): Call __libc_endutent. + * sysdeps/unix/getlogin_r (__getlogin_r): Call __libc_setutent, + __libc_getutlien_r, __libc_endutent. + * manual/users.texi (Who Logged In, Manipulating the Database): + Adjust. + +2019-08-15 Florian Weimer + + * malloc/Makefile (tests): Only add tst-mxfast for + $(have-tunables). + * malloc/tst-mxfast.c: Fix copyright year. + (do_test): Fix GNU style issues. Use TEST_COMPARE instead of + assert for checks. + +2019-08-09 DJ Delorie + + * elf/dl-tunables.list: Add glibc.malloc.mxfast. + * manual/tunables.texi: Document it. + * malloc/malloc.c (do_set_mxfast): New. + (__libc_mallopt): Call it. + * malloc/arena.c: Add mxfast tunable. + * malloc/tst-mxfast.c: New. + * malloc/Makefile: Add it. + +2019-08-08 Niklas Hambüchen + Carlos O'Donell + + [BZ #24026] + * malloc/malloc.c (__malloc_info): Account for top chunk. + +2019-11-01 Dragan Mladjenovic + + * sysdeps/unix/sysv/linux/mips/Makefile + (test-xfail-check-execstack): + Move under mips-has-gnustack != yes. + (CFLAGS-.o*, ASFLAGS-.o*): New rules. + Apply -Wa,-execstack if mips-force-execstack == yes. + * sysdeps/unix/sysv/linux/mips/configure: Regenerated. + * sysdeps/unix/sysv/linux/mips/configure.ac + (mips-force-execstack): New var. + Set to yes for hard-float builds with minimum_kernel < 4.8.0 + or minimum_kernel not set at all. + (mips-has-gnustack): New var. + Use value of libc_cv_as_noexecstack + if mips-force-execstack != yes, otherwise set to no. + +2019-10-08 Gabriel F. T. Gomes + + * Makefile: Fix locale dependency for a couple of tests. + ($(objpfx)tst-strftime2.out): New rule. + ($(objpfx)tst-strftime3.out): Likewise. + +2019-09-20 Joseph Myers + + * sysdeps/unix/sysv/linux/riscv/vfork.S: Do not include + . + (CLONE_VM): New macro. + (CLONE_VFORK): Likewise. + +2019-09-14 Aurelien Jarno + + [BZ #24986] + * sysdeps/unix/alpha/getegid.S: Move to ... + * sysdeps/unix/sysv/linux/alpha/getegid.S: ... here. + * sysdeps/unix/alpha/geteuid.S: Move to ... + * sysdeps/unix/sysv/linux/alpha/geteuid.S: ... here. + * sysdeps/unix/alpha/getppid.S: Move to ... + * sysdeps/unix/sysv/linux/alpha/getppid.S: ... here + +2019-09-08 Adhemerval Zanella + + * sysdeps/hppa/fpu/libm-test-ulps: Update. + +2019-09-03 Aurelien Jarno + + * sysdeps/alpha/fpu/libm-test-ulps: Regenerated using GCC 9.2. + +2019-08-28 Rafal Luzynski + + [BZ #24682] + * NEWS: Mention this bug fixed. + * localedata/locales/bo_CN (first_weekday): Add, set to 2 (Monday). + * localedata/locales/ug_CN (first_weekday): Likewise. + * localedata/locales/zh_CN (first_weekday): Likewise. + +2019-08-01 Florian Weimer + + [BZ #24867] + * malloc/malloc.c (__malloc_info): Remove unwanted leading + whitespace. + 2019-08-01 Carlos O'Donell * version.h (RELEASE): Set to "stable". diff --git a/NEWS b/NEWS index ee9ed4de5..a2911177c 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,54 @@ See the end for copying conditions. Please send GNU C library bug reports via using `glibc' in the "product" field. + +Version 2.30.1 + +Security related changes: + +CVE-2019-19126: ld.so failed to ignore the LD_PREFER_MAP_32BIT_EXEC + environment variable during program execution after a security + transition, allowing local attackers to restrict the possible mapping + addresses for loaded libraries and thus bypass ASLR for a setuid + program. Reported by Marcin Kościelnicki. + +CVE-2020-10029: Trigonometric functions on x86 targets suffered from stack + corruption when they were passed a pseudo-zero argument. Reported by Guido + Vranken / ForAllSecure Mayhem. + +CVE-2020-1751: A defect in the PowerPC backtrace function could cause an + out-of-bounds write when executed in a signal frame context. + +CVE-2020-1752: A use-after-free vulnerability in the glob function when + expanding ~user has been fixed. + +The following bugs are resolved with this release: + + [20543] Please move from .gnu.linkonce to comdat + [23296] Data race in setting function descriptor during lazy binding + [23518] login: Remove utmp backend jump tables + [24682] localedata: zh_CN first weekday should be Monday per GB/T + 7408-2005 + [24867] malloc: Remove unwanted leading whitespace in malloc_info + [24879] login: Disarm timer after utmp lock acquisition + [24880] login: Use struct flock64 in utmp + [24882] login: Acquire write lock early in pututline + [24986] alpha: new getegid, geteuid and getppid syscalls used + unconditionally + [24899] login: Add nonstring attributes to struct utmp, struct utmpx + [24902] login: pututxline could fail to overwrite existing entries + [25066] FAIL: nptl/tst-tls1 on hppa + [25189] Don't use a custom wrapper macro around __has_include + [25203] libio: Disable vtable validation for pre-2.1 interposed handles + [25204] Ignore LD_PREFER_MAP_32BIT_EXEC for SUID programs + [25225] ld.so fails to link on x86 if GCC defaults to -fcf-protection + [25232] No const correctness for strchr et al. for Clang++ + [25401] Remove incorrect alloc_size attribute from pvalloc + [25487] sinl() stack corruption from crafted input (CVE-2020-10029) + [25523] MIPS/Linux inline syscall template is miscompiled + [25635] arm: Wrong sysdep order selection for soft-fp + [25715] system() returns wrong errors when posix_spawn fails + Version 2.30 diff --git a/bits/utmp.h b/bits/utmp.h index 4c36ca19c..854b34216 100644 --- a/bits/utmp.h +++ b/bits/utmp.h @@ -1,4 +1,4 @@ -/* The `struct utmp' type, describing entries in the utmp file. Generic/BSDish +/* The `struct utmp' type, describing entries in the utmp file. Copyright (C) 1993-2019 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -21,29 +21,107 @@ #endif #include -#include +#include +#include +#include -#define UT_NAMESIZE 8 -#define UT_LINESIZE 8 -#define UT_HOSTSIZE 16 +#define UT_LINESIZE 32 +#define UT_NAMESIZE 32 +#define UT_HOSTSIZE 256 +/* The structure describing an entry in the database of + previous logins. */ struct lastlog { - time_t ll_time; +#if __WORDSIZE_TIME64_COMPAT32 + int32_t ll_time; +#else + __time_t ll_time; +#endif char ll_line[UT_LINESIZE]; char ll_host[UT_HOSTSIZE]; }; -struct utmp + +/* The structure describing the status of a terminated process. This + type is used in `struct utmp' below. */ +struct exit_status { - char ut_line[UT_LINESIZE]; - char ut_user[UT_NAMESIZE]; -#define ut_name ut_user - char ut_host[UT_HOSTSIZE]; - long int ut_time; + short int e_termination; /* Process termination status. */ + short int e_exit; /* Process exit status. */ }; -#define _HAVE_UT_HOST 1 /* We have the ut_host field. */ +/* The structure describing an entry in the user accounting database. */ +struct utmp +{ + short int ut_type; /* Type of login. */ + pid_t ut_pid; /* Process ID of login process. */ + char ut_line[UT_LINESIZE] + __attribute_nonstring__; /* Devicename. */ + char ut_id[4] + __attribute_nonstring__; /* Inittab ID. */ + char ut_user[UT_NAMESIZE] + __attribute_nonstring__; /* Username. */ + char ut_host[UT_HOSTSIZE] + __attribute_nonstring__; /* Hostname for remote login. */ + struct exit_status ut_exit; /* Exit status of a process marked + as DEAD_PROCESS. */ +/* The ut_session and ut_tv fields must be the same size when compiled + 32- and 64-bit. This allows data files and shared memory to be + shared between 32- and 64-bit applications. */ +#if __WORDSIZE_TIME64_COMPAT32 + int32_t ut_session; /* Session ID, used for windowing. */ + struct + { + int32_t tv_sec; /* Seconds. */ + int32_t tv_usec; /* Microseconds. */ + } ut_tv; /* Time entry was made. */ +#else + long int ut_session; /* Session ID, used for windowing. */ + struct timeval ut_tv; /* Time entry was made. */ +#endif + + int32_t ut_addr_v6[4]; /* Internet address of remote host. */ + char __glibc_reserved[20]; /* Reserved for future use. */ +}; + +/* Backwards compatibility hacks. */ +#define ut_name ut_user +#ifndef _NO_UT_TIME +/* We have a problem here: `ut_time' is also used otherwise. Define + _NO_UT_TIME if the compiler complains. */ +# define ut_time ut_tv.tv_sec +#endif +#define ut_xtime ut_tv.tv_sec +#define ut_addr ut_addr_v6[0] + + +/* Values for the `ut_type' field of a `struct utmp'. */ +#define EMPTY 0 /* No valid user accounting information. */ + +#define RUN_LVL 1 /* The system's runlevel. */ +#define BOOT_TIME 2 /* Time of system boot. */ +#define NEW_TIME 3 /* Time after system clock changed. */ +#define OLD_TIME 4 /* Time when system clock changed. */ + +#define INIT_PROCESS 5 /* Process spawned by the init process. */ +#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */ +#define USER_PROCESS 7 /* Normal process. */ +#define DEAD_PROCESS 8 /* Terminated process. */ + +#define ACCOUNTING 9 + +/* Old Linux name for the EMPTY type. */ +#define UT_UNKNOWN EMPTY + + +/* Tell the user that we have a modern system with UT_HOST, UT_PID, + UT_TYPE, UT_ID and UT_TV fields. */ +#define _HAVE_UT_TYPE 1 +#define _HAVE_UT_PID 1 +#define _HAVE_UT_ID 1 +#define _HAVE_UT_TV 1 +#define _HAVE_UT_HOST 1 diff --git a/configure b/configure index c773c487b..83ae6899c 100755 --- a/configure +++ b/configure @@ -3777,11 +3777,32 @@ else fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __CET__ +#error no CET compiler support +#endif + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + libc_cv_compiler_default_cet=yes +else + libc_cv_compiler_default_cet=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # Check whether --enable-cet was given. if test "${enable_cet+set}" = set; then : enableval=$enable_cet; enable_cet=$enableval else - enable_cet=no + enable_cet=$libc_cv_compiler_default_cet fi @@ -4014,7 +4035,7 @@ if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ -o conftest conftest.S 1>&5 2>&5; then # Do a link to see if the backend supports IFUNC relocs. $READELF -r conftest 1>&5 - LC_ALL=C $READELF -r conftest | grep 'no relocations' >/dev/null || { + LC_ALL=C $READELF -Wr conftest | grep -q 'IRELATIVE\|R_SPARC_JMP_IREL' && { libc_cv_ld_gnu_indirect_function=yes } fi diff --git a/configure.ac b/configure.ac index 598ba6c4a..51b85359e 100644 --- a/configure.ac +++ b/configure.ac @@ -472,11 +472,18 @@ AC_ARG_ENABLE([mathvec], [build_mathvec=$enableval], [build_mathvec=notset]) +AC_TRY_COMPILE([], [ +#ifndef __CET__ +# error no CET compiler support +#endif], + [libc_cv_compiler_default_cet=yes], + [libc_cv_compiler_default_cet=no]) + AC_ARG_ENABLE([cet], AC_HELP_STRING([--enable-cet], [enable Intel Control-flow Enforcement Technology (CET), x86 only]), [enable_cet=$enableval], - [enable_cet=no]) + [enable_cet=$libc_cv_compiler_default_cet]) # We keep the original values in `$config_*' and never modify them, so we # can write them unchanged into config.make. Everything else uses @@ -641,7 +648,7 @@ if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ -o conftest conftest.S 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then # Do a link to see if the backend supports IFUNC relocs. $READELF -r conftest 1>&AS_MESSAGE_LOG_FD - LC_ALL=C $READELF -r conftest | grep 'no relocations' >/dev/null || { + LC_ALL=C $READELF -Wr conftest | grep -q 'IRELATIVE\|R_SPARC_JMP_IREL' && { libc_cv_ld_gnu_indirect_function=yes } fi diff --git a/debug/tst-backtrace5.c b/debug/tst-backtrace5.c index 5a5ce8bc7..aed5ee4c9 100644 --- a/debug/tst-backtrace5.c +++ b/debug/tst-backtrace5.c @@ -89,6 +89,18 @@ handle_signal (int signum) } /* Symbol names are not available for static functions, so we do not check do_test. */ + + /* Check that backtrace does not return more than what fits in the array + (bug 25423). */ + for (int j = 0; j < NUM_FUNCTIONS; j++) + { + n = backtrace (addresses, j); + if (n > j) + { + FAIL (); + return; + } + } } NO_INLINE int diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 1fc2d8886..525c3767b 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -85,6 +85,11 @@ glibc { tcache_unsorted_limit { type: SIZE_T } + mxfast { + type: SIZE_T + minval: 0 + security_level: SXID_IGNORE + } } cpu { hwcap_mask { diff --git a/libio/oldstdfiles.c b/libio/oldstdfiles.c index 2b861cd75..7503cdd62 100644 --- a/libio/oldstdfiles.c +++ b/libio/oldstdfiles.c @@ -83,6 +83,11 @@ _IO_check_libio (void) = stderr->_vtable_offset = ((int) sizeof (struct _IO_FILE) - (int) sizeof (struct _IO_FILE_complete)); + + if (_IO_stdin_.vtable != &_IO_old_file_jumps + || _IO_stdout_.vtable != &_IO_old_file_jumps + || _IO_stderr_.vtable != &_IO_old_file_jumps) + IO_set_accept_foreign_vtables (&_IO_vtable_check); } } diff --git a/localedata/locales/bo_CN b/localedata/locales/bo_CN index 90cbc7807..9df91a172 100644 --- a/localedata/locales/bo_CN +++ b/localedata/locales/bo_CN @@ -128,6 +128,7 @@ t_fmt_ampm "/ " week 7;19971130;1 +first_weekday 2 END LC_TIME LC_MESSAGES diff --git a/localedata/locales/ug_CN b/localedata/locales/ug_CN index 1ba583c58..83d15c90e 100644 --- a/localedata/locales/ug_CN +++ b/localedata/locales/ug_CN @@ -165,6 +165,7 @@ am_pm "";"" date_fmt "%a %d-%m-%Y %T" week 7;19971130;1 +first_weekday 2 END LC_TIME LC_MESSAGES diff --git a/localedata/locales/zh_CN b/localedata/locales/zh_CN index 62a46415c..cd4b33602 100644 --- a/localedata/locales/zh_CN +++ b/localedata/locales/zh_CN @@ -139,6 +139,7 @@ t_fmt_ampm "%p %I%M%S" date_fmt "%Y %m %d %A %H:%M:%S %Z" week 7;19971130;1 +first_weekday 2 END LC_TIME LC_MESSAGES diff --git a/login/Makefile b/login/Makefile index 92535f0ae..4fd8195e7 100644 --- a/login/Makefile +++ b/login/Makefile @@ -43,7 +43,8 @@ endif subdir-dirs = programs vpath %.c programs -tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin +tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \ + tst-pututxline-lockfail tst-pututxline-cache # Build the -lutil library with these extra functions. extra-libs := libutil @@ -71,3 +72,6 @@ endif $(inst_libexecdir)/pt_chown: $(objpfx)pt_chown $(+force) $(make-target-directory) -$(INSTALL_PROGRAM) -m 4755 -o root $< $@ + +$(objpfx)tst-pututxline-lockfail: $(shared-thread-library) +$(objpfx)tst-pututxline-cache: $(shared-thread-library) diff --git a/login/getutent_r.c b/login/getutent_r.c index 98ffc5d1c..fd13be8a1 100644 --- a/login/getutent_r.c +++ b/login/getutent_r.c @@ -23,115 +23,16 @@ #include "utmp-private.h" - -/* Functions defined here. */ -static int setutent_unknown (void); -static int getutent_r_unknown (struct utmp *buffer, struct utmp **result); -static int getutid_r_unknown (const struct utmp *line, struct utmp *buffer, - struct utmp **result); -static int getutline_r_unknown (const struct utmp *id, struct utmp *buffer, - struct utmp **result); -static struct utmp *pututline_unknown (const struct utmp *data); -static void endutent_unknown (void); - -/* Initial Jump table. */ -const struct utfuncs __libc_utmp_unknown_functions = -{ - setutent_unknown, - getutent_r_unknown, - getutid_r_unknown, - getutline_r_unknown, - pututline_unknown, - endutent_unknown, - NULL -}; - -/* Currently selected backend. */ -const struct utfuncs *__libc_utmp_jump_table = &__libc_utmp_unknown_functions; - /* We need to protect the opening of the file. */ __libc_lock_define_initialized (, __libc_utmp_lock attribute_hidden) -static int -setutent_unknown (void) -{ - int result; - - result = (*__libc_utmp_file_functions.setutent) (); - if (result) - __libc_utmp_jump_table = &__libc_utmp_file_functions; - - return result; -} - - -static int -getutent_r_unknown (struct utmp *buffer, struct utmp **result) -{ - /* The backend was not yet initialized. */ - if (setutent_unknown ()) - return (*__libc_utmp_jump_table->getutent_r) (buffer, result); - - /* Not available. */ - *result = NULL; - return -1; -} - - -static int -getutid_r_unknown (const struct utmp *id, struct utmp *buffer, - struct utmp **result) -{ - /* The backend was not yet initialized. */ - if (setutent_unknown ()) - return (*__libc_utmp_jump_table->getutid_r) (id, buffer, result); - - /* Not available. */ - *result = NULL; - return -1; -} - - -static int -getutline_r_unknown (const struct utmp *line, struct utmp *buffer, - struct utmp **result) -{ - /* The backend was not yet initialized. */ - if (setutent_unknown ()) - return (*__libc_utmp_jump_table->getutline_r) (line, buffer, result); - - /* Not available. */ - *result = NULL; - return -1; -} - - -static struct utmp * -pututline_unknown (const struct utmp *data) -{ - /* The backend was not yet initialized. */ - if (setutent_unknown ()) - return (*__libc_utmp_jump_table->pututline) (data); - - /* Not available. */ - return NULL; -} - - -static void -endutent_unknown (void) -{ - /* Nothing to do. */ -} - - void __setutent (void) { __libc_lock_lock (__libc_utmp_lock); - (*__libc_utmp_jump_table->setutent) (); + __libc_setutent (); __libc_lock_unlock (__libc_utmp_lock); } @@ -145,7 +46,7 @@ __getutent_r (struct utmp *buffer, struct utmp **result) __libc_lock_lock (__libc_utmp_lock); - retval = (*__libc_utmp_jump_table->getutent_r) (buffer, result); + retval = __libc_getutent_r (buffer, result); __libc_lock_unlock (__libc_utmp_lock); @@ -162,7 +63,7 @@ __pututline (const struct utmp *data) __libc_lock_lock (__libc_utmp_lock); - buffer = (*__libc_utmp_jump_table->pututline) (data); + buffer = __libc_pututline (data); __libc_lock_unlock (__libc_utmp_lock); @@ -177,8 +78,7 @@ __endutent (void) { __libc_lock_lock (__libc_utmp_lock); - (*__libc_utmp_jump_table->endutent) (); - __libc_utmp_jump_table = &__libc_utmp_unknown_functions; + __libc_endutent (); __libc_lock_unlock (__libc_utmp_lock); } diff --git a/login/getutid_r.c b/login/getutid_r.c index 34ea61d8f..460d94be0 100644 --- a/login/getutid_r.c +++ b/login/getutid_r.c @@ -32,7 +32,6 @@ __libc_lock_define (extern, __libc_utmp_lock attribute_hidden) int __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result) { -#if (_HAVE_UT_ID - 0) && (_HAVE_UT_TYPE - 0) int retval; /* Test whether ID has any of the legal types. */ @@ -49,15 +48,11 @@ __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result) __libc_lock_lock (__libc_utmp_lock); - retval = (*__libc_utmp_jump_table->getutid_r) (id, buffer, result); + retval = __libc_getutid_r (id, buffer, result); __libc_lock_unlock (__libc_utmp_lock); return retval; -#else /* !_HAVE_UT_ID && !_HAVE_UT_TYPE */ - __set_errno (ENOSYS); - return -1; -#endif } libc_hidden_def (__getutid_r) weak_alias (__getutid_r, getutid_r) diff --git a/login/getutline_r.c b/login/getutline_r.c index 110b89e43..f03255dbb 100644 --- a/login/getutline_r.c +++ b/login/getutline_r.c @@ -36,7 +36,7 @@ __getutline_r (const struct utmp *line, struct utmp *buffer, __libc_lock_lock (__libc_utmp_lock); - retval = (*__libc_utmp_jump_table->getutline_r) (line, buffer, result); + retval = __libc_getutline_r (line, buffer, result); __libc_lock_unlock (__libc_utmp_lock); diff --git a/login/getutmp.c b/login/getutmp.c index 73bc15d78..4e3be1121 100644 --- a/login/getutmp.c +++ b/login/getutmp.c @@ -23,23 +23,11 @@ void getutmp (const struct utmpx *utmpx, struct utmp *utmp) { -#if _HAVE_UT_TYPE - 0 utmp->ut_type = utmpx->ut_type; -#endif -#if _HAVE_UT_PID - 0 utmp->ut_pid = utmpx->ut_pid; -#endif memcpy (utmp->ut_line, utmpx->ut_line, sizeof (utmp->ut_line)); memcpy (utmp->ut_user, utmpx->ut_user, sizeof (utmp->ut_user)); -#if _HAVE_UT_ID - 0 memcpy (utmp->ut_id, utmpx->ut_id, sizeof (utmp->ut_id)); -#endif -#if _HAVE_UT_HOST - 0 memcpy (utmp->ut_host, utmpx->ut_host, sizeof (utmp->ut_host)); -#endif -#if _HAVE_UT_TV - 0 utmp->ut_tv = utmpx->ut_tv; -#else - utmp->ut_time = utmpx->ut_time; -#endif } diff --git a/login/getutmpx.c b/login/getutmpx.c index b181d9bc3..da28d339a 100644 --- a/login/getutmpx.c +++ b/login/getutmpx.c @@ -24,24 +24,11 @@ void getutmpx (const struct utmp *utmp, struct utmpx *utmpx) { memset (utmpx, 0, sizeof (struct utmpx)); - -#if _HAVE_UT_TYPE - 0 utmpx->ut_type = utmp->ut_type; -#endif -#if _HAVE_UT_PID - 0 utmpx->ut_pid = utmp->ut_pid; -#endif memcpy (utmpx->ut_line, utmp->ut_line, sizeof (utmp->ut_line)); memcpy (utmpx->ut_user, utmp->ut_user, sizeof (utmp->ut_user)); -#if _HAVE_UT_ID - 0 memcpy (utmpx->ut_id, utmp->ut_id, sizeof (utmp->ut_id)); -#endif -#if _HAVE_UT_HOST - 0 memcpy (utmpx->ut_host, utmp->ut_host, sizeof (utmp->ut_host)); -#endif -#if _HAVE_UT_TV - 0 utmpx->ut_tv = utmp->ut_tv; -#else - utmpx->ut_time = utmp->ut_time; -#endif } diff --git a/login/login.c b/login/login.c index 09ef3f75a..b7d638c69 100644 --- a/login/login.c +++ b/login/login.c @@ -91,12 +91,8 @@ login (const struct utmp *ut) struct utmp copy = *ut; /* Fill in those fields we supply. */ -#if _HAVE_UT_TYPE - 0 copy.ut_type = USER_PROCESS; -#endif -#if _HAVE_UT_PID - 0 copy.ut_pid = getpid (); -#endif /* Seek tty. */ found_tty = tty_name (STDIN_FILENO, &tty, sizeof (_tty)); diff --git a/login/logout.c b/login/logout.c index 85254d032..5015c1af0 100644 --- a/login/logout.c +++ b/login/logout.c @@ -36,9 +36,7 @@ logout (const char *line) setutent (); /* Fill in search information. */ -#if _HAVE_UT_TYPE - 0 tmp.ut_type = USER_PROCESS; -#endif strncpy (tmp.ut_line, line, sizeof tmp.ut_line); /* Read the record. */ @@ -46,20 +44,12 @@ logout (const char *line) { /* Clear information about who & from where. */ memset (ut->ut_name, '\0', sizeof ut->ut_name); -#if _HAVE_UT_HOST - 0 memset (ut->ut_host, '\0', sizeof ut->ut_host); -#endif -#if _HAVE_UT_TV - 0 struct timeval tv; __gettimeofday (&tv, NULL); ut->ut_tv.tv_sec = tv.tv_sec; ut->ut_tv.tv_usec = tv.tv_usec; -#else - ut->ut_time = time (NULL); -#endif -#if _HAVE_UT_TYPE - 0 ut->ut_type = DEAD_PROCESS; -#endif if (pututline (ut) != NULL) result = 1; diff --git a/login/logwtmp.c b/login/logwtmp.c index f53187121..50d14976c 100644 --- a/login/logwtmp.c +++ b/login/logwtmp.c @@ -30,26 +30,16 @@ logwtmp (const char *line, const char *name, const char *host) /* Set information in new entry. */ memset (&ut, 0, sizeof (ut)); -#if _HAVE_UT_PID - 0 ut.ut_pid = getpid (); -#endif -#if _HAVE_UT_TYPE - 0 ut.ut_type = name[0] ? USER_PROCESS : DEAD_PROCESS; -#endif strncpy (ut.ut_line, line, sizeof ut.ut_line); strncpy (ut.ut_name, name, sizeof ut.ut_name); -#if _HAVE_UT_HOST - 0 strncpy (ut.ut_host, host, sizeof ut.ut_host); -#endif -#if _HAVE_UT_TV - 0 struct timeval tv; __gettimeofday (&tv, NULL); ut.ut_tv.tv_sec = tv.tv_sec; ut.ut_tv.tv_usec = tv.tv_usec; -#else - ut.ut_time = time (NULL); -#endif updwtmp (_PATH_WTMP, &ut); } diff --git a/login/programs/utmpdump.c b/login/programs/utmpdump.c index 4c312f093..85d8e31b4 100644 --- a/login/programs/utmpdump.c +++ b/login/programs/utmpdump.c @@ -37,47 +37,11 @@ print_entry (struct utmp *up) temp_tv.tv_sec = up->ut_tv.tv_sec; temp_tv.tv_usec = up->ut_tv.tv_usec; - (printf) ( - /* The format string. */ -#if _HAVE_UT_TYPE - "[%d] " -#endif -#if _HAVE_UT_PID - "[%05d] " -#endif -#if _HAVE_UT_ID - "[%-4.4s] " -#endif - "[%-8.8s] [%-12.12s]" -#if _HAVE_UT_HOST - " [%-16.16s]" -#endif - " [%-15.15s]" -#if _HAVE_UT_TV - " [%ld]" -#endif - "\n" - /* The arguments. */ -#if _HAVE_UT_TYPE - , up->ut_type -#endif -#if _HAVE_UT_PID - , up->ut_pid -#endif -#if _HAVE_UT_ID - , up->ut_id -#endif - , up->ut_user, up->ut_line -#if _HAVE_UT_HOST - , up->ut_host -#endif -#if _HAVE_UT_TV - , 4 + ctime (&temp_tv.tv_sec) - , (long int) temp_tv.tv_usec -#else - , 4 + ctime (&up->ut_time) -#endif - ); + printf ("[%d] [%05d] [%-4.4s] [%-8.8s] [%-12.12s] [%-16.16s] [%-15.15s]" + " [%ld]\n", + up->ut_type, up->ut_pid, up->ut_id, up->ut_user, up->ut_line, + up->ut_host, 4 + ctime (&temp_tv.tv_sec), + (long int) temp_tv.tv_usec); } int diff --git a/login/tst-pututxline-cache.c b/login/tst-pututxline-cache.c new file mode 100644 index 000000000..3f30dd177 --- /dev/null +++ b/login/tst-pututxline-cache.c @@ -0,0 +1,193 @@ +/* Test case for cache invalidation after concurrent write (bug 24882). + Copyright (C) 2019 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; see the file COPYING.LIB. If + not, see . */ + +/* This test writes an entry to the utmpx file, reads it (so that it + is cached) in process1, and overwrites the same entry in process2 + with something that does not match the search criteria. At this + point, the cache of the first process is stale, and when process1 + attempts to write a new record which would have gone to the same + place (as indicated by the cache), it needs to realize that it has + to pick a different slot because the old slot is now used for + something else. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Set to the path of the utmp file. */ +static char *utmp_file; + +/* Used to synchronize the subprocesses. The barrier itself is + allocated in shared memory. */ +static pthread_barrier_t *barrier; + +/* setutxent with error checking. */ +static void +xsetutxent (void) +{ + errno = 0; + setutxent (); + TEST_COMPARE (errno, 0); +} + +/* getutxent with error checking. */ +static struct utmpx * +xgetutxent (void) +{ + errno = 0; + struct utmpx *result = getutxent (); + if (result == NULL) + FAIL_EXIT1 ("getutxent: %m"); + return result; +} + +static void +put_entry (const char *id, pid_t pid, const char *user, const char *line) +{ + struct utmpx ut = + { + .ut_type = LOGIN_PROCESS, + .ut_pid = pid, + .ut_host = "localhost", + }; + strcpy (ut.ut_id, id); + strncpy (ut.ut_user, user, sizeof (ut.ut_user)); + strncpy (ut.ut_line, line, sizeof (ut.ut_line)); + TEST_VERIFY (pututxline (&ut) != NULL); +} + +/* Use two cooperating subprocesses to avoid issues related to + unlock-on-close semantics of POSIX advisory locks. */ + +static __attribute__ ((noreturn)) void +process1 (void) +{ + TEST_COMPARE (utmpname (utmp_file), 0); + + /* Create an entry. */ + xsetutxent (); + put_entry ("1", 101, "root", "process1"); + + /* Retrieve the entry. This will fill the internal cache. */ + { + errno = 0; + setutxent (); + TEST_COMPARE (errno, 0); + struct utmpx ut = + { + .ut_type = LOGIN_PROCESS, + .ut_line = "process1", + }; + struct utmpx *result = getutxline (&ut); + if (result == NULL) + FAIL_EXIT1 ("getutxline (\"process1\"): %m"); + TEST_COMPARE (result->ut_pid, 101); + } + + /* Signal the other process to overwrite the entry. */ + xpthread_barrier_wait (barrier); + + /* Wait for the other process to complete the write operation. */ + xpthread_barrier_wait (barrier); + + /* Add another entry. Note: This time, there is no setutxent call. */ + put_entry ("1", 103, "root", "process1"); + + _exit (0); +} + +static void +process2 (void *closure) +{ + /* Wait for the first process to write its entry. */ + xpthread_barrier_wait (barrier); + + /* Truncate the file. The glibc interface does not support + re-purposing records, but an external expiration mechanism may + trigger this. */ + TEST_COMPARE (truncate64 (utmp_file, 0), 0); + + /* Write the replacement entry. */ + TEST_COMPARE (utmpname (utmp_file), 0); + xsetutxent (); + put_entry ("2", 102, "user", "process2"); + + /* Signal the other process that the entry has been replaced. */ + xpthread_barrier_wait (barrier); +} + +static int +do_test (void) +{ + xclose (create_temp_file ("tst-tumpx-cache-write-", &utmp_file)); + { + pthread_barrierattr_t attr; + xpthread_barrierattr_init (&attr); + xpthread_barrierattr_setpshared (&attr, PTHREAD_SCOPE_PROCESS); + barrier = support_shared_allocate (sizeof (*barrier)); + xpthread_barrier_init (barrier, &attr, 2); + } + + /* Run both subprocesses in parallel. */ + { + pid_t pid1 = xfork (); + if (pid1 == 0) + process1 (); + support_isolate_in_subprocess (process2, NULL); + int status; + xwaitpid (pid1, &status, 0); + TEST_COMPARE (status, 0); + } + + /* Check that the utmpx database contains the expected records. */ + { + TEST_COMPARE (utmpname (utmp_file), 0); + xsetutxent (); + + struct utmpx *ut = xgetutxent (); + TEST_COMPARE_STRING (ut->ut_id, "2"); + TEST_COMPARE (ut->ut_pid, 102); + TEST_COMPARE_STRING (ut->ut_user, "user"); + TEST_COMPARE_STRING (ut->ut_line, "process2"); + + ut = xgetutxent (); + TEST_COMPARE_STRING (ut->ut_id, "1"); + TEST_COMPARE (ut->ut_pid, 103); + TEST_COMPARE_STRING (ut->ut_user, "root"); + TEST_COMPARE_STRING (ut->ut_line, "process1"); + + if (getutxent () != NULL) + FAIL_EXIT1 ("additional utmpx entry"); + } + + xpthread_barrier_destroy (barrier); + support_shared_free (barrier); + free (utmp_file); + + return 0; +} + +#include diff --git a/login/tst-pututxline-lockfail.c b/login/tst-pututxline-lockfail.c new file mode 100644 index 000000000..47c25dc06 --- /dev/null +++ b/login/tst-pututxline-lockfail.c @@ -0,0 +1,176 @@ +/* Test the lock upgrade path in tst-pututxline. + Copyright (C) 2019 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; see the file COPYING.LIB. If + not, see . */ + +/* pututxline upgrades the read lock on the file to a write lock. + This test verifies that if the lock upgrade fails, the utmp + subsystem remains in a consistent state, so that pututxline can be + called again. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Path to the temporary utmp file. */ +static char *path; + +/* Used to synchronize the subprocesses. The barrier itself is + allocated in shared memory. */ +static pthread_barrier_t *barrier; + +/* Use pututxline to write an entry for PID. */ +static struct utmpx * +write_entry (pid_t pid) +{ + struct utmpx ut = + { + .ut_type = LOGIN_PROCESS, + .ut_id = "1", + .ut_user = "root", + .ut_pid = pid, + .ut_line = "entry", + .ut_host = "localhost", + }; + return pututxline (&ut); +} + +/* Create the initial entry in a subprocess, so that the utmp + subsystem in the original process is not disturbed. */ +static void +subprocess_create_entry (void *closure) +{ + TEST_COMPARE (utmpname (path), 0); + TEST_VERIFY (write_entry (101) != NULL); +} + +/* Acquire an advisory read lock on PATH. */ +__attribute__ ((noreturn)) static void +subprocess_lock_file (void) +{ + int fd = xopen (path, O_RDONLY, 0); + + struct flock64 fl = + { + .l_type = F_RDLCK, + fl.l_whence = SEEK_SET, + }; + TEST_COMPARE (fcntl64 (fd, F_SETLKW, &fl), 0); + + /* Signal to the main process that the lock has been acquired. */ + xpthread_barrier_wait (barrier); + + /* Wait for the unlock request from the main process. */ + xpthread_barrier_wait (barrier); + + /* Implicitly unlock the file. */ + xclose (fd); + + /* Overwrite the existing entry. */ + TEST_COMPARE (utmpname (path), 0); + errno = 0; + setutxent (); + TEST_COMPARE (errno, 0); + TEST_VERIFY (write_entry (102) != NULL); + errno = 0; + endutxent (); + TEST_COMPARE (errno, 0); + + _exit (0); +} + +static int +do_test (void) +{ + xclose (create_temp_file ("tst-pututxline-lockfail-", &path)); + + { + pthread_barrierattr_t attr; + xpthread_barrierattr_init (&attr); + xpthread_barrierattr_setpshared (&attr, PTHREAD_SCOPE_PROCESS); + barrier = support_shared_allocate (sizeof (*barrier)); + xpthread_barrier_init (barrier, &attr, 2); + xpthread_barrierattr_destroy (&attr); + } + + /* Write the initial entry. */ + support_isolate_in_subprocess (subprocess_create_entry, NULL); + + pid_t locker_pid = xfork (); + if (locker_pid == 0) + subprocess_lock_file (); + + /* Wait for the file locking to complete. */ + xpthread_barrier_wait (barrier); + + /* Try to add another entry. This attempt will fail, with EINTR or + EAGAIN. */ + TEST_COMPARE (utmpname (path), 0); + TEST_VERIFY (write_entry (102) == NULL); + if (errno != EINTR) + TEST_COMPARE (errno, EAGAIN); + + /* Signal the subprocess to overwrite the entry. */ + xpthread_barrier_wait (barrier); + + /* Wait for write and unlock to complete. */ + { + int status; + xwaitpid (locker_pid, &status, 0); + TEST_COMPARE (status, 0); + } + + /* The file is no longer locked, so this operation will succeed. */ + TEST_VERIFY (write_entry (103) != NULL); + errno = 0; + endutxent (); + TEST_COMPARE (errno, 0); + + /* Check that there is just one entry with the expected contents. + If pututxline becomes desynchronized internally, the entry is not + overwritten (bug 24902). */ + errno = 0; + setutxent (); + TEST_COMPARE (errno, 0); + struct utmpx *ut = getutxent (); + TEST_VERIFY_EXIT (ut != NULL); + TEST_COMPARE (ut->ut_type, LOGIN_PROCESS); + TEST_COMPARE_STRING (ut->ut_id, "1"); + TEST_COMPARE_STRING (ut->ut_user, "root"); + TEST_COMPARE (ut->ut_pid, 103); + TEST_COMPARE_STRING (ut->ut_line, "entry"); + TEST_COMPARE_STRING (ut->ut_host, "localhost"); + TEST_VERIFY (getutxent () == NULL); + errno = 0; + endutxent (); + TEST_COMPARE (errno, 0); + + xpthread_barrier_destroy (barrier); + support_shared_free (barrier); + free (path); + return 0; +} + +#include diff --git a/login/tst-updwtmpx.c b/login/tst-updwtmpx.c new file mode 100644 index 000000000..0a4a27dae --- /dev/null +++ b/login/tst-updwtmpx.c @@ -0,0 +1,112 @@ +/* Basic test coverage for updwtmpx. + Copyright (C) 2019 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; see the file COPYING.LIB. If + not, see . */ + +/* This program runs a series of tests. Each one calls updwtmpx + twice, to write two records, optionally with misalignment in the + file, and reads back the results. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int +do_test (void) +{ + /* Two entries filled with an arbitrary bit pattern. */ + struct utmpx entries[2]; + unsigned char pad; + { + unsigned char *p = (unsigned char *) &entries[0]; + for (size_t i = 0; i < sizeof (entries); ++i) + { + p[i] = i; + } + /* Make sure that the first and second entry and the padding are + different. */ + p[sizeof (struct utmpx)] = p[0] + 1; + pad = p[0] + 2; + } + + char *path; + int fd = create_temp_file ("tst-updwtmpx-", &path); + + /* Used to check that updwtmpx does not leave an open file + descriptor around. */ + struct support_descriptors *descriptors = support_descriptors_list (); + + /* updwtmpx is expected to remove misalignment. Optionally insert + one byte of misalignment at the start and in the middle (after + the first entry). */ + for (int misaligned_start = 0; misaligned_start < 2; ++misaligned_start) + for (int misaligned_middle = 0; misaligned_middle < 2; ++misaligned_middle) + { + if (test_verbose > 0) + printf ("info: misaligned_start=%d misaligned_middle=%d\n", + misaligned_start, misaligned_middle); + + xftruncate (fd, 0); + TEST_COMPARE (pwrite64 (fd, &pad, misaligned_start, 0), + misaligned_start); + + /* Write first entry and check it. */ + errno = 0; + updwtmpx (path, &entries[0]); + TEST_COMPARE (errno, 0); + support_descriptors_check (descriptors); + TEST_COMPARE (xlseek (fd, 0, SEEK_END), sizeof (struct utmpx)); + struct utmpx buffer; + TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), 0), + sizeof (buffer)); + TEST_COMPARE_BLOB (&entries[0], sizeof (entries[0]), + &buffer, sizeof (buffer)); + + /* Middle mis-alignmet. */ + TEST_COMPARE (pwrite64 (fd, &pad, misaligned_middle, + sizeof (struct utmpx)), misaligned_middle); + + /* Write second entry and check both entries. */ + errno = 0; + updwtmpx (path, &entries[1]); + TEST_COMPARE (errno, 0); + support_descriptors_check (descriptors); + TEST_COMPARE (xlseek (fd, 0, SEEK_END), 2 * sizeof (struct utmpx)); + TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), 0), + sizeof (buffer)); + TEST_COMPARE_BLOB (&entries[0], sizeof (entries[0]), + &buffer, sizeof (buffer)); + TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), sizeof (buffer)), + sizeof (buffer)); + TEST_COMPARE_BLOB (&entries[1], sizeof (entries[1]), + &buffer, sizeof (buffer)); + } + + support_descriptors_free (descriptors); + free (path); + xclose (fd); + + return 0; +} + +#include diff --git a/login/tst-utmp.c b/login/tst-utmp.c index ce48e8326..02d0c1fe8 100644 --- a/login/tst-utmp.c +++ b/login/tst-utmp.c @@ -39,8 +39,6 @@ #endif -#if defined UTMPX || _HAVE_UT_TYPE - /* Prototype for our test function. */ static int do_test (int argc, char *argv[]); @@ -75,11 +73,7 @@ do_prepare (int argc, char *argv[]) struct utmp entry[] = { -#if defined UTMPX || _HAVE_UT_TV #define UT(a) .ut_tv = { .tv_sec = (a)} -#else -#define UT(a) .ut_time = (a) -#endif { .ut_type = BOOT_TIME, .ut_pid = 1, UT(1000) }, { .ut_type = RUN_LVL, .ut_pid = 1, UT(2000) }, @@ -167,11 +161,7 @@ simulate_login (const char *line, const char *user) entry[n].ut_pid = (entry_pid += 27); entry[n].ut_type = USER_PROCESS; strncpy (entry[n].ut_user, user, sizeof (entry[n].ut_user)); -#if defined UTMPX || _HAVE_UT_TV - 0 entry[n].ut_tv.tv_sec = (entry_time += 1000); -#else - entry[n].ut_time = (entry_time += 1000); -#endif setutent (); if (pututline (&entry[n]) == NULL) @@ -201,11 +191,7 @@ simulate_logout (const char *line) { entry[n].ut_type = DEAD_PROCESS; strncpy (entry[n].ut_user, "", sizeof (entry[n].ut_user)); -#if defined UTMPX || _HAVE_UT_TV - 0 entry[n].ut_tv.tv_sec = (entry_time += 1000); -#else - entry[n].ut_time = (entry_time += 1000); -#endif setutent (); if (pututline (&entry[n]) == NULL) @@ -390,14 +376,3 @@ do_test (int argc, char *argv[]) return result; } - -#else - -/* No field 'ut_type' in struct utmp. */ -int -main (void) -{ - return 0; -} - -#endif diff --git a/login/updwtmp.c b/login/updwtmp.c index b9bccd9b6..387e58082 100644 --- a/login/updwtmp.c +++ b/login/updwtmp.c @@ -29,7 +29,7 @@ __updwtmp (const char *wtmp_file, const struct utmp *utmp) { const char *file_name = TRANSFORM_UTMP_FILE_NAME (wtmp_file); - (*__libc_utmp_file_functions.updwtmp) (file_name, utmp); + __libc_updwtmp (file_name, utmp); } libc_hidden_def (__updwtmp) weak_alias (__updwtmp, updwtmp) diff --git a/login/utmp-private.h b/login/utmp-private.h index a82a92365..d60461d64 100644 --- a/login/utmp-private.h +++ b/login/utmp-private.h @@ -24,24 +24,17 @@ #include #include -/* The structure describing the functions in a backend. */ -struct utfuncs -{ - int (*setutent) (void); - int (*getutent_r) (struct utmp *, struct utmp **); - int (*getutid_r) (const struct utmp *, struct utmp *, struct utmp **); - int (*getutline_r) (const struct utmp *, struct utmp *, struct utmp **); - struct utmp *(*pututline) (const struct utmp *); - void (*endutent) (void); - int (*updwtmp) (const char *, const struct utmp *); -}; - -/* The tables from the services. */ -extern const struct utfuncs __libc_utmp_file_functions attribute_hidden; -extern const struct utfuncs __libc_utmp_unknown_functions attribute_hidden; - -/* Currently selected backend. */ -extern const struct utfuncs *__libc_utmp_jump_table attribute_hidden; +/* These functions check for initialization, but not perform any + locking. */ +int __libc_setutent (void) attribute_hidden; +int __libc_getutent_r (struct utmp *, struct utmp **) attribute_hidden; +int __libc_getutid_r (const struct utmp *, struct utmp *, struct utmp **) + attribute_hidden; +int __libc_getutline_r (const struct utmp *, struct utmp *, struct utmp **) + attribute_hidden; +struct utmp *__libc_pututline (const struct utmp *) attribute_hidden; +void __libc_endutent (void) attribute_hidden; +int __libc_updwtmp (const char *, const struct utmp *) attribute_hidden; /* Current file name. */ extern const char *__libc_utmp_file_name attribute_hidden; diff --git a/login/utmp_file.c b/login/utmp_file.c index b19d3caf0..e98bc3189 100644 --- a/login/utmp_file.c +++ b/login/utmp_file.c @@ -43,6 +43,25 @@ static off64_t file_offset; /* Cache for the last read entry. */ static struct utmp last_entry; +/* Returns true if *ENTRY matches last_entry, based on + data->ut_type. */ +static bool +matches_last_entry (const struct utmp *data) +{ + if (file_offset <= 0) + /* Nothing has been read. last_entry is stale and cannot match. */ + return false; + + if (data->ut_type == RUN_LVL + || data->ut_type == BOOT_TIME + || data->ut_type == OLD_TIME + || data->ut_type == NEW_TIME) + /* For some entry types, only a type match is required. */ + return data->ut_type == last_entry.ut_type; + else + /* For the process-related entries, a full match is needed. */ + return __utmp_equal (&last_entry, data); +} /* Locking timeout. */ #ifndef TIMEOUT @@ -52,90 +71,70 @@ static struct utmp last_entry; /* Do-nothing handler for locking timeout. */ static void timeout_handler (int signum) {}; -/* LOCK_FILE(fd, type) failure_statement - attempts to get a lock on the utmp file referenced by FD. If it fails, - the failure_statement is executed, otherwise it is skipped. - LOCKING_FAILED() - jumps into the UNLOCK_FILE macro and ensures cleanup of LOCK_FILE. - UNLOCK_FILE(fd) - unlocks the utmp file referenced by FD and performs the cleanup of - LOCK_FILE. - */ -#define LOCK_FILE(fd, type) \ -{ \ - struct flock fl; \ - struct sigaction action, old_action; \ - unsigned int old_timeout; \ - \ - /* Cancel any existing alarm. */ \ - old_timeout = alarm (0); \ - \ - /* Establish signal handler. */ \ - action.sa_handler = timeout_handler; \ - __sigemptyset (&action.sa_mask); \ - action.sa_flags = 0; \ - __sigaction (SIGALRM, &action, &old_action); \ - \ - alarm (TIMEOUT); \ - \ - /* Try to get the lock. */ \ - memset (&fl, '\0', sizeof (struct flock)); \ - fl.l_type = (type); \ - fl.l_whence = SEEK_SET; \ - if (__fcntl64_nocancel ((fd), F_SETLKW, &fl) < 0) - -#define LOCKING_FAILED() \ - goto unalarm_return - -#define UNLOCK_FILE(fd) \ - /* Unlock the file. */ \ - fl.l_type = F_UNLCK; \ - __fcntl64_nocancel ((fd), F_SETLKW, &fl); \ - \ - unalarm_return: \ - /* Reset the signal handler and alarm. We must reset the alarm \ - before resetting the handler so our alarm does not generate a \ - spurious SIGALRM seen by the user. However, we cannot just set \ - the user's old alarm before restoring the handler, because then \ - it's possible our handler could catch the user alarm's SIGARLM \ - and then the user would never see the signal he expected. */ \ - alarm (0); \ - __sigaction (SIGALRM, &old_action, NULL); \ - if (old_timeout != 0) \ - alarm (old_timeout); \ -} while (0) - - -/* Functions defined here. */ -static int setutent_file (void); -static int getutent_r_file (struct utmp *buffer, struct utmp **result); -static int getutid_r_file (const struct utmp *key, struct utmp *buffer, - struct utmp **result); -static int getutline_r_file (const struct utmp *key, struct utmp *buffer, - struct utmp **result); -static struct utmp *pututline_file (const struct utmp *data); -static void endutent_file (void); -static int updwtmp_file (const char *file, const struct utmp *utmp); - -/* Jump table for file functions. */ -const struct utfuncs __libc_utmp_file_functions = + +/* try_file_lock (LOCKING, FD, TYPE) returns true if the locking + operation failed and recovery needs to be performed. + + file_unlock (FD) removes the lock (which must have been + successfully acquired). */ + +static bool +try_file_lock (int fd, int type) { - setutent_file, - getutent_r_file, - getutid_r_file, - getutline_r_file, - pututline_file, - endutent_file, - updwtmp_file -}; + /* Cancel any existing alarm. */ + int old_timeout = alarm (0); + + /* Establish signal handler. */ + struct sigaction old_action; + struct sigaction action; + action.sa_handler = timeout_handler; + __sigemptyset (&action.sa_mask); + action.sa_flags = 0; + __sigaction (SIGALRM, &action, &old_action); + + alarm (TIMEOUT); + + /* Try to get the lock. */ + struct flock64 fl = + { + .l_type = type, + .l_whence = SEEK_SET, + }; + + bool status = __fcntl64_nocancel (fd, F_SETLKW, &fl) < 0; + int saved_errno = errno; + + /* Reset the signal handler and alarm. We must reset the alarm + before resetting the handler so our alarm does not generate a + spurious SIGALRM seen by the user. However, we cannot just set + the user's old alarm before restoring the handler, because then + it's possible our handler could catch the user alarm's SIGARLM and + then the user would never see the signal he expected. */ + alarm (0); + __sigaction (SIGALRM, &old_action, NULL); + if (old_timeout != 0) + alarm (old_timeout); + + __set_errno (saved_errno); + return status; +} +static void +file_unlock (int fd) +{ + struct flock64 fl = + { + .l_type = F_UNLCK, + }; + __fcntl64_nocancel (fd, F_SETLKW, &fl); +} #ifndef TRANSFORM_UTMP_FILE_NAME # define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name) #endif -static int -setutent_file (void) +int +__libc_setutent (void) { if (file_fd < 0) { @@ -153,56 +152,68 @@ setutent_file (void) __lseek64 (file_fd, 0, SEEK_SET); file_offset = 0; - /* Make sure the entry won't match. */ -#if _HAVE_UT_TYPE - 0 - last_entry.ut_type = -1; -#else - last_entry.ut_line[0] = '\177'; -# if _HAVE_UT_ID - 0 - last_entry.ut_id[0] = '\0'; -# endif -#endif - return 1; } +/* Preform initialization if necessary. */ +static bool +maybe_setutent (void) +{ + return file_fd >= 0 || __libc_setutent (); +} -static int -getutent_r_file (struct utmp *buffer, struct utmp **result) +/* Reads the entry at file_offset, storing it in last_entry and + updating file_offset on success. Returns -1 for a read error, 0 + for EOF, and 1 for a successful read. last_entry and file_offset + are only updated on a successful and complete read. */ +static ssize_t +read_last_entry (void) { - ssize_t nbytes; + struct utmp buffer; + ssize_t nbytes = __pread64_nocancel (file_fd, &buffer, sizeof (buffer), + file_offset); + if (nbytes < 0) + return -1; + else if (nbytes != sizeof (buffer)) + /* Assume EOF. */ + return 0; + else + { + last_entry = buffer; + file_offset += sizeof (buffer); + return 1; + } +} - assert (file_fd >= 0); +int +__libc_getutent_r (struct utmp *buffer, struct utmp **result) +{ + int saved_errno = errno; - if (file_offset == -1l) + if (!maybe_setutent ()) { /* Not available. */ *result = NULL; return -1; } - LOCK_FILE (file_fd, F_RDLCK) - { - nbytes = 0; - LOCKING_FAILED (); - } - - /* Read the next entry. */ - nbytes = __read_nocancel (file_fd, &last_entry, sizeof (struct utmp)); + if (try_file_lock (file_fd, F_RDLCK)) + return -1; - UNLOCK_FILE (file_fd); + ssize_t nbytes = read_last_entry (); + file_unlock (file_fd); - if (nbytes != sizeof (struct utmp)) + if (nbytes <= 0) /* Read error or EOF. */ { - if (nbytes != 0) - file_offset = -1l; + if (nbytes == 0) + /* errno should be unchanged to indicate success. A premature + EOF is treated like an EOF (missing complete record at the + end). */ + __set_errno (saved_errno); *result = NULL; return -1; } - /* Update position pointer. */ - file_offset += sizeof (struct utmp); - memcpy (buffer, &last_entry, sizeof (struct utmp)); *result = buffer; @@ -210,82 +221,55 @@ getutent_r_file (struct utmp *buffer, struct utmp **result) } +/* Search for *ID, updating last_entry and file_offset. Return 0 on + success and -1 on failure. Does not perform locking; for that see + internal_getut_r below. */ static int -internal_getut_r (const struct utmp *id, struct utmp *buffer, - bool *lock_failed) +internal_getut_nolock (const struct utmp *id) { - int result = -1; - - LOCK_FILE (file_fd, F_RDLCK) - { - *lock_failed = true; - LOCKING_FAILED (); - } - -#if _HAVE_UT_TYPE - 0 - if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME - || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME) + while (1) { - /* Search for next entry with type RUN_LVL, BOOT_TIME, - OLD_TIME, or NEW_TIME. */ - - while (1) + ssize_t nbytes = read_last_entry (); + if (nbytes < 0) + return -1; + if (nbytes == 0) { - /* Read the next entry. */ - if (__read_nocancel (file_fd, buffer, sizeof (struct utmp)) - != sizeof (struct utmp)) - { - __set_errno (ESRCH); - file_offset = -1l; - goto unlock_return; - } - file_offset += sizeof (struct utmp); - - if (id->ut_type == buffer->ut_type) - break; + /* End of file reached. */ + __set_errno (ESRCH); + return -1; } - } - else -#endif /* _HAVE_UT_TYPE */ - { - /* Search for the next entry with the specified ID and with type - INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS. */ - while (1) - { - /* Read the next entry. */ - if (__read_nocancel (file_fd, buffer, sizeof (struct utmp)) - != sizeof (struct utmp)) - { - __set_errno (ESRCH); - file_offset = -1l; - goto unlock_return; - } - file_offset += sizeof (struct utmp); - - if (__utmp_equal (buffer, id)) - break; - } + if (matches_last_entry (id)) + break; } - result = 0; + return 0; +} -unlock_return: - UNLOCK_FILE (file_fd); +/* Search for *ID, updating last_entry and file_offset. Return 0 on + success and -1 on failure. If the locking operation failed, write + true to *LOCK_FAILED. */ +static int +internal_getut_r (const struct utmp *id, bool *lock_failed) +{ + if (try_file_lock (file_fd, F_RDLCK)) + { + *lock_failed = true; + return -1; + } + int result = internal_getut_nolock (id); + file_unlock (file_fd); return result; } - /* For implementing this function we don't use the getutent_r function because we can avoid the reposition on every new entry this way. */ -static int -getutid_r_file (const struct utmp *id, struct utmp *buffer, - struct utmp **result) +int +__libc_getutid_r (const struct utmp *id, struct utmp *buffer, + struct utmp **result) { - assert (file_fd >= 0); - - if (file_offset == -1l) + if (!maybe_setutent ()) { *result = NULL; return -1; @@ -294,7 +278,7 @@ getutid_r_file (const struct utmp *id, struct utmp *buffer, /* We don't have to distinguish whether we can lock the file or whether there is no entry. */ bool lock_failed = false; - if (internal_getut_r (id, &last_entry, &lock_failed) < 0) + if (internal_getut_r (id, &lock_failed) < 0) { *result = NULL; return -1; @@ -306,69 +290,65 @@ getutid_r_file (const struct utmp *id, struct utmp *buffer, return 0; } - /* For implementing this function we don't use the getutent_r function because we can avoid the reposition on every new entry this way. */ -static int -getutline_r_file (const struct utmp *line, struct utmp *buffer, - struct utmp **result) +int +__libc_getutline_r (const struct utmp *line, struct utmp *buffer, + struct utmp **result) { - assert (file_fd >= 0); - - if (file_offset == -1l) + if (!maybe_setutent ()) { *result = NULL; return -1; } - LOCK_FILE (file_fd, F_RDLCK) + if (try_file_lock (file_fd, F_RDLCK)) { *result = NULL; - LOCKING_FAILED (); + return -1; } while (1) { - /* Read the next entry. */ - if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp)) - != sizeof (struct utmp)) + ssize_t nbytes = read_last_entry (); + if (nbytes < 0) + { + file_unlock (file_fd); + *result = NULL; + return -1; + } + if (nbytes == 0) { + /* End of file reached. */ + file_unlock (file_fd); __set_errno (ESRCH); - file_offset = -1l; *result = NULL; - goto unlock_return; + return -1; } - file_offset += sizeof (struct utmp); /* Stop if we found a user or login entry. */ - if ( -#if _HAVE_UT_TYPE - 0 - (last_entry.ut_type == USER_PROCESS + if ((last_entry.ut_type == USER_PROCESS || last_entry.ut_type == LOGIN_PROCESS) - && -#endif - !strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line)) + && (strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line) + == 0)) break; } + file_unlock (file_fd); memcpy (buffer, &last_entry, sizeof (struct utmp)); *result = buffer; -unlock_return: - UNLOCK_FILE (file_fd); - - return ((*result == NULL) ? -1 : 0); + return 0; } -static struct utmp * -pututline_file (const struct utmp *data) +struct utmp * +__libc_pututline (const struct utmp *data) { - struct utmp buffer; - struct utmp *pbuf; - int found; + if (!maybe_setutent ()) + return NULL; - assert (file_fd >= 0); + struct utmp *pbuf; if (! file_writable) { @@ -380,8 +360,7 @@ pututline_file (const struct utmp *data) if (new_fd == -1) return NULL; - if (__lseek64 (new_fd, __lseek64 (file_fd, 0, SEEK_CUR), SEEK_SET) == -1 - || __dup2 (new_fd, file_fd) < 0) + if (__dup2 (new_fd, file_fd) < 0) { __close_nocancel_nostatus (new_fd); return NULL; @@ -390,95 +369,96 @@ pututline_file (const struct utmp *data) file_writable = true; } + /* Exclude other writers before validating the cache. */ + if (try_file_lock (file_fd, F_WRLCK)) + return NULL; + /* Find the correct place to insert the data. */ - if (file_offset > 0 - && ( -#if _HAVE_UT_TYPE - 0 - (last_entry.ut_type == data->ut_type - && (last_entry.ut_type == RUN_LVL - || last_entry.ut_type == BOOT_TIME - || last_entry.ut_type == OLD_TIME - || last_entry.ut_type == NEW_TIME)) - || -#endif - __utmp_equal (&last_entry, data))) - found = 1; - else + bool found = false; + if (matches_last_entry (data)) { - bool lock_failed = false; - found = internal_getut_r (data, &buffer, &lock_failed); - - if (__builtin_expect (lock_failed, false)) + /* Read back the entry under the write lock. */ + file_offset -= sizeof (last_entry); + ssize_t nbytes = read_last_entry (); + if (nbytes < 0) { - __set_errno (EAGAIN); + file_unlock (file_fd); return NULL; } - } - LOCK_FILE (file_fd, F_WRLCK) - { - pbuf = NULL; - LOCKING_FAILED (); + if (nbytes == 0) + /* End of file reached. */ + found = false; + else + found = matches_last_entry (data); } - if (found < 0) + if (!found) + /* Search forward for the entry. */ + found = internal_getut_nolock (data) >= 0; + + off64_t write_offset; + if (!found) { /* We append the next entry. */ - file_offset = __lseek64 (file_fd, 0, SEEK_END); - if (file_offset % sizeof (struct utmp) != 0) - { - file_offset -= file_offset % sizeof (struct utmp); - __ftruncate64 (file_fd, file_offset); - - if (__lseek64 (file_fd, 0, SEEK_END) < 0) - { - pbuf = NULL; - goto unlock_return; - } - } + write_offset = __lseek64 (file_fd, 0, SEEK_END); + + /* Round down to the next multiple of the entry size. This + ensures any partially-written record is overwritten by the + new record. */ + write_offset = (write_offset / sizeof (struct utmp) + * sizeof (struct utmp)); } else + /* Overwrite last_entry. */ + write_offset = file_offset - sizeof (struct utmp); + + /* Write the new data. */ + ssize_t nbytes; + if (__lseek64 (file_fd, write_offset, SEEK_SET) < 0 + || (nbytes = __write_nocancel (file_fd, data, sizeof (struct utmp))) < 0) { - /* We replace the just read entry. */ - file_offset -= sizeof (struct utmp); - __lseek64 (file_fd, file_offset, SEEK_SET); + /* There is no need to recover the file position because all + reads use pread64, and any future write is preceded by + another seek. */ + file_unlock (file_fd); + return NULL; } - /* Write the new data. */ - if (__write_nocancel (file_fd, data, sizeof (struct utmp)) - != sizeof (struct utmp)) + if (nbytes != sizeof (struct utmp)) { /* If we appended a new record this is only partially written. Remove it. */ - if (found < 0) - (void) __ftruncate64 (file_fd, file_offset); - pbuf = NULL; - } - else - { - file_offset += sizeof (struct utmp); - pbuf = (struct utmp *) data; + if (!found) + (void) __ftruncate64 (file_fd, write_offset); + file_unlock (file_fd); + /* Assume that the write failure was due to missing disk + space. */ + __set_errno (ENOSPC); + return NULL; } - unlock_return: - UNLOCK_FILE (file_fd); + file_unlock (file_fd); + file_offset = write_offset + sizeof (struct utmp); + pbuf = (struct utmp *) data; return pbuf; } -static void -endutent_file (void) +void +__libc_endutent (void) { - assert (file_fd >= 0); - - __close_nocancel_nostatus (file_fd); - file_fd = -1; + if (file_fd >= 0) + { + __close_nocancel_nostatus (file_fd); + file_fd = -1; + } } -static int -updwtmp_file (const char *file, const struct utmp *utmp) +int +__libc_updwtmp (const char *file, const struct utmp *utmp) { int result = -1; off64_t offset; @@ -489,8 +469,11 @@ updwtmp_file (const char *file, const struct utmp *utmp) if (fd < 0) return -1; - LOCK_FILE (fd, F_WRLCK) - LOCKING_FAILED (); + if (try_file_lock (fd, F_WRLCK)) + { + __close_nocancel_nostatus (fd); + return -1; + } /* Remember original size of log file. */ offset = __lseek64 (fd, 0, SEEK_END); @@ -516,7 +499,7 @@ updwtmp_file (const char *file, const struct utmp *utmp) result = 0; unlock_return: - UNLOCK_FILE (fd); + file_unlock (fd); /* Close WTMP file. */ __close_nocancel_nostatus (fd); diff --git a/login/utmpname.c b/login/utmpname.c index c3da183d5..8f94b19ca 100644 --- a/login/utmpname.c +++ b/login/utmpname.c @@ -42,8 +42,7 @@ __utmpname (const char *file) __libc_lock_lock (__libc_utmp_lock); /* Close the old file. */ - (*__libc_utmp_jump_table->endutent) (); - __libc_utmp_jump_table = &__libc_utmp_unknown_functions; + __libc_endutent (); if (strcmp (file, __libc_utmp_file_name) != 0) { diff --git a/malloc/Makefile b/malloc/Makefile index d2fba2995..9698574bb 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -27,7 +27,7 @@ headers := $(dist-headers) obstack.h mcheck.h tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ tst-mcheck tst-mallocfork tst-trim1 \ tst-malloc-usable tst-realloc tst-reallocarray tst-posix_memalign \ - tst-pvalloc tst-memalign tst-mallopt \ + tst-pvalloc tst-pvalloc-fortify tst-memalign tst-mallopt \ tst-malloc-backtrace tst-malloc-thread-exit \ tst-malloc-thread-fail tst-malloc-fork-deadlock \ tst-mallocfork2 \ @@ -54,7 +54,7 @@ tests-internal += \ tst-dynarray-at-fail \ ifneq (no,$(have-tunables)) -tests += tst-malloc-usable-tunables +tests += tst-malloc-usable-tunables tst-mxfast tests-static += tst-malloc-usable-static-tunables endif @@ -196,6 +196,8 @@ tst-malloc-usable-static-ENV = $(tst-malloc-usable-ENV) tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 tst-malloc-usable-static-tunables-ENV = $(tst-malloc-usable-tunables-ENV) +tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0 + ifeq ($(experimental-malloc),yes) CPPFLAGS-malloc.c += -DUSE_TCACHE=1 else diff --git a/malloc/arena.c b/malloc/arena.c index 8309c1334..a32eb403e 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -236,6 +236,7 @@ TUNABLE_CALLBACK_FNDECL (set_tcache_max, size_t) TUNABLE_CALLBACK_FNDECL (set_tcache_count, size_t) TUNABLE_CALLBACK_FNDECL (set_tcache_unsorted_limit, size_t) #endif +TUNABLE_CALLBACK_FNDECL (set_mxfast, size_t) #else /* Initialization routine. */ #include @@ -323,6 +324,7 @@ ptmalloc_init (void) TUNABLE_GET (tcache_unsorted_limit, size_t, TUNABLE_CALLBACK (set_tcache_unsorted_limit)); # endif + TUNABLE_GET (mxfast, size_t, TUNABLE_CALLBACK (set_mxfast)); #else const char *s = NULL; if (__glibc_likely (_environ != NULL)) diff --git a/malloc/malloc.c b/malloc/malloc.c index 00ce48cf5..8c68b21b2 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -1621,7 +1621,7 @@ static INTERNAL_SIZE_T global_max_fast; #define set_max_fast(s) \ global_max_fast = (((s) == 0) \ - ? SMALLBIN_WIDTH : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK)) + ? MIN_CHUNK_SIZE / 2 : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK)) static inline INTERNAL_SIZE_T get_max_fast (void) @@ -5115,6 +5115,19 @@ do_set_tcache_unsorted_limit (size_t value) } #endif +static inline int +__always_inline +do_set_mxfast (size_t value) +{ + if (value >= 0 && value <= MAX_FAST_SIZE) + { + LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ()); + set_max_fast (value); + return 1; + } + return 0; +} + int __libc_mallopt (int param_number, int value) { @@ -5134,13 +5147,7 @@ __libc_mallopt (int param_number, int value) switch (param_number) { case M_MXFAST: - if (value >= 0 && value <= MAX_FAST_SIZE) - { - LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ()); - set_max_fast (value); - } - else - res = 0; + do_set_mxfast (value); break; case M_TRIM_THRESHOLD: @@ -5406,6 +5413,12 @@ __malloc_info (int options, FILE *fp) __libc_lock_lock (ar_ptr->mutex); + /* Account for top chunk. The top-most available chunk is + treated specially and is never in any bin. See "initial_top" + comments. */ + avail = chunksize (ar_ptr->top); + nblocks = 1; /* Top always exists. */ + for (size_t i = 0; i < NFASTBINS; ++i) { mchunkptr p = fastbin (ar_ptr, i); @@ -5491,7 +5504,7 @@ __malloc_info (int options, FILE *fp) for (size_t i = 0; i < nsizes; ++i) if (sizes[i].count != 0 && i != NFASTBINS) - fprintf (fp, " \ + fprintf (fp, "\ \n", sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count); diff --git a/malloc/malloc.h b/malloc/malloc.h index 70d8282bd..f62c6c594 100644 --- a/malloc/malloc.h +++ b/malloc/malloc.h @@ -71,8 +71,7 @@ extern void *valloc (size_t __size) __THROW __attribute_malloc__ /* Equivalent to valloc(minimum-page-that-holds(n)), that is, round up __size to nearest pagesize. */ -extern void *pvalloc (size_t __size) __THROW __attribute_malloc__ - __attribute_alloc_size__ ((1)) __wur; +extern void *pvalloc (size_t __size) __THROW __attribute_malloc__ __wur; /* Underlying allocation function; successive calls should return contiguous pieces of memory. */ diff --git a/malloc/tst-mallocfork2.c b/malloc/tst-mallocfork2.c index 30e7abe6f..c21e4d779 100644 --- a/malloc/tst-mallocfork2.c +++ b/malloc/tst-mallocfork2.c @@ -62,6 +62,9 @@ static volatile sig_atomic_t sigusr1_received; progress. Checked by liveness_signal_handler. */ static volatile sig_atomic_t progress_indicator = 1; +/* Set to 1 if an error occurs in the signal handler. */ +static volatile sig_atomic_t error_indicator = 0; + static void sigusr1_handler (int signo) { @@ -72,7 +75,8 @@ sigusr1_handler (int signo) if (pid == -1) { write_message ("error: fork\n"); - abort (); + error_indicator = 1; + return; } if (pid == 0) _exit (0); @@ -81,12 +85,14 @@ sigusr1_handler (int signo) if (ret < 0) { write_message ("error: waitpid\n"); - abort (); + error_indicator = 1; + return; } if (status != 0) { write_message ("error: unexpected exit status from subprocess\n"); - abort (); + error_indicator = 1; + return; } } @@ -122,9 +128,25 @@ signal_sender (int signo, bool sleep) } } +/* Children processes. */ +static pid_t sigusr1_sender_pids[5] = { 0 }; +static pid_t sigusr2_sender_pid = 0; + +static void +kill_children (void) +{ + for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i) + if (sigusr1_sender_pids[i] > 0) + kill (sigusr1_sender_pids[i], SIGKILL); + if (sigusr2_sender_pid > 0) + kill (sigusr2_sender_pid, SIGKILL); +} + static int do_test (void) { + atexit (kill_children); + /* shared->barrier is intialized along with sigusr1_sender_pids below. */ shared = support_shared_allocate (sizeof (*shared)); @@ -148,14 +170,13 @@ do_test (void) return 1; } - pid_t sigusr2_sender_pid = xfork (); + sigusr2_sender_pid = xfork (); if (sigusr2_sender_pid == 0) signal_sender (SIGUSR2, true); /* Send SIGUSR1 signals from several processes. Hopefully, one signal will hit one of the ciritical functions. Use a barrier to avoid sending signals while not running fork/free/malloc. */ - pid_t sigusr1_sender_pids[5]; { pthread_barrierattr_t attr; xpthread_barrierattr_init (&attr); @@ -166,7 +187,7 @@ do_test (void) } for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i) { - sigusr1_sender_pids[i] = fork (); + sigusr1_sender_pids[i] = xfork (); if (sigusr1_sender_pids[i] == 0) signal_sender (SIGUSR1, false); } @@ -211,7 +232,7 @@ do_test (void) ++malloc_signals; xpthread_barrier_wait (&shared->barrier); - if (objects[slot] == NULL) + if (objects[slot] == NULL || error_indicator != 0) { printf ("error: malloc: %m\n"); for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i) @@ -225,10 +246,6 @@ do_test (void) for (int slot = 0; slot < malloc_objects; ++slot) free (objects[slot]); - for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i) - kill (sigusr1_sender_pids[i], SIGKILL); - kill (sigusr2_sender_pid, SIGKILL); - printf ("info: signals received during fork: %u\n", fork_signals); printf ("info: signals received during free: %u\n", free_signals); printf ("info: signals received during malloc: %u\n", malloc_signals); diff --git a/malloc/tst-mxfast.c b/malloc/tst-mxfast.c new file mode 100644 index 000000000..7a7750bc7 --- /dev/null +++ b/malloc/tst-mxfast.c @@ -0,0 +1,50 @@ +/* Test that glibc.malloc.mxfast tunable works. + Copyright (C) 2019 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 + . */ + +/* This test verifies that setting the glibc.malloc.mxfast tunable to + zero results in free'd blocks being returned to the small bins, not + the fast bins. */ + +#include +#include + +int +do_test (void) +{ + struct mallinfo m; + char *volatile p1; + char *volatile p2; + + /* Arbitrary value; must be in default fastbin range. */ + p1 = malloc (3); + /* Something large so that p1 isn't a "top block" */ + p2 = malloc (512); + free (p1); + + m = mallinfo (); + + /* This will fail if there are any blocks in the fastbins. */ + TEST_COMPARE (m.smblks, 0); + + /* To keep gcc happy. */ + free (p2); + + return 0; +} + +#include diff --git a/malloc/tst-pvalloc-fortify.c b/malloc/tst-pvalloc-fortify.c new file mode 100644 index 000000000..391b7fa2f --- /dev/null +++ b/malloc/tst-pvalloc-fortify.c @@ -0,0 +1,48 @@ +/* Test fortify-source allocation size handling in pvalloc (bug 25401). + Copyright (C) 2020 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; see the file COPYING.LIB. If + not, see . */ + +#undef _FORTIFY_SOURCE +#define _FORTIFY_SOURCE 2 +#include +#include +#include +#include +#include + +static int +do_test (void) +{ + /* The test below assumes that pvalloc rounds up the allocation size + to at least 8. */ + TEST_VERIFY (xsysconf (_SC_PAGESIZE) >= 8); + + void *p = pvalloc (5); + TEST_VERIFY_EXIT (p != NULL); + + /* This is valid assuming the page size is at least 8 because + pvalloc rounds up the allocation size to a multiple of the page + size. Due to bug 25041, this used to trigger a compiler + warning. */ + strcpy (p, "abcdefg"); + + asm ("" : : "g" (p) : "memory"); /* Optimization barrier. */ + TEST_VERIFY (malloc_usable_size (p) >= xsysconf (_SC_PAGESIZE)); + return 0; +} + +#include diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h index f1bd994a1..b1695376d 100644 --- a/misc/sys/cdefs.h +++ b/misc/sys/cdefs.h @@ -412,14 +412,6 @@ # define __glibc_has_attribute(attr) 0 #endif -#ifdef __has_include -/* Do not use a function-like macro, so that __has_include can inhibit - macro expansion. */ -# define __glibc_has_include __has_include -#else -# define __glibc_has_include(header) 0 -#endif - #if (!defined _Noreturn \ && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ && !__GNUC_PREREQ (4,7)) diff --git a/posix/glob.c b/posix/glob.c index e73e35c51..c6cbd0eb4 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -827,31 +827,32 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { size_t home_len = strlen (p->pw_dir); size_t rest_len = end_name == NULL ? 0 : strlen (end_name); - char *d; + char *d, *newp; + bool use_alloca = glob_use_alloca (alloca_used, + home_len + rest_len + 1); - if (__glibc_unlikely (malloc_dirname)) - free (dirname); - malloc_dirname = 0; - - if (glob_use_alloca (alloca_used, home_len + rest_len + 1)) - dirname = alloca_account (home_len + rest_len + 1, - alloca_used); + if (use_alloca) + newp = alloca_account (home_len + rest_len + 1, alloca_used); else { - dirname = malloc (home_len + rest_len + 1); - if (dirname == NULL) + newp = malloc (home_len + rest_len + 1); + if (newp == NULL) { scratch_buffer_free (&pwtmpbuf); retval = GLOB_NOSPACE; goto out; } - malloc_dirname = 1; } - d = mempcpy (dirname, p->pw_dir, home_len); + d = mempcpy (newp, p->pw_dir, home_len); if (end_name != NULL) d = mempcpy (d, end_name, rest_len); *d = '\0'; + if (__glibc_unlikely (malloc_dirname)) + free (dirname); + dirname = newp; + malloc_dirname = !use_alloca; + dirlen = home_len + rest_len; dirname_modified = 1; } diff --git a/stdlib/Makefile b/stdlib/Makefile index 32f6050ec..4b2bdb08a 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -70,7 +70,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ test-canon test-canon2 tst-strtoll tst-environ \ tst-xpg-basename tst-random tst-random2 tst-bsearch \ tst-limits tst-rand48 bug-strtod tst-setcontext \ - tst-setcontext2 test-a64l tst-qsort tst-system testmb2 \ + tst-setcontext2 test-a64l tst-qsort testmb2 \ bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 \ tst-rand48-2 tst-makecontext tst-strtod5 \ tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \ @@ -92,6 +92,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \ tst-tls-atexit tst-tls-atexit-nodelete tests-static := tst-secure-getenv +tests-container := tst-system ifeq ($(build-hardcoded-path-in-tests),yes) tests += tst-empty-env diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c index 06afbf24c..8e1f23d5c 100644 --- a/stdlib/tst-system.c +++ b/stdlib/tst-system.c @@ -17,14 +17,130 @@ . */ #include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *tmpdir; +static long int namemax; + +static void +do_prepare (int argc, char *argv[]) +{ + tmpdir = support_create_temp_directory ("tst-system-"); + /* Include the last '/0'. */ + namemax = pathconf (tmpdir, _PC_NAME_MAX) + 1; + TEST_VERIFY_EXIT (namemax != -1); +} +#define PREPARE do_prepare + +struct args +{ + const char *command; + int exit_status; + int term_sig; + const char *path; +}; + +static void +call_system (void *closure) +{ + struct args *args = (struct args *) closure; + int ret; + + if (args->path != NULL) + TEST_COMPARE (setenv ("PATH", args->path, 1), 0); + ret = system (args->command); + if (args->term_sig == 0) + { + /* Expect regular termination. */ + TEST_VERIFY (WIFEXITED (ret) != 0); + TEST_COMPARE (WEXITSTATUS (ret), args->exit_status); + } + else + { + /* status_or_signal < 0. Expect termination by signal. */ + TEST_VERIFY (WIFSIGNALED (ret) != 0); + TEST_COMPARE (WTERMSIG (ret), args->term_sig); + } +} static int do_test (void) { - return system (":"); -} + TEST_VERIFY (system (NULL) != 0); + { + char cmd[namemax]; + memset (cmd, 'a', sizeof(cmd)); + cmd[sizeof(cmd) - 1] = '\0'; + + struct support_capture_subprocess result; + result = support_capture_subprocess (call_system, + &(struct args) { + cmd, 127, 0, tmpdir + }); + support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr); + + char *returnerr = xasprintf ("%s: execing %s failed: " + "No such file or directory", + basename(_PATH_BSHELL), cmd); + TEST_COMPARE_STRING (result.err.buffer, returnerr); + free (returnerr); + } + + { + char cmd[namemax + 1]; + memset (cmd, 'a', sizeof(cmd)); + cmd[sizeof(cmd) - 1] = '\0'; + + struct support_capture_subprocess result; + result = support_capture_subprocess (call_system, + &(struct args) { + cmd, 127, 0, tmpdir + }); + support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr); + + char *returnerr = xasprintf ("%s: execing %s failed: " + "File name too long", + basename(_PATH_BSHELL), cmd); + TEST_COMPARE_STRING (result.err.buffer, returnerr); + free (returnerr); + } + + { + struct support_capture_subprocess result; + result = support_capture_subprocess (call_system, + &(struct args) { + "kill $$", 0, SIGTERM + }); + support_capture_subprocess_check (&result, "system", 0, sc_allow_none); + } + + { + struct support_capture_subprocess result; + result = support_capture_subprocess (call_system, + &(struct args) { "echo ...", 0 }); + support_capture_subprocess_check (&result, "system", 0, sc_allow_stdout); + TEST_COMPARE_STRING (result.out.buffer, "...\n"); + } + + { + struct support_capture_subprocess result; + result = support_capture_subprocess (call_system, + &(struct args) { "exit 1", 1 }); + support_capture_subprocess_check (&result, "system", 0, sc_allow_none); + } + + TEST_COMPARE (system (""), 0); + + return 0; +} -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include diff --git a/string/string.h b/string/string.h index c38eea971..608ed496b 100644 --- a/string/string.h +++ b/string/string.h @@ -33,7 +33,8 @@ __BEGIN_DECLS #include /* Tell the caller that we provide correct C++ prototypes. */ -#if defined __cplusplus && __GNUC_PREREQ (4, 4) +#if defined __cplusplus && (__GNUC_PREREQ (4, 4) \ + || __glibc_clang_prereq (3, 5)) # define __CORRECT_ISO_CPP_STRING_H_PROTO #endif diff --git a/string/test-strstr.c b/string/test-strstr.c index df6dbc251..daed9a270 100644 --- a/string/test-strstr.c +++ b/string/test-strstr.c @@ -139,16 +139,45 @@ check1 (void) static void check2 (void) { - const char s1[] = ", enable_static, \0, enable_shared, "; + const char s1_stack[] = ", enable_static, \0, enable_shared, "; + const size_t s1_byte_count = 18; + const char *s2_stack = &(s1_stack[s1_byte_count]); + const size_t s2_byte_count = 18; char *exp_result; - char *s2 = (void *) buf1 + page_size - 18; + const size_t page_size_real = getpagesize (); - strcpy (s2, s1); - exp_result = stupid_strstr (s1, s1 + 18); + /* Haystack at end of page. The following page is protected. */ + char *s1_page_end = (void *) buf1 + page_size - s1_byte_count; + strcpy (s1_page_end, s1_stack); + + /* Haystack which crosses a page boundary. + Note: page_size is at least 2 * getpagesize. See test_init. */ + char *s1_page_cross = (void *) buf1 + page_size_real - 8; + strcpy (s1_page_cross, s1_stack); + + /* Needle at end of page. The following page is protected. */ + char *s2_page_end = (void *) buf2 + page_size - s2_byte_count; + strcpy (s2_page_end, s2_stack); + + /* Needle which crosses a page boundary. + Note: page_size is at least 2 * getpagesize. See test_init. */ + char *s2_page_cross = (void *) buf2 + page_size_real - 8; + strcpy (s2_page_cross, s2_stack); + + exp_result = stupid_strstr (s1_stack, s2_stack); FOR_EACH_IMPL (impl, 0) { - check_result (impl, s1, s1 + 18, exp_result); - check_result (impl, s2, s1 + 18, exp_result); + check_result (impl, s1_stack, s2_stack, exp_result); + check_result (impl, s1_stack, s2_page_end, exp_result); + check_result (impl, s1_stack, s2_page_cross, exp_result); + + check_result (impl, s1_page_end, s2_stack, exp_result); + check_result (impl, s1_page_end, s2_page_end, exp_result); + check_result (impl, s1_page_end, s2_page_cross, exp_result); + + check_result (impl, s1_page_cross, s2_stack, exp_result); + check_result (impl, s1_page_cross, s2_page_end, exp_result); + check_result (impl, s1_page_cross, s2_page_cross, exp_result); } } diff --git a/support/shell-container.c b/support/shell-container.c index ee3224dfd..51b01dce0 100644 --- a/support/shell-container.c +++ b/support/shell-container.c @@ -135,6 +135,37 @@ copy_func (char **argv) } +/* Emulate the 'exit' builtin. The exit value is optional. */ +static int +exit_func (char **argv) +{ + int exit_val = 0; + + if (argv[0] != 0) + exit_val = atoi (argv[0]) & 0xff; + exit (exit_val); + return 0; +} + +/* Emulate the "/bin/kill" command. Options are ignored. */ +static int +kill_func (char **argv) +{ + int signum = SIGTERM; + int i; + + for (i = 0; argv[i]; i++) + { + pid_t pid; + if (strcmp (argv[i], "$$") == 0) + pid = getpid (); + else + pid = atoi (argv[i]); + kill (pid, signum); + } + return 0; +} + /* This is a list of all the built-in commands we understand. */ static struct { const char *name; @@ -143,6 +174,8 @@ static struct { { "true", true_func }, { "echo", echo_func }, { "cp", copy_func }, + { "exit", exit_func }, + { "kill", kill_func }, { NULL, NULL } }; @@ -238,7 +271,7 @@ run_command_array (char **argv) fprintf (stderr, "sh: execing %s failed: %s", argv[0], strerror (errno)); - exit (1); + exit (127); } waitpid (pid, &status, 0); @@ -251,6 +284,11 @@ run_command_array (char **argv) if (rv) exit (rv); } + else if (WIFSIGNALED (status)) + { + int sig = WTERMSIG (status); + raise (sig); + } else exit (1); } diff --git a/sysdeps/alpha/fpu/libm-test-ulps b/sysdeps/alpha/fpu/libm-test-ulps index 0f77dd2ed..89c4527a8 100644 --- a/sysdeps/alpha/fpu/libm-test-ulps +++ b/sysdeps/alpha/fpu/libm-test-ulps @@ -1084,10 +1084,10 @@ ildouble: 1 ldouble: 1 Function: Real part of "cpow_downward": -double: 2 -float: 4 -idouble: 2 -ifloat: 4 +double: 5 +float: 8 +idouble: 5 +ifloat: 8 ildouble: 6 ldouble: 6 @@ -1100,10 +1100,10 @@ ildouble: 2 ldouble: 2 Function: Real part of "cpow_towardzero": -double: 2 -float: 4 -idouble: 2 -ifloat: 4 +double: 5 +float: 8 +idouble: 5 +ifloat: 8 ildouble: 6 ldouble: 6 diff --git a/sysdeps/arm/be/nofpu/Implies b/sysdeps/arm/be/nofpu/Implies new file mode 100644 index 000000000..c90dd7fd5 --- /dev/null +++ b/sysdeps/arm/be/nofpu/Implies @@ -0,0 +1 @@ +arm/nofpu diff --git a/sysdeps/arm/le/nofpu/Implies b/sysdeps/arm/le/nofpu/Implies new file mode 100644 index 000000000..c90dd7fd5 --- /dev/null +++ b/sysdeps/arm/le/nofpu/Implies @@ -0,0 +1 @@ +arm/nofpu diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h index f3d862651..724c3e5e7 100644 --- a/sysdeps/generic/not-cancel.h +++ b/sysdeps/generic/not-cancel.h @@ -41,6 +41,8 @@ (void) __close (fd) #define __read_nocancel(fd, buf, n) \ __read (fd, buf, n) +#define __pread64_nocancel(fd, buf, count, offset) \ + __pread64 (fd, buf, count, offset) #define __write_nocancel(fd, buf, n) \ __write (fd, buf, n) #define __writev_nocancel_nostatus(fd, iov, n) \ diff --git a/sysdeps/generic/utmp-equal.h b/sysdeps/generic/utmp-equal.h index d077147a7..d61cbb330 100644 --- a/sysdeps/generic/utmp-equal.h +++ b/sysdeps/generic/utmp-equal.h @@ -27,26 +27,16 @@ static int __utmp_equal (const struct utmp *entry, const struct utmp *match) { - return - ( -#if _HAVE_UT_TYPE - 0 - (entry->ut_type == INIT_PROCESS - || entry->ut_type == LOGIN_PROCESS - || entry->ut_type == USER_PROCESS - || entry->ut_type == DEAD_PROCESS) - && - (match->ut_type == INIT_PROCESS - || match->ut_type == LOGIN_PROCESS - || match->ut_type == USER_PROCESS - || match->ut_type == DEAD_PROCESS) - && -#endif -#if _HAVE_UT_ID - 0 - (entry->ut_id[0] && match->ut_id[0] - ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0 - : strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0) -#else - strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0 -#endif - ); + return (entry->ut_type == INIT_PROCESS + || entry->ut_type == LOGIN_PROCESS + || entry->ut_type == USER_PROCESS + || entry->ut_type == DEAD_PROCESS) + && (match->ut_type == INIT_PROCESS + || match->ut_type == LOGIN_PROCESS + || match->ut_type == USER_PROCESS + || match->ut_type == DEAD_PROCESS) + && (entry->ut_id[0] && match->ut_id[0] + ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0 + : (strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) + == 0)); } diff --git a/sysdeps/gnu/bits/utmp.h b/sysdeps/gnu/bits/utmp.h deleted file mode 100644 index 7357034cb..000000000 --- a/sysdeps/gnu/bits/utmp.h +++ /dev/null @@ -1,126 +0,0 @@ -/* The `struct utmp' type, describing entries in the utmp file. GNU version. - Copyright (C) 1993-2019 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 - . */ - -#ifndef _UTMP_H -# error "Never include directly; use instead." -#endif - -#include -#include -#include -#include - - -#define UT_LINESIZE 32 -#define UT_NAMESIZE 32 -#define UT_HOSTSIZE 256 - - -/* The structure describing an entry in the database of - previous logins. */ -struct lastlog - { -#if __WORDSIZE_TIME64_COMPAT32 - int32_t ll_time; -#else - __time_t ll_time; -#endif - char ll_line[UT_LINESIZE]; - char ll_host[UT_HOSTSIZE]; - }; - - -/* The structure describing the status of a terminated process. This - type is used in `struct utmp' below. */ -struct exit_status - { - short int e_termination; /* Process termination status. */ - short int e_exit; /* Process exit status. */ - }; - - -/* The structure describing an entry in the user accounting database. */ -struct utmp -{ - short int ut_type; /* Type of login. */ - pid_t ut_pid; /* Process ID of login process. */ - char ut_line[UT_LINESIZE] - __attribute_nonstring__; /* Devicename. */ - char ut_id[4]; /* Inittab ID. */ - char ut_user[UT_NAMESIZE] - __attribute_nonstring__; /* Username. */ - char ut_host[UT_HOSTSIZE] - __attribute_nonstring__; /* Hostname for remote login. */ - struct exit_status ut_exit; /* Exit status of a process marked - as DEAD_PROCESS. */ -/* The ut_session and ut_tv fields must be the same size when compiled - 32- and 64-bit. This allows data files and shared memory to be - shared between 32- and 64-bit applications. */ -#if __WORDSIZE_TIME64_COMPAT32 - int32_t ut_session; /* Session ID, used for windowing. */ - struct - { - int32_t tv_sec; /* Seconds. */ - int32_t tv_usec; /* Microseconds. */ - } ut_tv; /* Time entry was made. */ -#else - long int ut_session; /* Session ID, used for windowing. */ - struct timeval ut_tv; /* Time entry was made. */ -#endif - - int32_t ut_addr_v6[4]; /* Internet address of remote host. */ - char __glibc_reserved[20]; /* Reserved for future use. */ -}; - -/* Backwards compatibility hacks. */ -#define ut_name ut_user -#ifndef _NO_UT_TIME -/* We have a problem here: `ut_time' is also used otherwise. Define - _NO_UT_TIME if the compiler complains. */ -# define ut_time ut_tv.tv_sec -#endif -#define ut_xtime ut_tv.tv_sec -#define ut_addr ut_addr_v6[0] - - -/* Values for the `ut_type' field of a `struct utmp'. */ -#define EMPTY 0 /* No valid user accounting information. */ - -#define RUN_LVL 1 /* The system's runlevel. */ -#define BOOT_TIME 2 /* Time of system boot. */ -#define NEW_TIME 3 /* Time after system clock changed. */ -#define OLD_TIME 4 /* Time when system clock changed. */ - -#define INIT_PROCESS 5 /* Process spawned by the init process. */ -#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */ -#define USER_PROCESS 7 /* Normal process. */ -#define DEAD_PROCESS 8 /* Terminated process. */ - -#define ACCOUNTING 9 - -/* Old Linux name for the EMPTY type. */ -#define UT_UNKNOWN EMPTY - - -/* Tell the user that we have a modern system with UT_HOST, UT_PID, - UT_TYPE, UT_ID and UT_TV fields. */ -#define _HAVE_UT_TYPE 1 -#define _HAVE_UT_PID 1 -#define _HAVE_UT_ID 1 -#define _HAVE_UT_TV 1 -#define _HAVE_UT_HOST 1 diff --git a/sysdeps/gnu/bits/utmpx.h b/sysdeps/gnu/bits/utmpx.h index 472a7d57d..2beadbf58 100644 --- a/sysdeps/gnu/bits/utmpx.h +++ b/sysdeps/gnu/bits/utmpx.h @@ -56,10 +56,14 @@ struct utmpx { short int ut_type; /* Type of login. */ __pid_t ut_pid; /* Process ID of login process. */ - char ut_line[__UT_LINESIZE]; /* Devicename. */ - char ut_id[4]; /* Inittab ID. */ - char ut_user[__UT_NAMESIZE]; /* Username. */ - char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ + char ut_line[__UT_LINESIZE] + __attribute_nonstring__; /* Devicename. */ + char ut_id[4] + __attribute_nonstring__; /* Inittab ID. */ + char ut_user[__UT_NAMESIZE] + __attribute_nonstring__; /* Username. */ + char ut_host[__UT_HOSTSIZE] + __attribute_nonstring__; /* Hostname for remote login. */ struct __exit_status ut_exit; /* Exit status of a process marked as DEAD_PROCESS. */ diff --git a/sysdeps/hppa/dl-fptr.c b/sysdeps/hppa/dl-fptr.c index af1acb070..e01e0fff6 100644 --- a/sysdeps/hppa/dl-fptr.c +++ b/sysdeps/hppa/dl-fptr.c @@ -172,8 +172,8 @@ make_fdesc (ElfW(Addr) ip, ElfW(Addr) gp) } install: - fdesc->ip = ip; fdesc->gp = gp; + fdesc->ip = ip; return (ElfW(Addr)) fdesc; } @@ -350,7 +350,9 @@ ElfW(Addr) _dl_lookup_address (const void *address) { ElfW(Addr) addr = (ElfW(Addr)) address; - unsigned int *desc, *gptr; + ElfW(Word) reloc_arg; + volatile unsigned int *desc; + unsigned int *gptr; /* Return ADDR if the least-significant two bits of ADDR are not consistent with ADDR being a linker defined function pointer. The normal value for @@ -367,7 +369,11 @@ _dl_lookup_address (const void *address) if (!_dl_read_access_allowed (desc)) return addr; - /* Load first word of candidate descriptor. It should be a pointer + /* First load the relocation offset. */ + reloc_arg = (ElfW(Word)) desc[1]; + atomic_full_barrier(); + + /* Then load first word of candidate descriptor. It should be a pointer with word alignment and point to memory that can be read. */ gptr = (unsigned int *) desc[0]; if (((unsigned int) gptr & 3) != 0 @@ -377,8 +383,8 @@ _dl_lookup_address (const void *address) /* See if descriptor requires resolution. The following trampoline is used in each global offset table for function resolution: - ldw 0(r20),r22 - bv r0(r22) + ldw 0(r20),r21 + bv r0(r21) ldw 4(r20),r21 tramp: b,l .-12,r20 depwi 0,31,2,r20 @@ -389,7 +395,15 @@ _dl_lookup_address (const void *address) if (gptr[0] == 0xea9f1fdd /* b,l .-12,r20 */ && gptr[1] == 0xd6801c1e /* depwi 0,31,2,r20 */ && (ElfW(Addr)) gptr[2] == elf_machine_resolve ()) - _dl_fixup ((struct link_map *) gptr[5], (ElfW(Word)) desc[1]); + { + struct link_map *l = (struct link_map *) gptr[5]; + + /* If gp has been resolved, we need to hunt for relocation offset. */ + if (!(reloc_arg & PA_GP_RELOC)) + reloc_arg = _dl_fix_reloc_arg (addr, l); + + _dl_fixup (l, reloc_arg); + } return (ElfW(Addr)) desc[0]; } diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h index 509c54112..b80b60bdb 100644 --- a/sysdeps/hppa/dl-machine.h +++ b/sysdeps/hppa/dl-machine.h @@ -48,6 +48,14 @@ #define GOT_FROM_PLT_STUB (4*4) #define PLT_ENTRY_SIZE (2*4) +/* The gp slot in the function descriptor contains the relocation offset + before resolution. To distinguish between a resolved gp value and an + unresolved relocation offset we set an unused bit in the relocation + offset. This would allow us to do a synchronzied two word update + using this bit (interlocked update), but instead of waiting for the + update we simply recompute the gp value given that we know the ip. */ +#define PA_GP_RELOC 1 + /* Initialize the function descriptor table before relocations */ static inline void __hppa_init_bootstrap_fdesc_table (struct link_map *map) @@ -117,10 +125,28 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t, volatile Elf32_Addr *rfdesc = reloc_addr; /* map is the link_map for the caller, t is the link_map for the object being called */ - rfdesc[1] = value.gp; - /* Need to ensure that the gp is visible before the code - entry point is updated */ - rfdesc[0] = value.ip; + + /* We would like the function descriptor to be double word aligned. This + helps performance (ip and gp then reside on the same cache line) and + we can update the pair atomically with a single store. The linker + now ensures this alignment but we still have to handle old code. */ + if ((unsigned int)reloc_addr & 7) + { + /* Need to ensure that the gp is visible before the code + entry point is updated */ + rfdesc[1] = value.gp; + atomic_full_barrier(); + rfdesc[0] = value.ip; + } + else + { + /* Update pair atomically with floating point store. */ + union { ElfW(Word) v[2]; double d; } u; + + u.v[0] = value.ip; + u.v[1] = value.gp; + *(volatile double *)rfdesc = u.d; + } return value; } @@ -265,7 +291,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) here. The trampoline code will load the proper LTP and pass the reloc offset to the fixup function. */ - fptr->gp = iplt - jmprel; + fptr->gp = (iplt - jmprel) | PA_GP_RELOC; } /* r_sym != 0 */ else { diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c new file mode 100644 index 000000000..885a3f183 --- /dev/null +++ b/sysdeps/hppa/dl-runtime.c @@ -0,0 +1,58 @@ +/* On-demand PLT fixup for shared objects. HPPA version. + Copyright (C) 2019 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Clear PA_GP_RELOC bit in relocation offset. */ +#define reloc_offset (reloc_arg & ~PA_GP_RELOC) +#define reloc_index (reloc_arg & ~PA_GP_RELOC) / sizeof (PLTREL) + +#include + +/* The caller has encountered a partially relocated function descriptor. + The gp of the descriptor has been updated, but not the ip. We find + the function descriptor again and compute the relocation offset and + return that to the caller. The caller will continue on to call + _dl_fixup with the relocation offset. */ + +ElfW(Word) +attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE +_dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l) +{ + Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type; + const Elf32_Rela *reloc; + + l_addr = l->l_addr; + jmprel = D_PTR(l, l_info[DT_JMPREL]); + end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val; + + /* Look for the entry... */ + for (iplt = jmprel; iplt < end_jmprel; iplt += sizeof (Elf32_Rela)) + { + reloc = (const Elf32_Rela *) iplt; + r_type = ELF32_R_TYPE (reloc->r_info); + + if (__builtin_expect (r_type == R_PARISC_IPLT, 1) + && fptr == (struct fdesc *) (reloc->r_offset + l_addr)) + /* Found entry. Return the reloc offset. */ + return iplt - jmprel; + } + + /* Crash if we weren't passed a valid function pointer. */ + ABORT_INSTRUCTION; + return 0; +} diff --git a/sysdeps/hppa/dl-trampoline.S b/sysdeps/hppa/dl-trampoline.S index 6df285203..f0f0fefad 100644 --- a/sysdeps/hppa/dl-trampoline.S +++ b/sysdeps/hppa/dl-trampoline.S @@ -31,7 +31,7 @@ slow down __cffc when it attempts to call fixup to resolve function descriptor references. Please refer to gcc/gcc/config/pa/fptr.c - Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp. */ + Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp, r22 = fp. */ /* RELOCATION MARKER: bl to provide gcc's __cffc with fixup loc. */ .text @@ -61,17 +61,20 @@ _dl_runtime_resolve: copy %sp, %r1 /* Copy previous sp */ /* Save function result address (on entry) */ stwm %r28,128(%sp) - /* Fillin some frame info to follow ABI */ + /* Fill in some frame info to follow ABI */ stw %r1,-4(%sp) /* Previous sp */ stw %r21,-32(%sp) /* PIC register value */ /* Save input floating point registers. This must be done in the new frame since the previous frame doesn't have enough space */ - ldo -56(%sp),%r1 + ldo -64(%sp),%r1 fstd,ma %fr4,-8(%r1) fstd,ma %fr5,-8(%r1) fstd,ma %fr6,-8(%r1) + + /* Test PA_GP_RELOC bit. */ + bb,>= %r19,31,2f /* branch if not reloc offset */ fstd,ma %fr7,-8(%r1) /* Set up args to fixup func, needs only two arguments */ @@ -79,7 +82,7 @@ _dl_runtime_resolve: copy %r19,%r25 /* (2) reloc offset */ /* Call the real address resolver. */ - bl _dl_fixup,%rp +3: bl _dl_fixup,%rp copy %r21,%r19 /* set fixup func ltp */ /* While the linker will set a function pointer to NULL when it @@ -102,7 +105,7 @@ _dl_runtime_resolve: copy %r29, %r19 /* Reload arguments fp args */ - ldo -56(%sp),%r1 + ldo -64(%sp),%r1 fldd,ma -8(%r1),%fr4 fldd,ma -8(%r1),%fr5 fldd,ma -8(%r1),%fr6 @@ -129,6 +132,25 @@ _dl_runtime_resolve: bv %r0(%rp) ldo -128(%sp),%sp +2: + /* Set up args for _dl_fix_reloc_arg. */ + copy %r22,%r26 /* (1) function pointer */ + depi 0,31,2,%r26 /* clear least significant bits */ + ldw 8+4(%r20),%r25 /* (2) got[1] == struct link_map */ + + /* Save ltp and link map arg for _dl_fixup. */ + stw %r21,-56(%sp) /* ltp */ + stw %r25,-60(%sp) /* struct link map */ + + /* Find reloc offset. */ + bl _dl_fix_reloc_arg,%rp + copy %r21,%r19 /* set func ltp */ + + /* Set up args for _dl_fixup. */ + ldw -56(%sp),%r21 /* ltp */ + ldw -60(%sp),%r26 /* (1) struct link map */ + b 3b + copy %ret0,%r25 /* (2) reloc offset */ .EXIT .PROCEND cfi_endproc @@ -153,7 +175,7 @@ _dl_runtime_profile: copy %sp, %r1 /* Copy previous sp */ /* Save function result address (on entry) */ stwm %r28,192(%sp) - /* Fillin some frame info to follow ABI */ + /* Fill in some frame info to follow ABI */ stw %r1,-4(%sp) /* Previous sp */ stw %r21,-32(%sp) /* PIC register value */ @@ -181,10 +203,11 @@ _dl_runtime_profile: fstd,ma %fr5,8(%r1) fstd,ma %fr6,8(%r1) fstd,ma %fr7,8(%r1) - /* 32-bit stack pointer and return register */ - stw %sp,-56(%sp) - stw %r2,-52(%sp) + /* Test PA_GP_RELOC bit. */ + bb,>= %r19,31,2f /* branch if not reloc offset */ + /* 32-bit stack pointer */ + stw %sp,-56(%sp) /* Set up args to fixup func, needs five arguments */ ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */ @@ -197,7 +220,7 @@ _dl_runtime_profile: stw %r1, -52(%sp) /* (5) long int *framesizep */ /* Call the real address resolver. */ - bl _dl_profile_fixup,%rp +3: bl _dl_profile_fixup,%rp copy %r21,%r19 /* set fixup func ltp */ /* Load up the returned function descriptor */ @@ -215,7 +238,9 @@ _dl_runtime_profile: fldd,ma 8(%r1),%fr5 fldd,ma 8(%r1),%fr6 fldd,ma 8(%r1),%fr7 - ldw -52(%sp),%rp + + /* Reload rp register -(192+20) without adjusting stack */ + ldw -212(%sp),%rp /* Reload static link register -(192+16) without adjusting stack */ ldw -208(%sp),%r29 @@ -303,6 +328,33 @@ L(cont): ldw -20(%sp),%rp /* Return */ bv,n 0(%r2) + +2: + /* Set up args for _dl_fix_reloc_arg. */ + copy %r22,%r26 /* (1) function pointer */ + depi 0,31,2,%r26 /* clear least significant bits */ + ldw 8+4(%r20),%r25 /* (2) got[1] == struct link_map */ + + /* Save ltp and link map arg for _dl_fixup. */ + stw %r21,-92(%sp) /* ltp */ + stw %r25,-116(%sp) /* struct link map */ + + /* Find reloc offset. */ + bl _dl_fix_reloc_arg,%rp + copy %r21,%r19 /* set func ltp */ + + /* Restore fixup ltp. */ + ldw -92(%sp),%r21 /* ltp */ + + /* Set up args to fixup func, needs five arguments */ + ldw -116(%sp),%r26 /* (1) struct link map */ + copy %ret0,%r25 /* (2) reloc offset */ + stw %r25,-120(%sp) /* Save reloc offset */ + ldw -212(%sp),%r24 /* (3) profile_fixup needs rp */ + ldo -56(%sp),%r23 /* (4) La_hppa_regs */ + ldo -112(%sp), %r1 + b 3b + stw %r1, -52(%sp) /* (5) long int *framesizep */ .EXIT .PROCEND cfi_endproc diff --git a/sysdeps/hppa/fpu/libm-test-ulps b/sysdeps/hppa/fpu/libm-test-ulps index d0c4dea00..2c61a7ae9 100644 --- a/sysdeps/hppa/fpu/libm-test-ulps +++ b/sysdeps/hppa/fpu/libm-test-ulps @@ -544,9 +544,9 @@ idouble: 1 ifloat: 1 Function: Imaginary part of "ccos_downward": -double: 2 +double: 3 float: 3 -idouble: 2 +idouble: 3 ifloat: 3 Function: Real part of "ccos_towardzero": @@ -556,9 +556,9 @@ idouble: 1 ifloat: 2 Function: Imaginary part of "ccos_towardzero": -double: 2 +double: 3 float: 3 -idouble: 2 +idouble: 3 ifloat: 3 Function: Real part of "ccos_upward": @@ -588,27 +588,27 @@ idouble: 1 ifloat: 1 Function: Real part of "ccosh_downward": -double: 1 +double: 2 float: 3 -idouble: 1 +idouble: 2 ifloat: 3 Function: Imaginary part of "ccosh_downward": -double: 2 +double: 3 float: 3 -idouble: 2 +idouble: 3 ifloat: 3 Function: Real part of "ccosh_towardzero": -double: 1 +double: 2 float: 3 -idouble: 1 +idouble: 2 ifloat: 3 Function: Imaginary part of "ccosh_towardzero": -double: 2 +double: 3 float: 3 -idouble: 2 +idouble: 3 ifloat: 3 Function: Real part of "ccosh_upward": @@ -636,27 +636,27 @@ idouble: 1 ifloat: 2 Function: Real part of "cexp_downward": -double: 1 +double: 2 float: 2 -idouble: 1 +idouble: 2 ifloat: 2 Function: Imaginary part of "cexp_downward": -double: 1 +double: 3 float: 3 -idouble: 1 +idouble: 3 ifloat: 3 Function: Real part of "cexp_towardzero": -double: 1 +double: 2 float: 2 -idouble: 1 +idouble: 2 ifloat: 2 Function: Imaginary part of "cexp_towardzero": -double: 1 +double: 3 float: 3 -idouble: 1 +idouble: 3 ifloat: 3 Function: Real part of "cexp_upward": @@ -666,9 +666,9 @@ idouble: 1 ifloat: 2 Function: Imaginary part of "cexp_upward": -double: 1 +double: 3 float: 2 -idouble: 1 +idouble: 3 ifloat: 2 Function: Real part of "clog": @@ -800,21 +800,21 @@ idouble: 1 ifloat: 1 Function: "cosh_downward": -double: 1 +double: 2 float: 1 -idouble: 1 +idouble: 2 ifloat: 1 Function: "cosh_towardzero": -double: 1 +double: 2 float: 1 -idouble: 1 +idouble: 2 ifloat: 1 Function: "cosh_upward": -double: 1 +double: 2 float: 2 -idouble: 1 +idouble: 2 ifloat: 2 Function: Real part of "cpow": @@ -834,9 +834,9 @@ ildouble: 2 ldouble: 2 Function: Real part of "cpow_downward": -double: 4 +double: 5 float: 8 -idouble: 4 +idouble: 5 ifloat: 8 Function: Imaginary part of "cpow_downward": @@ -846,9 +846,9 @@ idouble: 2 ifloat: 2 Function: Real part of "cpow_towardzero": -double: 4 +double: 5 float: 8 -idouble: 4 +idouble: 5 ifloat: 8 Function: Imaginary part of "cpow_towardzero": @@ -876,9 +876,9 @@ idouble: 1 ifloat: 1 Function: Real part of "csin_downward": -double: 2 +double: 3 float: 3 -idouble: 2 +idouble: 3 ifloat: 3 Function: Imaginary part of "csin_downward": @@ -888,9 +888,9 @@ idouble: 1 ifloat: 2 Function: Real part of "csin_towardzero": -double: 2 +double: 3 float: 3 -idouble: 2 +idouble: 3 ifloat: 3 Function: Imaginary part of "csin_towardzero": @@ -930,9 +930,9 @@ idouble: 2 ifloat: 2 Function: Imaginary part of "csinh_downward": -double: 2 +double: 3 float: 3 -idouble: 2 +idouble: 3 ifloat: 3 Function: Real part of "csinh_towardzero": @@ -942,9 +942,9 @@ idouble: 2 ifloat: 2 Function: Imaginary part of "csinh_towardzero": -double: 2 +double: 3 float: 3 -idouble: 2 +idouble: 3 ifloat: 3 Function: Real part of "csinh_upward": @@ -1172,15 +1172,15 @@ ildouble: 6 ldouble: 6 Function: "exp10_downward": -double: 2 +double: 3 float: 1 -idouble: 2 +idouble: 3 ifloat: 1 Function: "exp10_towardzero": -double: 2 +double: 3 float: 1 -idouble: 2 +idouble: 3 ifloat: 1 Function: "exp10_upward": diff --git a/sysdeps/i386/sysdep.h b/sysdeps/i386/sysdep.h index 749b55b07..eee6d586c 100644 --- a/sysdeps/i386/sysdep.h +++ b/sysdeps/i386/sysdep.h @@ -61,7 +61,7 @@ lose: SYSCALL_PIC_SETUP \ # define SETUP_PIC_REG(reg) \ .ifndef GET_PC_THUNK(reg); \ - .section .gnu.linkonce.t.GET_PC_THUNK(reg),"ax",@progbits; \ + .section .text.GET_PC_THUNK(reg),"axG",@progbits,GET_PC_THUNK(reg),comdat; \ .globl GET_PC_THUNK(reg); \ .hidden GET_PC_THUNK(reg); \ .p2align 4; \ @@ -97,7 +97,8 @@ GET_PC_THUNK(reg): \ # define SETUP_PIC_REG_STR(reg) \ ".ifndef " GET_PC_THUNK_STR (reg) "\n" \ - ".section .gnu.linkonce.t." GET_PC_THUNK_STR (reg) ",\"ax\",@progbits\n" \ + ".section .text." GET_PC_THUNK_STR (reg) ",\"axG\",@progbits," \ + GET_PC_THUNK_STR (reg) ",comdat\n" \ ".globl " GET_PC_THUNK_STR (reg) "\n" \ ".hidden " GET_PC_THUNK_STR (reg) "\n" \ ".p2align 4\n" \ diff --git a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile index b10325421..4142695ec 100644 --- a/sysdeps/ieee754/ldbl-96/Makefile +++ b/sysdeps/ieee754/ldbl-96/Makefile @@ -17,5 +17,8 @@ # . ifeq ($(subdir),math) -tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 +tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 test-sinl-pseudo +ifeq ($(have-ssp),yes) +CFLAGS-test-sinl-pseudo.c += -fstack-protector-all endif +endif # $(subdir) == math diff --git a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c index 805de22d7..1aeccb47d 100644 --- a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c +++ b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c @@ -210,6 +210,18 @@ __ieee754_rem_pio2l (long double x, long double *y) return 0; } + if ((i0 & 0x80000000) == 0) + { + /* Pseudo-zero and unnormal representations are not valid + representations of long double. We need to avoid stack + corruption in __kernel_rem_pio2, which expects input in a + particular normal form, but those representations do not need + to be consistently handled like any particular floating-point + value. */ + y[1] = y[0] = __builtin_nanl (""); + return 0; + } + /* Split the 64 bits of the mantissa into three 24-bit integers stored in a double array. */ exp = j0 - 23; diff --git a/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c new file mode 100644 index 000000000..f59b97769 --- /dev/null +++ b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c @@ -0,0 +1,41 @@ +/* Test sinl for pseudo-zeros and unnormals for ldbl-96 (bug 25487). + Copyright (C) 2020 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 + . */ + +#include +#include +#include + +static int +do_test (void) +{ + for (int i = 0; i < 64; i++) + { + uint64_t sig = i == 63 ? 0 : 1ULL << i; + long double ld; + SET_LDOUBLE_WORDS (ld, 0x4141, + sig >> 32, sig & 0xffffffffULL); + /* The requirement is that no stack overflow occurs when the + pseudo-zero or unnormal goes through range reduction. */ + volatile long double ldr; + ldr = sinl (ld); + (void) ldr; + } + return 0; +} + +#include diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c index a08d328b2..863d7c016 100644 --- a/sysdeps/posix/system.c +++ b/sysdeps/posix/system.c @@ -97,7 +97,8 @@ cancel_handler (void *arg) static int do_system (const char *line) { - int status; + int status = -1; + int ret; pid_t pid; struct sigaction sa; #ifndef _LIBC_REENTRANT @@ -140,14 +141,14 @@ do_system (const char *line) __posix_spawnattr_setflags (&spawn_attr, POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK); - status = __posix_spawn (&pid, SHELL_PATH, 0, &spawn_attr, - (char *const[]){ (char*) SHELL_NAME, - (char*) "-c", - (char *) line, NULL }, - __environ); + ret = __posix_spawn (&pid, SHELL_PATH, 0, &spawn_attr, + (char *const[]){ (char *) SHELL_NAME, + (char *) "-c", + (char *) line, NULL }, + __environ); __posix_spawnattr_destroy (&spawn_attr); - if (status == 0) + if (ret == 0) { /* Cancellation results in cleanup handlers running as exceptions in the block where they were installed, so it is safe to reference @@ -182,6 +183,9 @@ do_system (const char *line) } DO_UNLOCK (); + if (ret != 0) + __set_errno (ret); + return status; } diff --git a/sysdeps/powerpc/powerpc32/backtrace.c b/sysdeps/powerpc/powerpc32/backtrace.c index 857a8aad7..dc187a8f2 100644 --- a/sysdeps/powerpc/powerpc32/backtrace.c +++ b/sysdeps/powerpc/powerpc32/backtrace.c @@ -114,6 +114,8 @@ __backtrace (void **array, int size) } if (gregset) { + if (count + 1 == size) + break; array[++count] = (void*)((*gregset)[PT_NIP]); current = (void*)((*gregset)[PT_R1]); } diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c index 7a167838d..ce038a139 100644 --- a/sysdeps/powerpc/powerpc64/backtrace.c +++ b/sysdeps/powerpc/powerpc64/backtrace.c @@ -87,6 +87,8 @@ __backtrace (void **array, int size) if (is_sigtramp_address (current->return_address)) { struct signal_frame_64 *sigframe = (struct signal_frame_64*) current; + if (count + 1 == size) + break; array[++count] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP]; current = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_R1]; } diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c index 44c990180..1307ec41d 100644 --- a/sysdeps/s390/dl-procinfo.c +++ b/sysdeps/s390/dl-procinfo.c @@ -63,11 +63,11 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[19][9] #if !defined PROCINFO_DECL && defined SHARED ._dl_s390_platforms #else -PROCINFO_CLASS const char _dl_s390_platforms[9][7] +PROCINFO_CLASS const char _dl_s390_platforms[10][7] #endif #ifndef PROCINFO_DECL = { - "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14" + "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15" } #endif #if !defined SHARED || defined PROCINFO_DECL diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h index 3b1f6a642..689e961ce 100644 --- a/sysdeps/s390/dl-procinfo.h +++ b/sysdeps/s390/dl-procinfo.h @@ -23,7 +23,7 @@ #define _DL_HWCAP_COUNT 19 -#define _DL_PLATFORMS_COUNT 9 +#define _DL_PLATFORMS_COUNT 10 /* The kernel provides up to 32 capability bits with elf_hwcap. */ #define _DL_FIRST_PLATFORM 32 diff --git a/sysdeps/s390/strstr-arch13.S b/sysdeps/s390/strstr-arch13.S index 929b026ad..faa969849 100644 --- a/sysdeps/s390/strstr-arch13.S +++ b/sysdeps/s390/strstr-arch13.S @@ -164,7 +164,7 @@ ENTRY(STRSTR_ARCH13) vfenezb %v19,%v18,%v18 /* Search zero in loaded needle bytes. */ veclb %v19,%v21 /* Zero index <= max loaded byte index? */ jle .Lneedle_loaded /* -> v18 contains full needle. */ - vl %v16,0(%r3) /* Load needle beyond page boundary. */ + vl %v18,0(%r3) /* Load needle beyond page boundary. */ vfenezb %v19,%v18,%v18 j .Lneedle_loaded END(STRSTR_ARCH13) diff --git a/sysdeps/unix/getlogin_r.c b/sysdeps/unix/getlogin_r.c index 6c564d3b5..88971a993 100644 --- a/sysdeps/unix/getlogin_r.c +++ b/sysdeps/unix/getlogin_r.c @@ -64,8 +64,8 @@ __getlogin_r (char *name, size_t name_len) held so that our search is thread-safe. */ __libc_lock_lock (__libc_utmp_lock); - (*__libc_utmp_jump_table->setutent) (); - result = (*__libc_utmp_jump_table->getutline_r) (&line, &buffer, &ut); + __libc_setutent (); + result = __libc_getutline_r (&line, &buffer, &ut); if (result < 0) { if (errno == ESRCH) @@ -74,8 +74,7 @@ __getlogin_r (char *name, size_t name_len) else result = errno; } - (*__libc_utmp_jump_table->endutent) (); - __libc_utmp_jump_table = &__libc_utmp_unknown_functions; + __libc_endutent (); __libc_lock_unlock (__libc_utmp_lock); if (result == 0) diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 1ab6bcbfc..a7980a60f 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -212,8 +212,8 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \ close_nocancel fcntl_nocancel nanosleep_nocancel \ open_nocancel open64_nocancel \ openat_nocancel openat64_nocancel \ - pause_nocancel read_nocancel waitpid_nocancel \ - write_nocancel statx_cp + pause_nocancel read_nocancel pread64_nocancel \ + waitpid_nocancel write_nocancel statx_cp sysdep_headers += bits/fcntl-linux.h diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 1ca102a9e..d385085c6 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -182,6 +182,7 @@ libc { __syscall_rt_sigqueueinfo; __open_nocancel; __read_nocancel; + __pread64_nocancel; __close_nocancel; __sigtimedwait; # functions used by nscd diff --git a/sysdeps/unix/alpha/getegid.S b/sysdeps/unix/sysv/linux/alpha/getegid.S similarity index 100% rename from sysdeps/unix/alpha/getegid.S rename to sysdeps/unix/sysv/linux/alpha/getegid.S diff --git a/sysdeps/unix/alpha/geteuid.S b/sysdeps/unix/sysv/linux/alpha/geteuid.S similarity index 100% rename from sysdeps/unix/alpha/geteuid.S rename to sysdeps/unix/sysv/linux/alpha/geteuid.S diff --git a/sysdeps/unix/alpha/getppid.S b/sysdeps/unix/sysv/linux/alpha/getppid.S similarity index 100% rename from sysdeps/unix/alpha/getppid.S rename to sysdeps/unix/sysv/linux/alpha/getppid.S diff --git a/sysdeps/unix/sysv/linux/bits/statx.h b/sysdeps/unix/sysv/linux/bits/statx.h index 206878723..aaccfdc2d 100644 --- a/sysdeps/unix/sysv/linux/bits/statx.h +++ b/sysdeps/unix/sysv/linux/bits/statx.h @@ -26,11 +26,13 @@ /* Use "" to work around incorrect macro expansion of the __has_include argument (GCC PR 80005). */ -#if __glibc_has_include ("linux/stat.h") -# include "linux/stat.h" -# ifdef STATX_TYPE -# define __statx_timestamp_defined 1 -# define __statx_defined 1 +#ifdef __has_include +# if __has_include ("linux/stat.h") +# include "linux/stat.h" +# ifdef STATX_TYPE +# define __statx_timestamp_defined 1 +# define __statx_defined 1 +# endif # endif #endif diff --git a/sysdeps/unix/sysv/linux/hppa/atomic-machine.h b/sysdeps/unix/sysv/linux/hppa/atomic-machine.h index 222079499..c12888fa2 100644 --- a/sysdeps/unix/sysv/linux/hppa/atomic-machine.h +++ b/sysdeps/unix/sysv/linux/hppa/atomic-machine.h @@ -36,9 +36,37 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +#define atomic_full_barrier() __sync_synchronize () + #define __HAVE_64B_ATOMICS 0 #define USE_ATOMIC_COMPILER_BUILTINS 0 +/* We use the compiler atomic load and store builtins as the generic + defines are not atomic. In particular, we need to use compare and + exchange for stores as the implementation is synthesized. */ +void __atomic_link_error (void); +#define __atomic_check_size_ls(mem) \ + if ((sizeof (*mem) != 1) && (sizeof (*mem) != 2) && sizeof (*mem) != 4) \ + __atomic_link_error (); + +#define atomic_load_relaxed(mem) \ + ({ __atomic_check_size_ls((mem)); \ + __atomic_load_n ((mem), __ATOMIC_RELAXED); }) +#define atomic_load_acquire(mem) \ + ({ __atomic_check_size_ls((mem)); \ + __atomic_load_n ((mem), __ATOMIC_ACQUIRE); }) + +#define atomic_store_relaxed(mem, val) \ + do { \ + __atomic_check_size_ls((mem)); \ + __atomic_store_n ((mem), (val), __ATOMIC_RELAXED); \ + } while (0) +#define atomic_store_release(mem, val) \ + do { \ + __atomic_check_size_ls((mem)); \ + __atomic_store_n ((mem), (val), __ATOMIC_RELEASE); \ + } while (0) + /* XXX Is this actually correct? */ #define ATOMIC_EXCHANGE_USES_CAS 1 diff --git a/sysdeps/unix/sysv/linux/hppa/clone.S b/sysdeps/unix/sysv/linux/hppa/clone.S index 79fa4f614..1c0325e19 100644 --- a/sysdeps/unix/sysv/linux/hppa/clone.S +++ b/sysdeps/unix/sysv/linux/hppa/clone.S @@ -73,13 +73,18 @@ ENTRY(__clone) #endif /* Sanity check arguments. */ - comib,=,n 0, %arg0, .LerrorSanity /* no NULL function pointers */ - comib,=,n 0, %arg1, .LerrorSanity /* no NULL stack pointers */ + comib,=,n 0,%arg0,.LerrorSanity /* no NULL function pointers */ + comib,=,n 0,%arg1,.LerrorSanity /* no NULL stack pointers */ + + /* Ensure stack argument is 8-byte aligned. */ + ldo 7(%r25),%r25 + depi 0,31,3,%r25 /* Save the function pointer, arg, and flags on the new stack. */ stwm %r26, 64(%r25) stw %r23, -60(%r25) stw %r24, -56(%r25) + /* Clone arguments are (int flags, void * child_stack) */ copy %r24, %r26 /* flags are first */ /* User stack pointer is in the correct register already */ diff --git a/sysdeps/unix/sysv/linux/microblaze/sysdep.h b/sysdeps/unix/sysv/linux/microblaze/sysdep.h index 1228d0c57..4e6e4ba1f 100644 --- a/sysdeps/unix/sysv/linux/microblaze/sysdep.h +++ b/sysdeps/unix/sysv/linux/microblaze/sysdep.h @@ -209,8 +209,8 @@ SYSCALL_ERROR_LABEL_DCL: \ # define inline_syscall0(name,dummy) \ ({ \ - register long __ret __asm__("r3"); \ - register long __r12 __asm__("r12") = name; \ + register long int __ret __asm__("r3"); \ + register long int __r12 __asm__("r12") = name; \ __asm__ __volatile__( "brki r14,8; nop;" \ : "=r"(__ret) \ : "r"(__r12) \ @@ -219,9 +219,10 @@ SYSCALL_ERROR_LABEL_DCL: \ # define inline_syscall1(name,arg1) \ ({ \ - register long __ret __asm__("r3"); \ - register long __r12 __asm__("r12") = name; \ - register long __r5 __asm__("r5") = (long)(arg1); \ + long int __arg1 = (long int) (arg1); \ + register long int __ret __asm__("r3"); \ + register long int __r12 __asm__("r12") = name; \ + register long int __r5 __asm__("r5") = __arg1; \ __asm__ __volatile__( "brki r14,8; nop;" \ : "=r"(__ret) \ : "r"(__r5), "r"(__r12) \ @@ -230,10 +231,12 @@ SYSCALL_ERROR_LABEL_DCL: \ # define inline_syscall2(name,arg1,arg2) \ ({ \ - register long __ret __asm__("r3"); \ - register long __r12 __asm__("r12") = name; \ - register long __r5 __asm__("r5") = (long)(arg1); \ - register long __r6 __asm__("r6") = (long)(arg2); \ + long int __arg1 = (long int) (arg1); \ + long int __arg2 = (long int) (arg2); \ + register long int __ret __asm__("r3"); \ + register long int __r12 __asm__("r12") = name; \ + register long int __r5 __asm__("r5") = __arg1; \ + register long int __r6 __asm__("r6") = __arg2; \ __asm__ __volatile__( "brki r14,8; nop;" \ : "=r"(__ret) \ : "r"(__r5), "r"(__r6), "r"(__r12) \ @@ -243,11 +246,14 @@ SYSCALL_ERROR_LABEL_DCL: \ # define inline_syscall3(name,arg1,arg2,arg3) \ ({ \ - register long __ret __asm__("r3"); \ - register long __r12 __asm__("r12") = name; \ - register long __r5 __asm__("r5") = (long)(arg1); \ - register long __r6 __asm__("r6") = (long)(arg2); \ - register long __r7 __asm__("r7") = (long)(arg3); \ + long int __arg1 = (long int) (arg1); \ + long int __arg2 = (long int) (arg2); \ + long int __arg3 = (long int) (arg3); \ + register long int __ret __asm__("r3"); \ + register long int __r12 __asm__("r12") = name; \ + register long int __r5 __asm__("r5") = __arg1; \ + register long int __r6 __asm__("r6") = __arg2; \ + register long int __r7 __asm__("r7") = __arg3; \ __asm__ __volatile__( "brki r14,8; nop;" \ : "=r"(__ret) \ : "r"(__r5), "r"(__r6), "r"(__r7), "r"(__r12) \ @@ -257,12 +263,16 @@ SYSCALL_ERROR_LABEL_DCL: \ # define inline_syscall4(name,arg1,arg2,arg3,arg4) \ ({ \ - register long __ret __asm__("r3"); \ - register long __r12 __asm__("r12") = name; \ - register long __r5 __asm__("r5") = (long)(arg1); \ - register long __r6 __asm__("r6") = (long)(arg2); \ - register long __r7 __asm__("r7") = (long)(arg3); \ - register long __r8 __asm__("r8") = (long)(arg4); \ + long int __arg1 = (long int) (arg1); \ + long int __arg2 = (long int) (arg2); \ + long int __arg3 = (long int) (arg3); \ + long int __arg4 = (long int) (arg4); \ + register long int __ret __asm__("r3"); \ + register long int __r12 __asm__("r12") = name; \ + register long int __r5 __asm__("r5") = __arg1; \ + register long int __r6 __asm__("r6") = __arg2; \ + register long int __r7 __asm__("r7") = __arg3; \ + register long int __r8 __asm__("r8") = __arg4; \ __asm__ __volatile__( "brki r14,8; nop;" \ : "=r"(__ret) \ : "r"(__r5), "r"(__r6), "r"(__r7), "r"(__r8),"r"(__r12) \ @@ -272,13 +282,18 @@ SYSCALL_ERROR_LABEL_DCL: \ # define inline_syscall5(name,arg1,arg2,arg3,arg4,arg5) \ ({ \ - register long __ret __asm__("r3"); \ - register long __r12 __asm__("r12") = name; \ - register long __r5 __asm__("r5") = (long)(arg1); \ - register long __r6 __asm__("r6") = (long)(arg2); \ - register long __r7 __asm__("r7") = (long)(arg3); \ - register long __r8 __asm__("r8") = (long)(arg4); \ - register long __r9 __asm__("r9") = (long)(arg5); \ + long int __arg1 = (long int) (arg1); \ + long int __arg2 = (long int) (arg2); \ + long int __arg3 = (long int) (arg3); \ + long int __arg4 = (long int) (arg4); \ + long int __arg5 = (long int) (arg5); \ + register long int __ret __asm__("r3"); \ + register long int __r12 __asm__("r12") = name; \ + register long int __r5 __asm__("r5") = __arg1; \ + register long int __r6 __asm__("r6") = __arg2; \ + register long int __r7 __asm__("r7") = __arg3; \ + register long int __r8 __asm__("r8") = __arg4; \ + register long int __r9 __asm__("r9") = __arg5; \ __asm__ __volatile__( "brki r14,8; nop;" \ : "=r"(__ret) \ : "r"(__r5), "r"(__r6), "r"(__r7), "r"(__r8),"r"(__r9), "r"(__r12) \ @@ -288,14 +303,20 @@ SYSCALL_ERROR_LABEL_DCL: \ # define inline_syscall6(name,arg1,arg2,arg3,arg4,arg5,arg6) \ ({ \ - register long __ret __asm__("r3"); \ - register long __r12 __asm__("r12") = name; \ - register long __r5 __asm__("r5") = (long)(arg1); \ - register long __r6 __asm__("r6") = (long)(arg2); \ - register long __r7 __asm__("r7") = (long)(arg3); \ - register long __r8 __asm__("r8") = (long)(arg4); \ - register long __r9 __asm__("r9") = (long)(arg5); \ - register long __r10 __asm__("r10") = (long)(arg6); \ + long int __arg1 = (long int) (arg1); \ + long int __arg2 = (long int) (arg2); \ + long int __arg3 = (long int) (arg3); \ + long int __arg4 = (long int) (arg4); \ + long int __arg5 = (long int) (arg5); \ + long int __arg6 = (long int) (arg6); \ + register long int __ret __asm__("r3"); \ + register long int __r12 __asm__("r12") = name; \ + register long int __r5 __asm__("r5") = __arg1; \ + register long int __r6 __asm__("r6") = __arg2; \ + register long int __r7 __asm__("r7") = __arg3; \ + register long int __r8 __asm__("r8") = __arg4; \ + register long int __r9 __asm__("r9") = __arg5; \ + register long int __r10 __asm__("r10") = __arg6; \ __asm__ __volatile__( "brki r14,8; nop;" \ : "=r"(__ret) \ : "r"(__r5), "r"(__r6), "r"(__r7), "r"(__r8),"r"(__r9), "r"(__r10), \ diff --git a/sysdeps/unix/sysv/linux/mips/Makefile b/sysdeps/unix/sysv/linux/mips/Makefile index 8217f42e7..03044e736 100644 --- a/sysdeps/unix/sysv/linux/mips/Makefile +++ b/sysdeps/unix/sysv/linux/mips/Makefile @@ -63,14 +63,25 @@ sysdep-dl-routines += dl-static sysdep_routines += dl-vdso endif - -# Supporting non-executable stacks on MIPS requires changes to both -# the Linux kernel and glibc. See -# and -# . +# If the compiler doesn't use GNU.stack note, +# this test is expected to fail. +ifneq ($(mips-has-gnustack),yes) test-xfail-check-execstack = yes endif +endif ifeq ($(subdir),stdlib) gen-as-const-headers += ucontext_i.sym endif + +ifeq ($(mips-force-execstack),yes) +CFLAGS-.o += -Wa,-execstack +CFLAGS-.os += -Wa,-execstack +CFLAGS-.op += -Wa,-execstack +CFLAGS-.oS += -Wa,-execstack + +ASFLAGS-.o += -Wa,-execstack +ASFLAGS-.os += -Wa,-execstack +ASFLAGS-.op += -Wa,-execstack +ASFLAGS-.oS += -Wa,-execstack +endif diff --git a/sysdeps/unix/sysv/linux/mips/configure b/sysdeps/unix/sysv/linux/mips/configure index 1ee7f41a3..25f98e0c7 100644 --- a/sysdeps/unix/sysv/linux/mips/configure +++ b/sysdeps/unix/sysv/linux/mips/configure @@ -475,3 +475,44 @@ if test -z "$arch_minimum_kernel"; then arch_minimum_kernel=4.5.0 fi fi + +# Check if we are supposed to run on kernels older than 4.8.0. If so, +# force executable stack to avoid potential runtime problems with fpu +# emulation. +# NOTE: The check below assumes that in absence of user-provided minumum_kernel +# we will default to arch_minimum_kernel which is currently less than 4.8.0 for +# all known configurations. If this changes, the check must be updated. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler must use executable stack" >&5 +$as_echo_n "checking whether the compiler must use executable stack... " >&6; } +if ${libc_cv_mips_force_execstack+:} false; then : + $as_echo_n "(cached) " >&6 +else + libc_cv_mips_force_execstack=no + if test $libc_mips_float = hard; then + if test -n "$minimum_kernel"; then + + min_version=$((`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 65536 + \2 \* 256 + \3/'`)) + + if test $min_version -lt 264192; then + libc_cv_mips_force_execstack=yes + fi + else + libc_cv_mips_force_execstack=yes + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_force_execstack" >&5 +$as_echo "$libc_cv_mips_force_execstack" >&6; } + +libc_mips_has_gnustack=$libc_cv_as_noexecstack + +if test $libc_cv_mips_force_execstack = yes; then + libc_mips_has_gnustack=no + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: forcing executable stack for pre-4.8.0 Linux kernels" >&5 +$as_echo "$as_me: WARNING: forcing executable stack for pre-4.8.0 Linux kernels" >&2;} +fi + +config_vars="$config_vars +mips-force-execstack = ${libc_cv_mips_force_execstack}" +config_vars="$config_vars +mips-has-gnustack = ${libc_mips_has_gnustack}" diff --git a/sysdeps/unix/sysv/linux/mips/configure.ac b/sysdeps/unix/sysv/linux/mips/configure.ac index 9147aa458..3db1b32b0 100644 --- a/sysdeps/unix/sysv/linux/mips/configure.ac +++ b/sysdeps/unix/sysv/linux/mips/configure.ac @@ -134,3 +134,35 @@ if test -z "$arch_minimum_kernel"; then arch_minimum_kernel=4.5.0 fi fi + +# Check if we are supposed to run on kernels older than 4.8.0. If so, +# force executable stack to avoid potential runtime problems with fpu +# emulation. +# NOTE: The check below assumes that in absence of user-provided minumum_kernel +# we will default to arch_minimum_kernel which is currently less than 4.8.0 for +# all known configurations. If this changes, the check must be updated. +AC_CACHE_CHECK([whether the compiler must use executable stack], + libc_cv_mips_force_execstack, [dnl +libc_cv_mips_force_execstack=no + if test $libc_mips_float = hard; then + if test -n "$minimum_kernel"; then + changequote(,) + min_version=$((`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 65536 + \2 \* 256 + \3/'`)) + changequote([,]) + if test $min_version -lt 264192; then + libc_cv_mips_force_execstack=yes + fi + else + libc_cv_mips_force_execstack=yes + fi + fi]) + +libc_mips_has_gnustack=$libc_cv_as_noexecstack + +if test $libc_cv_mips_force_execstack = yes; then + libc_mips_has_gnustack=no + AC_MSG_WARN([forcing executable stack for pre-4.8.0 Linux kernels]) +fi + +LIBC_CONFIG_VAR([mips-force-execstack],[${libc_cv_mips_force_execstack}]) +LIBC_CONFIG_VAR([mips-has-gnustack],[${libc_mips_has_gnustack}]) diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S b/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S index 649881f8b..c0729252a 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S @@ -22,9 +22,9 @@ .text .set nomips16 -/* long long __mips_syscall5 (long arg1, long arg2, long arg3, long arg4, - long arg5, - long number) */ +/* long long int __mips_syscall5 (long int arg1, long int arg2, long int arg3, + long int arg4, long int arg5, + long int number) */ ENTRY(__mips_syscall5) lw v0, 20(sp) diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S b/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S index 2c954f8e7..e4c95fb1e 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S @@ -22,9 +22,9 @@ .text .set nomips16 -/* long long __mips_syscall6 (long arg1, long arg2, long arg3, long arg4, - long arg5, long arg6, - long number) */ +/* long long int __mips_syscall6 (long int arg1, long int arg2, long int arg3, + long int arg4, long int arg5, long int arg6, + long int number) */ ENTRY(__mips_syscall6) lw v0, 24(sp) diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S b/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S index fb6c9c5e0..489fab989 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S @@ -22,9 +22,10 @@ .text .set nomips16 -/* long long __mips_syscall7 (long arg1, long arg2, long arg3, long arg4, - long arg5, long arg6, long arg7, - long number) */ +/* long long int __mips_syscall7 (long int arg1, long int arg2, long int arg3, + long int arg4, long int arg5, long int arg6, + long int arg7, + long int number) */ ENTRY(__mips_syscall7) lw v0, 28(sp) diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h index 4f917c5d3..faa5ac68a 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h @@ -19,51 +19,57 @@ #ifndef MIPS16_SYSCALL_H #define MIPS16_SYSCALL_H 1 -long long __nomips16 __mips16_syscall0 (long number); +long long int __nomips16 __mips16_syscall0 (long int number); #define __mips16_syscall0(dummy, number) \ - __mips16_syscall0 ((long) (number)) + __mips16_syscall0 ((long int) (number)) -long long __nomips16 __mips16_syscall1 (long a0, - long number); +long long int __nomips16 __mips16_syscall1 (long int a0, + long int number); #define __mips16_syscall1(a0, number) \ - __mips16_syscall1 ((long) (a0), \ - (long) (number)) + __mips16_syscall1 ((long int) (a0), \ + (long int) (number)) -long long __nomips16 __mips16_syscall2 (long a0, long a1, - long number); +long long int __nomips16 __mips16_syscall2 (long int a0, long int a1, + long int number); #define __mips16_syscall2(a0, a1, number) \ - __mips16_syscall2 ((long) (a0), (long) (a1), \ - (long) (number)) + __mips16_syscall2 ((long int) (a0), (long int) (a1), \ + (long int) (number)) -long long __nomips16 __mips16_syscall3 (long a0, long a1, long a2, - long number); +long long int __nomips16 __mips16_syscall3 (long int a0, long int a1, + long int a2, + long int number); #define __mips16_syscall3(a0, a1, a2, number) \ - __mips16_syscall3 ((long) (a0), (long) (a1), (long) (a2), \ - (long) (number)) + __mips16_syscall3 ((long int) (a0), (long int) (a1), \ + (long int) (a2), \ + (long int) (number)) -long long __nomips16 __mips16_syscall4 (long a0, long a1, long a2, long a3, - long number); +long long int __nomips16 __mips16_syscall4 (long int a0, long int a1, + long int a2, long int a3, + long int number); #define __mips16_syscall4(a0, a1, a2, a3, number) \ - __mips16_syscall4 ((long) (a0), (long) (a1), (long) (a2), \ - (long) (a3), \ - (long) (number)) + __mips16_syscall4 ((long int) (a0), (long int) (a1), \ + (long int) (a2), (long int) (a3), \ + (long int) (number)) /* The remaining ones use regular MIPS wrappers. */ #define __mips16_syscall5(a0, a1, a2, a3, a4, number) \ - __mips_syscall5 ((long) (a0), (long) (a1), (long) (a2), \ - (long) (a3), (long) (a4), \ - (long) (number)) + __mips_syscall5 ((long int) (a0), (long int) (a1), \ + (long int) (a2), (long int) (a3), \ + (long int) (a4), \ + (long int) (number)) #define __mips16_syscall6(a0, a1, a2, a3, a4, a5, number) \ - __mips_syscall6 ((long) (a0), (long) (a1), (long) (a2), \ - (long) (a3), (long) (a4), (long) (a5), \ - (long) (number)) + __mips_syscall6 ((long int) (a0), (long int) (a1), \ + (long int) (a2), (long int) (a3), \ + (long int) (a4), (long int) (a5), \ + (long int) (number)) #define __mips16_syscall7(a0, a1, a2, a3, a4, a5, a6, number) \ - __mips_syscall7 ((long) (a0), (long) (a1), (long) (a2), \ - (long) (a3), (long) (a4), (long) (a5), \ - (long) (a6), \ - (long) (number)) + __mips_syscall7 ((long int) (a0), (long int) (a1), \ + (long int) (a2), (long int) (a3), \ + (long int) (a4), (long int) (a5), \ + (long int) (a6), \ + (long int) (number)) #endif diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c index c8f6fff40..28b48d99b 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c @@ -20,8 +20,8 @@ #undef __mips16_syscall0 -long long __nomips16 -__mips16_syscall0 (long number) +long long int __nomips16 +__mips16_syscall0 (long int number) { union __mips_syscall_return ret; ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 0); diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c index 2631ec25a..0e7ef00a8 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c @@ -20,9 +20,9 @@ #undef __mips16_syscall1 -long long __nomips16 -__mips16_syscall1 (long a0, - long number) +long long int __nomips16 +__mips16_syscall1 (long int a0, + long int number) { union __mips_syscall_return ret; ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 1, diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c index 235958e35..7464b88d7 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c @@ -20,9 +20,9 @@ #undef __mips16_syscall2 -long long __nomips16 -__mips16_syscall2 (long a0, long a1, - long number) +long long int __nomips16 +__mips16_syscall2 (long int a0, long int a1, + long int number) { union __mips_syscall_return ret; ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 2, diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c index 827c5e23a..38d48208e 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c @@ -20,9 +20,9 @@ #undef __mips16_syscall3 -long long __nomips16 -__mips16_syscall3 (long a0, long a1, long a2, - long number) +long long int __nomips16 +__mips16_syscall3 (long int a0, long int a1, long int a2, + long int number) { union __mips_syscall_return ret; ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 3, diff --git a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c index 3eb040056..5027b5ae1 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c +++ b/sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c @@ -20,9 +20,9 @@ #undef __mips16_syscall4 -long long __nomips16 -__mips16_syscall4 (long a0, long a1, long a2, long a3, - long number) +long long int __nomips16 +__mips16_syscall4 (long int a0, long int a1, long int a2, long int a3, + long int number) { union __mips_syscall_return ret; ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 4, diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h index 5a2704e3e..4384bf50e 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h +++ b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h @@ -54,7 +54,7 @@ #undef INLINE_SYSCALL #define INLINE_SYSCALL(name, nr, args...) \ ({ INTERNAL_SYSCALL_DECL (_sc_err); \ - long result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \ + long int result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \ if ( INTERNAL_SYSCALL_ERROR_P (result_var, _sc_err) ) \ { \ __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, _sc_err)); \ @@ -63,10 +63,10 @@ result_var; }) #undef INTERNAL_SYSCALL_DECL -#define INTERNAL_SYSCALL_DECL(err) long err __attribute__ ((unused)) +#define INTERNAL_SYSCALL_DECL(err) long int err __attribute__ ((unused)) #undef INTERNAL_SYSCALL_ERROR_P -#define INTERNAL_SYSCALL_ERROR_P(val, err) ((void) (val), (long) (err)) +#define INTERNAL_SYSCALL_ERROR_P(val, err) ((void) (val), (long int) (err)) #undef INTERNAL_SYSCALL_ERRNO #define INTERNAL_SYSCALL_ERRNO(val, err) ((void) (err), val) @@ -105,11 +105,11 @@ union __mips_syscall_return { - long long val; + long long int val; struct { - long v0; - long v1; + long int v0; + long int v1; } reg; }; @@ -154,13 +154,13 @@ union __mips_syscall_return #define internal_syscall0(v0_init, input, number, err, dummy...) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a3 asm ("$7"); \ + register long int __v0 asm ("$2"); \ + register long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -177,14 +177,15 @@ union __mips_syscall_return #define internal_syscall1(v0_init, input, number, err, arg1) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + long int _arg1 = (long int) (arg1); \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a0 asm ("$4") = (long) (arg1); \ - register long __a3 asm ("$7"); \ + register long int __v0 asm ("$2"); \ + register long int __a0 asm ("$4") = _arg1; \ + register long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -201,15 +202,17 @@ union __mips_syscall_return #define internal_syscall2(v0_init, input, number, err, arg1, arg2) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a0 asm ("$4") = (long) (arg1); \ - register long __a1 asm ("$5") = (long) (arg2); \ - register long __a3 asm ("$7"); \ + register long int __v0 asm ("$2"); \ + register long int __a0 asm ("$4") = _arg1; \ + register long int __a1 asm ("$5") = _arg2; \ + register long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -227,16 +230,19 @@ union __mips_syscall_return #define internal_syscall3(v0_init, input, number, err, \ arg1, arg2, arg3) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a0 asm ("$4") = (long) (arg1); \ - register long __a1 asm ("$5") = (long) (arg2); \ - register long __a2 asm ("$6") = (long) (arg3); \ - register long __a3 asm ("$7"); \ + register long int __v0 asm ("$2"); \ + register long int __a0 asm ("$4") = _arg1; \ + register long int __a1 asm ("$5") = _arg2; \ + register long int __a2 asm ("$6") = _arg3; \ + register long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -254,16 +260,20 @@ union __mips_syscall_return #define internal_syscall4(v0_init, input, number, err, \ arg1, arg2, arg3, arg4) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a0 asm ("$4") = (long) (arg1); \ - register long __a1 asm ("$5") = (long) (arg2); \ - register long __a2 asm ("$6") = (long) (arg3); \ - register long __a3 asm ("$7") = (long) (arg4); \ + register long int __v0 asm ("$2"); \ + register long int __a0 asm ("$4") = _arg1; \ + register long int __a1 asm ("$5") = _arg2; \ + register long int __a2 asm ("$6") = _arg3; \ + register long int __a3 asm ("$7") = _arg4; \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -287,63 +297,66 @@ union __mips_syscall_return compiler specifics required for the stack arguments to be pushed, which would be the case if these syscalls were inlined. */ -long long __nomips16 __mips_syscall5 (long arg1, long arg2, long arg3, - long arg4, long arg5, - long number); +long long int __nomips16 __mips_syscall5 (long int arg1, long int arg2, + long int arg3, long int arg4, + long int arg5, + long int number); libc_hidden_proto (__mips_syscall5, nomips16) #define internal_syscall5(v0_init, input, number, err, \ arg1, arg2, arg3, arg4, arg5) \ ({ \ union __mips_syscall_return _sc_ret; \ - _sc_ret.val = __mips_syscall5 ((long) (arg1), \ - (long) (arg2), \ - (long) (arg3), \ - (long) (arg4), \ - (long) (arg5), \ - (long) (number)); \ + _sc_ret.val = __mips_syscall5 ((long int) (arg1), \ + (long int) (arg2), \ + (long int) (arg3), \ + (long int) (arg4), \ + (long int) (arg5), \ + (long int) (number)); \ err = _sc_ret.reg.v1; \ _sc_ret.reg.v0; \ }) -long long __nomips16 __mips_syscall6 (long arg1, long arg2, long arg3, - long arg4, long arg5, long arg6, - long number); +long long int __nomips16 __mips_syscall6 (long int arg1, long int arg2, + long int arg3, long int arg4, + long int arg5, long int arg6, + long int number); libc_hidden_proto (__mips_syscall6, nomips16) #define internal_syscall6(v0_init, input, number, err, \ arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ union __mips_syscall_return _sc_ret; \ - _sc_ret.val = __mips_syscall6 ((long) (arg1), \ - (long) (arg2), \ - (long) (arg3), \ - (long) (arg4), \ - (long) (arg5), \ - (long) (arg6), \ - (long) (number)); \ + _sc_ret.val = __mips_syscall6 ((long int) (arg1), \ + (long int) (arg2), \ + (long int) (arg3), \ + (long int) (arg4), \ + (long int) (arg5), \ + (long int) (arg6), \ + (long int) (number)); \ err = _sc_ret.reg.v1; \ _sc_ret.reg.v0; \ }) -long long __nomips16 __mips_syscall7 (long arg1, long arg2, long arg3, - long arg4, long arg5, long arg6, - long arg7, - long number); +long long int __nomips16 __mips_syscall7 (long int arg1, long int arg2, + long int arg3, long int arg4, + long int arg5, long int arg6, + long int arg7, + long int number); libc_hidden_proto (__mips_syscall7, nomips16) #define internal_syscall7(v0_init, input, number, err, \ arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ ({ \ union __mips_syscall_return _sc_ret; \ - _sc_ret.val = __mips_syscall7 ((long) (arg1), \ - (long) (arg2), \ - (long) (arg3), \ - (long) (arg4), \ - (long) (arg5), \ - (long) (arg6), \ - (long) (arg7), \ - (long) (number)); \ + _sc_ret.val = __mips_syscall7 ((long int) (arg1), \ + (long int) (arg2), \ + (long int) (arg3), \ + (long int) (arg4), \ + (long int) (arg5), \ + (long int) (arg6), \ + (long int) (arg7), \ + (long int) (number)); \ err = _sc_ret.reg.v1; \ _sc_ret.reg.v0; \ }) @@ -357,7 +370,7 @@ libc_hidden_proto (__mips_syscall7, nomips16) #define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \ ({ \ long _ret = funcptr (args); \ - err = ((unsigned long) (_ret) >= (unsigned long) -4095L); \ + err = ((unsigned long) (_ret) >= (unsigned long int) -4095L); \ if (err) \ _ret = -_ret; \ _ret; \ diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h index a4f354703..e0251d551 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h @@ -49,14 +49,14 @@ /* Convert X to a long long, without losing any bits if it is one already or warning if it is a 32-bit pointer. */ -#define ARGIFY(X) ((long long) (__typeof__ ((X) - (X))) (X)) +#define ARGIFY(X) ((long long int) (__typeof__ ((X) - (X))) (X)) /* Define a macro which expands into the inline wrapper code for a system call. */ #undef INLINE_SYSCALL #define INLINE_SYSCALL(name, nr, args...) \ ({ INTERNAL_SYSCALL_DECL (_sc_err); \ - long result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \ + long int result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \ if ( INTERNAL_SYSCALL_ERROR_P (result_var, _sc_err) ) \ { \ __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, _sc_err)); \ @@ -65,10 +65,10 @@ result_var; }) #undef INTERNAL_SYSCALL_DECL -#define INTERNAL_SYSCALL_DECL(err) long err __attribute__ ((unused)) +#define INTERNAL_SYSCALL_DECL(err) long int err __attribute__ ((unused)) #undef INTERNAL_SYSCALL_ERROR_P -#define INTERNAL_SYSCALL_ERROR_P(val, err) ((void) (val), (long) (err)) +#define INTERNAL_SYSCALL_ERROR_P(val, err) ((void) (val), (long int) (err)) #undef INTERNAL_SYSCALL_ERRNO #define INTERNAL_SYSCALL_ERRNO(val, err) ((void) (err), val) @@ -114,13 +114,13 @@ #define internal_syscall0(v0_init, input, number, err, dummy...) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long long __s0 asm ("$16") __attribute__ ((unused)) \ + register long long int __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ - register long long __v0 asm ("$2"); \ - register long long __a3 asm ("$7"); \ + register long long int __v0 asm ("$2"); \ + register long long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -137,14 +137,15 @@ #define internal_syscall1(v0_init, input, number, err, arg1) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long long __s0 asm ("$16") __attribute__ ((unused)) \ + long long int _arg1 = ARGIFY (arg1); \ + register long long int __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ - register long long __v0 asm ("$2"); \ - register long long __a0 asm ("$4") = ARGIFY (arg1); \ - register long long __a3 asm ("$7"); \ + register long long int __v0 asm ("$2"); \ + register long long int __a0 asm ("$4") = _arg1; \ + register long long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -161,15 +162,17 @@ #define internal_syscall2(v0_init, input, number, err, arg1, arg2) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long long __s0 asm ("$16") __attribute__ ((unused)) \ + long long int _arg1 = ARGIFY (arg1); \ + long long int _arg2 = ARGIFY (arg2); \ + register long long int __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ - register long long __v0 asm ("$2"); \ - register long long __a0 asm ("$4") = ARGIFY (arg1); \ - register long long __a1 asm ("$5") = ARGIFY (arg2); \ - register long long __a3 asm ("$7"); \ + register long long int __v0 asm ("$2"); \ + register long long int __a0 asm ("$4") = _arg1; \ + register long long int __a1 asm ("$5") = _arg2; \ + register long long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -187,16 +190,19 @@ #define internal_syscall3(v0_init, input, number, err, \ arg1, arg2, arg3) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long long __s0 asm ("$16") __attribute__ ((unused)) \ + long long int _arg1 = ARGIFY (arg1); \ + long long int _arg2 = ARGIFY (arg2); \ + long long int _arg3 = ARGIFY (arg3); \ + register long long int __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ - register long long __v0 asm ("$2"); \ - register long long __a0 asm ("$4") = ARGIFY (arg1); \ - register long long __a1 asm ("$5") = ARGIFY (arg2); \ - register long long __a2 asm ("$6") = ARGIFY (arg3); \ - register long long __a3 asm ("$7"); \ + register long long int __v0 asm ("$2"); \ + register long long int __a0 asm ("$4") = _arg1; \ + register long long int __a1 asm ("$5") = _arg2; \ + register long long int __a2 asm ("$6") = _arg3; \ + register long long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -214,16 +220,20 @@ #define internal_syscall4(v0_init, input, number, err, \ arg1, arg2, arg3, arg4) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long long __s0 asm ("$16") __attribute__ ((unused)) \ + long long int _arg1 = ARGIFY (arg1); \ + long long int _arg2 = ARGIFY (arg2); \ + long long int _arg3 = ARGIFY (arg3); \ + long long int _arg4 = ARGIFY (arg4); \ + register long long int __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ - register long long __v0 asm ("$2"); \ - register long long __a0 asm ("$4") = ARGIFY (arg1); \ - register long long __a1 asm ("$5") = ARGIFY (arg2); \ - register long long __a2 asm ("$6") = ARGIFY (arg3); \ - register long long __a3 asm ("$7") = ARGIFY (arg4); \ + register long long int __v0 asm ("$2"); \ + register long long int __a0 asm ("$4") = _arg1; \ + register long long int __a1 asm ("$5") = _arg2; \ + register long long int __a2 asm ("$6") = _arg3; \ + register long long int __a3 asm ("$7") = _arg4; \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -241,17 +251,22 @@ #define internal_syscall5(v0_init, input, number, err, \ arg1, arg2, arg3, arg4, arg5) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long long __s0 asm ("$16") __attribute__ ((unused)) \ + long long int _arg1 = ARGIFY (arg1); \ + long long int _arg2 = ARGIFY (arg2); \ + long long int _arg3 = ARGIFY (arg3); \ + long long int _arg4 = ARGIFY (arg4); \ + long long int _arg5 = ARGIFY (arg5); \ + register long long int __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ - register long long __v0 asm ("$2"); \ - register long long __a0 asm ("$4") = ARGIFY (arg1); \ - register long long __a1 asm ("$5") = ARGIFY (arg2); \ - register long long __a2 asm ("$6") = ARGIFY (arg3); \ - register long long __a3 asm ("$7") = ARGIFY (arg4); \ - register long long __a4 asm ("$8") = ARGIFY (arg5); \ + register long long int __v0 asm ("$2"); \ + register long long int __a0 asm ("$4") = _arg1; \ + register long long int __a1 asm ("$5") = _arg2; \ + register long long int __a2 asm ("$6") = _arg3; \ + register long long int __a3 asm ("$7") = _arg4; \ + register long long int __a4 asm ("$8") = _arg5; \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -269,18 +284,24 @@ #define internal_syscall6(v0_init, input, number, err, \ arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long long __s0 asm ("$16") __attribute__ ((unused)) \ + long long int _arg1 = ARGIFY (arg1); \ + long long int _arg2 = ARGIFY (arg2); \ + long long int _arg3 = ARGIFY (arg3); \ + long long int _arg4 = ARGIFY (arg4); \ + long long int _arg5 = ARGIFY (arg5); \ + long long int _arg6 = ARGIFY (arg6); \ + register long long int __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ - register long long __v0 asm ("$2"); \ - register long long __a0 asm ("$4") = ARGIFY (arg1); \ - register long long __a1 asm ("$5") = ARGIFY (arg2); \ - register long long __a2 asm ("$6") = ARGIFY (arg3); \ - register long long __a3 asm ("$7") = ARGIFY (arg4); \ - register long long __a4 asm ("$8") = ARGIFY (arg5); \ - register long long __a5 asm ("$9") = ARGIFY (arg6); \ + register long long int __v0 asm ("$2"); \ + register long long int __a0 asm ("$4") = _arg1; \ + register long long int __a1 asm ("$5") = _arg2; \ + register long long int __a2 asm ("$6") = _arg3; \ + register long long int __a3 asm ("$7") = _arg4; \ + register long long int __a4 asm ("$8") = _arg5; \ + register long long int __a5 asm ("$9") = _arg6; \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -305,7 +326,7 @@ #define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \ ({ \ long _ret = funcptr (args); \ - err = ((unsigned long) (_ret) >= (unsigned long) -4095L); \ + err = ((unsigned long) (_ret) >= (unsigned long int) -4095L); \ if (err) \ _ret = -_ret; \ _ret; \ diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h index 5b4d27757..11172280c 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h @@ -52,7 +52,7 @@ #undef INLINE_SYSCALL #define INLINE_SYSCALL(name, nr, args...) \ ({ INTERNAL_SYSCALL_DECL (_sc_err); \ - long result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \ + long int result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \ if ( INTERNAL_SYSCALL_ERROR_P (result_var, _sc_err) ) \ { \ __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, _sc_err)); \ @@ -61,10 +61,10 @@ result_var; }) #undef INTERNAL_SYSCALL_DECL -#define INTERNAL_SYSCALL_DECL(err) long err __attribute__ ((unused)) +#define INTERNAL_SYSCALL_DECL(err) long int err __attribute__ ((unused)) #undef INTERNAL_SYSCALL_ERROR_P -#define INTERNAL_SYSCALL_ERROR_P(val, err) ((void) (val), (long) (err)) +#define INTERNAL_SYSCALL_ERROR_P(val, err) ((void) (val), (long int) (err)) #undef INTERNAL_SYSCALL_ERRNO #define INTERNAL_SYSCALL_ERRNO(val, err) ((void) (err), val) @@ -110,13 +110,13 @@ #define internal_syscall0(v0_init, input, number, err, dummy...) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a3 asm ("$7"); \ + register long int __v0 asm ("$2"); \ + register long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -133,14 +133,15 @@ #define internal_syscall1(v0_init, input, number, err, arg1) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + long int _arg1 = (long int) (arg1); \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a0 asm ("$4") = (long) (arg1); \ - register long __a3 asm ("$7"); \ + register long int __v0 asm ("$2"); \ + register long int __a0 asm ("$4") = _arg1; \ + register long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -157,15 +158,17 @@ #define internal_syscall2(v0_init, input, number, err, arg1, arg2) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a0 asm ("$4") = (long) (arg1); \ - register long __a1 asm ("$5") = (long) (arg2); \ - register long __a3 asm ("$7"); \ + register long int __v0 asm ("$2"); \ + register long int __a0 asm ("$4") = _arg1; \ + register long int __a1 asm ("$5") = _arg2; \ + register long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -183,16 +186,19 @@ #define internal_syscall3(v0_init, input, number, err, \ arg1, arg2, arg3) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a0 asm ("$4") = (long) (arg1); \ - register long __a1 asm ("$5") = (long) (arg2); \ - register long __a2 asm ("$6") = (long) (arg3); \ - register long __a3 asm ("$7"); \ + register long int __v0 asm ("$2"); \ + register long int __a0 asm ("$4") = _arg1; \ + register long int __a1 asm ("$5") = _arg2; \ + register long int __a2 asm ("$6") = _arg3; \ + register long int __a3 asm ("$7"); \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -210,16 +216,20 @@ #define internal_syscall4(v0_init, input, number, err, \ arg1, arg2, arg3, arg4) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a0 asm ("$4") = (long) (arg1); \ - register long __a1 asm ("$5") = (long) (arg2); \ - register long __a2 asm ("$6") = (long) (arg3); \ - register long __a3 asm ("$7") = (long) (arg4); \ + register long int __v0 asm ("$2"); \ + register long int __a0 asm ("$4") = _arg1; \ + register long int __a1 asm ("$5") = _arg2; \ + register long int __a2 asm ("$6") = _arg3; \ + register long int __a3 asm ("$7") = _arg4; \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -237,17 +247,22 @@ #define internal_syscall5(v0_init, input, number, err, \ arg1, arg2, arg3, arg4, arg5) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + long int _arg5 = (long int) (arg5); \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a0 asm ("$4") = (long) (arg1); \ - register long __a1 asm ("$5") = (long) (arg2); \ - register long __a2 asm ("$6") = (long) (arg3); \ - register long __a3 asm ("$7") = (long) (arg4); \ - register long __a4 asm ("$8") = (long) (arg5); \ + register long int __v0 asm ("$2"); \ + register long int __a0 asm ("$4") = _arg1; \ + register long int __a1 asm ("$5") = _arg2; \ + register long int __a2 asm ("$6") = _arg3; \ + register long int __a3 asm ("$7") = _arg4; \ + register long int __a4 asm ("$8") = _arg5; \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -265,18 +280,24 @@ #define internal_syscall6(v0_init, input, number, err, \ arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ - long _sys_result; \ + long int _sys_result; \ \ { \ - register long __s0 asm ("$16") __attribute__ ((unused)) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + long int _arg5 = (long int) (arg5); \ + long int _arg6 = (long int) (arg6); \ + register long int __s0 asm ("$16") __attribute__ ((unused)) \ = (number); \ - register long __v0 asm ("$2"); \ - register long __a0 asm ("$4") = (long) (arg1); \ - register long __a1 asm ("$5") = (long) (arg2); \ - register long __a2 asm ("$6") = (long) (arg3); \ - register long __a3 asm ("$7") = (long) (arg4); \ - register long __a4 asm ("$8") = (long) (arg5); \ - register long __a5 asm ("$9") = (long) (arg6); \ + register long int __v0 asm ("$2"); \ + register long int __a0 asm ("$4") = _arg1; \ + register long int __a1 asm ("$5") = _arg2; \ + register long int __a2 asm ("$6") = _arg3; \ + register long int __a3 asm ("$7") = _arg4; \ + register long int __a4 asm ("$8") = _arg5; \ + register long int __a5 asm ("$9") = _arg6; \ __asm__ volatile ( \ ".set\tnoreorder\n\t" \ v0_init \ @@ -301,7 +322,7 @@ #define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \ ({ \ long _ret = funcptr (args); \ - err = ((unsigned long) (_ret) >= (unsigned long) -4095L); \ + err = ((unsigned long) (_ret) >= (unsigned long int) -4095L); \ if (err) \ _ret = -_ret; \ _ret; \ diff --git a/sysdeps/unix/sysv/linux/mips/mips64/syscall.S b/sysdeps/unix/sysv/linux/mips/mips64/syscall.S index 50a6e6dbe..251d59099 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/syscall.S +++ b/sysdeps/unix/sysv/linux/mips/mips64/syscall.S @@ -20,7 +20,7 @@ #include /* Usage: - long syscall (syscall_number, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + long int syscall (syscall_number, arg1, arg2, arg3, arg4, arg5, arg6, arg7) We need to do some arg shifting, syscall_number will be in v0. */ diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h index 16cc31cba..bf7d80125 100644 --- a/sysdeps/unix/sysv/linux/not-cancel.h +++ b/sysdeps/unix/sysv/linux/not-cancel.h @@ -43,6 +43,9 @@ __typeof (openat64) __openat64_nocancel; /* Non cancellable read syscall. */ __typeof (__read) __read_nocancel; +/* Non cancellable pread syscall (LFS version). */ +__typeof (__pread64) __pread64_nocancel; + /* Uncancelable write. */ __typeof (__write) __write_nocancel; @@ -84,6 +87,7 @@ hidden_proto (__open64_nocancel) hidden_proto (__openat_nocancel) hidden_proto (__openat64_nocancel) hidden_proto (__read_nocancel) +hidden_proto (__pread64_nocancel) hidden_proto (__write_nocancel) hidden_proto (__close_nocancel) hidden_proto (__waitpid_nocancel) diff --git a/sysdeps/unix/sysv/linux/pread64_nocancel.c b/sysdeps/unix/sysv/linux/pread64_nocancel.c new file mode 100644 index 000000000..dab61260e --- /dev/null +++ b/sysdeps/unix/sysv/linux/pread64_nocancel.c @@ -0,0 +1,32 @@ +/* Linux pread64() syscall implementation -- non-cancellable. + Copyright (C) 2019 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 + . */ + +#include +#include +#include + +#ifndef __NR_pread64 +# define __NR_pread64 __NR_pread +#endif + +ssize_t +__pread64_nocancel (int fd, void *buf, size_t count, off64_t offset) +{ + return INLINE_SYSCALL_CALL (pread64, fd, buf, count, SYSCALL_LL64_PRW (offset)); +} +hidden_def (__pread64_nocancel) diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h index 5470ea3d2..6fc63852c 100644 --- a/sysdeps/unix/sysv/linux/riscv/sysdep.h +++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h @@ -173,10 +173,11 @@ # define internal_syscall1(number, err, arg0) \ ({ \ long int _sys_result; \ + long int _arg0 = (long int) (arg0); \ \ { \ register long int __a7 asm ("a7") = number; \ - register long int __a0 asm ("a0") = (long int) (arg0); \ + register long int __a0 asm ("a0") = _arg0; \ __asm__ volatile ( \ "scall\n\t" \ : "+r" (__a0) \ @@ -190,11 +191,13 @@ # define internal_syscall2(number, err, arg0, arg1) \ ({ \ long int _sys_result; \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ \ { \ register long int __a7 asm ("a7") = number; \ - register long int __a0 asm ("a0") = (long int) (arg0); \ - register long int __a1 asm ("a1") = (long int) (arg1); \ + register long int __a0 asm ("a0") = _arg0; \ + register long int __a1 asm ("a1") = _arg1; \ __asm__ volatile ( \ "scall\n\t" \ : "+r" (__a0) \ @@ -208,12 +211,15 @@ # define internal_syscall3(number, err, arg0, arg1, arg2) \ ({ \ long int _sys_result; \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ \ { \ register long int __a7 asm ("a7") = number; \ - register long int __a0 asm ("a0") = (long int) (arg0); \ - register long int __a1 asm ("a1") = (long int) (arg1); \ - register long int __a2 asm ("a2") = (long int) (arg2); \ + register long int __a0 asm ("a0") = _arg0; \ + register long int __a1 asm ("a1") = _arg1; \ + register long int __a2 asm ("a2") = _arg2; \ __asm__ volatile ( \ "scall\n\t" \ : "+r" (__a0) \ @@ -227,13 +233,17 @@ # define internal_syscall4(number, err, arg0, arg1, arg2, arg3) \ ({ \ long int _sys_result; \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ \ { \ register long int __a7 asm ("a7") = number; \ - register long int __a0 asm ("a0") = (long int) (arg0); \ - register long int __a1 asm ("a1") = (long int) (arg1); \ - register long int __a2 asm ("a2") = (long int) (arg2); \ - register long int __a3 asm ("a3") = (long int) (arg3); \ + register long int __a0 asm ("a0") = _arg0; \ + register long int __a1 asm ("a1") = _arg1; \ + register long int __a2 asm ("a2") = _arg2; \ + register long int __a3 asm ("a3") = _arg3; \ __asm__ volatile ( \ "scall\n\t" \ : "+r" (__a0) \ @@ -247,14 +257,19 @@ # define internal_syscall5(number, err, arg0, arg1, arg2, arg3, arg4) \ ({ \ long int _sys_result; \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ \ { \ register long int __a7 asm ("a7") = number; \ - register long int __a0 asm ("a0") = (long int) (arg0); \ - register long int __a1 asm ("a1") = (long int) (arg1); \ - register long int __a2 asm ("a2") = (long int) (arg2); \ - register long int __a3 asm ("a3") = (long int) (arg3); \ - register long int __a4 asm ("a4") = (long int) (arg4); \ + register long int __a0 asm ("a0") = _arg0; \ + register long int __a1 asm ("a1") = _arg1; \ + register long int __a2 asm ("a2") = _arg2; \ + register long int __a3 asm ("a3") = _arg3; \ + register long int __a4 asm ("a4") = _arg4; \ __asm__ volatile ( \ "scall\n\t" \ : "+r" (__a0) \ @@ -268,15 +283,21 @@ # define internal_syscall6(number, err, arg0, arg1, arg2, arg3, arg4, arg5) \ ({ \ long int _sys_result; \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + long int _arg5 = (long int) (arg5); \ \ { \ register long int __a7 asm ("a7") = number; \ - register long int __a0 asm ("a0") = (long int) (arg0); \ - register long int __a1 asm ("a1") = (long int) (arg1); \ - register long int __a2 asm ("a2") = (long int) (arg2); \ - register long int __a3 asm ("a3") = (long int) (arg3); \ - register long int __a4 asm ("a4") = (long int) (arg4); \ - register long int __a5 asm ("a5") = (long int) (arg5); \ + register long int __a0 asm ("a0") = _arg0; \ + register long int __a1 asm ("a1") = _arg1; \ + register long int __a2 asm ("a2") = _arg2; \ + register long int __a3 asm ("a3") = _arg3; \ + register long int __a4 asm ("a4") = _arg4; \ + register long int __a5 asm ("a5") = _arg5; \ __asm__ volatile ( \ "scall\n\t" \ : "+r" (__a0) \ @@ -291,16 +312,23 @@ # define internal_syscall7(number, err, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ ({ \ long int _sys_result; \ + long int _arg0 = (long int) (arg0); \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + long int _arg5 = (long int) (arg5); \ + long int _arg6 = (long int) (arg6); \ \ { \ register long int __a7 asm ("a7") = number; \ - register long int __a0 asm ("a0") = (long int) (arg0); \ - register long int __a1 asm ("a1") = (long int) (arg1); \ - register long int __a2 asm ("a2") = (long int) (arg2); \ - register long int __a3 asm ("a3") = (long int) (arg3); \ - register long int __a4 asm ("a4") = (long int) (arg4); \ - register long int __a5 asm ("a5") = (long int) (arg5); \ - register long int __a6 asm ("a6") = (long int) (arg6); \ + register long int __a0 asm ("a0") = _arg0; \ + register long int __a1 asm ("a1") = _arg1; \ + register long int __a2 asm ("a2") = _arg2; \ + register long int __a3 asm ("a3") = _arg3; \ + register long int __a4 asm ("a4") = _arg4; \ + register long int __a5 asm ("a5") = _arg5; \ + register long int __a6 asm ("a6") = _arg6; \ __asm__ volatile ( \ "scall\n\t" \ : "+r" (__a0) \ diff --git a/sysdeps/unix/sysv/linux/riscv/vfork.S b/sysdeps/unix/sysv/linux/riscv/vfork.S index 67373f181..dc173d6b4 100644 --- a/sysdeps/unix/sysv/linux/riscv/vfork.S +++ b/sysdeps/unix/sysv/linux/riscv/vfork.S @@ -21,9 +21,12 @@ #include #include #define __ASSEMBLY__ -#include #include +#define CLONE_VM 0x00000100 /* Set if VM shared between processes. */ +#define CLONE_VFORK 0x00004000 /* Set if the parent wants the child to + wake it up on mm_release. */ + .text LEAF (__libc_vfork) diff --git a/sysdeps/unix/sysv/linux/s390/bits/utmp.h b/sysdeps/unix/sysv/linux/s390/bits/utmp.h index 862115c6f..0569c3b78 100644 --- a/sysdeps/unix/sysv/linux/s390/bits/utmp.h +++ b/sysdeps/unix/sysv/linux/s390/bits/utmp.h @@ -61,7 +61,8 @@ struct utmp pid_t ut_pid; /* Process ID of login process. */ char ut_line[UT_LINESIZE] __attribute_nonstring__; /* Devicename. */ - char ut_id[4]; /* Inittab ID. */ + char ut_id[4] + __attribute_nonstring__; /* Inittab ID. */ char ut_user[UT_NAMESIZE] __attribute_nonstring__; /* Username. */ char ut_host[UT_HOSTSIZE] diff --git a/sysdeps/unix/sysv/linux/s390/bits/utmpx.h b/sysdeps/unix/sysv/linux/s390/bits/utmpx.h index ea3e860a2..737d9dca0 100644 --- a/sysdeps/unix/sysv/linux/s390/bits/utmpx.h +++ b/sysdeps/unix/sysv/linux/s390/bits/utmpx.h @@ -56,10 +56,14 @@ struct utmpx { short int ut_type; /* Type of login. */ __pid_t ut_pid; /* Process ID of login process. */ - char ut_line[__UT_LINESIZE]; /* Devicename. */ - char ut_id[4]; /* Inittab ID. */ - char ut_user[__UT_NAMESIZE]; /* Username. */ - char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ + char ut_line[__UT_LINESIZE] + __attribute_nonstring__; /* Devicename. */ + char ut_id[4] + __attribute_nonstring__; /* Inittab ID. */ + char ut_user[__UT_NAMESIZE] + __attribute_nonstring__; /* Username. */ + char ut_host[__UT_HOSTSIZE] + __attribute_nonstring__; /* Hostname for remote login. */ struct __exit_status ut_exit; /* Exit status of a process marked as DEAD_PROCESS. */ diff --git a/sysdeps/unix/sysv/linux/sparc/Makefile b/sysdeps/unix/sysv/linux/sparc/Makefile index fb3ee5b8a..7b91ff182 100644 --- a/sysdeps/unix/sysv/linux/sparc/Makefile +++ b/sysdeps/unix/sysv/linux/sparc/Makefile @@ -15,8 +15,12 @@ ifeq ($(subdir),sysvipc) sysdep_routines += getshmlba endif +ifeq ($(subdir),signal) +sysdep_routines += sigreturn_stub +endif + ifeq ($(subdir),nptl) # pull in __syscall_error routine -libpthread-routines += sysdep -libpthread-shared-only-routines += sysdep +libpthread-routines += sysdep sigreturn_stub +libpthread-shared-only-routines += sysdep sigreturn_stub endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c index de7ef6f15..f36e924af 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c @@ -24,8 +24,8 @@ #include #include -static void __rt_sigreturn_stub (void); -static void __sigreturn_stub (void); +void __rt_sigreturn_stub (void); +void __sigreturn_stub (void); #define STUB(act, sigsetsize) \ (act) ? ((unsigned long)((act->sa_flags & SA_SIGINFO) \ @@ -35,25 +35,3 @@ static void __sigreturn_stub (void); (sigsetsize) #include - -static -inhibit_stack_protector -void -__rt_sigreturn_stub (void) -{ - __asm__ ("mov %0, %%g1\n\t" - "ta 0x10\n\t" - : /* no outputs */ - : "i" (__NR_rt_sigreturn)); -} - -static -inhibit_stack_protector -void -__sigreturn_stub (void) -{ - __asm__ ("mov %0, %%g1\n\t" - "ta 0x10\n\t" - : /* no outputs */ - : "i" (__NR_sigreturn)); -} diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S new file mode 100644 index 000000000..727cc9473 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S @@ -0,0 +1,34 @@ +/* Sigreturn stub function used on sa_restore field. + Copyright (C) 2020 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 + . */ + +#include + +/* These functions must not change the register window or the stack + pointer [1]. + + [1] https://lkml.org/lkml/2016/5/27/465 */ + +ENTRY (__rt_sigreturn_stub) + mov __NR_rt_sigreturn, %g1 + ta 0x10 +END (__rt_sigreturn_stub) + +ENTRY (__sigreturn_stub) + mov __NR_sigreturn, %g1 + ta 0x10 +END (__sigreturn_stub) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c index 3b8be43c0..4772ec255 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c @@ -22,21 +22,11 @@ #include #include -static void __rt_sigreturn_stub (void); +/* Defined on sigreturn_stub.S. */ +void __rt_sigreturn_stub (void); #define STUB(act, sigsetsize) \ (((unsigned long) &__rt_sigreturn_stub) - 8), \ (sigsetsize) #include - -static -inhibit_stack_protector -void -__rt_sigreturn_stub (void) -{ - __asm__ ("mov %0, %%g1\n\t" - "ta 0x6d\n\t" - : /* no outputs */ - : "i" (__NR_rt_sigreturn)); -} diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S b/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S new file mode 100644 index 000000000..add476683 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S @@ -0,0 +1,29 @@ +/* Sigreturn stub function used on sa_restore field. + Copyright (C) 2020 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 + . */ + +#include + +/* This function must not change the register window or the stack + pointer [1]. + + [1] https://lkml.org/lkml/2016/5/27/465 */ + +ENTRY (__rt_sigreturn_stub) + mov __NR_rt_sigreturn, %g1 + ta 0x6d +END (__rt_sigreturn_stub) diff --git a/sysdeps/unix/sysv/linux/test-errno-linux.c b/sysdeps/unix/sysv/linux/test-errno-linux.c index cb979d44b..aaa9eadc0 100644 --- a/sysdeps/unix/sysv/linux/test-errno-linux.c +++ b/sysdeps/unix/sysv/linux/test-errno-linux.c @@ -160,8 +160,9 @@ do_test (void) fails |= test_wrp (EINVAL, poll, &pollfd, -1, 0); /* quotactl returns ENOSYS for kernels not configured with CONFIG_QUOTA, and may return EPERM if called within certain types - of containers. */ - fails |= test_wrp2 (LIST (ENODEV, ENOSYS, EPERM), + of containers. Linux 5.4 added additional argument validation + and can return EINVAL. */ + fails |= test_wrp2 (LIST (ENODEV, ENOSYS, EPERM, EINVAL), quotactl, Q_GETINFO, NULL, -1, (caddr_t) &dqblk); fails |= test_wrp (EINVAL, sched_getparam, -1, &sch_param); fails |= test_wrp (EINVAL, sched_getscheduler, -1); diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h index 975cbe295..df2cdfdb6 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h +++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h @@ -31,7 +31,8 @@ environment variable, LD_PREFER_MAP_32BIT_EXEC. */ #define EXTRA_LD_ENVVARS \ case 21: \ - if (memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \ + if (!__libc_enable_secure \ + && memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \ GLRO(dl_x86_cpu_features).feature[index_arch_Prefer_MAP_32BIT_EXEC] \ |= bit_arch_Prefer_MAP_32BIT_EXEC; \ break; diff --git a/time/Makefile b/time/Makefile index a428f5524..63b8d735e 100644 --- a/time/Makefile +++ b/time/Makefile @@ -57,6 +57,8 @@ include ../gen-locales.mk $(objpfx)tst-ftime_l.out: $(gen-locales) $(objpfx)tst-strptime.out: $(gen-locales) +$(objpfx)tst-strftime2.out: $(gen-locales) +$(objpfx)tst-strftime3.out: $(gen-locales) endif tz-cflags = -DTZDIR='"$(zonedir)"' \ -- 2.30.2