mirror of
https://github.com/void-linux/void-packages.git
synced 2025-04-26 19:13:51 +02:00
glibc: update patches
Signed-off-by: Jürgen Buchmüller <pullmoll@t-online.de>
This commit is contained in:
parent
f9590020d9
commit
12d24f1120
13 changed files with 2253 additions and 1 deletions
|
@ -50,3 +50,4 @@ index 1fd2fee44b..9bfbb2bb9b 100644
|
|||
"+:6:1873//01//01:1912//07//29:<U660E><U6CBB>:%EC%Ey<U5E74>";/
|
||||
"+:1:0001//01//01:1872//12//31:<U897F><U66A6>:%EC%Ey<U5E74>";/
|
||||
"+:1:-0001//12//31:-*:<U7D00><U5143><U524D>:%EC%Ey<U5E74>"
|
||||
|
||||
|
|
66
srcpkgs/glibc/patches/glibc-upstream-12.patch
Normal file
66
srcpkgs/glibc/patches/glibc-upstream-12.patch
Normal file
|
@ -0,0 +1,66 @@
|
|||
From 0941350c20a52447e53c5169354408e3db591f73 Mon Sep 17 00:00:00 2001
|
||||
From: TAMUKI Shoichi <tamuki@linet.gr.jp>
|
||||
Date: Tue, 2 Apr 2019 16:46:55 +0900
|
||||
Subject: [PATCH 12] ja_JP locale: Add entry for the new Japanese era [BZ
|
||||
#22964]
|
||||
|
||||
The Japanese era name will be changed on May 1, 2019. The Japanese
|
||||
government made a preliminary announcement on April 1, 2019.
|
||||
|
||||
The glibc ja_JP locale must be updated to include the new era name for
|
||||
strftime's alternative year format support.
|
||||
|
||||
This is a minimal cherry pick of just the required locale changes.
|
||||
|
||||
(cherry picked from commit 466afec30896585b60c2106df7a722a86247c9f3)
|
||||
---
|
||||
ChangeLog | 6 ++++++
|
||||
NEWS | 4 ++++
|
||||
localedata/locales/ja_JP | 4 +++-
|
||||
3 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 048ca9644c..3b5d24cf67 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,9 @@
|
||||
+2019-04-02 TAMUKI Shoichi <tamuki@linet.gr.jp>
|
||||
+
|
||||
+ [BZ #22964]
|
||||
+ * localedata/locales/ja_JP (LC_TIME): Add entry for the new Japanese
|
||||
+ era.
|
||||
+
|
||||
2019-03-02 TAMUKI Shoichi <tamuki@linet.gr.jp>
|
||||
|
||||
[BZ #24162]
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 271bf7a2cd..703864ac75 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -7,6 +7,10 @@ using `glibc' in the "product" field.
|
||||
|
||||
Version 2.29.1
|
||||
|
||||
+Major new features:
|
||||
+
|
||||
+* The entry for the new Japanese era has been added for ja_JP locale.
|
||||
+
|
||||
The following bugs are resolved with this release:
|
||||
|
||||
[24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309)
|
||||
diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP
|
||||
index 9bfbb2bb9b..c64aaaff55 100644
|
||||
--- a/localedata/locales/ja_JP
|
||||
+++ b/localedata/locales/ja_JP
|
||||
@@ -14946,7 +14946,9 @@ am_pm "<U5348><U524D>";"<U5348><U5F8C>"
|
||||
|
||||
t_fmt_ampm "%p%I<U6642>%M<U5206>%S<U79D2>"
|
||||
|
||||
-era "+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
|
||||
+era "+:2:2020//01//01:+*:<U4EE4><U548C>:%EC%Ey<U5E74>";/
|
||||
+ "+:1:2019//05//01:2019//12//31:<U4EE4><U548C>:%EC<U5143><U5E74>";/
|
||||
+ "+:2:1990//01//01:2019//04//30:<U5E73><U6210>:%EC%Ey<U5E74>";/
|
||||
"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
|
||||
"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
|
||||
"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
|
||||
|
206
srcpkgs/glibc/patches/glibc-upstream-13.patch
Normal file
206
srcpkgs/glibc/patches/glibc-upstream-13.patch
Normal file
|
@ -0,0 +1,206 @@
|
|||
From dcd2b97dd1d695445d45beb4daa815cfe06691dd Mon Sep 17 00:00:00 2001
|
||||
From: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Mon, 15 Apr 2019 20:49:32 +0200
|
||||
Subject: [PATCH 13] malloc: Set and reset all hooks for tracing (Bug 16573)
|
||||
|
||||
If an error occurs during the tracing operation, particularly during a
|
||||
call to lock_and_info() which calls _dl_addr, we may end up calling back
|
||||
into the malloc-subsystem and relock the loader lock and deadlock. For
|
||||
all intents and purposes the call to _dl_addr can call any of the malloc
|
||||
family API functions and so we should disable all tracing before calling
|
||||
such loader functions. This is similar to the strategy that the new
|
||||
malloc tracer takes when calling the real malloc, namely that all
|
||||
tracing ceases at the boundary to the real function and any faults at
|
||||
that point are the purvue of the library (though the new tracer does
|
||||
this on a per-thread basis in an MT-safe fashion). Since the new tracer
|
||||
and the hook deprecation are not yet complete we must fix these issues
|
||||
where we can.
|
||||
|
||||
Tested on x86_64 with no regressions.
|
||||
|
||||
Co-authored-by: Kwok Cheung Yeung <kcy@codesourcery.com>
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
(cherry picked from commit e621246ec6393ea08ae50310f9d5e72500f8c9bc)
|
||||
---
|
||||
ChangeLog | 15 +++++++++++
|
||||
NEWS | 1 +
|
||||
malloc/mtrace.c | 72 +++++++++++++++++++++++++++++++------------------
|
||||
3 files changed, 62 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 3b5d24cf67..077d0dae29 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,18 @@
|
||||
+2019-04-09 Carlos O'Donell <carlos@redhat.com>
|
||||
+ Kwok Cheung Yeung <kcy@codesourcery.com>
|
||||
+
|
||||
+ [BZ #16573]
|
||||
+ * malloc/mtrace.c: Define prototypes for all hooks.
|
||||
+ (set_default_hooks): New function.
|
||||
+ (set_trace_hooks): Likewise.
|
||||
+ (save_default_hooks): Likewise.
|
||||
+ (tr_freehook): Use new s*_hooks functions.
|
||||
+ (tr_mallochook): Likewise.
|
||||
+ (tr_reallochook): Likewise.
|
||||
+ (tr_memalignhook): Likewise.
|
||||
+ (mtrace): Likewise.
|
||||
+ (muntrace): Likewise.
|
||||
+
|
||||
2019-04-02 TAMUKI Shoichi <tamuki@linet.gr.jp>
|
||||
|
||||
[BZ #22964]
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 703864ac75..117646df7b 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -13,6 +13,7 @@ Major new features:
|
||||
|
||||
The following bugs are resolved with this release:
|
||||
|
||||
+ [16573] malloc: Set and reset all hooks for tracing
|
||||
[24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309)
|
||||
[24164] Systemtap probes need to use "nr" constraint on 32-bit Arm
|
||||
[24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2
|
||||
diff --git a/malloc/mtrace.c b/malloc/mtrace.c
|
||||
index a2facf65ea..2fda262508 100644
|
||||
--- a/malloc/mtrace.c
|
||||
+++ b/malloc/mtrace.c
|
||||
@@ -121,6 +121,41 @@ lock_and_info (const void *caller, Dl_info *mem)
|
||||
return res;
|
||||
}
|
||||
|
||||
+static void tr_freehook (void *, const void *);
|
||||
+static void * tr_mallochook (size_t, const void *);
|
||||
+static void * tr_reallochook (void *, size_t, const void *);
|
||||
+static void * tr_memalignhook (size_t, size_t, const void *);
|
||||
+
|
||||
+/* Set all the default non-trace hooks. */
|
||||
+static __always_inline void
|
||||
+set_default_hooks (void)
|
||||
+{
|
||||
+ __free_hook = tr_old_free_hook;
|
||||
+ __malloc_hook = tr_old_malloc_hook;
|
||||
+ __realloc_hook = tr_old_realloc_hook;
|
||||
+ __memalign_hook = tr_old_memalign_hook;
|
||||
+}
|
||||
+
|
||||
+/* Set all of the tracing hooks used for mtrace. */
|
||||
+static __always_inline void
|
||||
+set_trace_hooks (void)
|
||||
+{
|
||||
+ __free_hook = tr_freehook;
|
||||
+ __malloc_hook = tr_mallochook;
|
||||
+ __realloc_hook = tr_reallochook;
|
||||
+ __memalign_hook = tr_memalignhook;
|
||||
+}
|
||||
+
|
||||
+/* Save the current set of hooks as the default hooks. */
|
||||
+static __always_inline void
|
||||
+save_default_hooks (void)
|
||||
+{
|
||||
+ tr_old_free_hook = __free_hook;
|
||||
+ tr_old_malloc_hook = __malloc_hook;
|
||||
+ tr_old_realloc_hook = __realloc_hook;
|
||||
+ tr_old_memalign_hook = __memalign_hook;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
tr_freehook (void *ptr, const void *caller)
|
||||
{
|
||||
@@ -138,12 +173,12 @@ tr_freehook (void *ptr, const void *caller)
|
||||
tr_break ();
|
||||
__libc_lock_lock (lock);
|
||||
}
|
||||
- __free_hook = tr_old_free_hook;
|
||||
+ set_default_hooks ();
|
||||
if (tr_old_free_hook != NULL)
|
||||
(*tr_old_free_hook)(ptr, caller);
|
||||
else
|
||||
free (ptr);
|
||||
- __free_hook = tr_freehook;
|
||||
+ set_trace_hooks ();
|
||||
__libc_lock_unlock (lock);
|
||||
}
|
||||
|
||||
@@ -155,12 +190,12 @@ tr_mallochook (size_t size, const void *caller)
|
||||
Dl_info mem;
|
||||
Dl_info *info = lock_and_info (caller, &mem);
|
||||
|
||||
- __malloc_hook = tr_old_malloc_hook;
|
||||
+ set_default_hooks ();
|
||||
if (tr_old_malloc_hook != NULL)
|
||||
hdr = (void *) (*tr_old_malloc_hook)(size, caller);
|
||||
else
|
||||
hdr = (void *) malloc (size);
|
||||
- __malloc_hook = tr_mallochook;
|
||||
+ set_trace_hooks ();
|
||||
|
||||
tr_where (caller, info);
|
||||
/* We could be printing a NULL here; that's OK. */
|
||||
@@ -185,16 +220,12 @@ tr_reallochook (void *ptr, size_t size, const void *caller)
|
||||
Dl_info mem;
|
||||
Dl_info *info = lock_and_info (caller, &mem);
|
||||
|
||||
- __free_hook = tr_old_free_hook;
|
||||
- __malloc_hook = tr_old_malloc_hook;
|
||||
- __realloc_hook = tr_old_realloc_hook;
|
||||
+ set_default_hooks ();
|
||||
if (tr_old_realloc_hook != NULL)
|
||||
hdr = (void *) (*tr_old_realloc_hook)(ptr, size, caller);
|
||||
else
|
||||
hdr = (void *) realloc (ptr, size);
|
||||
- __free_hook = tr_freehook;
|
||||
- __malloc_hook = tr_mallochook;
|
||||
- __realloc_hook = tr_reallochook;
|
||||
+ set_trace_hooks ();
|
||||
|
||||
tr_where (caller, info);
|
||||
if (hdr == NULL)
|
||||
@@ -230,14 +261,12 @@ tr_memalignhook (size_t alignment, size_t size, const void *caller)
|
||||
Dl_info mem;
|
||||
Dl_info *info = lock_and_info (caller, &mem);
|
||||
|
||||
- __memalign_hook = tr_old_memalign_hook;
|
||||
- __malloc_hook = tr_old_malloc_hook;
|
||||
+ set_default_hooks ();
|
||||
if (tr_old_memalign_hook != NULL)
|
||||
hdr = (void *) (*tr_old_memalign_hook)(alignment, size, caller);
|
||||
else
|
||||
hdr = (void *) memalign (alignment, size);
|
||||
- __memalign_hook = tr_memalignhook;
|
||||
- __malloc_hook = tr_mallochook;
|
||||
+ set_trace_hooks ();
|
||||
|
||||
tr_where (caller, info);
|
||||
/* We could be printing a NULL here; that's OK. */
|
||||
@@ -305,14 +334,8 @@ mtrace (void)
|
||||
malloc_trace_buffer = mtb;
|
||||
setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
|
||||
fprintf (mallstream, "= Start\n");
|
||||
- tr_old_free_hook = __free_hook;
|
||||
- __free_hook = tr_freehook;
|
||||
- tr_old_malloc_hook = __malloc_hook;
|
||||
- __malloc_hook = tr_mallochook;
|
||||
- tr_old_realloc_hook = __realloc_hook;
|
||||
- __realloc_hook = tr_reallochook;
|
||||
- tr_old_memalign_hook = __memalign_hook;
|
||||
- __memalign_hook = tr_memalignhook;
|
||||
+ save_default_hooks ();
|
||||
+ set_trace_hooks ();
|
||||
#ifdef _LIBC
|
||||
if (!added_atexit_handler)
|
||||
{
|
||||
@@ -338,10 +361,7 @@ muntrace (void)
|
||||
file. */
|
||||
FILE *f = mallstream;
|
||||
mallstream = NULL;
|
||||
- __free_hook = tr_old_free_hook;
|
||||
- __malloc_hook = tr_old_malloc_hook;
|
||||
- __realloc_hook = tr_old_realloc_hook;
|
||||
- __memalign_hook = tr_old_memalign_hook;
|
||||
+ set_default_hooks ();
|
||||
|
||||
fprintf (f, "= End\n");
|
||||
fclose (f);
|
||||
|
69
srcpkgs/glibc/patches/glibc-upstream-14.patch
Normal file
69
srcpkgs/glibc/patches/glibc-upstream-14.patch
Normal file
|
@ -0,0 +1,69 @@
|
|||
From 42dfc13abf6fbb4c7a0215238eb636b7d374e0e0 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Frysinger <vapier@gentoo.org>
|
||||
Date: Wed, 24 Apr 2019 19:07:46 +0200
|
||||
Subject: [PATCH 14] memusagestat: use local glibc when linking [BZ #18465]
|
||||
|
||||
The memusagestat is the only binary that has its own link line which
|
||||
causes it to be linked against the existing installed C library. It
|
||||
has been this way since it was originally committed in 1999, but I
|
||||
don't see any reason as to why. Since we want all the programs we
|
||||
build locally to be against the new copy of glibc, change the build
|
||||
to be like all other programs.
|
||||
|
||||
(cherry picked from commit f9b645b4b0a10c43753296ce3fa40053fa44606a)
|
||||
---
|
||||
ChangeLog | 7 +++++++
|
||||
NEWS | 1 +
|
||||
malloc/Makefile | 4 ++--
|
||||
3 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 077d0dae29..5291a88f85 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,10 @@
|
||||
+2019-04-24 Mike Frysinger <vapier@gentoo.org>
|
||||
+
|
||||
+ [BZ #18465]
|
||||
+ * malloc/Makefile (others): Add memusagestat.
|
||||
+ ($(objpfx)memusagestat): Delete rule.
|
||||
+ (LDLIBS-memusagestat): New variable.
|
||||
+
|
||||
2019-04-09 Carlos O'Donell <carlos@redhat.com>
|
||||
Kwok Cheung Yeung <kcy@codesourcery.com>
|
||||
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 117646df7b..07e099b5ec 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -14,6 +14,7 @@ Major new features:
|
||||
The following bugs are resolved with this release:
|
||||
|
||||
[16573] malloc: Set and reset all hooks for tracing
|
||||
+ [18465] memusagestat: use local glibc when linking
|
||||
[24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309)
|
||||
[24164] Systemtap probes need to use "nr" constraint on 32-bit Arm
|
||||
[24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2
|
||||
diff --git a/malloc/Makefile b/malloc/Makefile
|
||||
index ab2eed09c6..aadf602dfd 100644
|
||||
--- a/malloc/Makefile
|
||||
+++ b/malloc/Makefile
|
||||
@@ -131,6 +131,7 @@ ifneq ($(cross-compiling),yes)
|
||||
# If the gd library is available we build the `memusagestat' program.
|
||||
ifneq ($(LIBGD),no)
|
||||
others: $(objpfx)memusage
|
||||
+others += memusagestat
|
||||
install-bin = memusagestat
|
||||
install-bin-script += memusage
|
||||
generated += memusagestat memusage
|
||||
@@ -154,8 +155,7 @@ cpp-srcs-left := $(memusagestat-modules)
|
||||
lib := memusagestat
|
||||
include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
|
||||
|
||||
-$(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o)
|
||||
- $(LINK.o) -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm
|
||||
+LDLIBS-memusagestat = $(libgd-LDFLAGS) -lgd -lpng -lz -lm
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
ifeq (yes,$(build-shared))
|
||||
|
67
srcpkgs/glibc/patches/glibc-upstream-15.patch
Normal file
67
srcpkgs/glibc/patches/glibc-upstream-15.patch
Normal file
|
@ -0,0 +1,67 @@
|
|||
From 0744a268bc73e42b14b83e4cf3d083c6df6344e8 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu, 25 Apr 2019 14:58:13 +0200
|
||||
Subject: [PATCH 15] Revert "memusagestat: use local glibc when linking [BZ
|
||||
#18465]"
|
||||
|
||||
This reverts commit 42dfc13abf6fbb4c7a0215238eb636b7d374e0e0.
|
||||
|
||||
The position of the -Wl,-rpath-link= options on the linker command
|
||||
line is not correct, so the new way of linking memusagestat does not
|
||||
always work.
|
||||
---
|
||||
ChangeLog | 7 -------
|
||||
NEWS | 1 -
|
||||
malloc/Makefile | 4 ++--
|
||||
3 files changed, 2 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 5291a88f85..077d0dae29 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,10 +1,3 @@
|
||||
-2019-04-24 Mike Frysinger <vapier@gentoo.org>
|
||||
-
|
||||
- [BZ #18465]
|
||||
- * malloc/Makefile (others): Add memusagestat.
|
||||
- ($(objpfx)memusagestat): Delete rule.
|
||||
- (LDLIBS-memusagestat): New variable.
|
||||
-
|
||||
2019-04-09 Carlos O'Donell <carlos@redhat.com>
|
||||
Kwok Cheung Yeung <kcy@codesourcery.com>
|
||||
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 07e099b5ec..117646df7b 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -14,7 +14,6 @@ Major new features:
|
||||
The following bugs are resolved with this release:
|
||||
|
||||
[16573] malloc: Set and reset all hooks for tracing
|
||||
- [18465] memusagestat: use local glibc when linking
|
||||
[24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309)
|
||||
[24164] Systemtap probes need to use "nr" constraint on 32-bit Arm
|
||||
[24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2
|
||||
diff --git a/malloc/Makefile b/malloc/Makefile
|
||||
index aadf602dfd..ab2eed09c6 100644
|
||||
--- a/malloc/Makefile
|
||||
+++ b/malloc/Makefile
|
||||
@@ -131,7 +131,6 @@ ifneq ($(cross-compiling),yes)
|
||||
# If the gd library is available we build the `memusagestat' program.
|
||||
ifneq ($(LIBGD),no)
|
||||
others: $(objpfx)memusage
|
||||
-others += memusagestat
|
||||
install-bin = memusagestat
|
||||
install-bin-script += memusage
|
||||
generated += memusagestat memusage
|
||||
@@ -155,7 +154,8 @@ cpp-srcs-left := $(memusagestat-modules)
|
||||
lib := memusagestat
|
||||
include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
|
||||
|
||||
-LDLIBS-memusagestat = $(libgd-LDFLAGS) -lgd -lpng -lz -lm
|
||||
+$(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o)
|
||||
+ $(LINK.o) -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
ifeq (yes,$(build-shared))
|
||||
|
852
srcpkgs/glibc/patches/glibc-upstream-16.patch
Normal file
852
srcpkgs/glibc/patches/glibc-upstream-16.patch
Normal file
|
@ -0,0 +1,852 @@
|
|||
From f62d21a1f0107e6f7182f346293583c9121a877d Mon Sep 17 00:00:00 2001
|
||||
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Fri, 12 Apr 2019 17:39:53 -0300
|
||||
Subject: [PATCH 16] support: Add support_capture_subprogram
|
||||
|
||||
Its API is similar to support_capture_subprocess, but rather creates a
|
||||
new process based on the input path and arguments. Under the hoods it
|
||||
uses posix_spawn to create the new process.
|
||||
|
||||
It also allows the use of other support_capture_* functions to check
|
||||
for expected results and free the resources.
|
||||
|
||||
Checked on x86_64-linux-gnu.
|
||||
|
||||
* support/Makefile (libsupport-routines): Add support_subprocess,
|
||||
xposix_spawn, xposix_spawn_file_actions_addclose, and
|
||||
xposix_spawn_file_actions_adddup2.
|
||||
(tst-support_capture_subprocess-ARGS): New rule.
|
||||
* support/capture_subprocess.h (support_capture_subprogram): New
|
||||
prototype.
|
||||
* support/support_capture_subprocess.c (support_capture_subprocess):
|
||||
Refactor to use support_subprocess and support_capture_poll.
|
||||
(support_capture_subprogram): New function.
|
||||
* support/tst-support_capture_subprocess.c (write_mode_to_str,
|
||||
str_to_write_mode, test_common, parse_int, handle_restart,
|
||||
do_subprocess, do_subprogram, do_multiple_tests): New functions.
|
||||
(do_test): Add support_capture_subprogram tests.
|
||||
* support/subprocess.h: New file.
|
||||
* support/support_subprocess.c: Likewise.
|
||||
* support/xposix_spawn.c: Likewise.
|
||||
* support/xposix_spawn_file_actions_addclose.c: Likewise.
|
||||
* support/xposix_spawn_file_actions_adddup2.c: Likewise.
|
||||
* support/xspawn.h: Likewise.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit 0e169691290a6d2187a4ff41495fc5678cbfdcdc)
|
||||
---
|
||||
ChangeLog | 22 +++
|
||||
support/Makefile | 6 +
|
||||
support/capture_subprocess.h | 6 +
|
||||
support/subprocess.h | 49 +++++
|
||||
support/support_capture_subprocess.c | 80 ++++----
|
||||
support/support_subprocess.c | 152 +++++++++++++++
|
||||
support/tst-support_capture_subprocess.c | 183 ++++++++++++++++++-
|
||||
support/xposix_spawn.c | 32 ++++
|
||||
support/xposix_spawn_file_actions_addclose.c | 29 +++
|
||||
support/xposix_spawn_file_actions_adddup2.c | 30 +++
|
||||
support/xspawn.h | 34 ++++
|
||||
11 files changed, 573 insertions(+), 50 deletions(-)
|
||||
create mode 100644 support/subprocess.h
|
||||
create mode 100644 support/support_subprocess.c
|
||||
create mode 100644 support/xposix_spawn.c
|
||||
create mode 100644 support/xposix_spawn_file_actions_addclose.c
|
||||
create mode 100644 support/xposix_spawn_file_actions_adddup2.c
|
||||
create mode 100644 support/xspawn.h
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 077d0dae29..2524e25697 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,25 @@
|
||||
+2019-04-17 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
+
|
||||
+ * support/Makefile (libsupport-routines): Add support_subprocess,
|
||||
+ xposix_spawn, xposix_spawn_file_actions_addclose, and
|
||||
+ xposix_spawn_file_actions_adddup2.
|
||||
+ (tst-support_capture_subprocess-ARGS): New rule.
|
||||
+ * support/capture_subprocess.h (support_capture_subprogram): New
|
||||
+ prototype.
|
||||
+ * support/support_capture_subprocess.c (support_capture_subprocess):
|
||||
+ Refactor to use support_subprocess and support_capture_poll.
|
||||
+ (support_capture_subprogram): New function.
|
||||
+ * support/tst-support_capture_subprocess.c (write_mode_to_str,
|
||||
+ str_to_write_mode, test_common, parse_int, handle_restart,
|
||||
+ do_subprocess, do_subprogram, do_multiple_tests): New functions.
|
||||
+ (do_test): Add support_capture_subprogram tests.
|
||||
+ * support/subprocess.h: New file.
|
||||
+ * support/support_subprocess.c: Likewise.
|
||||
+ * support/xposix_spawn.c: Likewise.
|
||||
+ * support/xposix_spawn_file_actions_addclose.c: Likewise.
|
||||
+ * support/xposix_spawn_file_actions_adddup2.c: Likewise.
|
||||
+ * support/xspawn.h: Likewise.
|
||||
+
|
||||
2019-04-09 Carlos O'Donell <carlos@redhat.com>
|
||||
Kwok Cheung Yeung <kcy@codesourcery.com>
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index c15b93647c..8d61de6c57 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -63,6 +63,7 @@ libsupport-routines = \
|
||||
support_record_failure \
|
||||
support_run_diff \
|
||||
support_shared_allocate \
|
||||
+ support_subprocess \
|
||||
support_test_compare_blob \
|
||||
support_test_compare_failure \
|
||||
support_test_compare_string \
|
||||
@@ -148,6 +149,9 @@ libsupport-routines = \
|
||||
xsignal \
|
||||
xsigstack \
|
||||
xsocket \
|
||||
+ xposix_spawn \
|
||||
+ xposix_spawn_file_actions_addclose \
|
||||
+ xposix_spawn_file_actions_adddup2 \
|
||||
xstrdup \
|
||||
xstrndup \
|
||||
xsymlink \
|
||||
@@ -223,4 +227,6 @@ endif
|
||||
|
||||
$(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so
|
||||
|
||||
+tst-support_capture_subprocess-ARGS = -- $(host-test-program-cmd)
|
||||
+
|
||||
include ../Rules
|
||||
diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h
|
||||
index 2dce42e3a3..2832cfc635 100644
|
||||
--- a/support/capture_subprocess.h
|
||||
+++ b/support/capture_subprocess.h
|
||||
@@ -35,6 +35,12 @@ struct support_capture_subprocess
|
||||
struct support_capture_subprocess support_capture_subprocess
|
||||
(void (*callback) (void *), void *closure);
|
||||
|
||||
+/* Issue FILE with ARGV arguments by using posix_spawn and capture standard
|
||||
+ output, standard error, and the exit status. The out.buffer and err.buffer
|
||||
+ are handle as support_capture_subprocess. */
|
||||
+struct support_capture_subprocess support_capture_subprogram
|
||||
+ (const char *file, char *const argv[]);
|
||||
+
|
||||
/* Deallocate the subprocess data captured by
|
||||
support_capture_subprocess. */
|
||||
void support_capture_subprocess_free (struct support_capture_subprocess *);
|
||||
diff --git a/support/subprocess.h b/support/subprocess.h
|
||||
new file mode 100644
|
||||
index 0000000000..c031878d94
|
||||
--- /dev/null
|
||||
+++ b/support/subprocess.h
|
||||
@@ -0,0 +1,49 @@
|
||||
+/* Create a subprocess.
|
||||
+ 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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#ifndef SUPPORT_SUBPROCESS_H
|
||||
+#define SUPPORT_SUBPROCESS_H
|
||||
+
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
+struct support_subprocess
|
||||
+{
|
||||
+ int stdout_pipe[2];
|
||||
+ int stderr_pipe[2];
|
||||
+ pid_t pid;
|
||||
+};
|
||||
+
|
||||
+/* Invoke CALLBACK (CLOSURE) in a subprocess created with fork and return
|
||||
+ its PID, a pipe redirected to STDOUT, and a pipe redirected to STDERR. */
|
||||
+struct support_subprocess support_subprocess
|
||||
+ (void (*callback) (void *), void *closure);
|
||||
+
|
||||
+/* Issue FILE with ARGV arguments by using posix_spawn and return is PID, a
|
||||
+ pipe redirected to STDOUT, and a pipe redirected to STDERR. */
|
||||
+struct support_subprocess support_subprogram
|
||||
+ (const char *file, char *const argv[]);
|
||||
+
|
||||
+/* Wait for the subprocess indicated by PROC::PID. Return the status
|
||||
+ indicate by waitpid call. */
|
||||
+int support_process_wait (struct support_subprocess *proc);
|
||||
+
|
||||
+/* Terminate the subprocess indicated by PROC::PID, first with a SIGTERM and
|
||||
+ then with a SIGKILL. Return the status as for waitpid call. */
|
||||
+int support_process_terminate (struct support_subprocess *proc);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
|
||||
index 167514faf1..948ce5a0c6 100644
|
||||
--- a/support/support_capture_subprocess.c
|
||||
+++ b/support/support_capture_subprocess.c
|
||||
@@ -16,6 +16,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <support/subprocess.h>
|
||||
#include <support/capture_subprocess.h>
|
||||
|
||||
#include <errno.h>
|
||||
@@ -23,6 +24,7 @@
|
||||
#include <support/check.h>
|
||||
#include <support/xunistd.h>
|
||||
#include <support/xsocket.h>
|
||||
+#include <support/xspawn.h>
|
||||
|
||||
static void
|
||||
transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream)
|
||||
@@ -50,59 +52,53 @@ transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream)
|
||||
}
|
||||
}
|
||||
|
||||
-struct support_capture_subprocess
|
||||
-support_capture_subprocess (void (*callback) (void *), void *closure)
|
||||
+static void
|
||||
+support_capture_poll (struct support_capture_subprocess *result,
|
||||
+ struct support_subprocess *proc)
|
||||
{
|
||||
- struct support_capture_subprocess result;
|
||||
- xopen_memstream (&result.out);
|
||||
- xopen_memstream (&result.err);
|
||||
-
|
||||
- int stdout_pipe[2];
|
||||
- xpipe (stdout_pipe);
|
||||
- TEST_VERIFY (stdout_pipe[0] > STDERR_FILENO);
|
||||
- TEST_VERIFY (stdout_pipe[1] > STDERR_FILENO);
|
||||
- int stderr_pipe[2];
|
||||
- xpipe (stderr_pipe);
|
||||
- TEST_VERIFY (stderr_pipe[0] > STDERR_FILENO);
|
||||
- TEST_VERIFY (stderr_pipe[1] > STDERR_FILENO);
|
||||
-
|
||||
- TEST_VERIFY (fflush (stdout) == 0);
|
||||
- TEST_VERIFY (fflush (stderr) == 0);
|
||||
-
|
||||
- pid_t pid = xfork ();
|
||||
- if (pid == 0)
|
||||
- {
|
||||
- xclose (stdout_pipe[0]);
|
||||
- xclose (stderr_pipe[0]);
|
||||
- xdup2 (stdout_pipe[1], STDOUT_FILENO);
|
||||
- xdup2 (stderr_pipe[1], STDERR_FILENO);
|
||||
- xclose (stdout_pipe[1]);
|
||||
- xclose (stderr_pipe[1]);
|
||||
- callback (closure);
|
||||
- _exit (0);
|
||||
- }
|
||||
- xclose (stdout_pipe[1]);
|
||||
- xclose (stderr_pipe[1]);
|
||||
-
|
||||
struct pollfd fds[2] =
|
||||
{
|
||||
- { .fd = stdout_pipe[0], .events = POLLIN },
|
||||
- { .fd = stderr_pipe[0], .events = POLLIN },
|
||||
+ { .fd = proc->stdout_pipe[0], .events = POLLIN },
|
||||
+ { .fd = proc->stderr_pipe[0], .events = POLLIN },
|
||||
};
|
||||
|
||||
do
|
||||
{
|
||||
xpoll (fds, 2, -1);
|
||||
- transfer ("stdout", &fds[0], &result.out);
|
||||
- transfer ("stderr", &fds[1], &result.err);
|
||||
+ transfer ("stdout", &fds[0], &result->out);
|
||||
+ transfer ("stderr", &fds[1], &result->err);
|
||||
}
|
||||
while (fds[0].events != 0 || fds[1].events != 0);
|
||||
- xclose (stdout_pipe[0]);
|
||||
- xclose (stderr_pipe[0]);
|
||||
|
||||
- xfclose_memstream (&result.out);
|
||||
- xfclose_memstream (&result.err);
|
||||
- xwaitpid (pid, &result.status, 0);
|
||||
+ xfclose_memstream (&result->out);
|
||||
+ xfclose_memstream (&result->err);
|
||||
+
|
||||
+ result->status = support_process_wait (proc);
|
||||
+}
|
||||
+
|
||||
+struct support_capture_subprocess
|
||||
+support_capture_subprocess (void (*callback) (void *), void *closure)
|
||||
+{
|
||||
+ struct support_capture_subprocess result;
|
||||
+ xopen_memstream (&result.out);
|
||||
+ xopen_memstream (&result.err);
|
||||
+
|
||||
+ struct support_subprocess proc = support_subprocess (callback, closure);
|
||||
+
|
||||
+ support_capture_poll (&result, &proc);
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+struct support_capture_subprocess
|
||||
+support_capture_subprogram (const char *file, char *const argv[])
|
||||
+{
|
||||
+ struct support_capture_subprocess result;
|
||||
+ xopen_memstream (&result.out);
|
||||
+ xopen_memstream (&result.err);
|
||||
+
|
||||
+ struct support_subprocess proc = support_subprogram (file, argv);
|
||||
+
|
||||
+ support_capture_poll (&result, &proc);
|
||||
return result;
|
||||
}
|
||||
|
||||
diff --git a/support/support_subprocess.c b/support/support_subprocess.c
|
||||
new file mode 100644
|
||||
index 0000000000..0c8cc6af30
|
||||
--- /dev/null
|
||||
+++ b/support/support_subprocess.c
|
||||
@@ -0,0 +1,152 @@
|
||||
+/* Create subprocess.
|
||||
+ 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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <signal.h>
|
||||
+#include <time.h>
|
||||
+#include <sys/wait.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <support/xspawn.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/xunistd.h>
|
||||
+#include <support/subprocess.h>
|
||||
+
|
||||
+static struct support_subprocess
|
||||
+support_suprocess_init (void)
|
||||
+{
|
||||
+ struct support_subprocess result;
|
||||
+
|
||||
+ xpipe (result.stdout_pipe);
|
||||
+ TEST_VERIFY (result.stdout_pipe[0] > STDERR_FILENO);
|
||||
+ TEST_VERIFY (result.stdout_pipe[1] > STDERR_FILENO);
|
||||
+
|
||||
+ xpipe (result.stderr_pipe);
|
||||
+ TEST_VERIFY (result.stderr_pipe[0] > STDERR_FILENO);
|
||||
+ TEST_VERIFY (result.stderr_pipe[1] > STDERR_FILENO);
|
||||
+
|
||||
+ TEST_VERIFY (fflush (stdout) == 0);
|
||||
+ TEST_VERIFY (fflush (stderr) == 0);
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+struct support_subprocess
|
||||
+support_subprocess (void (*callback) (void *), void *closure)
|
||||
+{
|
||||
+ struct support_subprocess result = support_suprocess_init ();
|
||||
+
|
||||
+ result.pid = xfork ();
|
||||
+ if (result.pid == 0)
|
||||
+ {
|
||||
+ xclose (result.stdout_pipe[0]);
|
||||
+ xclose (result.stderr_pipe[0]);
|
||||
+ xdup2 (result.stdout_pipe[1], STDOUT_FILENO);
|
||||
+ xdup2 (result.stderr_pipe[1], STDERR_FILENO);
|
||||
+ xclose (result.stdout_pipe[1]);
|
||||
+ xclose (result.stderr_pipe[1]);
|
||||
+ callback (closure);
|
||||
+ _exit (0);
|
||||
+ }
|
||||
+ xclose (result.stdout_pipe[1]);
|
||||
+ xclose (result.stderr_pipe[1]);
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+struct support_subprocess
|
||||
+support_subprogram (const char *file, char *const argv[])
|
||||
+{
|
||||
+ struct support_subprocess result = support_suprocess_init ();
|
||||
+
|
||||
+ posix_spawn_file_actions_t fa;
|
||||
+ /* posix_spawn_file_actions_init does not fail. */
|
||||
+ posix_spawn_file_actions_init (&fa);
|
||||
+
|
||||
+ xposix_spawn_file_actions_addclose (&fa, result.stdout_pipe[0]);
|
||||
+ xposix_spawn_file_actions_addclose (&fa, result.stderr_pipe[0]);
|
||||
+ xposix_spawn_file_actions_adddup2 (&fa, result.stdout_pipe[1], STDOUT_FILENO);
|
||||
+ xposix_spawn_file_actions_adddup2 (&fa, result.stderr_pipe[1], STDERR_FILENO);
|
||||
+ xposix_spawn_file_actions_addclose (&fa, result.stdout_pipe[1]);
|
||||
+ xposix_spawn_file_actions_addclose (&fa, result.stderr_pipe[1]);
|
||||
+
|
||||
+ result.pid = xposix_spawn (file, &fa, NULL, argv, NULL);
|
||||
+
|
||||
+ xclose (result.stdout_pipe[1]);
|
||||
+ xclose (result.stderr_pipe[1]);
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+support_process_wait (struct support_subprocess *proc)
|
||||
+{
|
||||
+ xclose (proc->stdout_pipe[0]);
|
||||
+ xclose (proc->stderr_pipe[0]);
|
||||
+
|
||||
+ int status;
|
||||
+ xwaitpid (proc->pid, &status, 0);
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static bool
|
||||
+support_process_kill (int pid, int signo, int *status)
|
||||
+{
|
||||
+ /* Kill the whole process group. */
|
||||
+ kill (-pid, signo);
|
||||
+ /* In case setpgid failed in the child, kill it individually too. */
|
||||
+ kill (pid, signo);
|
||||
+
|
||||
+ /* Wait for it to terminate. */
|
||||
+ pid_t killed;
|
||||
+ for (int i = 0; i < 5; ++i)
|
||||
+ {
|
||||
+ int status;
|
||||
+ killed = xwaitpid (pid, &status, WNOHANG|WUNTRACED);
|
||||
+ if (killed != 0)
|
||||
+ break;
|
||||
+
|
||||
+ /* Delay, give the system time to process the kill. If the
|
||||
+ nanosleep() call return prematurely, all the better. We
|
||||
+ won't restart it since this probably means the child process
|
||||
+ finally died. */
|
||||
+ nanosleep (&((struct timespec) { 0, 100000000 }), NULL);
|
||||
+ }
|
||||
+ if (killed != 0 && killed != pid)
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+support_process_terminate (struct support_subprocess *proc)
|
||||
+{
|
||||
+ xclose (proc->stdout_pipe[0]);
|
||||
+ xclose (proc->stderr_pipe[0]);
|
||||
+
|
||||
+ int status;
|
||||
+ pid_t killed = xwaitpid (proc->pid, &status, WNOHANG|WUNTRACED);
|
||||
+ if (killed != 0 && killed == proc->pid)
|
||||
+ return status;
|
||||
+
|
||||
+ /* Subprocess is still running, terminate it. */
|
||||
+ if (!support_process_kill (proc->pid, SIGTERM, &status) )
|
||||
+ support_process_kill (proc->pid, SIGKILL, &status);
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
diff --git a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c
|
||||
index d8ba42ea8b..ab363e41ac 100644
|
||||
--- a/support/tst-support_capture_subprocess.c
|
||||
+++ b/support/tst-support_capture_subprocess.c
|
||||
@@ -23,8 +23,20 @@
|
||||
#include <support/capture_subprocess.h>
|
||||
#include <support/check.h>
|
||||
#include <support/support.h>
|
||||
+#include <support/temp_file.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
+#include <paths.h>
|
||||
+#include <getopt.h>
|
||||
+#include <limits.h>
|
||||
+#include <errno.h>
|
||||
+#include <array_length.h>
|
||||
+
|
||||
+/* Nonzero if the program gets called via 'exec'. */
|
||||
+static int restart;
|
||||
+
|
||||
+/* Hold the four initial argument used to respawn the process. */
|
||||
+static char *initial_argv[5];
|
||||
|
||||
/* Write one byte at *P to FD and advance *P. Do nothing if *P is
|
||||
'\0'. */
|
||||
@@ -42,6 +54,30 @@ transfer (const unsigned char **p, int fd)
|
||||
enum write_mode { out_first, err_first, interleave,
|
||||
write_mode_last = interleave };
|
||||
|
||||
+static const char *
|
||||
+write_mode_to_str (enum write_mode mode)
|
||||
+{
|
||||
+ switch (mode)
|
||||
+ {
|
||||
+ case out_first: return "out_first";
|
||||
+ case err_first: return "err_first";
|
||||
+ case interleave: return "interleave";
|
||||
+ default: return "write_mode_last";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static enum write_mode
|
||||
+str_to_write_mode (const char *mode)
|
||||
+{
|
||||
+ if (strcmp (mode, "out_first") == 0)
|
||||
+ return out_first;
|
||||
+ else if (strcmp (mode, "err_first") == 0)
|
||||
+ return err_first;
|
||||
+ else if (strcmp (mode, "interleave") == 0)
|
||||
+ return interleave;
|
||||
+ return write_mode_last;
|
||||
+}
|
||||
+
|
||||
/* Describe what to write in the subprocess. */
|
||||
struct test
|
||||
{
|
||||
@@ -52,11 +88,9 @@ struct test
|
||||
int status;
|
||||
};
|
||||
|
||||
-/* For use with support_capture_subprocess. */
|
||||
-static void
|
||||
-callback (void *closure)
|
||||
+_Noreturn static void
|
||||
+test_common (const struct test *test)
|
||||
{
|
||||
- const struct test *test = closure;
|
||||
bool mode_ok = false;
|
||||
switch (test->write_mode)
|
||||
{
|
||||
@@ -95,6 +129,40 @@ callback (void *closure)
|
||||
exit (test->status);
|
||||
}
|
||||
|
||||
+static int
|
||||
+parse_int (const char *str)
|
||||
+{
|
||||
+ char *endptr;
|
||||
+ long int ret = strtol (str, &endptr, 10);
|
||||
+ TEST_COMPARE (errno, 0);
|
||||
+ TEST_VERIFY (ret >= 0 && ret <= INT_MAX);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* For use with support_capture_subprogram. */
|
||||
+_Noreturn static void
|
||||
+handle_restart (char *out, char *err, const char *write_mode,
|
||||
+ const char *signal, const char *status)
|
||||
+{
|
||||
+ struct test test =
|
||||
+ {
|
||||
+ out,
|
||||
+ err,
|
||||
+ str_to_write_mode (write_mode),
|
||||
+ parse_int (signal),
|
||||
+ parse_int (status)
|
||||
+ };
|
||||
+ test_common (&test);
|
||||
+}
|
||||
+
|
||||
+/* For use with support_capture_subprocess. */
|
||||
+_Noreturn static void
|
||||
+callback (void *closure)
|
||||
+{
|
||||
+ const struct test *test = closure;
|
||||
+ test_common (test);
|
||||
+}
|
||||
+
|
||||
/* Create a heap-allocated random string of letters. */
|
||||
static char *
|
||||
random_string (size_t length)
|
||||
@@ -130,12 +198,59 @@ check_stream (const char *what, const struct xmemstream *stream,
|
||||
}
|
||||
}
|
||||
|
||||
+static struct support_capture_subprocess
|
||||
+do_subprocess (struct test *test)
|
||||
+{
|
||||
+ return support_capture_subprocess (callback, test);
|
||||
+}
|
||||
+
|
||||
+static struct support_capture_subprocess
|
||||
+do_subprogram (const struct test *test)
|
||||
+{
|
||||
+ /* Three digits per byte plus null terminator. */
|
||||
+ char signalstr[3 * sizeof(int) + 1];
|
||||
+ snprintf (signalstr, sizeof (signalstr), "%d", test->signal);
|
||||
+ char statusstr[3 * sizeof(int) + 1];
|
||||
+ snprintf (statusstr, sizeof (statusstr), "%d", test->status);
|
||||
+
|
||||
+ int argc = 0;
|
||||
+ enum {
|
||||
+ /* 4 elements from initial_argv (path to ld.so, '--library-path', the
|
||||
+ path', and application name'), 2 for restart argument ('--direct',
|
||||
+ '--restart'), 5 arguments plus NULL. */
|
||||
+ argv_size = 12
|
||||
+ };
|
||||
+ char *args[argv_size];
|
||||
+
|
||||
+ for (char **arg = initial_argv; *arg != NULL; arg++)
|
||||
+ args[argc++] = *arg;
|
||||
+
|
||||
+ args[argc++] = (char*) "--direct";
|
||||
+ args[argc++] = (char*) "--restart";
|
||||
+
|
||||
+ args[argc++] = test->out;
|
||||
+ args[argc++] = test->err;
|
||||
+ args[argc++] = (char*) write_mode_to_str (test->write_mode);
|
||||
+ args[argc++] = signalstr;
|
||||
+ args[argc++] = statusstr;
|
||||
+ args[argc] = NULL;
|
||||
+ TEST_VERIFY (argc < argv_size);
|
||||
+
|
||||
+ return support_capture_subprogram (args[0], args);
|
||||
+}
|
||||
+
|
||||
+enum test_type
|
||||
+{
|
||||
+ subprocess,
|
||||
+ subprogram,
|
||||
+};
|
||||
+
|
||||
static int
|
||||
-do_test (void)
|
||||
+do_multiple_tests (enum test_type type)
|
||||
{
|
||||
const int lengths[] = {0, 1, 17, 512, 20000, -1};
|
||||
|
||||
- /* Test multiple combinations of support_capture_subprocess.
|
||||
+ /* Test multiple combinations of support_capture_sub{process,program}.
|
||||
|
||||
length_idx_stdout: Index into the lengths array above,
|
||||
controls how many bytes are written by the subprocess to
|
||||
@@ -164,8 +279,10 @@ do_test (void)
|
||||
TEST_VERIFY (strlen (test.out) == lengths[length_idx_stdout]);
|
||||
TEST_VERIFY (strlen (test.err) == lengths[length_idx_stderr]);
|
||||
|
||||
- struct support_capture_subprocess result
|
||||
- = support_capture_subprocess (callback, &test);
|
||||
+ struct support_capture_subprocess result
|
||||
+ = type == subprocess ? do_subprocess (&test)
|
||||
+ : do_subprogram (&test);
|
||||
+
|
||||
check_stream ("stdout", &result.out, test.out);
|
||||
check_stream ("stderr", &result.err, test.err);
|
||||
|
||||
@@ -199,4 +316,54 @@ do_test (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+do_test (int argc, char *argv[])
|
||||
+{
|
||||
+ /* We must have either:
|
||||
+
|
||||
+ - one or four parameters if called initially:
|
||||
+ + argv[1]: path for ld.so optional
|
||||
+ + argv[2]: "--library-path" optional
|
||||
+ + argv[3]: the library path optional
|
||||
+ + argv[4]: the application name
|
||||
+
|
||||
+ - six parameters left if called through re-execution:
|
||||
+ + argv[1]: the application name
|
||||
+ + argv[2]: the stdout to print
|
||||
+ + argv[3]: the stderr to print
|
||||
+ + argv[4]: the write mode to use
|
||||
+ + argv[5]: the signal to issue
|
||||
+ + argv[6]: the exit status code to use
|
||||
+
|
||||
+ * When built with --enable-hardcoded-path-in-tests or issued without
|
||||
+ using the loader directly.
|
||||
+ */
|
||||
+
|
||||
+ if (argc != (restart ? 6 : 5) && argc != (restart ? 6 : 2))
|
||||
+ FAIL_EXIT1 ("wrong number of arguments (%d)", argc);
|
||||
+
|
||||
+ if (restart)
|
||||
+ {
|
||||
+ handle_restart (argv[1], /* stdout */
|
||||
+ argv[2], /* stderr */
|
||||
+ argv[3], /* write_mode */
|
||||
+ argv[4], /* signal */
|
||||
+ argv[5]); /* status */
|
||||
+ }
|
||||
+
|
||||
+ initial_argv[0] = argv[1]; /* path for ld.so */
|
||||
+ initial_argv[1] = argv[2]; /* "--library-path" */
|
||||
+ initial_argv[2] = argv[3]; /* the library path */
|
||||
+ initial_argv[3] = argv[4]; /* the application name */
|
||||
+ initial_argv[4] = NULL;
|
||||
+
|
||||
+ do_multiple_tests (subprocess);
|
||||
+ do_multiple_tests (subprogram);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define CMDLINE_OPTIONS \
|
||||
+ { "restart", no_argument, &restart, 1 },
|
||||
+#define TEST_FUNCTION_ARGV do_test
|
||||
#include <support/test-driver.c>
|
||||
diff --git a/support/xposix_spawn.c b/support/xposix_spawn.c
|
||||
new file mode 100644
|
||||
index 0000000000..e846017632
|
||||
--- /dev/null
|
||||
+++ b/support/xposix_spawn.c
|
||||
@@ -0,0 +1,32 @@
|
||||
+/* xposix_spawn implementation.
|
||||
+ 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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/xspawn.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+pid_t
|
||||
+xposix_spawn (const char *file, const posix_spawn_file_actions_t *fa,
|
||||
+ const posix_spawnattr_t *attr, char *const args[],
|
||||
+ char *const envp[])
|
||||
+{
|
||||
+ pid_t pid;
|
||||
+ int status = posix_spawn (&pid, file, fa, attr, args, envp);
|
||||
+ if (status != 0)
|
||||
+ FAIL_EXIT1 ("posix_spawn to %s file failed: %m", file);
|
||||
+ return pid;
|
||||
+}
|
||||
diff --git a/support/xposix_spawn_file_actions_addclose.c b/support/xposix_spawn_file_actions_addclose.c
|
||||
new file mode 100644
|
||||
index 0000000000..eed54a6514
|
||||
--- /dev/null
|
||||
+++ b/support/xposix_spawn_file_actions_addclose.c
|
||||
@@ -0,0 +1,29 @@
|
||||
+/* xposix_spawn_file_actions_addclose implementation.
|
||||
+ 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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/xspawn.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+int
|
||||
+xposix_spawn_file_actions_addclose (posix_spawn_file_actions_t *fa, int fd)
|
||||
+{
|
||||
+ int status = posix_spawn_file_actions_addclose (fa, fd);
|
||||
+ if (status == -1)
|
||||
+ FAIL_EXIT1 ("posix_spawn_file_actions_addclose failed: %m\n");
|
||||
+ return status;
|
||||
+}
|
||||
diff --git a/support/xposix_spawn_file_actions_adddup2.c b/support/xposix_spawn_file_actions_adddup2.c
|
||||
new file mode 100644
|
||||
index 0000000000..a43b6490be
|
||||
--- /dev/null
|
||||
+++ b/support/xposix_spawn_file_actions_adddup2.c
|
||||
@@ -0,0 +1,30 @@
|
||||
+/* xposix_spawn_file_actions_adddup2 implementation.
|
||||
+ 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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <support/xspawn.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+int
|
||||
+xposix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *fa, int fd,
|
||||
+ int newfd)
|
||||
+{
|
||||
+ int status = posix_spawn_file_actions_adddup2 (fa, fd, newfd);
|
||||
+ if (status == -1)
|
||||
+ FAIL_EXIT1 ("posix_spawn_file_actions_adddup2 failed: %m\n");
|
||||
+ return status;
|
||||
+}
|
||||
diff --git a/support/xspawn.h b/support/xspawn.h
|
||||
new file mode 100644
|
||||
index 0000000000..bbf89132e4
|
||||
--- /dev/null
|
||||
+++ b/support/xspawn.h
|
||||
@@ -0,0 +1,34 @@
|
||||
+/* posix_spawn with support checks.
|
||||
+ 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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#ifndef SUPPORT_XSPAWN_H
|
||||
+#define SUPPORT_XSPAWN_H
|
||||
+
|
||||
+#include <spawn.h>
|
||||
+
|
||||
+__BEGIN_DECLS
|
||||
+
|
||||
+int xposix_spawn_file_actions_addclose (posix_spawn_file_actions_t *, int);
|
||||
+int xposix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *, int, int);
|
||||
+
|
||||
+pid_t xposix_spawn (const char *, const posix_spawn_file_actions_t *,
|
||||
+ const posix_spawnattr_t *, char *const [], char *const []);
|
||||
+
|
||||
+__END_DECLS
|
||||
+
|
||||
+#endif
|
||||
|
616
srcpkgs/glibc/patches/glibc-upstream-17.patch
Normal file
616
srcpkgs/glibc/patches/glibc-upstream-17.patch
Normal file
|
@ -0,0 +1,616 @@
|
|||
From eaea1dfbe95a31c29adc259100569962cddb6f19 Mon Sep 17 00:00:00 2001
|
||||
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Fri, 26 Apr 2019 13:58:31 +0200
|
||||
Subject: [PATCH 17] elf: Fix pldd (BZ#18035)
|
||||
|
||||
Since 9182aa67994 (Fix vDSO l_name for GDB's, BZ#387) the initial link_map
|
||||
for executable itself and loader will have both l_name and l_libname->name
|
||||
holding the same value due:
|
||||
|
||||
elf/dl-object.c
|
||||
|
||||
95 new->l_name = *realname ? realname : (char *) newname->name + libname_len - 1;
|
||||
|
||||
Since newname->name points to new->l_libname->name.
|
||||
|
||||
This leads to pldd to an infinite call at:
|
||||
|
||||
elf/pldd-xx.c
|
||||
|
||||
203 again:
|
||||
204 while (1)
|
||||
205 {
|
||||
206 ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset);
|
||||
|
||||
228 /* Try the l_libname element. */
|
||||
229 struct E(libname_list) ln;
|
||||
230 if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln))
|
||||
231 {
|
||||
232 name_offset = ln.name;
|
||||
233 goto again;
|
||||
234 }
|
||||
|
||||
Since the value at ln.name (l_libname->name) will be the same as previously
|
||||
read. The straightforward fix is just avoid the check and read the new list
|
||||
entry.
|
||||
|
||||
I checked also against binaries issues with old loaders with fix for BZ#387,
|
||||
and pldd could dump the shared objects.
|
||||
|
||||
Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, and
|
||||
powerpc64le-linux-gnu.
|
||||
|
||||
[BZ #18035]
|
||||
* elf/Makefile (tests-container): Add tst-pldd.
|
||||
* elf/pldd-xx.c: Use _Static_assert in of pldd_assert.
|
||||
(E(find_maps)): Avoid use alloca, use default read file operations
|
||||
instead of explicit LFS names, and fix infinite loop.
|
||||
* elf/pldd.c: Explicit set _FILE_OFFSET_BITS, cleanup headers.
|
||||
(get_process_info): Use _Static_assert instead of assert, use default
|
||||
directory operations instead of explicit LFS names, and free some
|
||||
leadek pointers.
|
||||
* elf/tst-pldd.c: New file.
|
||||
|
||||
(cherry picked from commit 1a4c27355e146b6d8cc6487b998462c7fdd1048f)
|
||||
---
|
||||
ChangeLog | 13 ++++++
|
||||
NEWS | 1 +
|
||||
elf/Makefile | 1 +
|
||||
elf/pldd-xx.c | 114 +++++++++++++++++------------------------------
|
||||
elf/pldd.c | 64 +++++++++++++--------------
|
||||
elf/tst-pldd.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
6 files changed, 203 insertions(+), 108 deletions(-)
|
||||
create mode 100644 elf/tst-pldd.c
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 2524e25697..5af8e27ab9 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,16 @@
|
||||
+2019-04-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
+
|
||||
+ [BZ #18035]
|
||||
+ * elf/Makefile (tests-container): Add tst-pldd.
|
||||
+ * elf/pldd-xx.c: Use _Static_assert in of pldd_assert.
|
||||
+ (E(find_maps)): Avoid use alloca, use default read file operations
|
||||
+ instead of explicit LFS names, and fix infinite loop.
|
||||
+ * elf/pldd.c: Explicit set _FILE_OFFSET_BITS, cleanup headers.
|
||||
+ (get_process_info): Use _Static_assert instead of assert, use default
|
||||
+ directory operations instead of explicit LFS names, and free some
|
||||
+ leadek pointers.
|
||||
+ * elf/tst-pldd.c: New file.
|
||||
+
|
||||
2019-04-17 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
* support/Makefile (libsupport-routines): Add support_subprocess,
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 117646df7b..b39a0ccf91 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -14,6 +14,7 @@ Major new features:
|
||||
The following bugs are resolved with this release:
|
||||
|
||||
[16573] malloc: Set and reset all hooks for tracing
|
||||
+ [18035] Fix pldd hang
|
||||
[24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309)
|
||||
[24164] Systemtap probes need to use "nr" constraint on 32-bit Arm
|
||||
[24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 9cf5cd8dfd..e7457e809f 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -194,6 +194,7 @@ tests-internal += loadtest unload unload2 circleload1 \
|
||||
tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
|
||||
tst-ptrguard1 tst-stackguard1 tst-libc_dlvsym \
|
||||
tst-create_format1
|
||||
+tests-container += tst-pldd
|
||||
ifeq ($(build-hardcoded-path-in-tests),yes)
|
||||
tests += tst-dlopen-aout
|
||||
tst-dlopen-aout-no-pie = yes
|
||||
diff --git a/elf/pldd-xx.c b/elf/pldd-xx.c
|
||||
index 547f840ee1..756f6d7a1c 100644
|
||||
--- a/elf/pldd-xx.c
|
||||
+++ b/elf/pldd-xx.c
|
||||
@@ -23,10 +23,6 @@
|
||||
#define EW_(e, w, t) EW__(e, w, _##t)
|
||||
#define EW__(e, w, t) e##w##t
|
||||
|
||||
-#define pldd_assert(name, exp) \
|
||||
- typedef int __assert_##name[((exp) != 0) - 1]
|
||||
-
|
||||
-
|
||||
struct E(link_map)
|
||||
{
|
||||
EW(Addr) l_addr;
|
||||
@@ -39,12 +35,12 @@ struct E(link_map)
|
||||
EW(Addr) l_libname;
|
||||
};
|
||||
#if CLASS == __ELF_NATIVE_CLASS
|
||||
-pldd_assert (l_addr, (offsetof (struct link_map, l_addr)
|
||||
- == offsetof (struct E(link_map), l_addr)));
|
||||
-pldd_assert (l_name, (offsetof (struct link_map, l_name)
|
||||
- == offsetof (struct E(link_map), l_name)));
|
||||
-pldd_assert (l_next, (offsetof (struct link_map, l_next)
|
||||
- == offsetof (struct E(link_map), l_next)));
|
||||
+_Static_assert (offsetof (struct link_map, l_addr)
|
||||
+ == offsetof (struct E(link_map), l_addr), "l_addr");
|
||||
+_Static_assert (offsetof (struct link_map, l_name)
|
||||
+ == offsetof (struct E(link_map), l_name), "l_name");
|
||||
+_Static_assert (offsetof (struct link_map, l_next)
|
||||
+ == offsetof (struct E(link_map), l_next), "l_next");
|
||||
#endif
|
||||
|
||||
|
||||
@@ -54,10 +50,10 @@ struct E(libname_list)
|
||||
EW(Addr) next;
|
||||
};
|
||||
#if CLASS == __ELF_NATIVE_CLASS
|
||||
-pldd_assert (name, (offsetof (struct libname_list, name)
|
||||
- == offsetof (struct E(libname_list), name)));
|
||||
-pldd_assert (next, (offsetof (struct libname_list, next)
|
||||
- == offsetof (struct E(libname_list), next)));
|
||||
+_Static_assert (offsetof (struct libname_list, name)
|
||||
+ == offsetof (struct E(libname_list), name), "name");
|
||||
+_Static_assert (offsetof (struct libname_list, next)
|
||||
+ == offsetof (struct E(libname_list), next), "next");
|
||||
#endif
|
||||
|
||||
struct E(r_debug)
|
||||
@@ -69,16 +65,17 @@ struct E(r_debug)
|
||||
EW(Addr) r_map;
|
||||
};
|
||||
#if CLASS == __ELF_NATIVE_CLASS
|
||||
-pldd_assert (r_version, (offsetof (struct r_debug, r_version)
|
||||
- == offsetof (struct E(r_debug), r_version)));
|
||||
-pldd_assert (r_map, (offsetof (struct r_debug, r_map)
|
||||
- == offsetof (struct E(r_debug), r_map)));
|
||||
+_Static_assert (offsetof (struct r_debug, r_version)
|
||||
+ == offsetof (struct E(r_debug), r_version), "r_version");
|
||||
+_Static_assert (offsetof (struct r_debug, r_map)
|
||||
+ == offsetof (struct E(r_debug), r_map), "r_map");
|
||||
#endif
|
||||
|
||||
|
||||
static int
|
||||
|
||||
-E(find_maps) (pid_t pid, void *auxv, size_t auxv_size)
|
||||
+E(find_maps) (const char *exe, int memfd, pid_t pid, void *auxv,
|
||||
+ size_t auxv_size)
|
||||
{
|
||||
EW(Addr) phdr = 0;
|
||||
unsigned int phnum = 0;
|
||||
@@ -104,12 +101,9 @@ E(find_maps) (pid_t pid, void *auxv, size_t auxv_size)
|
||||
if (phdr == 0 || phnum == 0 || phent == 0)
|
||||
error (EXIT_FAILURE, 0, gettext ("cannot find program header of process"));
|
||||
|
||||
- EW(Phdr) *p = alloca (phnum * phent);
|
||||
- if (pread64 (memfd, p, phnum * phent, phdr) != phnum * phent)
|
||||
- {
|
||||
- error (0, 0, gettext ("cannot read program header"));
|
||||
- return EXIT_FAILURE;
|
||||
- }
|
||||
+ EW(Phdr) *p = xmalloc (phnum * phent);
|
||||
+ if (pread (memfd, p, phnum * phent, phdr) != phnum * phent)
|
||||
+ error (EXIT_FAILURE, 0, gettext ("cannot read program header"));
|
||||
|
||||
/* Determine the load offset. We need this for interpreting the
|
||||
other program header entries so we do this in a separate loop.
|
||||
@@ -129,24 +123,18 @@ E(find_maps) (pid_t pid, void *auxv, size_t auxv_size)
|
||||
if (p[i].p_type == PT_DYNAMIC)
|
||||
{
|
||||
EW(Dyn) *dyn = xmalloc (p[i].p_filesz);
|
||||
- if (pread64 (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr)
|
||||
+ if (pread (memfd, dyn, p[i].p_filesz, offset + p[i].p_vaddr)
|
||||
!= p[i].p_filesz)
|
||||
- {
|
||||
- error (0, 0, gettext ("cannot read dynamic section"));
|
||||
- return EXIT_FAILURE;
|
||||
- }
|
||||
+ error (EXIT_FAILURE, 0, gettext ("cannot read dynamic section"));
|
||||
|
||||
/* Search for the DT_DEBUG entry. */
|
||||
for (unsigned int j = 0; j < p[i].p_filesz / sizeof (EW(Dyn)); ++j)
|
||||
if (dyn[j].d_tag == DT_DEBUG && dyn[j].d_un.d_ptr != 0)
|
||||
{
|
||||
struct E(r_debug) r;
|
||||
- if (pread64 (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr)
|
||||
+ if (pread (memfd, &r, sizeof (r), dyn[j].d_un.d_ptr)
|
||||
!= sizeof (r))
|
||||
- {
|
||||
- error (0, 0, gettext ("cannot read r_debug"));
|
||||
- return EXIT_FAILURE;
|
||||
- }
|
||||
+ error (EXIT_FAILURE, 0, gettext ("cannot read r_debug"));
|
||||
|
||||
if (r.r_map != 0)
|
||||
{
|
||||
@@ -160,13 +148,10 @@ E(find_maps) (pid_t pid, void *auxv, size_t auxv_size)
|
||||
}
|
||||
else if (p[i].p_type == PT_INTERP)
|
||||
{
|
||||
- interp = alloca (p[i].p_filesz);
|
||||
- if (pread64 (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr)
|
||||
+ interp = xmalloc (p[i].p_filesz);
|
||||
+ if (pread (memfd, interp, p[i].p_filesz, offset + p[i].p_vaddr)
|
||||
!= p[i].p_filesz)
|
||||
- {
|
||||
- error (0, 0, gettext ("cannot read program interpreter"));
|
||||
- return EXIT_FAILURE;
|
||||
- }
|
||||
+ error (EXIT_FAILURE, 0, gettext ("cannot read program interpreter"));
|
||||
}
|
||||
|
||||
if (list == 0)
|
||||
@@ -174,14 +159,16 @@ E(find_maps) (pid_t pid, void *auxv, size_t auxv_size)
|
||||
if (interp == NULL)
|
||||
{
|
||||
// XXX check whether the executable itself is the loader
|
||||
- return EXIT_FAILURE;
|
||||
+ exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// XXX perhaps try finding ld.so and _r_debug in it
|
||||
-
|
||||
- return EXIT_FAILURE;
|
||||
+ exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
+ free (p);
|
||||
+ free (interp);
|
||||
+
|
||||
/* Print the PID and program name first. */
|
||||
printf ("%lu:\t%s\n", (unsigned long int) pid, exe);
|
||||
|
||||
@@ -192,47 +179,27 @@ E(find_maps) (pid_t pid, void *auxv, size_t auxv_size)
|
||||
do
|
||||
{
|
||||
struct E(link_map) m;
|
||||
- if (pread64 (memfd, &m, sizeof (m), list) != sizeof (m))
|
||||
- {
|
||||
- error (0, 0, gettext ("cannot read link map"));
|
||||
- status = EXIT_FAILURE;
|
||||
- goto out;
|
||||
- }
|
||||
+ if (pread (memfd, &m, sizeof (m), list) != sizeof (m))
|
||||
+ error (EXIT_FAILURE, 0, gettext ("cannot read link map"));
|
||||
|
||||
EW(Addr) name_offset = m.l_name;
|
||||
- again:
|
||||
while (1)
|
||||
{
|
||||
- ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset);
|
||||
+ ssize_t n = pread (memfd, tmpbuf.data, tmpbuf.length, name_offset);
|
||||
if (n == -1)
|
||||
- {
|
||||
- error (0, 0, gettext ("cannot read object name"));
|
||||
- status = EXIT_FAILURE;
|
||||
- goto out;
|
||||
- }
|
||||
+ error (EXIT_FAILURE, 0, gettext ("cannot read object name"));
|
||||
|
||||
if (memchr (tmpbuf.data, '\0', n) != NULL)
|
||||
break;
|
||||
|
||||
if (!scratch_buffer_grow (&tmpbuf))
|
||||
- {
|
||||
- error (0, 0, gettext ("cannot allocate buffer for object name"));
|
||||
- status = EXIT_FAILURE;
|
||||
- goto out;
|
||||
- }
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ gettext ("cannot allocate buffer for object name"));
|
||||
}
|
||||
|
||||
- if (((char *)tmpbuf.data)[0] == '\0' && name_offset == m.l_name
|
||||
- && m.l_libname != 0)
|
||||
- {
|
||||
- /* Try the l_libname element. */
|
||||
- struct E(libname_list) ln;
|
||||
- if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln))
|
||||
- {
|
||||
- name_offset = ln.name;
|
||||
- goto again;
|
||||
- }
|
||||
- }
|
||||
+ /* The m.l_name and m.l_libname.name for loader linkmap points to same
|
||||
+ values (since BZ#387 fix). Trying to use l_libname name as the
|
||||
+ shared object name might lead to an infinite loop (BZ#18035). */
|
||||
|
||||
/* Skip over the executable. */
|
||||
if (((char *)tmpbuf.data)[0] != '\0')
|
||||
@@ -242,7 +209,6 @@ E(find_maps) (pid_t pid, void *auxv, size_t auxv_size)
|
||||
}
|
||||
while (list != 0);
|
||||
|
||||
- out:
|
||||
scratch_buffer_free (&tmpbuf);
|
||||
return status;
|
||||
}
|
||||
diff --git a/elf/pldd.c b/elf/pldd.c
|
||||
index f3fac4e487..69629bd5d2 100644
|
||||
--- a/elf/pldd.c
|
||||
+++ b/elf/pldd.c
|
||||
@@ -17,23 +17,17 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
-#include <alloca.h>
|
||||
+#define _FILE_OFFSET_BITS 64
|
||||
+
|
||||
#include <argp.h>
|
||||
-#include <assert.h>
|
||||
#include <dirent.h>
|
||||
-#include <elf.h>
|
||||
-#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <fcntl.h>
|
||||
#include <libintl.h>
|
||||
-#include <link.h>
|
||||
-#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
-#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ptrace.h>
|
||||
-#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <scratch_buffer.h>
|
||||
|
||||
@@ -76,14 +70,9 @@ static struct argp argp =
|
||||
options, parse_opt, args_doc, doc, NULL, more_help, NULL
|
||||
};
|
||||
|
||||
-// File descriptor of /proc/*/mem file.
|
||||
-static int memfd;
|
||||
-
|
||||
-/* Name of the executable */
|
||||
-static char *exe;
|
||||
|
||||
/* Local functions. */
|
||||
-static int get_process_info (int dfd, long int pid);
|
||||
+static int get_process_info (const char *exe, int dfd, long int pid);
|
||||
static void wait_for_ptrace_stop (long int pid);
|
||||
|
||||
|
||||
@@ -102,8 +91,10 @@ main (int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
- assert (sizeof (pid_t) == sizeof (int)
|
||||
- || sizeof (pid_t) == sizeof (long int));
|
||||
+ _Static_assert (sizeof (pid_t) == sizeof (int)
|
||||
+ || sizeof (pid_t) == sizeof (long int),
|
||||
+ "sizeof (pid_t) != sizeof (int) or sizeof (long int)");
|
||||
+
|
||||
char *endp;
|
||||
errno = 0;
|
||||
long int pid = strtol (argv[remaining], &endp, 10);
|
||||
@@ -119,25 +110,24 @@ main (int argc, char *argv[])
|
||||
if (dfd == -1)
|
||||
error (EXIT_FAILURE, errno, gettext ("cannot open %s"), buf);
|
||||
|
||||
- struct scratch_buffer exebuf;
|
||||
- scratch_buffer_init (&exebuf);
|
||||
+ /* Name of the executable */
|
||||
+ struct scratch_buffer exe;
|
||||
+ scratch_buffer_init (&exe);
|
||||
ssize_t nexe;
|
||||
while ((nexe = readlinkat (dfd, "exe",
|
||||
- exebuf.data, exebuf.length)) == exebuf.length)
|
||||
+ exe.data, exe.length)) == exe.length)
|
||||
{
|
||||
- if (!scratch_buffer_grow (&exebuf))
|
||||
+ if (!scratch_buffer_grow (&exe))
|
||||
{
|
||||
nexe = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nexe == -1)
|
||||
- exe = (char *) "<program name undetermined>";
|
||||
+ /* Default stack allocation is at least 1024. */
|
||||
+ snprintf (exe.data, exe.length, "<program name undetermined>");
|
||||
else
|
||||
- {
|
||||
- exe = exebuf.data;
|
||||
- exe[nexe] = '\0';
|
||||
- }
|
||||
+ ((char*)exe.data)[nexe] = '\0';
|
||||
|
||||
/* Stop all threads since otherwise the list of loaded modules might
|
||||
change while we are reading it. */
|
||||
@@ -155,8 +145,8 @@ main (int argc, char *argv[])
|
||||
error (EXIT_FAILURE, errno, gettext ("cannot prepare reading %s/task"),
|
||||
buf);
|
||||
|
||||
- struct dirent64 *d;
|
||||
- while ((d = readdir64 (dir)) != NULL)
|
||||
+ struct dirent *d;
|
||||
+ while ((d = readdir (dir)) != NULL)
|
||||
{
|
||||
if (! isdigit (d->d_name[0]))
|
||||
continue;
|
||||
@@ -182,7 +172,7 @@ main (int argc, char *argv[])
|
||||
|
||||
wait_for_ptrace_stop (tid);
|
||||
|
||||
- struct thread_list *newp = alloca (sizeof (*newp));
|
||||
+ struct thread_list *newp = xmalloc (sizeof (*newp));
|
||||
newp->tid = tid;
|
||||
newp->next = thread_list;
|
||||
thread_list = newp;
|
||||
@@ -190,17 +180,22 @@ main (int argc, char *argv[])
|
||||
|
||||
closedir (dir);
|
||||
|
||||
- int status = get_process_info (dfd, pid);
|
||||
+ if (thread_list == NULL)
|
||||
+ error (EXIT_FAILURE, 0, gettext ("no valid %s/task entries"), buf);
|
||||
+
|
||||
+ int status = get_process_info (exe.data, dfd, pid);
|
||||
|
||||
- assert (thread_list != NULL);
|
||||
do
|
||||
{
|
||||
ptrace (PTRACE_DETACH, thread_list->tid, NULL, NULL);
|
||||
+ struct thread_list *prev = thread_list;
|
||||
thread_list = thread_list->next;
|
||||
+ free (prev);
|
||||
}
|
||||
while (thread_list != NULL);
|
||||
|
||||
close (dfd);
|
||||
+ scratch_buffer_free (&exe);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -281,9 +276,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
|
||||
|
||||
|
||||
static int
|
||||
-get_process_info (int dfd, long int pid)
|
||||
+get_process_info (const char *exe, int dfd, long int pid)
|
||||
{
|
||||
- memfd = openat (dfd, "mem", O_RDONLY);
|
||||
+ /* File descriptor of /proc/<pid>/mem file. */
|
||||
+ int memfd = openat (dfd, "mem", O_RDONLY);
|
||||
if (memfd == -1)
|
||||
goto no_info;
|
||||
|
||||
@@ -333,9 +329,9 @@ get_process_info (int dfd, long int pid)
|
||||
|
||||
int retval;
|
||||
if (e_ident[EI_CLASS] == ELFCLASS32)
|
||||
- retval = find_maps32 (pid, auxv, auxv_size);
|
||||
+ retval = find_maps32 (exe, memfd, pid, auxv, auxv_size);
|
||||
else
|
||||
- retval = find_maps64 (pid, auxv, auxv_size);
|
||||
+ retval = find_maps64 (exe, memfd, pid, auxv, auxv_size);
|
||||
|
||||
free (auxv);
|
||||
close (memfd);
|
||||
diff --git a/elf/tst-pldd.c b/elf/tst-pldd.c
|
||||
new file mode 100644
|
||||
index 0000000000..ed19cedd05
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-pldd.c
|
||||
@@ -0,0 +1,118 @@
|
||||
+/* Basic tests for pldd program.
|
||||
+ 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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+#include <stdint.h>
|
||||
+#include <libgen.h>
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
+#include <array_length.h>
|
||||
+#include <gnu/lib-names.h>
|
||||
+
|
||||
+#include <support/subprocess.h>
|
||||
+#include <support/capture_subprocess.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+static void
|
||||
+target_process (void *arg)
|
||||
+{
|
||||
+ pause ();
|
||||
+}
|
||||
+
|
||||
+/* The test runs in a container because pldd does not support tracing
|
||||
+ a binary started by the loader iself (as with testrun.sh). */
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ /* Create a copy of current test to check with pldd. */
|
||||
+ struct support_subprocess target = support_subprocess (target_process, NULL);
|
||||
+
|
||||
+ /* Run 'pldd' on test subprocess. */
|
||||
+ struct support_capture_subprocess pldd;
|
||||
+ {
|
||||
+ /* Three digits per byte plus null terminator. */
|
||||
+ char pid[3 * sizeof (uint32_t) + 1];
|
||||
+ snprintf (pid, array_length (pid), "%d", target.pid);
|
||||
+
|
||||
+ const char prog[] = "/usr/bin/pldd";
|
||||
+
|
||||
+ pldd = support_capture_subprogram (prog,
|
||||
+ (char *const []) { (char *) prog, pid, NULL });
|
||||
+
|
||||
+ support_capture_subprocess_check (&pldd, "pldd", 0, sc_allow_stdout);
|
||||
+ }
|
||||
+
|
||||
+ /* Check 'pldd' output. The test is expected to be linked against only
|
||||
+ loader and libc. */
|
||||
+ {
|
||||
+ pid_t pid;
|
||||
+ char buffer[512];
|
||||
+#define STRINPUT(size) "%" # size "s"
|
||||
+
|
||||
+ FILE *out = fmemopen (pldd.out.buffer, pldd.out.length, "r");
|
||||
+ TEST_VERIFY (out != NULL);
|
||||
+
|
||||
+ /* First line is in the form of <pid>: <full path of executable> */
|
||||
+ TEST_COMPARE (fscanf (out, "%u: " STRINPUT (512), &pid, buffer), 2);
|
||||
+
|
||||
+ TEST_COMPARE (pid, target.pid);
|
||||
+ TEST_COMPARE (strcmp (basename (buffer), "tst-pldd"), 0);
|
||||
+
|
||||
+ /* It expects only one loader and libc loaded by the program. */
|
||||
+ bool interpreter_found = false, libc_found = false;
|
||||
+ while (fgets (buffer, array_length (buffer), out) != NULL)
|
||||
+ {
|
||||
+ /* Ignore vDSO. */
|
||||
+ if (buffer[0] != '/')
|
||||
+ continue;
|
||||
+
|
||||
+ /* Remove newline so baseline (buffer) can compare against the
|
||||
+ LD_SO and LIBC_SO macros unmodified. */
|
||||
+ if (buffer[strlen(buffer)-1] == '\n')
|
||||
+ buffer[strlen(buffer)-1] = '\0';
|
||||
+
|
||||
+ if (strcmp (basename (buffer), LD_SO) == 0)
|
||||
+ {
|
||||
+ TEST_COMPARE (interpreter_found, false);
|
||||
+ interpreter_found = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp (basename (buffer), LIBC_SO) == 0)
|
||||
+ {
|
||||
+ TEST_COMPARE (libc_found, false);
|
||||
+ libc_found = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ TEST_COMPARE (interpreter_found, true);
|
||||
+ TEST_COMPARE (libc_found, true);
|
||||
+
|
||||
+ fclose (out);
|
||||
+ }
|
||||
+
|
||||
+ support_capture_subprocess_free (&pldd);
|
||||
+ support_process_terminate (&target);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
|
37
srcpkgs/glibc/patches/glibc-upstream-18.patch
Normal file
37
srcpkgs/glibc/patches/glibc-upstream-18.patch
Normal file
|
@ -0,0 +1,37 @@
|
|||
From 52b7cd6e9a701bb203023d56e84551943dc6a4c0 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Maris <amaris@redhat.com>
|
||||
Date: Thu, 14 Mar 2019 16:51:16 -0400
|
||||
Subject: [PATCH 18] malloc: Check for large bin list corruption when
|
||||
inserting unsorted chunk
|
||||
|
||||
Fixes bug 24216. This patch adds security checks for bk and bk_nextsize pointers
|
||||
of chunks in large bin when inserting chunk from unsorted bin. It was possible
|
||||
to write the pointer to victim (newly inserted chunk) to arbitrary memory
|
||||
locations if bk or bk_nextsize pointers of the next large bin chunk
|
||||
got corrupted.
|
||||
|
||||
(cherry picked from commit 5b06f538c5aee0389ed034f60d90a8884d6d54de)
|
||||
---
|
||||
malloc/malloc.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index feaf7ee0bf..ce771375b6 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -3876,10 +3876,14 @@ _int_malloc (mstate av, size_t bytes)
|
||||
{
|
||||
victim->fd_nextsize = fwd;
|
||||
victim->bk_nextsize = fwd->bk_nextsize;
|
||||
+ if (__glibc_unlikely (fwd->bk_nextsize->fd_nextsize != fwd))
|
||||
+ malloc_printerr ("malloc(): largebin double linked list corrupted (nextsize)");
|
||||
fwd->bk_nextsize = victim;
|
||||
victim->bk_nextsize->fd_nextsize = victim;
|
||||
}
|
||||
bck = fwd->bk;
|
||||
+ if (bck->fd != fwd)
|
||||
+ malloc_printerr ("malloc(): largebin double linked list corrupted (bk)");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
144
srcpkgs/glibc/patches/glibc-upstream-19.patch
Normal file
144
srcpkgs/glibc/patches/glibc-upstream-19.patch
Normal file
|
@ -0,0 +1,144 @@
|
|||
From c6177be4b92d5d7df50a785652d1912db511423e Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Schwab <schwab@suse.de>
|
||||
Date: Wed, 15 May 2019 17:09:05 +0200
|
||||
Subject: [PATCH 19] Fix crash in _IO_wfile_sync (bug 20568)
|
||||
|
||||
When computing the length of the converted part of the stdio buffer, use
|
||||
the number of consumed wide characters, not the (negative) distance to the
|
||||
end of the wide buffer.
|
||||
|
||||
(cherry picked from commit 32ff397533715988c19cbf3675dcbd727ec13e18)
|
||||
---
|
||||
ChangeLog | 10 ++++++++++
|
||||
NEWS | 1 +
|
||||
libio/Makefile | 3 ++-
|
||||
libio/tst-wfile-sync.c | 39 ++++++++++++++++++++++++++++++++++++++
|
||||
libio/tst-wfile-sync.input | 1 +
|
||||
libio/wfileops.c | 5 +++--
|
||||
6 files changed, 56 insertions(+), 3 deletions(-)
|
||||
create mode 100644 libio/tst-wfile-sync.c
|
||||
create mode 100644 libio/tst-wfile-sync.input
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index 5af8e27ab9..d3fcf73e47 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,13 @@
|
||||
+2019-05-15 Andreas Schwab <schwab@suse.de>
|
||||
+
|
||||
+ [BZ #20568]
|
||||
+ * libio/wfileops.c (_IO_wfile_sync): Correct last argument to
|
||||
+ __codecvt_do_length.
|
||||
+ * libio/Makefile (tests): Add tst-wfile-sync.
|
||||
+ ($(objpfx)tst-wfile-sync.out): Depend on $(gen-locales).
|
||||
+ * libio/tst-wfile-sync.c: New file.
|
||||
+ * libio/tst-wfile-sync.input: New file.
|
||||
+
|
||||
2019-04-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
[BZ #18035]
|
||||
diff --git a/NEWS b/NEWS
|
||||
index b39a0ccf91..c10ab5e851 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -15,6 +15,7 @@ The following bugs are resolved with this release:
|
||||
|
||||
[16573] malloc: Set and reset all hooks for tracing
|
||||
[18035] Fix pldd hang
|
||||
+ [20568] Fix crash in _IO_wfile_sync
|
||||
[24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309)
|
||||
[24164] Systemtap probes need to use "nr" constraint on 32-bit Arm
|
||||
[24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2
|
||||
diff --git a/libio/Makefile b/libio/Makefile
|
||||
index 5bee83e55c..ee3a34cc3b 100644
|
||||
--- a/libio/Makefile
|
||||
+++ b/libio/Makefile
|
||||
@@ -65,7 +65,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
|
||||
tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
|
||||
tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
|
||||
tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \
|
||||
- tst-sprintf-ub tst-sprintf-chk-ub
|
||||
+ tst-sprintf-ub tst-sprintf-chk-ub tst-wfile-sync
|
||||
|
||||
tests-internal = tst-vtables tst-vtables-interposed tst-readline
|
||||
|
||||
@@ -212,6 +212,7 @@ $(objpfx)tst-ungetwc1.out: $(gen-locales)
|
||||
$(objpfx)tst-ungetwc2.out: $(gen-locales)
|
||||
$(objpfx)tst-widetext.out: $(gen-locales)
|
||||
$(objpfx)tst_wprintf2.out: $(gen-locales)
|
||||
+$(objpfx)tst-wfile-sync.out: $(gen-locales)
|
||||
endif
|
||||
|
||||
$(objpfx)test-freopen.out: test-freopen.sh $(objpfx)test-freopen
|
||||
diff --git a/libio/tst-wfile-sync.c b/libio/tst-wfile-sync.c
|
||||
new file mode 100644
|
||||
index 0000000000..618682064d
|
||||
--- /dev/null
|
||||
+++ b/libio/tst-wfile-sync.c
|
||||
@@ -0,0 +1,39 @@
|
||||
+/* Test that _IO_wfile_sync does not crash (bug 20568).
|
||||
+ 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
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <locale.h>
|
||||
+#include <stdio.h>
|
||||
+#include <wchar.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ TEST_VERIFY_EXIT (setlocale (LC_ALL, "de_DE.UTF-8") != NULL);
|
||||
+ /* Fill the stdio buffer and advance the read pointer. */
|
||||
+ TEST_VERIFY_EXIT (fgetwc (stdin) != WEOF);
|
||||
+ /* This calls _IO_wfile_sync, it should not crash. */
|
||||
+ TEST_VERIFY_EXIT (setvbuf (stdin, NULL, _IONBF, 0) == 0);
|
||||
+ /* Verify that the external file offset has been synchronized. */
|
||||
+ TEST_COMPARE (xlseek (0, 0, SEEK_CUR), 1);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/libio/tst-wfile-sync.input b/libio/tst-wfile-sync.input
|
||||
new file mode 100644
|
||||
index 0000000000..12d0958f7a
|
||||
--- /dev/null
|
||||
+++ b/libio/tst-wfile-sync.input
|
||||
@@ -0,0 +1 @@
|
||||
+This is a test of _IO_wfile_sync.
|
||||
diff --git a/libio/wfileops.c b/libio/wfileops.c
|
||||
index 78f20486e5..bab2ba4892 100644
|
||||
--- a/libio/wfileops.c
|
||||
+++ b/libio/wfileops.c
|
||||
@@ -508,11 +508,12 @@ _IO_wfile_sync (FILE *fp)
|
||||
generate the wide characters up to the current reading
|
||||
position. */
|
||||
int nread;
|
||||
-
|
||||
+ size_t wnread = (fp->_wide_data->_IO_read_ptr
|
||||
+ - fp->_wide_data->_IO_read_base);
|
||||
fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
|
||||
nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
|
||||
fp->_IO_read_base,
|
||||
- fp->_IO_read_end, delta);
|
||||
+ fp->_IO_read_end, wnread);
|
||||
fp->_IO_read_ptr = fp->_IO_read_base + nread;
|
||||
delta = -(fp->_IO_read_end - fp->_IO_read_base - nread);
|
||||
}
|
||||
|
93
srcpkgs/glibc/patches/glibc-upstream-20.patch
Normal file
93
srcpkgs/glibc/patches/glibc-upstream-20.patch
Normal file
|
@ -0,0 +1,93 @@
|
|||
From e3f828b8bd6e21922da8be8dee35edef09382d8d Mon Sep 17 00:00:00 2001
|
||||
From: Mark Wielaard <mark@klomp.org>
|
||||
Date: Wed, 15 May 2019 17:14:01 +0200
|
||||
Subject: [PATCH 20] dlfcn: Guard __dlerror_main_freeres with
|
||||
__libc_once_get (once) [BZ#24476]
|
||||
|
||||
dlerror.c (__dlerror_main_freeres) will try to free resources which only
|
||||
have been initialized when init () has been called. That function is
|
||||
called when resources are needed using __libc_once (once, init) where
|
||||
once is a __libc_once_define (static, once) in the dlerror.c file.
|
||||
Trying to free those resources if init () hasn't been called will
|
||||
produce errors under valgrind memcheck. So guard the freeing of those
|
||||
resources using __libc_once_get (once) and make sure we have a valid
|
||||
key. Also add a similar guard to __dlerror ().
|
||||
|
||||
* dlfcn/dlerror.c (__dlerror_main_freeres): Guard using
|
||||
__libc_once_get (once) and static_bug == NULL.
|
||||
(__dlerror): Check we have a valid key, set result to static_buf
|
||||
otherwise.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit 11b451c8868d8a2b0edc5dfd44fc58d9ee538be0)
|
||||
---
|
||||
ChangeLog | 8 ++++++++
|
||||
dlfcn/dlerror.c | 29 +++++++++++++++++++++--------
|
||||
2 files changed, 29 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index d3fcf73e47..de8c5c214d 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,11 @@
|
||||
+2019-05-15 Mark Wielaard <mark@klomp.org>
|
||||
+
|
||||
+ [BZ#24476]
|
||||
+ * dlfcn/dlerror.c (__dlerror_main_freeres): Guard using
|
||||
+ __libc_once_get (once) and static_buf == NULL.
|
||||
+ (__dlerror): Check we have a valid key, set result to static_buf
|
||||
+ otherwise.
|
||||
+
|
||||
2019-05-15 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
[BZ #20568]
|
||||
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
|
||||
index 27376582d0..ca42c126c1 100644
|
||||
--- a/dlfcn/dlerror.c
|
||||
+++ b/dlfcn/dlerror.c
|
||||
@@ -72,9 +72,16 @@ __dlerror (void)
|
||||
__libc_once (once, init);
|
||||
|
||||
/* Get error string. */
|
||||
- result = (struct dl_action_result *) __libc_getspecific (key);
|
||||
- if (result == NULL)
|
||||
- result = &last_result;
|
||||
+ if (static_buf != NULL)
|
||||
+ result = static_buf;
|
||||
+ else
|
||||
+ {
|
||||
+ /* init () has been run and we don't use the static buffer.
|
||||
+ So we have a valid key. */
|
||||
+ result = (struct dl_action_result *) __libc_getspecific (key);
|
||||
+ if (result == NULL)
|
||||
+ result = &last_result;
|
||||
+ }
|
||||
|
||||
/* Test whether we already returned the string. */
|
||||
if (result->returned != 0)
|
||||
@@ -230,13 +237,19 @@ free_key_mem (void *mem)
|
||||
void
|
||||
__dlerror_main_freeres (void)
|
||||
{
|
||||
- void *mem;
|
||||
/* Free the global memory if used. */
|
||||
check_free (&last_result);
|
||||
- /* Free the TSD memory if used. */
|
||||
- mem = __libc_getspecific (key);
|
||||
- if (mem != NULL)
|
||||
- free_key_mem (mem);
|
||||
+
|
||||
+ if (__libc_once_get (once) && static_buf == NULL)
|
||||
+ {
|
||||
+ /* init () has been run and we don't use the static buffer.
|
||||
+ So we have a valid key. */
|
||||
+ void *mem;
|
||||
+ /* Free the TSD memory if used. */
|
||||
+ mem = __libc_getspecific (key);
|
||||
+ if (mem != NULL)
|
||||
+ free_key_mem (mem);
|
||||
+ }
|
||||
}
|
||||
|
||||
struct dlfcn_hook *_dlfcn_hook __attribute__((nocommon));
|
||||
|
22
srcpkgs/glibc/patches/glibc-upstream-21.patch
Normal file
22
srcpkgs/glibc/patches/glibc-upstream-21.patch
Normal file
|
@ -0,0 +1,22 @@
|
|||
From 980cb43f15c4320afc6272e7a508f1415413b945 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Wielaard <mark@klomp.org>
|
||||
Date: Thu, 16 May 2019 15:25:40 +0200
|
||||
Subject: [PATCH 21] Update NEWS for BZ#24476 Guard __dlerror_main_freeres.
|
||||
|
||||
---
|
||||
NEWS | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/NEWS b/NEWS
|
||||
index c10ab5e851..17dcaa7b74 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -20,6 +20,7 @@ The following bugs are resolved with this release:
|
||||
[24164] Systemtap probes need to use "nr" constraint on 32-bit Arm
|
||||
[24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2
|
||||
[24211] Use-after-free in Systemtap probe in pthread_join
|
||||
+ [24476] dlfcn: Guard __dlerror_main_freeres with __libc_once_get (once)
|
||||
|
||||
Security related changes:
|
||||
|
||||
|
79
srcpkgs/glibc/patches/glibc-upstream-22.patch
Normal file
79
srcpkgs/glibc/patches/glibc-upstream-22.patch
Normal file
|
@ -0,0 +1,79 @@
|
|||
From 95d66fecaabbc92ab53027e808f0fc1929c9f21a Mon Sep 17 00:00:00 2001
|
||||
From: Wilco Dijkstra <wdijkstr@arm.com>
|
||||
Date: Fri, 10 May 2019 16:38:21 +0100
|
||||
Subject: [PATCH 22] Fix tcache count maximum (BZ #24531)
|
||||
|
||||
The tcache counts[] array is a char, which has a very small range and thus
|
||||
may overflow. When setting tcache_count tunable, there is no overflow check.
|
||||
However the tunable must not be larger than the maximum value of the tcache
|
||||
counts[] array, otherwise it can overflow when filling the tcache.
|
||||
|
||||
[BZ #24531]
|
||||
* malloc/malloc.c (MAX_TCACHE_COUNT): New define.
|
||||
(do_set_tcache_count): Only update if count is small enough.
|
||||
* manual/tunables.texi (glibc.malloc.tcache_count): Document max value.
|
||||
|
||||
(cherry picked from commit 5ad533e8e65092be962e414e0417112c65d154fb)
|
||||
---
|
||||
ChangeLog | 7 +++++++
|
||||
malloc/malloc.c | 9 +++++++--
|
||||
manual/tunables.texi | 4 ++--
|
||||
3 files changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ChangeLog b/ChangeLog
|
||||
index de8c5c214d..f4586d34a3 100644
|
||||
--- a/ChangeLog
|
||||
+++ b/ChangeLog
|
||||
@@ -1,3 +1,10 @@
|
||||
+2019-05-22 Wilco Dijkstra <wdijkstr@arm.com>
|
||||
+
|
||||
+ [BZ #24531]
|
||||
+ * malloc/malloc.c (MAX_TCACHE_COUNT): New define.
|
||||
+ (do_set_tcache_count): Only update if count is small enough.
|
||||
+ * manual/tunables.texi (glibc.malloc.tcache_count): Document max value.
|
||||
+
|
||||
2019-05-15 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
[BZ#24476]
|
||||
diff --git a/malloc/malloc.c b/malloc/malloc.c
|
||||
index ce771375b6..0abd653be2 100644
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -2919,6 +2919,8 @@ typedef struct tcache_perthread_struct
|
||||
tcache_entry *entries[TCACHE_MAX_BINS];
|
||||
} tcache_perthread_struct;
|
||||
|
||||
+#define MAX_TCACHE_COUNT 127 /* Maximum value of counts[] entries. */
|
||||
+
|
||||
static __thread bool tcache_shutting_down = false;
|
||||
static __thread tcache_perthread_struct *tcache = NULL;
|
||||
|
||||
@@ -5124,8 +5126,11 @@ static inline int
|
||||
__always_inline
|
||||
do_set_tcache_count (size_t value)
|
||||
{
|
||||
- LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count);
|
||||
- mp_.tcache_count = value;
|
||||
+ if (value <= MAX_TCACHE_COUNT)
|
||||
+ {
|
||||
+ LIBC_PROBE (memory_tunable_tcache_count, 2, value, mp_.tcache_count);
|
||||
+ mp_.tcache_count = value;
|
||||
+ }
|
||||
return 1;
|
||||
}
|
||||
|
||||
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||
index af820820e0..8edfea4edd 100644
|
||||
--- a/manual/tunables.texi
|
||||
+++ b/manual/tunables.texi
|
||||
@@ -189,8 +189,8 @@ per-thread cache. The default (and maximum) value is 1032 bytes on
|
||||
|
||||
@deftp Tunable glibc.malloc.tcache_count
|
||||
The maximum number of chunks of each size to cache. The default is 7.
|
||||
-There is no upper limit, other than available system memory. If set
|
||||
-to zero, the per-thread cache is effectively disabled.
|
||||
+The upper limit is 127. If set to zero, the per-thread cache is effectively
|
||||
+disabled.
|
||||
|
||||
The approximate maximum overhead of the per-thread cache is thus equal
|
||||
to the number of bins times the chunk count in each bin times the size
|
|
@ -1,7 +1,7 @@
|
|||
# Template file for 'glibc'
|
||||
pkgname=glibc
|
||||
version=2.29
|
||||
revision=3
|
||||
revision=4
|
||||
bootstrap=yes
|
||||
short_desc="GNU C library"
|
||||
maintainer="Juan RP <xtraeme@voidlinux.org>"
|
||||
|
|
Loading…
Add table
Reference in a new issue