glibc:zack/wip-check-localplt-2

Last commit made on 2018-03-26
Get this branch:
git clone -b zack/wip-check-localplt-2 https://git.launchpad.net/glibc

Branch merges

Branch information

Name:
zack/wip-check-localplt-2
Repository:
lp:glibc

Recent commits

f66704a... by Zack Weinberg on 2018-03-18

WIP finer-grained, more aggressive local PLT call check

9ea49e1... by Zack Weinberg on 2018-03-23

[Bug 15368] Move pthread_kill to libc and use it to implement raise.

The fix for bug #15368 was unnecessarily Linux-specific. To recap,
POSIX specifies raise to be async-signal-safe, but also specifies it
to be equivalent to pthread_kill(pthread_self(), sig), which is not
an async-signal-safe sequence of operations; a signal handler could
run in between pthread_self and pthread_kill, and do something (such
as calling fork, which is also async-signal-safe) that would invalidate
the thread descriptor. This is even true in the hypothetical case of
a port that doesn't implement multithreading: kill(getpid(), sig) will
fire the signal twice if a signal handler runs in between, calls fork,
and then returns on both sides of the fork. I don't see anything in
the standards to forbid that.

The Linux-specific fix was to override the definitions of raise in
both libpthread and libc to the same unitary function that blocks
signals, retrieves TID and PID directly from the kernel, calls tgkill,
and only then unblocks signals. This patch generalizes that to any
port: pthread_kill is moved from libpthread to libc, with a forwarding
stub left behind. The definition of raise in libpthread is also
replaced with a forwarding stub. The Linux-specific definition of
raise is deleted; those ports will now use sysdeps/pthread/raise.c,
which blocks signals first, then calls pthread_self and pthread_kill,
and then unblocks signals. Similarly, sysdeps/posix/raise.c (which
would be used on a port that didn't implement multithreading) blocks
signals, calls getpid and kill, and then unblocks signals. Thus,
ports need only implement the primitives correctly and do not need to
worry about making raise async-signal-safe.

The only wrinkle was that up till now, we did not bother initializing
the ->tid field of the initial thread's descriptor unless libpthread
was loaded; now that raise calls pthread_kill even in a single-
threaded environment, that won't fly. This is abstractly easy to fix;
the tricky part was figuring out _where_ to put the calls (two of
them, as it happens) to __pthread_initialize_pids, and I'd appreciate
careful eyes on those changes.

You might be wondering why it's safe to rely on the TID in the thread
descriptor, rather than calling gettid directly. Since all signals
are blocked from before calling pthread_self until after pthread_kill
uses the TID to call tgkill, the question is whether some _other_
thread could do something that would invalidate the calling thread's
descriptor, and I believe there is no such thing.

While I was at it I fixed another bug: raise was returning an error
code on failure (like pthread_kill does) instead of setting errno as
specified. This is user-visible but I don't think it's worth recording
as a fixed bug, nobody bothers checking whether raise failed anyway.

 * nptl/pt-raise.c
 * sysdeps/unix/sysv/linux/pt-raise.c
 * sysdeps/unix/sysv/linux/raise.c:
 Remove file.

 * sysdeps/unix/sysv/linux/pthread_kill.c: Use __is_internal_signal
 to check for forbidden signals. Use INTERNAL_SYSCALL_CALL to call
 getpid. Provide __libc_pthread_kill, with __pthread_kill as
 strong alias and pthread_kill as weak alias.

 * sysdeps/posix/raise.c: Block signals around the calls to
 __getpid and __kill. Provide __libc_raise, with raise as strong
 alias, libc_hidden_def for raise, and gsignal as weak alias.
 * sysdeps/pthread/raise.c: New file. Implement by blocking
 signals, calling pthread_self and pthread_kill, and then
 unblocking signals again. Provide same symbols as above.

 * sysdeps/generic/internal-signals.h: Define all of the same
 functions that sysdeps/unix/sysv/linux/internal-signals.h does,
 with sensible default definitions.
 * sysdeps/unix/sysv/linux/internal-signals.h: Clarify comments.

 * nptl/pthread_kill.c: Define __libc_pthread_kill, with
 __pthread_kill as strong alias and pthread_kill as weak alias.
 * nptl/pthread_self.c: Define __pthread_self, with
 pthread_self as weak alias.
 * signal/raise.c: Define __libc_raise, with raise as strong alias,
 libc_hidden_def for raise, and gsignal as weak alias.

 * nptl/Makefile: Move pthread_kill from libpthread-routines to
 routines. Remove pt-raise from libpthread-routines.
 * nptl/Versions (libc/GLIBC_2.28): Add pthread_kill.
 (libc/GLIBC_PRIVATE): Add __libc_pthread_kill and __libc_raise.
 * sysdeps/generic/pt-compat-stubs.S: Add stubs for raise and
 pthread_kill.

 * nptl/nptl-init.c (__pthread_initialize_minimal_internal):
 Don't call __pthread_initialize_pids here.
 * csu/libc-tls.c (__libc_setup_tls):
        Call __pthread_initialize_pids after all other setup.
 * elf/rtld.c (init_tls): Likewise.

 * include/pthreadP.h: New forwarder.
 * include/pthread.h: Add multiple inclusion guard. Declare
 __pthread_self.
 * include/signal.h: Declare __pthread_kill.

 * sysdeps/**/libc.abilist (GLIBC_2.28): Add pthread_kill.

3d8eb80... by Zack Weinberg on 2018-03-23

WIP no duplicate function definitions in pthread

65a7c4c... by Zack Weinberg on 2018-03-18

RFC: Introduce pt-compat-stubs and use it to replace pt-vfork.

I am looking into the possibility of eliminating all of the duplicate
function definitions from libpthread, replacing them with
properly-tagged weak compatibility symbols that just call the
definition in libc. Because one of the duplicated functions is vfork,
the calls to libc absolutely must reuse the stack frame (a "sibcall"
in GCC internals jargon), and on several important targets, GCC does
not implement sibcalls, or only implements them for intra-module
calls. But we only need to implement a single special case,
sibcalling a function with exactly the same signature, from
immediately after the caller's own entry point; so doing it by hand in
assembly language is not a crazy notion. I believe I have managed to
turn the trick for all currently-supported targets. This patch just
converts the existing vfork stub, so that review can focus on the new
sysdep.h SIBCALL macros.

 * sysdeps/generic/pt-compat-stubs.S: New file.
 * nptl/Makefile (libpthread-routines): Remove pt-vfork, add
 pt-compat-stubs.
 (libpthread-shared-only-routines): Add pt-compat-stubs.
 * posix/vfork.c: Define __libc_vfork as well as __vfork and vfork.

 * sysdeps/generic/sysdep.h (SIBCALL): New macro to perform
 sibling calls; the generic definition errors out if used.
 * sysdeps/aarch64/sysdep.h, sysdeps/arm/sysdep.h
 * sysdeps/hppa/sysdep.h, sysdeps/ia64/sysdep.h
 * sysdeps/m68k/sysdep.h, sysdeps/microblaze/sysdep.h
 * sysdeps/nios2/sysdep.h, sysdeps/powerpc/powerpc32/sysdep.h
 * sysdeps/powerpc/powerpc64/sysdep.h, sysdeps/s390/s390-32/sysdep.h
 * sysdeps/s390/s390-64/sysdep.h, sysdeps/tile/sysdep.h
 * sysdeps/unix/alpha/sysdep.h, sysdeps/unix/mips/mips32/sysdep.h
 * sysdeps/unix/mips/mips64/n32/sysdep.h
 * sysdeps/unix/mips/mips64/n64/sysdep.h
 * sysdeps/unix/sysv/linux/riscv/sysdep.h
 * sysdeps/x86/sysdep.h
 Provide appropriate architecture-specific definitions of
 SIBCALL and, if necessary, SIBCALL_ENTRY.

 * nptl/pt-vfork.c
 * sysdeps/unix/sysv/linux/aarch64/pt-vfork.c
 * sysdeps/unix/sysv/linux/m68k/pt-vfork.c
 * sysdeps/unix/sysv/linux/tile/pt-vfork.c
 * sysdeps/unix/sysv/linux/alpha/pt-vfork.S
 * sysdeps/unix/sysv/linux/hppa/pt-vfork.S
 * sysdeps/unix/sysv/linux/ia64/pt-vfork.S
 * sysdeps/unix/sysv/linux/microblaze/pt-vfork.S
 * sysdeps/unix/sysv/linux/mips/pt-vfork.S
 * sysdeps/unix/sysv/linux/riscv/pt-vfork.S
 * sysdeps/unix/sysv/linux/s390/pt-vfork.S
 * sysdeps/unix/sysv/linux/sh/pt-vfork.S
 * sysdeps/unix/sysv/linux/sparc/pt-vfork.S
 Remove file.

3dfd23e... by Andreas Schwab <email address hidden> on 2018-03-22

RISC-V: add remaining relocations

2d813d7... by Samuel thibault on 2018-03-25

hurd: Regenerate errno.h header

 * sysdeps/mach/hurd/bits/errno.h: Regenerate.

978a680... by Samuel thibault on 2018-03-24

hurd: Fix calling __pthread_initialize_minimal in shared case

 * sysdeps/generic/ldsodefs.h [SHARED] (__pthread_initialize_minimal):
 Declare function.

37be82a... by Samuel thibault on 2018-03-24

Add missing changelog from previous commit

bcfa607... by Samuel thibault on 2018-03-17

hurd: Initialize TLS and libpthread before signal thread start

* sysdeps/generic/libc-start.h [!SHARED] (ARCH_SETUP_TLS): Define to
__libc_setup_tls.
* sysdeps/unix/sysv/linux/powerpc/libc-start.h [!SHARED]
(ARCH_SETUP_TLS): Likewise.
* sysdeps/mach/hurd/libc-start.h: New file copied from
sysdeps/generic/libc-start.h, but define ARCH_SETUP_TLS to empty.
* csu/libc-start.c [!SHARED] (LIBC_START_MAIN): Call ARCH_SETUP_TLS instead
of __libc_setup_tls.
* sysdeps/mach/hurd/i386/init-first.c [!SHARED] (init1): Call
__libc_setup_tls before initializing libpthread and running _hurd_init which
starts the signal thread.

fa97d2a... by Samuel thibault on 2018-03-24

hurd: Fix accessing errno from rtld

Letting rtld access errno through TLS can not work at early stages since
TLS will not be initialized yet. When a private errno is not possible,
we thus have no other way than going through __errno_location.

 * include/errno.h [IS_IN(rtld) && !RTLD_PRIVATE_ERRNO]: Do not use the
 TLS declaration of errno.