This patch implements a new posix_spawn{p} implementation for Linux. The main
difference is it uses the clone syscall directly with CLONE_VM and CLONE_VFORK
flags and a direct allocated stack. The new stack and start function solves
most the vfork limitation (possible parent clobber due stack spilling). The
remaning issue are related to signal handling:
1. That no signal handlers must run in child context, to avoid corrupt
parent's state.
2. Child must synchronize with parent to enforce stack deallocation and
to possible return execv issues.
The first one is solved by blocking all signals in child, even NPTL-internal
ones (SIGCANCEL and SIGSETXID). The second issue is done by a stack allocation
in parent and a synchronization with using a pipe or waitpid (in case or error).
The pipe has the advantage of allowing the child signal an exec error (checked
with new tst-spawn2 test).
There is an inherent race condition in pipe2 usage for architectures that do not
support the syscall directly. In such cases the a pipe plus fctnl is used
instead and it may lead to file descriptor leak in parent (as decribed by fcntl
documentation).
The child process stack is allocate with a mmap with MAP_STACK flag using
default architecture stack size. Although it is slower than use a stack buffer
from parent, it allows some slack for the compatibility code to run scripts
with no shebang (which may use a buffer with size depending of argument list
count).
Performance should be similar to the vfork default posix implementation and
way faster than fork path (vfork on mostly linux ports are basically
clone with CLONE_VM plus CLONE_VFORK). The only difference is the syscalls
required for the stack allocation/deallocation.
It fixes BZ#10354, BZ#14750, and BZ#18433.
Tested on i386, x86_64, powerpc64le, and aarch64.
[BZ #14750]
[BZ #10354]
[BZ #18433]
* include/sched.h (__clone): Add hidden prototype.
(__clone2): Likewise.
* include/unistd.h (__dup): Likewise.
* posix/Makefile (tests): Add tst-spawn2.
* posix/tst-spawn2.c: New file.
* sysdeps/posix/dup.c (__dup): Add hidden definition.
* sysdeps/unix/sysv/linux/aarch64/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/alpha/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/arm/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/hppa/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/i386/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/ia64/clone2.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/m68k/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/microblaze/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/mips/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/nios2/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S (__clone):
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S (__clone):
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/sh/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc64/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/tile/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/x86_64/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/nptl-signals.h
(____nptl_is_internal_signal): New function.
* sysdeps/unix/sysv/linux/spawni.c: New file.
Linux 2.6.32 and forward do not show the issue regarding SysV SIGCHLD
vs. SIG_IGN for nanosleep which make it feasible to use it for sleep
implementation without requiring any hacking to handle the spurious
wake up. The issue is likely being fixed before 2.6 and git
history [1] [2].
This patch simplifies the sleep code to call nanosleep directly by
using the posix default version. It also removes the early cancellation
tests for zero argument, since nanosleep will handle cancellation
in this case.
[1] https://lkml.org/lkml/2004/11/25/5
[2] https://lkml.org/lkml/2003/11/8/50
Checked on x86_64, ppc64le, and aarch64.
[BZ #16364]
* sysdeps/unix/sysv/linux/sleep.c: Remove file
* sysdeps/posix/sleep.c (__sleep): Simplify cancellation handling.
nice (XPG3) calls getpriority and setpriority (in XPG4 but not XPG3,
i.e. UX-shaded in XPG4). This patch fixes this by making those
functions into weak aliases of __* functions and calling the __*
versions as needed.
Tested for x86_64 and x86 (testsuite, and that disassembly of
installed shared libraries is unchanged by this patch).
This completes cleaning up the unsorted linknamespace test XFAILs.
[BZ #18553]
* resource/getpriority.c (getpriority): Rename to __getpriority
and define as weak alias of __getpriority.
* resource/setpriority.c (setpriority): Rename to __setpriority
and define as weak alias of __setpriority.
* sysdeps/mach/hurd/getpriority.c (getpriority): Rename to
__getpriority and define as weak alias of __getpriority.
* sysdeps/mach/hurd/setpriority.c (setpriority): Rename to
__setpriority and define as weak alias of __setpriority.
* sysdeps/unix/syscalls.list (getpriority): Use __getpriority as
strong name.
(setpriority): Use __setpriority as strong name.
* sysdeps/unix/sysv/linux/getpriority.c (getpriority): Rename to
__getpriority and define as weak alias of __getpriority.
* include/sys/resource.h (__getpriority): Declare. Use
libc_hidden_proto.
(__setpriority): Likewise.
(getpriority): Don't use libc_hidden_proto.
(setpriority): Likewise.
* sysdeps/posix/nice.c (nice): Call __getpriority instead of
getpriority. Call __setpriority instead of setpriority.
* conform/Makefile (test-xfail-XPG3/unistd.h/linknamespace):
Remove variable.
Handle signed integer overflow correctly. Detect and reject O_APPEND.
Document drawbacks of emulation.
This does not completely address bug 15661, but improves the situation
somewhat.
Both open and openat load their last argument 'mode' lazily, using
va_arg() only if O_CREAT is found in oflag. This is wrong, mode is also
necessary if O_TMPFILE is in oflag.
By chance on x86_64, the problem wasn't evident when using O_TMPFILE
with open, as the 3rd argument of open, even when not loaded with
va_arg, is left untouched in RDX, where the syscall expects it.
However, openat was not so lucky, and O_TMPFILE couldn't be used: mode
is the 4th argument, in RCX, but the syscall expects its 4th argument in
a different register than the glibc wrapper, in R10.
Introduce a macro __OPEN_NEEDS_MODE (oflag) to test if either O_CREAT or
O_TMPFILE is set in oflag.
Tested on Linux x86_64.
[BZ #17523]
* io/fcntl.h (__OPEN_NEEDS_MODE): New macro.
* io/bits/fcntl2.h (open): Use it.
(openat): Likewise.
* io/open.c (__libc_open): Likewise.
* io/open64.c (__libc_open64): Likewise.
* io/open64_2.c (__open64_2): Likewise.
* io/open_2.c (__open_2): Likewise.
* io/openat.c (__openat): Likewise.
* io/openat64.c (__openat64): Likewise.
* io/openat64_2.c (__openat64_2): Likewise.
* io/openat_2.c (__openat_2): Likewise.
* sysdeps/mach/hurd/open.c (__libc_open): Likewise.
* sysdeps/mach/hurd/openat.c (__openat): Likewise.
* sysdeps/posix/open64.c (__libc_open64): Likewise.
* sysdeps/unix/sysv/linux/dl-openat64.c (openat64): Likewise.
* sysdeps/unix/sysv/linux/generic/open.c (__libc_open): Likewise.
(__open_nocancel): Likewise.
* sysdeps/unix/sysv/linux/generic/open64.c (__libc_open64): Likewise.
* sysdeps/unix/sysv/linux/open64.c (__libc_open64): Likewise.
* sysdeps/unix/sysv/linux/openat.c (__OPENAT): Likewise.
posix_spawn (a standard POSIX function) brings in a use of getrlimit64
(not a standard POSIX function). This patch fixes this by using
__getrlimit64 and making getrlimit64 a weak alias.
This is more complicated than some such changes because of files that
define getrlimit64 in their own way using symbol versioning after
including the main sysdeps/unix/sysv/linux/getrlimit64.c with a
getrlimit macro defined. There are various existing patterns for such
cases in glibc; the one I've used here is that a getrlimit64 macro
disables the weak_alias / libc_hidden_weak calls, leaving it to the
including file to define the getrlimit64 name in whatever way is
appropriate.
Tested for x86_64 and x86 that installed stripped shared libraries are
unchanged by this patch.
[BZ #17991]
* include/sys/resource.h (__getrlimit64): Declare. Use
libc_hidden_proto.
* resource/getrlimit64.c (getrlimit64): Rename to __getrlimit64
and define as weak alias of __getrlimit64. Use libc_hidden_weak.
* sysdeps/posix/spawni.c (__spawni): Call __getrlimit64 instead of
getrlimit64.
* sysdeps/unix/sysv/linux/getrlimit64.c (getrlimit64): Rename to
__getrlimit64.
[!getrlimit64] (getrlimit64): Define as weak alias of
__getrlimit64. Use libc_hidden_weak.
* sysdeps/unix/sysv/linux/i386/getrlimit64.c (getrlimit64): Define
using __getrlimit64 not __new_getrlimit64.
(__GI_getrlimit64): Likewise.
* sysdeps/unix/sysv/linux/mips/getrlimit64.c (getrlimit64):
Likewise.
(__GI_getrlimit64): Likewise.
(__old_getrlimit64): Use __getrlimit64 not __new_getrlimit64.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list
(getrlimit): Add __getrlimit64 alias.
* sysdeps/unix/sysv/linux/wordsize-64/syscalls.list (getrlimit):
Likewise.
* conform/Makefile (test-xfail-XOPEN2K/spawn.h/linknamespace):
Remove variable.
(test-xfail-POSIX2008/spawn.h/linknamespace): Likewise.
(test-xfail-XOPEN2K8/spawn.h/linknamespace): Likewise.
This patch adds support to generate the spec array in getconf from the
conf.list. The generated code is mostly unchanged. the only changes
are due to the change in layout of the spec and val arrays in the ELF.
The val array can also be auto-generated from posix-conf-vars.list
once the remaining macros are added to it.
* posix/posix-conf-vars.list (SPEC:XBS5): Add sysconf prefix.
* posix/confstr.c: Define NEED_SPEC_ARRAY to 0.
* posix/posix-envs.def: Likewise.
* sysdeps/posix/sysconf.c: Likewise.
* posix/getconf.c: Define NEED_SPEC_ARRAY to 1.
(specs): Remove array.
* scripts/gen-posix-conf-vars.awk: Support generation of specs
array.
This fixes the remaining -Wundef warnings. Tested on x86_64.
* posix/posix-conf-vars.list: Add _POSIX sysconf namespace.
* sysdeps/posix/sysconf.c: Include posix-conf-vars.h.
(__sysconf): Use CONF_IS_* macros.
On ARM, where profil_counter is not static, it is brought in by
references to various standard functions, as noted in
<https://sourceware.org/ml/libc-alpha/2014-11/msg00890.html>, although
it is not a standard function itself. I don't know if this also
causes test failures on SPARC, although I see no reason for it not to
do so.
This patch fixes this namespace issue. profil_counter is renamed to
__profil_counter and made a weak alias on ARM and SPARC. Because of
the uses in profil.c / sprofil.c it seems simplest to make the rename
globally, including on the other architectures for which
profil_counter was static and so the change is of no substance. The
variant names profil_counter_* used in sprofil.c are also renamed to
start with __ so that undesired function names do not get exported in
static libc.
As I noted in bug 17726, profil_counter should probably be a compat
symbol on ARM and SPARC, so it wouldn't exist at all in static libc
even as a weak alias. Since defining a compat symbol still requires
an internal name as a target of an alias, this patch still seems
reasonable as an intermediate step towards that goal: it wouldn't be
possible for the function simply to be static profil_counter on ARM
and SPARC with profil_counter also being the exported compat symbol
name, so profil.c / sprofil.c would still need to be prepared to call
the function under another name (here, __profil_counter).
Tested for x86_64 (testsuite, and that stripped installed shared
libraries are unchanged by the patch) and ARM (ABI and linknamespace
tests - this patch reduces the number of linknamespace failures I see
on ARM from 227 to 5, the residue being math.h failures for fe*
functions and for j0l/j1n/jnl/y0l/y1l/ynl aliases).
2014-12-17 Joseph Myers <joseph@codesourcery.com>
[BZ #17725]
* sysdeps/generic/profil-counter.h (profil_counter): Rename to
__profil_counter.
* sysdeps/unix/sysv/linux/hppa/profil-counter.h (profil_counter):
Likewise.
* sysdeps/unix/sysv/linux/i386/profil-counter.h (profil_counter):
Likewise.
* sysdeps/unix/sysv/linux/ia64/profil-counter.h (profil_counter):
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h
(profil_counter): Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h
(profil_counter): Likewise.
* sysdeps/unix/sysv/linux/sh/profil-counter.h (profil_counter):
Likewise.
* sysdeps/unix/sysv/linux/tile/profil-counter.h (profil_counter):
Likewise.
* sysdeps/unix/sysv/linux/x86_64/profil-counter.h
(profil_counter): Likewise.
* sysdeps/unix/sysv/linux/arm/profil-counter.h (profil_counter):
Likewise.
[!__profil_counter] (profil_counter): Define as weak alias of
__profil_counter.
* sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h
(profil_counter): Rename to __profil_counter.
[!__profil_counter] (profil_counter): Define as weak alias of
__profil_counter.
* sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h
(profil_counter): Rename to __profil_counter.
[!__profil_counter] (profil_counter): Define as weak alias of
__profil_counter.
* sysdeps/posix/profil.c: Update comment referring to
profil_counter.
(__profil): Use __profil_counter instead of profil_counter.
* sysdeps/posix/sprofil.c (profil_counter): Rename to
__profil_counter. Use __profil_counter_ushort and
__profil_counter_uint in definitions.
(__sprofil): Use __profil_counter_uint and __profil_counter_ushort
instead of profil_counter_uint and profil_counter_ushort.
for ChangeLog
* sysdeps/posix/ctermid.c (ctermid): Return a pointer to a
string literal if not passed a buffer.
* manual/job.texi (ctermid): Update reasoning, note deviation
from posix, suggest mtasurace when not passed a buffer, for
future non-preliminary safety notes.
qsort_r is defined in the same file as qsort, but is not an ISO C
function, so should be a weak alias for __qsort_r. The uses in
getaddrinfo should also call __qsort_r, since getaddrinfo is a POSIX
function and qsort_r isn't. This patch implements this. Because nscd
uses the getaddrinfo sources outside libc, as do the tst-rfc3484
tests, a #define of __qsort_r to qsort_r is added there alongside the
similar defines for other libc-internal symbols used in getaddrinfo.
Tested for x86_64 (testsuite, and that disassembly of installed shared
libraries is unchanged by the patch).
[BZ #17571]
* stdlib/msort.c (qsort_r): Rename to __qsort_r and define as weak
alias of __qsort_r.
(qsort): Call __qsort_r instead of qsort_r.
* include/stdlib.h (qsort_r): Do not call libc_hidden_proto.
(__qsort_r): Declare. Call libc_hidden_proto.
* sysdeps/posix/getaddrinfo.c (getaddrinfo): Call __qsort_r
instead of qsort_r.
* nscd/gai.c (__qsort_r): Define to qsort_r.
* posix/tst-rfc3484.c (__qsort_r): Likewise.
* posix/tst-rfc3484-2.c (__qsort_r): Likewise.
* posix/tst-rfc3484-3.c (__qsort_r): Likewise.
__getcwd is called from dcigettext.o (brought in by various ISO C
functionality), but calls rewinddir, which is not an ISO C function.
This patch makes __getcwd call __rewinddir instead and makes rewinddir
a weak alias for __rewinddir.
Since getcwd.c is shared with gnulib (albeit not merged in either
direction for a long time, and omitted from gnulib's
config/srclist.txt list of shared files) I put in a #ifndef _LIBC
define of __rewinddir to rewinddir, although a future merged version
of getcwd could end up looking significantly different.
Tested for x86_64 (testsuite, and that disassembly of installed shared
libraries is unchanged by this patch).
[BZ #17584]
* dirent/rewinddir.c (rewinddir): Rename to __rewinddir and define
as weak alias of __rewinddir. Don't use libc_hidden_def.
(__rewinddir): Use libc_hidden_def.
* sysdeps/mach/hurd/rewinddir.c: Rename to __rewinddir and define
as weak alias of __rewinddir. Don't use libc_hidden_def.
(__rewinddir): Use libc_hidden_def.
* sysdeps/posix/rewinddir.c: Rename to __rewinddir and define as
weak alias of __rewinddir. Don't use libc_hidden_def.
(__rewinddir): Use libc_hidden_def.
* include/dirent.h (rewinddir): Don't use libc_hidden_proto.
(__rewinddir): Use libc_hidden_proto.
* sysdeps/posix/getcwd.c [!_LIBC] (__rewinddir): Define to
rewinddir.
(__getcwd): Use __rewinddir instead of rewinddir.
Continuing the removal of __libc_* function names that are no longer
used anywhere, this patch removes the __libc_readv and __libc_writev
names.
Tested for x86_64 that stripped installed shared libraries are
unchanged by the patch.
* include/sys/uio.h (__libc_readv): Remove declaration.
(__libc_writev): Likewise.
* misc/readv.c (__libc_readv): Rename to __readv.
(__readv): Do not define as alias.
(readv): Define as alias of __readv.
* misc/writev.c (__libc_writev): Rename to __writev.
(__writev): Do not define as alias.
(writev): Define as alias of __writev.
* sysdeps/posix/readv.c (__libc_readv): Rename to __readv.
(__readv): Do not define as alias.
(readv): Define unconditionally as alias of __readv.
* sysdeps/posix/writev.c (__libc_writev): Rename to __writev.
(__writev): Do not define as alias.
(writev): Define unconditionally as alias of __writev.
* sysdeps/unix/syscalls.list (readv): Do not define __libc_readv
name.
(writev): Do not define __libc_writev name.
There is no _POSIX_REGEX_VERSION, so don't check for it.
_REGEX_VERSION has been removed as well[1], so only keep the -1 return
for backward compatibility. I found this when trying to make the
getconf environment variables typo-proof.
* sysdeps/posix/sysconf.c (__sysconf): Return -1 for
_SC_REGEX_VERSION.
[1] http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html
Spell _POSIX_DEVICE_SPECIFIC and _POSIX_DEVICE_SPECIFIC_R correctly.
Found when trying to make the getconf environment variables
typo-proof.
* sysdeps/posix/sysconf.c (__sysconf): Spell
_POSIX_DEVICE_SPECIFIC and _POSIX_DEVICE_SPECIFIC_R correctly.
Partial merge from gnulib which fixes a number of -Wundef warnings.
The parts that differ from gnulib are the header comment, use of
__glibc_unlikely, a #define of __secure_getenv and the use of tabs.
The majority of the patch is cosmetic comment changes, the only runtime
change is an abort if an unknown kind is passed to __gen_tempname.
ChangeLog:
2014-06-25 Will Newton <will.newton@linaro.org>
* sysdeps/posix/tempname.c: Merge from gnulib, cosmetic
comment changes throughout the file. Remove checks
for HAVE_*_H definitions that are not required.
(__gen_tempname): Call abort if an unknown kind value is
passed.
getaddrinfo correctly returns EAI_AGAIN for AF_INET and AF_INET6
queries. For AF_UNSPEC however, an older change
(a682a1bf55) broke the check and due to
that the returned error was EAI_NONAME.
This patch fixes the check so that a non-authoritative not-found is
returned as EAI_AGAIN to the user instead of EAI_NONAME.
pathconf(_PC_NAME_MAX) was implemented on top of statfs(). The 32bit
version therefore fails EOVERFLOW if the filesystem blockcount is
sufficiently large.
Most pathconf() queries use statvfs64(), which avoids this issue. This
patch modifies pathconf(_PC_NAME_MAX) to do likewise.
This fixes a bug in the way the results from __nscd_getai are collected:
for every returned result a new entry is first added to the
gaih_addrtuple list, but if that result doesn't match the request this
entry remains uninitialized. So for this non-matching result an extra
result with uninitialized content is returned.
To reproduce (with nscd running):
$ getent ahostsv4 localhost
127.0.0.1 STREAM localhost
127.0.0.1 DGRAM
127.0.0.1 RAW
(null) STREAM
(null) DGRAM
(null) RAW
We needlessly enabled thread cancellation before it was necessary. As
only call that needs to be guarded is waitpid which is cancellation
point we could remove cancellation altogether.
Only gaih_inet() and gaih_inet_serv() use a special bit flag denoted
by the GAIH_OKIFUNSPEC macro. Only the return value of
gaih_inet_serv() is actively checked for the bit flag which is
redundant because it just copies the nonzero property of the value
otherwise returned. The return value of gaih_inet() is only checked
for being zero and then the bit flag is filtered out. As the bit flag
is set only for otherwise nonzero return values, it doesn't affect the
zero comparison. GAIH_EAI just an alias to ~GAIH_OKIFUNSPEC.
Resolves#16072 (CVE-2013-4458).
This patch fixes another stack overflow in getaddrinfo when it is
called with AF_INET6. The AF_UNSPEC case was fixed as CVE-2013-1914,
but the AF_INET6 case went undetected back then.
[BZ #9954]
With the following /etc/hosts:
127.0.0.1 www.my-domain.es
127.0.1.1 www.my-domain.es
192.168.0.1 www.my-domain.es
Using getaddrinfo() on www.my-domain.es, trigger the following assertion:
../sysdeps/posix/getaddrinfo.c:1473: rfc3484_sort: Assertion
`src->results[i].native == -1 || src->results[i].native == a1_native' failed.
This is due to two different bugs:
- In rfc3484_sort() rule 7, src->results[i].native is assigned even if
src->results[i].index is -1, meaning that no interface is associated.
- In getaddrinfo() the source IP address used with the lo interface needs a
special case, as it can be any IP within 127.X.Y.Z.