Bug#904808: libcap-ng0: libcap-ng's use of pthread_atfork causes segfaults
The problem here is the weak declaration: $ eu-readelf --symbols=.dynsym /lib64/libcap-ng.so.0.0.0 | grep pthread_atfork 28: 0 NOTYPE WEAK DEFAULTUNDEF pthread_atfork In the Fedora 29 build, the constructor looks like this: Dump of assembler code for function init_lib: 0x25d0 <+0>: endbr64 0x25d4 <+4>: cmpq $0x0,0x4a0c(%rip)# 0x6fe8 0x25dc <+12>:je 0x25ee 0x25de <+14>:lea0xcb(%rip),%rdx# 0x26b0 0x25e5 <+21>:xor%esi,%esi 0x25e7 <+23>:xor%edi,%edi 0x25e9 <+25>:jmpq 0x24f0 0x25ee <+30>:retq src/cap-ng.c has this: /* * The pthread_atfork function is being made weak so that we can use it * if the program is linked with pthreads and not requiring it for * everything that uses libcap-ng. */ extern int __attribute__((weak)) pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)); … static void init_lib(void) __attribute__ ((constructor)); static void init_lib(void) { if (pthread_atfork) pthread_atfork(NULL, NULL, deinit); } This is wrong. pthread_atfork needs to be *strong* reference, otherwise the implementation in libc_nonshared.a is not used. This implementation provides the correct __dso_handle argument, allowing unregistration at dlclose. For glibc 2.28 and later, the fix should be simple: Just delete the weak declaration. For older glibc versions, you need to call __register_atfork directly, with an explicit __dso_handle argument. (I believe systemd has an example of this which looks correct.) This is a stable glibc ABI, despite all those glibc internals. We cannot fix this in libpthread because of the tail call in init_lib. It destroys the caller's stack frame, so the identity of the calling DSO is not available to pthread_atfork. (Without the tail call, we could use __builtin_return_address (0) and the internal variant of dladdr to figure out the caller.) Thanks, Florian
Bug#904808: libcap-ng0: libcap-ng's use of pthread_atfork causes segfaults
Hello,Here is a patch trying to address that, as suggested by Simon McVittie in https://github.com/stevegrubb/libcap-ng/issues/5and Carlos O'Donell at https://sourceware.org/bugzilla/show_bug.cgi?id=13502Using the package built with this patch also fixes this bug:https://bugs.debian.org/cgi-bin/bugreport.cgi?archive=no=915642Sincerly,René libcap-ng.patch Description: Binary data
Bug#904808: libcap-ng0: libcap-ng's use of pthread_atfork causes segfaults
Package: libcap-ng0 Version: 0.7.9-1 Severity: grave Justification: renders package unusable Hi, apache httpd loads and unloads modules during a reload of the server configuration. This causes the pthread_atfork entry that is installed by libcap-ng0 to point to code that is no longer in the process, causing a segfault at the next fork. See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=902657 There is already an upstream bug report about this: https://github.com/stevegrubb/libcap-ng/issues/5 Since there is no interface to undo a pthread_atfork() call, there is no way a shared library can call pthread_atfork() in a safe way. libcap-ng0 should not do it. Cheers, Stefan -- System Information: Debian Release: buster/sid APT prefers unstable-debug APT policy: (500, 'unstable-debug'), (500, 'unstable'), (500, 'stable') Architecture: amd64 (x86_64) Foreign Architectures: armhf, i386 Kernel: Linux 4.17.0-1-amd64 (SMP w/8 CPU cores) Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8), LANGUAGE= (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages libcap-ng0 depends on: ii libc6 2.27-5 libcap-ng0 recommends no packages. libcap-ng0 suggests no packages. -- no debconf information