Commit 1d63539e authored by Matti Kosola's avatar Matti Kosola

Merge branch 'jb36174' into 'master'

[glibc] Update to glibc-2.25, fixes jb#36174

See merge request !14
parents 12d81991 c2700b8a
......@@ -12,10 +12,10 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include "../locale/hashval.h"
#include "locale/hashval.h"
#define __LC_LAST 13
#include "../locale/locarchive.h"
#include "../crypt/md5.h"
#include "locale/locarchive.h"
#include "crypt/md5.h"
const char *alias_file = DATADIR "/locale/locale.alias";
const char *locar_file = PREFIX "/lib/locale/locale-archive";
......@@ -36,7 +36,7 @@ static const char *locnames[] =
{
#define DEFINE_CATEGORY(category, category_name, items, a) \
[category] = category_name,
#include "../locale/categories.def"
#include "locale/categories.def"
#undef DEFINE_CATEGORY
};
......@@ -147,7 +147,7 @@ extern void add_alias (struct locarhandle *ah, const char *alias,
bool replace, const char *oldname,
uint32_t *locrec_offset_p);
extern struct namehashent *
static struct namehashent *
insert_name (struct locarhandle *ah,
const char *name, size_t name_len, bool replace);
......
diff -Naur eglibc-2.15.old/localedata/Makefile eglibc-2.15/localedata/Makefile
--- eglibc-2.15.old/localedata/Makefile 2011-11-17 21:56:08.000000000 +0000
+++ eglibc-2.15/localedata/Makefile 2013-03-18 15:25:40.078955980 +0000
@@ -159,7 +159,11 @@
# Dependency for the locale files. We actually make it depend only on
# one of the files.
$(addprefix $(objpfx),$(CTYPE_FILES)): %: \
- gen-locale.sh $(common-objpfx)locale/localedef Makefile \
+ if [ -f /usr/bin/localedef ]; then \
+ gen-locale.sh /usr/bin/localedef Makefile \
+ else \
+ gen-locale.sh $(common-objpfx)locale/localedef Makefile \
+ fi\
$(addprefix charmaps/,$(CHARMAPS)) $(addprefix locales/,$(LOCALE_SRCS))
@$(SHELL) -e gen-locale.sh $(common-objpfx) \
'$(if $(cross-localedef), \
@@ -235,8 +239,12 @@
INSTALL-SUPPORTED-LOCALES=$(addprefix install-, $(SUPPORTED-LOCALES))
# Sometimes the whole collection of locale files should be installed.
-LOCALEDEF=I18NPATH=. GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
-$(common-objpfx)elf/ld.so --library-path $(rpath-link) $(common-objpfx)locale/localedef
+ifeq (,$(wildcard /usr/bin/localedef))
+LOCALEDEF=I18NPATH=. GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C $(common-objpfx)elf/ld.so --library-path $(rpath-link) $(common-objpfx)locale/localedef
+else
+LOCALEDEF=I18NPATH=. GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C /usr/bin/localedef
+endif
+
install-locales: $(INSTALL-SUPPORTED-LOCALES)
install-locales-dir:
diff --git a/ports/sysdeps/aarch64/nptl/pthread_spin_lock.c b/ports/sysdeps/aarch64/nptl/pthread_spin_lock.c
index 490bd43..7f2505f 100644
--- a/ports/sysdeps/aarch64/nptl/pthread_spin_lock.c
+++ b/ports/sysdeps/aarch64/nptl/pthread_spin_lock.c
@@ -21,4 +21,4 @@
/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
it will resolve to this very file. Using "sysdeps/.." as reference to the
top level directory does the job. */
-#include <sysdeps/../nptl/pthread_spin_lock.c>
+#include <sysdeps/../../eglibc-2.19/nptl/pthread_spin_lock.c>
diff --git a/ports/sysdeps/arm/nptl/pthread_spin_lock.c b/ports/sysdeps/arm/nptl/pthread_spin_lock.c
index 7105c73..795db52 100644
--- a/ports/sysdeps/arm/nptl/pthread_spin_lock.c
+++ b/ports/sysdeps/arm/nptl/pthread_spin_lock.c
@@ -20,4 +20,4 @@
/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
it will resolve to this very file. Using "sysdeps/.." as reference to the
top level directory does the job. */
-#include <sysdeps/../nptl/pthread_spin_lock.c>
+#include <sysdeps/../../eglibc-2.19/nptl/pthread_spin_lock.c>
diff --git a/ports/sysdeps/mips/nptl/pthread_spin_lock.c b/ports/sysdeps/mips/nptl/pthread_spin_lock.c
index f3e718c..a6c4ca3 100644
--- a/ports/sysdeps/mips/nptl/pthread_spin_lock.c
+++ b/ports/sysdeps/mips/nptl/pthread_spin_lock.c
@@ -20,4 +20,5 @@
/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
it will resolve to this very file. Using "sysdeps/.." as reference to the
top level directory does the job. */
-#include <sysdeps/../nptl/pthread_spin_lock.c>
+#include <sysdeps/../../eglibc-2.19/nptl/pthread_spin_lock.c>
+
......@@ -11,10 +11,8 @@ diff -ru eglibc-2.18/csu/init-first.c eglibc-2.18-runfast/csu/init-first.c
/* Save the command-line arguments. */
__libc_argc = argc;
__libc_argv = argv;
Only in eglibc-2.18-runfast/ports/sysdeps/arm: .fpu_control.h.rej.swp
diff -ru eglibc-2.18/ports/sysdeps/arm/fpu_control.h eglibc-2.18-runfast/ports/sysdeps/arm/fpu_control.h
--- eglibc-2.18/ports/sysdeps/arm/fpu_control.h 2013-06-24 22:42:26.000000000 +0000
+++ eglibc-2.18-runfast/ports/sysdeps/arm/fpu_control.h 2014-01-01 11:06:13.000000000 +0000
+++ eglibc-2.18-runfast/sysdeps/arm/fpu_control.h 2014-01-01 11:06:13.000000000 +0000
@@ -22,7 +22,8 @@
#if !(defined(_LIBC) && !defined(_LIBC_TEST)) && defined(__SOFTFP__)
......@@ -25,19 +23,17 @@ diff -ru eglibc-2.18/ports/sysdeps/arm/fpu_control.h eglibc-2.18-runfast/ports/s
typedef unsigned int fpu_control_t;
#define _FPU_GETCW(cw) (cw) = 0
#define _FPU_SETCW(cw) (void) (cw)
@@ -40,9 +41,11 @@
@@ -44,10 +45,11 @@ extern fpu_control_t __fpu_control;
/* Some bits in the FPSCR are not yet defined. They must be preserved when
modifying the contents. */
#define _FPU_RESERVED 0x00086060
-#define _FPU_DEFAULT 0x00000000
+/* The default mode is RunFast */
+#define _FPU_DEFAULT (3 << 24)
+
/* Default + exceptions enabled. */
-#define _FPU_IEEE (_FPU_DEFAULT | 0x00001f00)
+#define _FPU_IEEE 0x00001f00
/* Type of the control word. */
typedef unsigned int fpu_control_t;
Only in eglibc-2.18-runfast/ports/sysdeps/arm: fpu_control.h.orig
Only in eglibc-2.18-runfast/ports/sysdeps/arm: fpu_control.h.rej
--- glibc-2.25/bits/wordsize.h.bak 2018-11-08 15:12:14.756848932 +0200
+++ glibc-2.25/bits/wordsize.h 2018-11-08 15:13:00.505009458 +0200
@@ -1,27 +1,25 @@
-#error "This file must be written based on the data type sizes of the target"
-
/* The following entries are a template for what defines should be in the
wordsize.h header file for a target. */
/* Size in bits of the 'long int' and pointer types. */
-#define __WORDSIZE
+#define __WORDSIZE 32
/* This should be set to 1 if __WORDSIZE is 32 and size_t is type
'unsigned long' instead of type 'unsigned int'. This will ensure
that SIZE_MAX is defined as an unsigned long constant instead of an
unsigned int constant. Set to 0 if __WORDSIZE is 32 and size_t is
'unsigned int' and leave undefined if __WORDSIZE is 64. */
-#define __WORDSIZE32_SIZE_ULONG
+#define __WORDSIZE32_SIZE_ULONG 0
/* This should be set to 1 if __WORDSIZE is 32 and ptrdiff_t is type 'long'
instead of type 'int'. This will ensure that PTRDIFF_MIN and PTRDIFF_MAX
are defined as long constants instead of int constants. Set to 0 if
__WORDSIZE is 32 and ptrdiff_t is type 'int' and leave undefined if
__WORDSIZE is 64. */
-#define __WORDSIZE32_PTRDIFF_LONG
+#define __WORDSIZE32_PTRDIFF_LONG 0
/* Set to 1 in order to force time types to be 32 bits instead of 64 bits in
struct lastlog and struct utmp{,x} on 64-bit ports. This may be done in
order to make 64-bit ports compatible with 32-bit ports. Set to 0 for
64-bit ports where the time types are 64-bits or for any 32-bit ports. */
-#define __WORDSIZE_TIME64_COMPAT32
+#define __WORDSIZE_TIME64_COMPAT32 0
--- glibc-2.25/bits/errno.h.bak 2018-11-08 14:32:39.009340807 +0200
+++ glibc-2.25/bits/errno.h 2018-11-08 14:43:21.450954354 +0200
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+/* Error constants. Linux specific version.
+ Copyright (C) 1996-2014 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
@@ -15,20 +16,51 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-/* This file defines the `errno' constants. */
+#ifdef _ERRNO_H
-#if !defined __Emath_defined && (defined _ERRNO_H || defined __need_Emath)
-#undef __need_Emath
-#define __Emath_defined 1
-
-# define EDOM XXX <--- fill in what is actually needed
-# define EILSEQ XXX <--- fill in what is actually needed
-# define ERANGE XXX <--- fill in what is actually needed
-#endif
-
-#ifdef _ERRNO_H
-# error "Define here all the missing error messages for the port. These"
-# error "must match the numbers of the kernel."
-# define Exxxx XXX
-...
-#endif
+# undef EDOM
+# undef EILSEQ
+# undef ERANGE
+# include <linux/errno.h>
+
+/* Linux has no ENOTSUP error code. */
+# define ENOTSUP EOPNOTSUPP
+
+/* Older Linux versions also had no ECANCELED error code. */
+# ifndef ECANCELED
+# define ECANCELED 125
+# endif
+
+/* Support for error codes to support robust mutexes was added later, too. */
+# ifndef EOWNERDEAD
+# define EOWNERDEAD 130
+# define ENOTRECOVERABLE 131
+# endif
+
+# ifndef ERFKILL
+# define ERFKILL 132
+# endif
+
+# ifndef EHWPOISON
+# define EHWPOISON 133
+# endif
+
+# ifndef __ASSEMBLER__
+/* Function to get address of global `errno' variable. */
+extern int *__errno_location (void) __THROW __attribute__ ((__const__));
+
+# if !defined _LIBC || defined _LIBC_REENTRANT
+/* When using threads, errno is a per-thread value. */
+# define errno (*__errno_location ())
+# endif
+# endif /* !__ASSEMBLER__ */
+#endif /* _ERRNO_H */
+
+#if !defined _ERRNO_H && defined __need_Emath
+/* This is ugly but the kernel header is not clean enough. We must
+ define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
+ defined. */
+# define EDOM 33 /* Math argument out of domain of function. */
+# define EILSEQ 84 /* Illegal byte sequence. */
+# define ERANGE 34 /* Math result not representable. */
+#endif /* !_ERRNO_H && __need_Emath */
--- glibc-2.25/bits/endian.h.bak 2018-11-08 15:51:55.110637120 +0200
+++ glibc-2.25/bits/endian.h 2018-11-08 15:52:20.538742585 +0200
@@ -1,13 +1,10 @@
-/* This file should define __BYTE_ORDER as appropriate for the machine
- in question. See string/endian.h for how to define it.
-
- If only the stub bits/endian.h applies to a particular configuration,
- bytesex.h is generated by running a program on the host machine.
- So if cross-compiling to a machine with a different byte order,
- the bits/endian.h file for that machine must exist. */
-
#ifndef _ENDIAN_H
# error "Never use <bits/endian.h> directly; include <endian.h> instead."
#endif
-#error Machine byte order unknown.
+/* ARM can be either big or little endian. */
+#ifdef __ARMEB__
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
......@@ -5,21 +5,21 @@ diff -ur glibc-2.14.1-orig/elf/rtld.c glibc-2.14.1/elf/rtld.c
if (*user_entry == (ElfW(Addr)) ENTRY_POINT)
{
+ const char *forced_argv0 = NULL;
+ char *forced_argv0 = NULL;
/* Ho ho. We are not the program interpreter! We are the program
itself! This means someone ran ld.so as a command. Well, that
might be convenient to do sometimes. We support it by
@@ -994,6 +995,14 @@
_dl_argc -= 2;
INTUSE(_dl_argv) += 2;
_dl_argv += 2;
}
+ else if (! strcmp (INTUSE(_dl_argv)[1], "--argv0") && _dl_argc > 2)
+ else if (! strcmp (_dl_argv[1], "--argv0") && _dl_argc > 2)
+ {
+ forced_argv0 = INTUSE(_dl_argv)[2];
+ forced_argv0 = _dl_argv[2];
+
+ _dl_skip_args += 2;
+ _dl_argc -= 2;
+ INTUSE(_dl_argv) += 2;
+ _dl_argv += 2;
+ }
else
break;
......@@ -40,4 +40,3 @@ diff -ur glibc-2.14.1-orig/elf/rtld.c glibc-2.14.1/elf/rtld.c
+
/* Now the map for the main executable is available. */
main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
......@@ -6,9 +6,9 @@ index 49f070f..621b5a3 100644
/* If the loader has the DF_1_NODEFLIB flag set we must not
use a cache entry from any of these directories. */
- if (__builtin_expect (l->l_flags_1 & DF_1_NODEFLIB, 0))
+ if (__builtin_expect (((l->l_flags_1 & DF_1_NODEFLIB) ||
+ GLRO(dl_no_default_dirs)), 0))
- if (__glibc_unlikely (l->l_flags_1 & DF_1_NODEFLIB))
+ if (__glibc_unlikely (l->l_flags_1 & DF_1_NODEFLIB) ||
+ GLRO(dl_no_default_dirs))
{
const char *dirp = system_dirs;
unsigned int cnt = 0;
......@@ -16,9 +16,9 @@ index 49f070f..621b5a3 100644
/* Finally, try the default path. */
if (fd == -1
&& ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
- || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
+ || __builtin_expect (!((l->l_flags_1 & DF_1_NODEFLIB) ||
+ GLRO(dl_no_default_dirs)), 1))
- || __glibc_likely (!(l->l_flags_1 & DF_1_NODEFLIB)))
+ || __glibc_likely (!(l->l_flags_1 & DF_1_NODEFLIB)) ||
+ GLRO(dl_no_default_dirs))
&& rtld_search_dirs.dirs != (void *) -1)
fd = open_path (name, namelen, mode & __RTLD_SECURE, &rtld_search_dirs,
&realname, &fb, l, LA_SER_DEFAULT, &found_other_class);
......@@ -28,7 +28,7 @@ index 49f070f..621b5a3 100644
/* Finally, try the default path. */
- if (!(loader->l_flags_1 & DF_1_NODEFLIB))
+ if (!((loader->l_flags_1 & DF_1_NODEFLIB) || GLRO(dl_no_default_dirs)))
add_path (&rtld_search_dirs, XXX_default);
add_path (&p, &rtld_search_dirs, XXX_default);
if (counting)
diff --git a/elf/dl-support.c b/elf/dl-support.c
......@@ -51,18 +51,18 @@ index ea3af55..75a2415 100644
+++ b/elf/rtld.c
@@ -976,6 +976,15 @@ dl_main (const ElfW(Phdr) *phdr,
--_dl_argc;
++INTUSE(_dl_argv);
++_dl_argv;
}
+ else if (! strcmp (INTUSE(_dl_argv)[1], "--nodefaultdirs")
+ else if (! strcmp (_dl_argv[1], "--nodefaultdirs")
+ && _dl_argc > 2)
+ {
+ GLRO(dl_no_default_dirs) = 1;
+
+ ++_dl_skip_args;
+ --_dl_argc;
+ ++INTUSE(_dl_argv);
+ ++_dl_argv;
+ }
else if (! strcmp (INTUSE(_dl_argv)[1], "--library-path")
else if (! strcmp (_dl_argv[1], "--library-path")
&& _dl_argc > 2)
{
@@ -1034,6 +1043,7 @@ of this helper program; chances are you did not intend to run this program.\n\
......
......@@ -45,7 +45,7 @@ Index: eglibc-2.19/elf/dl-load.c
+ size_t rpath_prefix_len = 0;
+
+ if (__builtin_expect (rpath_prefix != NULL, 0)
+ && !INTUSE(__libc_enable_secure))
+ && !__libc_enable_secure)
+ {
+ rpath_prefix_len = strlen (rpath_prefix);
+ if (*cp != '/') rpath_prefix_len++; /* need to add a '/' */
......@@ -90,7 +90,7 @@ Index: eglibc-2.19/elf/dl-load.c
@@ -566,7 +601,8 @@ fillin_rpath (char *rpath, struct r_sear
dirp->what = what;
if (__builtin_expect (where != NULL, 1))
if (__glibc_likely (where != NULL))
- dirp->where = memcpy ((char *) dirp + sizeof (*dirp) + len + 1
+ dirp->where = memcpy ((char *) dirp + sizeof (*dirp)
+ + rpath_prefix_len + len + 1
......@@ -109,7 +109,7 @@ Index: eglibc-2.19/elf/dl-load.c
@@ -871,7 +907,7 @@ _dl_init_paths (const char *llp)
(void) fillin_rpath (llp_tmp, env_path_list.dirs, ":;",
INTUSE(__libc_enable_secure), "LD_LIBRARY_PATH",
__libc_enable_secure, "LD_LIBRARY_PATH",
- NULL, l);
+ NULL, l, NULL/*no prefix*/);
......@@ -135,20 +135,20 @@ Index: eglibc-2.19/elf/rtld.c
+++ eglibc-2.19/elf/rtld.c
@@ -991,6 +991,15 @@ dl_main (const ElfW(Phdr) *phdr,
_dl_argc -= 2;
INTUSE(_dl_argv) += 2;
_dl_argv += 2;
}
+ else if (! strcmp (INTUSE(_dl_argv)[1], "--rpath-prefix")
+ else if (! strcmp (_dl_argv[1], "--rpath-prefix")
+ && _dl_argc > 2)
+ {
+ GLRO(dl_rpath_prefix) = INTUSE(_dl_argv)[2];
+ GLRO(dl_rpath_prefix) = _dl_argv[2];
+
+ _dl_skip_args += 2;
+ _dl_argc -= 2;
+ INTUSE(_dl_argv) += 2;
+ _dl_argv += 2;
+ }
else if (! strcmp (INTUSE(_dl_argv)[1], "--audit") && _dl_argc > 2)
else if (! strcmp (_dl_argv[1], "--audit") && _dl_argc > 2)
{
process_dl_audit (INTUSE(_dl_argv)[2]);
process_dl_audit (_dl_argv[2]);
@@ -1025,6 +1034,7 @@ of this helper program; chances are you
--inhibit-cache Do not use " LD_SO_CACHE "\n\
--library-path PATH use given PATH instead of content of the environment\n\
......
diff -ru glibc-2.13/csu/Makefile glibc-2.13-no-timestamping/csu/Makefile
--- glibc-2.13/csu/Makefile 2011-01-18 05:34:07.000000000 +0100
+++ glibc-2.13-no-timestamping/csu/Makefile 2011-08-23 17:07:34.363191368 +0200
@@ -234,8 +234,8 @@
if [ -z "$$os" ]; then \
os=Linux; \
fi; \
- printf '"Compiled on a %s %s system on %s.\\n"\n' \
- "$$os" "$$version" "`date +%Y-%m-%d`";; \
+ printf '"Compiled on OBS, see rpm -q glibc for more information\\n"\n' \
+ ;; \
*) ;; \
esac; \
files="$(all-Banner-files)"; \
Only in glibc-2.13-no-timestamping/csu: Makefile~
diff -ru glibc-2.13/nscd/nscd_stat.c glibc-2.13-no-timestamping/nscd/nscd_stat.c
--- glibc-2.13/nscd/nscd_stat.c 2011-08-24 07:43:18.419464199 +0200
+++ glibc-2.13-no-timestamping/nscd/nscd_stat.c 2011-08-24 07:43:52.837209224 +0200
......
......@@ -37,7 +37,7 @@ diff -ur glibc-2.14.1+p3/nscd/connections.c glibc-2.14.1/nscd/connections.c
{
- dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
+ dbg_log ("%s: %s", sock_addr.sun_path, strerror (errno));
exit (errno == EACCES ? 4 : 1);
do_exit (errno == EACCES ? 4 : 1, 0, NULL);
}
@@ -930,7 +949,7 @@
......
diff -ru eglibc-2.15/nss/nsswitch.c eglibc-2.15-nsswitch/nss/nsswitch.c
--- eglibc-2.15/nss/nsswitch.c 2011-11-17 22:56:08.000000000 +0100
+++ eglibc-2.15-nsswitch/nss/nsswitch.c 2012-02-22 10:38:02.004928523 +0100
@@ -53,6 +53,8 @@
See ../option-groups.def for the details. */
#if __OPTION_EGLIBC_NSSWITCH
@@ -41,6 +41,8 @@
#include "../nscd/nscd_proto.h"
#include <sysdep.h>
+#include <unistd.h> /* __libc_enable_secure */
+
/* Prototypes for the local functions. */
static name_database *nss_parse_file (const char *fname) internal_function;
static name_database_entry *nss_getline (char *line) internal_function;
@@ -141,8 +143,16 @@
#if __OPTION_EGLIBC_NSSWITCH
@@ -121,8 +123,16 @@ __nss_database_lookup (const char *datab
/* Are we initialized yet? */
if (service_table == NULL)
- /* Read config file. */
- service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
+ {
+ const char *ext_nss_config_file = NULL;
+ if (__libc_enable_secure == 0)
+ {
+ ext_nss_config_file = getenv ("NSSWITCH_CONF_PATH");
+ }
+ /* Read config file. */
/* Read config file. */
- service_table = nss_parse_file (_PATH_NSSWITCH_CONF);
+ service_table = nss_parse_file (ext_nss_config_file ?
+ ext_nss_config_file : _PATH_NSSWITCH_CONF);
+ }
#endif
/* Test whether configuration data is available. */
Only in eglibc-2.15-nsswitch/nss: nsswitch.c~
Only in eglibc-2.15-nsswitch/nss: nsswitch.c.orig
Only in eglibc-2.15-nsswitch/nss: nsswitch.c.rej
if (service_table != NULL)
From fe05e1cb6d64dba6172249c79526f1e9af8f2bfd Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Thu, 12 Oct 2017 15:20:57 -0300
Subject: [PATCH] posix: Fix improper assert in Linux posix_spawn (BZ#22273)
As noted by Florian Weimer, current Linux posix_spawn implementation
can trigger an assert if the auxiliary process is terminated before
actually setting the err member:
340 /* Child must set args.err to something non-negative - we rely on
341 the parent and child sharing VM. */
342 args.err = -1;
[...]
362 new_pid = CLONE (__spawni_child, STACK (stack, stack_size), stack_size,
363 CLONE_VM | CLONE_VFORK | SIGCHLD, &args);
364
365 if (new_pid > 0)
366 {
367 ec = args.err;
368 assert (ec >= 0);
Another possible issue is killing the child between setting the err and
actually calling execve. In this case the process will not ran, but
posix_spawn also will not report any error:
269
270 args->err = 0;
271 args->exec (args->file, args->argv, args->envp);
As suggested by Andreas Schwab, this patch removes the faulty assert
and also handles any signal that happens before fork and execve as the
spawn was successful (and thus relaying the handling to the caller to
figure this out). Different than Florian, I can not see why using
atomics to set err would help here, essentially the code runs
sequentially (due CLONE_VFORK) and I think it would not be legal the
compiler evaluate ec without checking for new_pid result (thus there
is no need to compiler barrier).
Summarizing the possible scenarios on posix_spawn execution, we
have:
1. For default case with a success execution, args.err will be 0, pid
will not be collected and it will be reported to caller.
2. For default failure case, args.err will be positive and the it will
be collected by the waitpid. An error will be reported to the
caller.
3. For the unlikely case where the process was terminated and not
collected by a caller signal handler, it will be reported as succeful
execution and not be collected by posix_spawn (since args.err will
be 0). The caller will need to actually handle this case.
4. For the unlikely case where the process was terminated and collected
by caller we have 3 other possible scenarios:
4.1. The auxiliary process was terminated with args.err equal to 0:
it will handled as 1. (so it does not matter if we hit the pid
reuse race since we won't possible collect an unexpected
process).
4.2. The auxiliary process was terminated after execve (due a failure
in calling it) and before setting args.err to -1: it will also
be handle as 1. but with the issue of not be able to report the
caller a possible execve failures.
4.3. The auxiliary process was terminated after args.err is set to -1:
this is the case where it will be possible to hit the pid reuse
case where we will need to collected the auxiliary pid but we
can not be sure if it will be expected one. I think for this
case we need to actually change waitpid to use WNOHANG to avoid
hanging indefinitely on the call and report an error to caller
since we can't differentiate between a default failure as 2.
and a possible pid reuse race issue.
Checked on x86_64-linux-gnu.
* sysdeps/unix/sysv/linux/spawni.c (__spawnix): Handle the case where
the auxiliary process is terminated by a signal before calling _exit
or execve.
diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c
index dea1650..d15fbb1 100644
--- a/sysdeps/unix/sysv/linux/spawni.c
+++ b/sysdeps/unix/sysv/linux/spawni.c
@@ -17,7 +17,6 @@
<http://www.gnu.org/licenses/>. */
#include <spawn.h>
-#include <assert.h>
#include <fcntl.h>
#include <paths.h>
#include <string.h>
@@ -268,7 +267,6 @@ __spawni_child (void *arguments)
__sigprocmask (SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK)
? &attr->__ss : &args->oldmask, 0);
- args->err = 0;
args->exec (args->file, args->argv, args->envp);
/* This is compatibility function required to enable posix_spawn run
@@ -339,7 +337,7 @@ __spawnix (pid_t * pid, const char *file,
/* Child must set args.err to something non-negative - we rely on
the parent and child sharing VM. */
- args.err = -1;
+ args.err = 0;
args.file = file;
args.exec = exec;
args.fa = file_actions;
@@ -362,12 +360,26 @@ __spawnix (pid_t * pid, const char *file,
new_pid = CLONE (__spawni_child, STACK (stack, stack_size), stack_size,
CLONE_VM | CLONE_VFORK | SIGCHLD, &args);
+ /* It needs to collect the case where the auxiliary process was created
+ but failed to execute the file (due either any preparation step or
+ for execve itself). */
if (new_pid > 0)
{
+ /* Also, it handles the unlikely case where the auxiliary process was
+ terminated before calling execve as if it was successfully. The
+ args.err is set to 0 as default and changed to a positive value
+ only in case of failure, so in case of premature termination
+ due a signal args.err will remain zeroed and it will be up to
+ caller to actually collect it. */
ec = args.err;
- assert (ec >= 0);
- if (ec != 0)
- __waitpid (new_pid, NULL, 0);
+ if (ec > 0)
+ /* There still an unlikely case where the child is cancelled after
+ setting args.err, due to a positive error value. Also due a
+ possible pid reuse race (where the kernel allocated the same pid
+ to unrelated process) we need not to undefinitely hang expecting
+ an invalid pid. In both cases an error is returned to the
+ caller. */
+ __waitpid (new_pid, NULL, WNOHANG);
}
else
ec = -new_pid;
--
2.9.3
* Mon Nov 12 2018 Marko Kenttälä <marko.kenttala@jolla.com> - 2.25.1
- Upgrade to glibc-2.25, fixes jb#36174
* Tue Oct 3 2017 Pekka Vuorela <pekka.vuorela@jolla.com> - 2.19+6.13.1
- Add ldconfig to %post. Fixes JB#39841
- Move docs out of main package.
......@@ -241,4 +244,3 @@
* Tue Aug 19 2008 Anas Nashif <anas.nashif@intel.com> - 2.8
- exclude i586 from aux arches
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment