backport patches from upstream
(cherry picked from commit d7460c58d721d6a431ce21d0bd3e455c1070abea)
This commit is contained in:
parent
1606a31010
commit
8b3679adf0
120
backport-Avoid-use-of-atoi-in-some-places-in-libc.patch
Normal file
120
backport-Avoid-use-of-atoi-in-some-places-in-libc.patch
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
From a3708cf6b0a5a68e2ed1ce3db28a03ed21d368d2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Mon, 19 Dec 2022 14:45:44 +0000
|
||||||
|
Subject: [PATCH] Avoid use of atoi in some places in libc
|
||||||
|
|
||||||
|
This patch is split out of
|
||||||
|
<https://sourceware.org/pipermail/libc-alpha/2022-December/144122.html>.
|
||||||
|
|
||||||
|
atoi has undefined behavior on out-of-range input, which makes it
|
||||||
|
problematic to use anywhere in glibc that might be processing input
|
||||||
|
out-of-range for atoi but not specified to produce undefined behavior
|
||||||
|
for the function calling atoi. Change some uses of atoi to call
|
||||||
|
strtol instead; this avoids the undefined behavior, though there is no
|
||||||
|
guarantee that the overflow handling of strtol is really right in
|
||||||
|
those places either. This also serves to avoid localplt test failures
|
||||||
|
given an installed header redirection for strtol (which means that the
|
||||||
|
call from the inline atoi implementation doesn't end up at a hidden
|
||||||
|
alias from libc_hidden_proto).
|
||||||
|
|
||||||
|
Certainly, the use of atoi is questionable in argp-help.c (shared with
|
||||||
|
gnulib, so shouldn't depend on glibc implementation details, and
|
||||||
|
processing user-provided input), and maybe also in argp-parse.c (I'm
|
||||||
|
not sure what that code in argp-parse.c is meant to be used for). I
|
||||||
|
also changed inet/rexec.c and resolv/res_init.c similarly to use
|
||||||
|
strtol to avoid such localplt failures, although given those files (in
|
||||||
|
those versions) are only used in glibc it's not problematic for them
|
||||||
|
to rely on the specific behavior of glibc's atoi on out-of-range input
|
||||||
|
(in the absence of compiler optimizations based on the undefined
|
||||||
|
behavior) in the same way it's problematic for gnulib code to do so.
|
||||||
|
|
||||||
|
There may be other uses of atoi (or atol or atoll), in any of glibc's
|
||||||
|
installed code, for which it would also be appropriate to avoid the
|
||||||
|
undefined behavior on out-of-range input; this patch only fixes the
|
||||||
|
specific cases needed to avoid localplt failures.
|
||||||
|
|
||||||
|
Tested for x86_64.
|
||||||
|
---
|
||||||
|
argp/argp-help.c | 6 +++---
|
||||||
|
argp/argp-parse.c | 2 +-
|
||||||
|
inet/rexec.c | 2 +-
|
||||||
|
resolv/res_init.c | 6 +++---
|
||||||
|
4 files changed, 8 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/argp/argp-help.c b/argp/argp-help.c
|
||||||
|
index 90a2795cef..f7f1134c80 100644
|
||||||
|
--- a/argp/argp-help.c
|
||||||
|
+++ b/argp/argp-help.c
|
||||||
|
@@ -210,9 +210,9 @@ fill_in_uparams (const struct argp_state *state)
|
||||||
|
}
|
||||||
|
else if (isdigit ((unsigned char) *arg))
|
||||||
|
{
|
||||||
|
- val = atoi (arg);
|
||||||
|
- while (isdigit ((unsigned char) *arg))
|
||||||
|
- arg++;
|
||||||
|
+ char *ep;
|
||||||
|
+ val = strtol (arg, &ep, 10);
|
||||||
|
+ arg = ep;
|
||||||
|
SKIPWS (arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/argp/argp-parse.c b/argp/argp-parse.c
|
||||||
|
index 68dc45417b..1533b43aaf 100644
|
||||||
|
--- a/argp/argp-parse.c
|
||||||
|
+++ b/argp/argp-parse.c
|
||||||
|
@@ -147,7 +147,7 @@ argp_default_parser (int key, char *arg, struct argp_state *state)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPT_HANG:
|
||||||
|
- _argp_hang = atoi (arg ? arg : "3600");
|
||||||
|
+ _argp_hang = arg ? strtol (arg, NULL, 10) : 3600;
|
||||||
|
while (_argp_hang-- > 0)
|
||||||
|
__sleep (1);
|
||||||
|
break;
|
||||||
|
diff --git a/inet/rexec.c b/inet/rexec.c
|
||||||
|
index 064e979d68..c647b7ac34 100644
|
||||||
|
--- a/inet/rexec.c
|
||||||
|
+++ b/inet/rexec.c
|
||||||
|
@@ -134,7 +134,7 @@ retry:
|
||||||
|
if (!getnameinfo(&sa2.sa, sa2len,
|
||||||
|
NULL, 0, servbuff, sizeof(servbuff),
|
||||||
|
NI_NUMERICSERV))
|
||||||
|
- port = atoi(servbuff);
|
||||||
|
+ port = strtol(servbuff, NULL, 10);
|
||||||
|
(void) sprintf(num, "%u", port);
|
||||||
|
(void) __write(s, num, strlen(num)+1);
|
||||||
|
{ socklen_t len = sizeof (from);
|
||||||
|
diff --git a/resolv/res_init.c b/resolv/res_init.c
|
||||||
|
index 2c0bea658e..61b958a437 100644
|
||||||
|
--- a/resolv/res_init.c
|
||||||
|
+++ b/resolv/res_init.c
|
||||||
|
@@ -654,7 +654,7 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options)
|
||||||
|
/* Search for and process individual options. */
|
||||||
|
if (!strncmp (cp, "ndots:", sizeof ("ndots:") - 1))
|
||||||
|
{
|
||||||
|
- int i = atoi (cp + sizeof ("ndots:") - 1);
|
||||||
|
+ int i = strtol (cp + sizeof ("ndots:") - 1, NULL, 10);
|
||||||
|
if (i <= RES_MAXNDOTS)
|
||||||
|
parser->template.ndots = i;
|
||||||
|
else
|
||||||
|
@@ -662,7 +662,7 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options)
|
||||||
|
}
|
||||||
|
else if (!strncmp (cp, "timeout:", sizeof ("timeout:") - 1))
|
||||||
|
{
|
||||||
|
- int i = atoi (cp + sizeof ("timeout:") - 1);
|
||||||
|
+ int i = strtol (cp + sizeof ("timeout:") - 1, NULL, 10);
|
||||||
|
if (i <= RES_MAXRETRANS)
|
||||||
|
parser->template.retrans = i;
|
||||||
|
else
|
||||||
|
@@ -670,7 +670,7 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options)
|
||||||
|
}
|
||||||
|
else if (!strncmp (cp, "attempts:", sizeof ("attempts:") - 1))
|
||||||
|
{
|
||||||
|
- int i = atoi (cp + sizeof ("attempts:") - 1);
|
||||||
|
+ int i = strtol (cp + sizeof ("attempts:") - 1, NULL, 10);
|
||||||
|
if (i <= RES_MAXRETRY)
|
||||||
|
parser->template.retry = i;
|
||||||
|
else
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
194
backport-gmon-fix-memory-corruption-issues-BZ-30101.patch
Normal file
194
backport-gmon-fix-memory-corruption-issues-BZ-30101.patch
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
From bde121872001d8f3224eeafa5b7effb871c3fbca Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Kissane <skissane@gmail.com>
|
||||||
|
Date: Sat, 11 Feb 2023 08:58:02 +1100
|
||||||
|
Subject: [PATCH] gmon: fix memory corruption issues [BZ# 30101]
|
||||||
|
|
||||||
|
V2 of this patch fixes an issue in V1, where the state was changed to ON not
|
||||||
|
OFF at end of _mcleanup. I hadn't noticed that (counterintuitively) ON=0 and
|
||||||
|
OFF=3, hence zeroing the buffer turned it back on. So set the state to OFF
|
||||||
|
after the memset.
|
||||||
|
|
||||||
|
1. Prevent double free, and reads from unallocated memory, when
|
||||||
|
_mcleanup is (incorrectly) called two or more times in a row,
|
||||||
|
without an intervening call to __monstartup; with this patch, the
|
||||||
|
second and subsequent calls effectively become no-ops instead.
|
||||||
|
While setting tos=NULL is minimal fix, safest action is to zero the
|
||||||
|
whole gmonparam buffer.
|
||||||
|
|
||||||
|
2. Prevent memory leak when __monstartup is (incorrectly) called two
|
||||||
|
or more times in a row, without an intervening call to _mcleanup;
|
||||||
|
with this patch, the second and subsequent calls effectively become
|
||||||
|
no-ops instead.
|
||||||
|
|
||||||
|
3. After _mcleanup, treat __moncontrol(1) as __moncontrol(0) instead.
|
||||||
|
With zeroing of gmonparam buffer in _mcleanup, this stops the
|
||||||
|
state incorrectly being changed to GMON_PROF_ON despite profiling
|
||||||
|
actually being off. If we'd just done the minimal fix to _mcleanup
|
||||||
|
of setting tos=NULL, there is risk of far worse memory corruption:
|
||||||
|
kcount would point to deallocated memory, and the __profil syscall
|
||||||
|
would make the kernel write profiling data into that memory,
|
||||||
|
which could have since been reallocated to something unrelated.
|
||||||
|
|
||||||
|
4. Ensure __moncontrol(0) still turns off profiling even in error
|
||||||
|
state. Otherwise, if mcount overflows and sets state to
|
||||||
|
GMON_PROF_ERROR, when _mcleanup calls __moncontrol(0), the __profil
|
||||||
|
syscall to disable profiling will not be invoked. _mcleanup will
|
||||||
|
free the buffer, but the kernel will still be writing profiling
|
||||||
|
data into it, potentially corrupted arbitrary memory.
|
||||||
|
|
||||||
|
Also adds a test case for (1). Issues (2)-(4) are not feasible to test.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Kissane <skissane@gmail.com>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
---
|
||||||
|
gmon/Makefile | 15 ++++++++++++++-
|
||||||
|
gmon/gmon.c | 26 +++++++++++++++++++-------
|
||||||
|
gmon/tst-mcleanup.c | 31 +++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 64 insertions(+), 8 deletions(-)
|
||||||
|
create mode 100644 gmon/tst-mcleanup.c
|
||||||
|
|
||||||
|
diff --git a/gmon/Makefile b/gmon/Makefile
|
||||||
|
index 706f50f7..475e533c 100644
|
||||||
|
--- a/gmon/Makefile
|
||||||
|
+++ b/gmon/Makefile
|
||||||
|
@@ -1,4 +1,5 @@
|
||||||
|
# Copyright (C) 1995-2021 Free Software Foundation, Inc.
|
||||||
|
+# Copyright The GNU Toolchain Authors.
|
||||||
|
# This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
# The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@@ -25,7 +26,7 @@ include ../Makeconfig
|
||||||
|
headers := sys/gmon.h sys/gmon_out.h sys/profil.h
|
||||||
|
routines := gmon mcount profil sprofil prof-freq
|
||||||
|
|
||||||
|
-tests = tst-sprofil tst-gmon tst-mcount-overflow
|
||||||
|
+tests = tst-sprofil tst-gmon tst-mcount-overflow tst-mcleanup
|
||||||
|
ifeq ($(build-profile),yes)
|
||||||
|
tests += tst-profile-static
|
||||||
|
tests-static += tst-profile-static
|
||||||
|
@@ -68,6 +69,14 @@ ifeq ($(run-built-tests),yes)
|
||||||
|
tests-special += $(objpfx)tst-mcount-overflow-check.out
|
||||||
|
endif
|
||||||
|
|
||||||
|
+CFLAGS-tst-mcleanup.c := -fno-omit-frame-pointer -pg
|
||||||
|
+tst-mcleanup-no-pie = yes
|
||||||
|
+CRT-tst-mcleanup := $(csu-objpfx)g$(start-installed-name)
|
||||||
|
+tst-mcleanup-ENV := GMON_OUT_PREFIX=$(objpfx)tst-mcleanup.data
|
||||||
|
+ifeq ($(run-built-tests),yes)
|
||||||
|
+tests-special += $(objpfx)tst-mcleanup.out
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
CFLAGS-tst-gmon-static.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg
|
||||||
|
CRT-tst-gmon-static := $(csu-objpfx)gcrt1.o
|
||||||
|
tst-gmon-static-no-pie = yes
|
||||||
|
@@ -123,6 +132,10 @@ $(objpfx)tst-mcount-overflow-check.out: tst-mcount-overflow-check.sh $(objpfx)ts
|
||||||
|
$(SHELL) $< $(objpfx)tst-mcount-overflow > $@; \
|
||||||
|
$(evaluate-test)
|
||||||
|
|
||||||
|
+$(objpfx)tst-mcleanup.out: clean-tst-mcleanup-data
|
||||||
|
+clean-tst-mcleanup-data:
|
||||||
|
+ rm -f $(objpfx)tst-mcleanup.data.*
|
||||||
|
+
|
||||||
|
$(objpfx)tst-gmon-gprof.out: tst-gmon-gprof.sh $(objpfx)tst-gmon.out
|
||||||
|
$(SHELL) $< $(GPROF) $(objpfx)tst-gmon $(objpfx)tst-gmon.data.* > $@; \
|
||||||
|
$(evaluate-test)
|
||||||
|
diff --git a/gmon/gmon.c b/gmon/gmon.c
|
||||||
|
index 689bf801..5e99a735 100644
|
||||||
|
--- a/gmon/gmon.c
|
||||||
|
+++ b/gmon/gmon.c
|
||||||
|
@@ -102,11 +102,8 @@ __moncontrol (int mode)
|
||||||
|
{
|
||||||
|
struct gmonparam *p = &_gmonparam;
|
||||||
|
|
||||||
|
- /* Don't change the state if we ran into an error. */
|
||||||
|
- if (p->state == GMON_PROF_ERROR)
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
- if (mode)
|
||||||
|
+ /* Treat start request as stop if error or gmon not initialized. */
|
||||||
|
+ if (mode && p->state != GMON_PROF_ERROR && p->tos != NULL)
|
||||||
|
{
|
||||||
|
/* start */
|
||||||
|
__profil((void *) p->kcount, p->kcountsize, p->lowpc, s_scale);
|
||||||
|
@@ -116,7 +113,9 @@ __moncontrol (int mode)
|
||||||
|
{
|
||||||
|
/* stop */
|
||||||
|
__profil(NULL, 0, 0, 0);
|
||||||
|
- p->state = GMON_PROF_OFF;
|
||||||
|
+ /* Don't change the state if we ran into an error. */
|
||||||
|
+ if (p->state != GMON_PROF_ERROR)
|
||||||
|
+ p->state = GMON_PROF_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
libc_hidden_def (__moncontrol)
|
||||||
|
@@ -146,6 +145,14 @@ __monstartup (u_long lowpc, u_long highpc)
|
||||||
|
maxarcs = MAXARCS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * If we are incorrectly called twice in a row (without an
|
||||||
|
+ * intervening call to _mcleanup), ignore the second call to
|
||||||
|
+ * prevent leaking memory.
|
||||||
|
+ */
|
||||||
|
+ if (p->tos != NULL)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* round lowpc and highpc to multiples of the density we're using
|
||||||
|
* so the rest of the scaling (here and in gprof) stays in ints.
|
||||||
|
@@ -463,9 +470,14 @@ _mcleanup (void)
|
||||||
|
{
|
||||||
|
__moncontrol (0);
|
||||||
|
|
||||||
|
- if (_gmonparam.state != GMON_PROF_ERROR)
|
||||||
|
+ if (_gmonparam.state != GMON_PROF_ERROR && _gmonparam.tos != NULL)
|
||||||
|
write_gmon ();
|
||||||
|
|
||||||
|
/* free the memory. */
|
||||||
|
free (_gmonparam.tos);
|
||||||
|
+
|
||||||
|
+ /* reset buffer to initial state for safety */
|
||||||
|
+ memset(&_gmonparam, 0, sizeof _gmonparam);
|
||||||
|
+ /* somewhat confusingly, ON=0, OFF=3 */
|
||||||
|
+ _gmonparam.state = GMON_PROF_OFF;
|
||||||
|
}
|
||||||
|
diff --git a/gmon/tst-mcleanup.c b/gmon/tst-mcleanup.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..b259653e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/gmon/tst-mcleanup.c
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+/* Test program for repeated invocation of _mcleanup
|
||||||
|
+ Copyright The GNU Toolchain Authors.
|
||||||
|
+ 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
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+/* Intentionally calls _mcleanup() twice: once manually, it will be
|
||||||
|
+ called again as an atexit handler. This is incorrect use of the API,
|
||||||
|
+ but the point of the test is to make sure we don't crash when the
|
||||||
|
+ API is misused in this way. */
|
||||||
|
+
|
||||||
|
+#include <sys/gmon.h>
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+main (void)
|
||||||
|
+{
|
||||||
|
+ _mcleanup();
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
424
backport-gmon-improve-mcount-overflow-handling-BZ-27576.patch
Normal file
424
backport-gmon-improve-mcount-overflow-handling-BZ-27576.patch
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
From 31be941e4367c001b2009308839db5c67bf9dcbc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Kissane <skissane@gmail.com>
|
||||||
|
Date: Sat, 11 Feb 2023 20:12:13 +1100
|
||||||
|
Subject: [PATCH] gmon: improve mcount overflow handling [BZ# 27576]
|
||||||
|
|
||||||
|
When mcount overflows, no gmon.out file is generated, but no message is printed
|
||||||
|
to the user, leaving the user with no idea why, and thinking maybe there is
|
||||||
|
some bug - which is how BZ 27576 ended up being logged. Print a message to
|
||||||
|
stderr in this case so the user knows what is going on.
|
||||||
|
|
||||||
|
As a comment in sys/gmon.h acknowledges, the hardcoded MAXARCS value is too
|
||||||
|
small for some large applications, including the test case in that BZ. Rather
|
||||||
|
than increase it, add tunables to enable MINARCS and MAXARCS to be overridden
|
||||||
|
at runtime (glibc.gmon.minarcs and glibc.gmon.maxarcs). So if a user gets the
|
||||||
|
mcount overflow error, they can try increasing maxarcs (they might need to
|
||||||
|
increase minarcs too if the heuristic is wrong in their case.)
|
||||||
|
|
||||||
|
Note setting minarcs/maxarcs too large can cause monstartup to fail with an
|
||||||
|
out of memory error. If you set them large enough, it can cause an integer
|
||||||
|
overflow in calculating the buffer size. I haven't done anything to defend
|
||||||
|
against that - it would not generally be a security vulnerability, since these
|
||||||
|
tunables will be ignored in suid/sgid programs (due to the SXID_ERASE default),
|
||||||
|
and if you can set GLIBC_TUNABLES in the environment of a process, you can take
|
||||||
|
it over anyway (LD_PRELOAD, LD_LIBRARY_PATH, etc). I thought about modifying
|
||||||
|
the code of monstartup to defend against integer overflows, but doing so is
|
||||||
|
complicated, and I realise the existing code is susceptible to them even prior
|
||||||
|
to this change (e.g. try passing a pathologically large highpc argument to
|
||||||
|
monstartup), so I decided just to leave that possibility in-place.
|
||||||
|
|
||||||
|
Add a test case which demonstrates mcount overflow and the tunables.
|
||||||
|
|
||||||
|
Document the new tunables in the manual.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Kissane <skissane@gmail.com>
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
---
|
||||||
|
elf/dl-tunables.list | 13 ++++++
|
||||||
|
gmon/Makefile | 22 +++++++++-
|
||||||
|
gmon/gmon.c | 29 +++++++++++--
|
||||||
|
gmon/mcount.c | 5 +++
|
||||||
|
gmon/sys/gmon.h | 6 ++-
|
||||||
|
gmon/tst-mcount-overflow-check.sh | 45 +++++++++++++++++++
|
||||||
|
gmon/tst-mcount-overflow.c | 72 +++++++++++++++++++++++++++++++
|
||||||
|
manual/tunables.texi | 59 +++++++++++++++++++++++++
|
||||||
|
8 files changed, 244 insertions(+), 7 deletions(-)
|
||||||
|
create mode 100644 gmon/tst-mcount-overflow-check.sh
|
||||||
|
create mode 100644 gmon/tst-mcount-overflow.c
|
||||||
|
|
||||||
|
diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
|
||||||
|
index 379701b8..ea19387d 100644
|
||||||
|
--- a/elf/dl-tunables.list
|
||||||
|
+++ b/elf/dl-tunables.list
|
||||||
|
@@ -160,4 +160,17 @@ glibc {
|
||||||
|
security_level: SXID_IGNORE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ gmon {
|
||||||
|
+ minarcs {
|
||||||
|
+ type: INT_32
|
||||||
|
+ minval: 50
|
||||||
|
+ default: 50
|
||||||
|
+ }
|
||||||
|
+ maxarcs {
|
||||||
|
+ type: INT_32
|
||||||
|
+ minval: 50
|
||||||
|
+ default: 1048576
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
diff --git a/gmon/Makefile b/gmon/Makefile
|
||||||
|
index 7b7b8543..706f50f7 100644
|
||||||
|
--- a/gmon/Makefile
|
||||||
|
+++ b/gmon/Makefile
|
||||||
|
@@ -25,7 +25,7 @@ include ../Makeconfig
|
||||||
|
headers := sys/gmon.h sys/gmon_out.h sys/profil.h
|
||||||
|
routines := gmon mcount profil sprofil prof-freq
|
||||||
|
|
||||||
|
-tests = tst-sprofil tst-gmon
|
||||||
|
+tests = tst-sprofil tst-gmon tst-mcount-overflow
|
||||||
|
ifeq ($(build-profile),yes)
|
||||||
|
tests += tst-profile-static
|
||||||
|
tests-static += tst-profile-static
|
||||||
|
@@ -56,6 +56,18 @@ ifeq ($(run-built-tests),yes)
|
||||||
|
tests-special += $(objpfx)tst-gmon-gprof.out
|
||||||
|
endif
|
||||||
|
|
||||||
|
+CFLAGS-tst-mcount-overflow.c := -fno-omit-frame-pointer -pg
|
||||||
|
+tst-mcount-overflow-no-pie = yes
|
||||||
|
+CRT-tst-mcount-overflow := $(csu-objpfx)g$(start-installed-name)
|
||||||
|
+# Intentionally use invalid config where maxarcs<minarcs to check warning is printed
|
||||||
|
+tst-mcount-overflow-ENV := GMON_OUT_PREFIX=$(objpfx)tst-mcount-overflow.data \
|
||||||
|
+ GLIBC_TUNABLES=glibc.gmon.minarcs=51:glibc.gmon.maxarcs=50
|
||||||
|
+# Send stderr into output file because we make sure expected messages are printed
|
||||||
|
+tst-mcount-overflow-ARGS := 2>&1 1>/dev/null | cat
|
||||||
|
+ifeq ($(run-built-tests),yes)
|
||||||
|
+tests-special += $(objpfx)tst-mcount-overflow-check.out
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
CFLAGS-tst-gmon-static.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg
|
||||||
|
CRT-tst-gmon-static := $(csu-objpfx)gcrt1.o
|
||||||
|
tst-gmon-static-no-pie = yes
|
||||||
|
@@ -103,6 +115,14 @@ $(objpfx)tst-gmon.out: clean-tst-gmon-data
|
||||||
|
clean-tst-gmon-data:
|
||||||
|
rm -f $(objpfx)tst-gmon.data.*
|
||||||
|
|
||||||
|
+$(objpfx)tst-mcount-overflow.o: clean-tst-mcount-overflow-data
|
||||||
|
+clean-tst-mcount-overflow-data:
|
||||||
|
+ rm -f $(objpfx)tst-mcount-overflow.data.*
|
||||||
|
+
|
||||||
|
+$(objpfx)tst-mcount-overflow-check.out: tst-mcount-overflow-check.sh $(objpfx)tst-mcount-overflow.out
|
||||||
|
+ $(SHELL) $< $(objpfx)tst-mcount-overflow > $@; \
|
||||||
|
+ $(evaluate-test)
|
||||||
|
+
|
||||||
|
$(objpfx)tst-gmon-gprof.out: tst-gmon-gprof.sh $(objpfx)tst-gmon.out
|
||||||
|
$(SHELL) $< $(GPROF) $(objpfx)tst-gmon $(objpfx)tst-gmon.data.* > $@; \
|
||||||
|
$(evaluate-test)
|
||||||
|
diff --git a/gmon/gmon.c b/gmon/gmon.c
|
||||||
|
index bf76358d..689bf801 100644
|
||||||
|
--- a/gmon/gmon.c
|
||||||
|
+++ b/gmon/gmon.c
|
||||||
|
@@ -46,6 +46,11 @@
|
||||||
|
#include <libc-internal.h>
|
||||||
|
#include <not-cancel.h>
|
||||||
|
|
||||||
|
+#if HAVE_TUNABLES
|
||||||
|
+# define TUNABLE_NAMESPACE gmon
|
||||||
|
+# include <elf/dl-tunables.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#ifdef PIC
|
||||||
|
# include <link.h>
|
||||||
|
|
||||||
|
@@ -124,6 +129,22 @@ __monstartup (u_long lowpc, u_long highpc)
|
||||||
|
int o;
|
||||||
|
char *cp;
|
||||||
|
struct gmonparam *p = &_gmonparam;
|
||||||
|
+ long int minarcs, maxarcs;
|
||||||
|
+
|
||||||
|
+#if HAVE_TUNABLES
|
||||||
|
+ /* Read minarcs/maxarcs tunables. */
|
||||||
|
+ minarcs = TUNABLE_GET (minarcs, int32_t, NULL);
|
||||||
|
+ maxarcs = TUNABLE_GET (maxarcs, int32_t, NULL);
|
||||||
|
+ if (maxarcs < minarcs)
|
||||||
|
+ {
|
||||||
|
+ ERR("monstartup: maxarcs < minarcs, setting maxarcs = minarcs\n");
|
||||||
|
+ maxarcs = minarcs;
|
||||||
|
+ }
|
||||||
|
+#else
|
||||||
|
+ /* No tunables, we use hardcoded defaults */
|
||||||
|
+ minarcs = MINARCS;
|
||||||
|
+ maxarcs = MAXARCS;
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* round lowpc and highpc to multiples of the density we're using
|
||||||
|
@@ -146,10 +167,10 @@ __monstartup (u_long lowpc, u_long highpc)
|
||||||
|
}
|
||||||
|
p->fromssize = ROUNDUP(p->textsize / HASHFRACTION, sizeof(*p->froms));
|
||||||
|
p->tolimit = p->textsize * ARCDENSITY / 100;
|
||||||
|
- if (p->tolimit < MINARCS)
|
||||||
|
- p->tolimit = MINARCS;
|
||||||
|
- else if (p->tolimit > MAXARCS)
|
||||||
|
- p->tolimit = MAXARCS;
|
||||||
|
+ if (p->tolimit < minarcs)
|
||||||
|
+ p->tolimit = minarcs;
|
||||||
|
+ else if (p->tolimit > maxarcs)
|
||||||
|
+ p->tolimit = maxarcs;
|
||||||
|
p->tossize = p->tolimit * sizeof(struct tostruct);
|
||||||
|
|
||||||
|
cp = calloc (p->kcountsize + p->fromssize + p->tossize, 1);
|
||||||
|
diff --git a/gmon/mcount.c b/gmon/mcount.c
|
||||||
|
index 9d4a1a50..f7180fdb 100644
|
||||||
|
--- a/gmon/mcount.c
|
||||||
|
+++ b/gmon/mcount.c
|
||||||
|
@@ -41,6 +41,10 @@ static char sccsid[] = "@(#)mcount.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
|
||||||
|
#include <atomic.h>
|
||||||
|
|
||||||
|
+#include <not-cancel.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#define ERR(s) __write_nocancel (STDERR_FILENO, s, sizeof (s) - 1)
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* mcount is called on entry to each function compiled with the profiling
|
||||||
|
* switch set. _mcount(), which is declared in a machine-dependent way
|
||||||
|
@@ -170,6 +174,7 @@ done:
|
||||||
|
return;
|
||||||
|
overflow:
|
||||||
|
p->state = GMON_PROF_ERROR;
|
||||||
|
+ ERR("mcount: call graph buffer size limit exceeded, gmon.out will not be generated\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/gmon/sys/gmon.h b/gmon/sys/gmon.h
|
||||||
|
index b4cc3b04..af0582a3 100644
|
||||||
|
--- a/gmon/sys/gmon.h
|
||||||
|
+++ b/gmon/sys/gmon.h
|
||||||
|
@@ -111,6 +111,8 @@ extern struct __bb *__bb_head;
|
||||||
|
* Always allocate at least this many tostructs. This
|
||||||
|
* hides the inadequacy of the ARCDENSITY heuristic, at least
|
||||||
|
* for small programs.
|
||||||
|
+ *
|
||||||
|
+ * Value can be overridden at runtime by glibc.gmon.minarcs tunable.
|
||||||
|
*/
|
||||||
|
#define MINARCS 50
|
||||||
|
|
||||||
|
@@ -124,8 +126,8 @@ extern struct __bb *__bb_head;
|
||||||
|
* Used to be max representable value of ARCINDEX minus 2, but now
|
||||||
|
* that ARCINDEX is a long, that's too large; we don't really want
|
||||||
|
* to allow a 48 gigabyte table.
|
||||||
|
- * The old value of 1<<16 wasn't high enough in practice for large C++
|
||||||
|
- * programs; will 1<<20 be adequate for long? FIXME
|
||||||
|
+ *
|
||||||
|
+ * Value can be overridden at runtime by glibc.gmon.maxarcs tunable.
|
||||||
|
*/
|
||||||
|
#define MAXARCS (1 << 20)
|
||||||
|
|
||||||
|
diff --git a/gmon/tst-mcount-overflow-check.sh b/gmon/tst-mcount-overflow-check.sh
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..27eb5538
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/gmon/tst-mcount-overflow-check.sh
|
||||||
|
@@ -0,0 +1,45 @@
|
||||||
|
+#!/bin/sh
|
||||||
|
+# Test expected messages generated when mcount overflows
|
||||||
|
+# Copyright (C) 2017-2023 Free Software Foundation, Inc.
|
||||||
|
+# Copyright The GNU Toolchain Authors.
|
||||||
|
+# 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
|
||||||
|
+# <https://www.gnu.org/licenses/>.
|
||||||
|
+
|
||||||
|
+LC_ALL=C
|
||||||
|
+export LC_ALL
|
||||||
|
+set -e
|
||||||
|
+exec 2>&1
|
||||||
|
+
|
||||||
|
+program="$1"
|
||||||
|
+
|
||||||
|
+check_msg() {
|
||||||
|
+ if ! grep -q "$1" "$program.out"; then
|
||||||
|
+ echo "FAIL: expected message not in output: $1"
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+check_msg 'monstartup: maxarcs < minarcs, setting maxarcs = minarcs'
|
||||||
|
+check_msg 'mcount: call graph buffer size limit exceeded, gmon.out will not be generated'
|
||||||
|
+
|
||||||
|
+for data_file in $1.data.*; do
|
||||||
|
+ if [ -f "$data_file" ]; then
|
||||||
|
+ echo "FAIL: expected no data files, but found $data_file"
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+echo PASS
|
||||||
|
diff --git a/gmon/tst-mcount-overflow.c b/gmon/tst-mcount-overflow.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..06cc93ef
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/gmon/tst-mcount-overflow.c
|
||||||
|
@@ -0,0 +1,72 @@
|
||||||
|
+/* Test program to trigger mcount overflow in profiling collection.
|
||||||
|
+ Copyright (C) 2017-2023 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
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+/* Program with sufficiently complex, yet pointless, call graph
|
||||||
|
+ that it will trigger an mcount overflow, when you set the
|
||||||
|
+ minarcs/maxarcs tunables to very low values. */
|
||||||
|
+
|
||||||
|
+#define PREVENT_TAIL_CALL asm volatile ("")
|
||||||
|
+
|
||||||
|
+/* Calls REP(n) macro 16 times, for n=0..15.
|
||||||
|
+ * You need to define REP(n) before using this.
|
||||||
|
+ */
|
||||||
|
+#define REPS \
|
||||||
|
+ REP(0) REP(1) REP(2) REP(3) REP(4) REP(5) REP(6) REP(7) \
|
||||||
|
+ REP(8) REP(9) REP(10) REP(11) REP(12) REP(13) REP(14) REP(15)
|
||||||
|
+
|
||||||
|
+/* Defines 16 leaf functions named f1_0 to f1_15 */
|
||||||
|
+#define REP(n) \
|
||||||
|
+ __attribute__ ((noinline, noclone, weak)) void f1_##n (void) {};
|
||||||
|
+REPS
|
||||||
|
+#undef REP
|
||||||
|
+
|
||||||
|
+/* Calls all 16 leaf functions f1_* in succession */
|
||||||
|
+__attribute__ ((noinline, noclone, weak)) void
|
||||||
|
+f2 (void)
|
||||||
|
+{
|
||||||
|
+# define REP(n) f1_##n();
|
||||||
|
+ REPS
|
||||||
|
+# undef REP
|
||||||
|
+ PREVENT_TAIL_CALL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Defines 16 functions named f2_0 to f2_15, which all just call f2 */
|
||||||
|
+#define REP(n) \
|
||||||
|
+ __attribute__ ((noinline, noclone, weak)) void \
|
||||||
|
+ f2_##n (void) { f2(); PREVENT_TAIL_CALL; };
|
||||||
|
+REPS
|
||||||
|
+#undef REP
|
||||||
|
+
|
||||||
|
+__attribute__ ((noinline, noclone, weak)) void
|
||||||
|
+f3 (int count)
|
||||||
|
+{
|
||||||
|
+ for (int i = 0; i < count; ++i)
|
||||||
|
+ {
|
||||||
|
+ /* Calls f1_0(), f2_0(), f1_1(), f2_1(), f3_0(), etc */
|
||||||
|
+# define REP(n) f1_##n(); f2_##n();
|
||||||
|
+ REPS
|
||||||
|
+# undef REP
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+main (void)
|
||||||
|
+{
|
||||||
|
+ f3 (1000);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/manual/tunables.texi b/manual/tunables.texi
|
||||||
|
index 00a83b0c..ff98a18f 100644
|
||||||
|
--- a/manual/tunables.texi
|
||||||
|
+++ b/manual/tunables.texi
|
||||||
|
@@ -77,6 +77,9 @@ glibc.malloc.check: 0 (min: 0, max: 3)
|
||||||
|
capabilities seen by @theglibc{}
|
||||||
|
* Memory Related Tunables:: Tunables that control the use of memory by
|
||||||
|
@theglibc{}.
|
||||||
|
+* gmon Tunables:: Tunables that control the gmon profiler, used in
|
||||||
|
+ conjunction with gprof
|
||||||
|
+
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Tunable names
|
||||||
|
@@ -598,3 +601,59 @@ support in the kernel if this tunable has any non-zero value.
|
||||||
|
|
||||||
|
The default value is @samp{0}, which disables all memory tagging.
|
||||||
|
@end deftp
|
||||||
|
+
|
||||||
|
+@node gmon Tunables
|
||||||
|
+@section gmon Tunables
|
||||||
|
+@cindex gmon tunables
|
||||||
|
+
|
||||||
|
+@deftp {Tunable namespace} glibc.gmon
|
||||||
|
+This tunable namespace affects the behaviour of the gmon profiler.
|
||||||
|
+gmon is a component of @theglibc{} which is normally used in
|
||||||
|
+conjunction with gprof.
|
||||||
|
+
|
||||||
|
+When GCC compiles a program with the @code{-pg} option, it instruments
|
||||||
|
+the program with calls to the @code{mcount} function, to record the
|
||||||
|
+program's call graph. At program startup, a memory buffer is allocated
|
||||||
|
+to store this call graph; the size of the buffer is calculated using a
|
||||||
|
+heuristic based on code size. If during execution, the buffer is found
|
||||||
|
+to be too small, profiling will be aborted and no @file{gmon.out} file
|
||||||
|
+will be produced. In that case, you will see the following message
|
||||||
|
+printed to standard error:
|
||||||
|
+
|
||||||
|
+@example
|
||||||
|
+mcount: call graph buffer size limit exceeded, gmon.out will not be generated
|
||||||
|
+@end example
|
||||||
|
+
|
||||||
|
+Most of the symbols discussed in this section are defined in the header
|
||||||
|
+@code{sys/gmon.h}. However, some symbols (for example @code{mcount})
|
||||||
|
+are not defined in any header file, since they are only intended to be
|
||||||
|
+called from code generated by the compiler.
|
||||||
|
+@end deftp
|
||||||
|
+
|
||||||
|
+@deftp Tunable glibc.mem.minarcs
|
||||||
|
+The heuristic for sizing the call graph buffer is known to be
|
||||||
|
+insufficient for small programs; hence, the calculated value is clamped
|
||||||
|
+to be at least a minimum size. The default minimum (in units of
|
||||||
|
+call graph entries, @code{struct tostruct}), is given by the macro
|
||||||
|
+@code{MINARCS}. If you have some program with an unusually complex
|
||||||
|
+call graph, for which the heuristic fails to allocate enough space,
|
||||||
|
+you can use this tunable to increase the minimum to a larger value.
|
||||||
|
+@end deftp
|
||||||
|
+
|
||||||
|
+@deftp Tunable glibc.mem.maxarcs
|
||||||
|
+To prevent excessive memory consumption when profiling very large
|
||||||
|
+programs, the call graph buffer is allowed to have a maximum of
|
||||||
|
+@code{MAXARCS} entries. For some very large programs, the default
|
||||||
|
+value of @code{MAXARCS} defined in @file{sys/gmon.h} is too small; in
|
||||||
|
+that case, you can use this tunable to increase it.
|
||||||
|
+
|
||||||
|
+Note the value of the @code{maxarcs} tunable must be greater or equal
|
||||||
|
+to that of the @code{minarcs} tunable; if this constraint is violated,
|
||||||
|
+a warning will printed to standard error at program startup, and
|
||||||
|
+the @code{minarcs} value will be used as the maximum as well.
|
||||||
|
+
|
||||||
|
+Setting either tunable too high may result in a call graph buffer
|
||||||
|
+whose size exceeds the available memory; in that case, an out of memory
|
||||||
|
+error will be printed at program startup, the profiler will be
|
||||||
|
+disabled, and no @file{gmon.out} file will be generated.
|
||||||
|
+@end deftp
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,290 @@
|
|||||||
|
From 436a604b7dc741fc76b5a6704c6cd8bb178518e7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adam Yi <ayi@janestreet.com>
|
||||||
|
Date: Tue, 7 Mar 2023 07:30:02 -0500
|
||||||
|
Subject: [PATCH] posix: Fix system blocks SIGCHLD erroneously [BZ #30163]
|
||||||
|
|
||||||
|
Fix bug that SIGCHLD is erroneously blocked forever in the following
|
||||||
|
scenario:
|
||||||
|
|
||||||
|
1. Thread A calls system but hasn't returned yet
|
||||||
|
2. Thread B calls another system but returns
|
||||||
|
|
||||||
|
SIGCHLD would be blocked forever in thread B after its system() returns,
|
||||||
|
even after the system() in thread A returns.
|
||||||
|
|
||||||
|
Although POSIX does not require, glibc system implementation aims to be
|
||||||
|
thread and cancellation safe. This bug was introduced in
|
||||||
|
5fb7fc96350575c9adb1316833e48ca11553be49 when we moved reverting signal
|
||||||
|
mask to happen when the last concurrently running system returns,
|
||||||
|
despite that signal mask is per thread. This commit reverts this logic
|
||||||
|
and adds a test.
|
||||||
|
|
||||||
|
Signed-off-by: Adam Yi <ayi@janestreet.com>
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
---
|
||||||
|
stdlib/tst-system.c | 26 +++++++++++++++++++
|
||||||
|
support/Makefile | 2 ++
|
||||||
|
support/dtotimespec-time64.c | 27 +++++++++++++++++++
|
||||||
|
support/dtotimespec.c | 50 ++++++++++++++++++++++++++++++++++++
|
||||||
|
support/shell-container.c | 28 ++++++++++++++++++++
|
||||||
|
support/timespec.h | 4 +++
|
||||||
|
sysdeps/posix/system.c | 6 ++---
|
||||||
|
7 files changed, 140 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 support/dtotimespec-time64.c
|
||||||
|
create mode 100644 support/dtotimespec.c
|
||||||
|
|
||||||
|
diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c
|
||||||
|
index 178808e0..d1413d7c 100644
|
||||||
|
--- a/stdlib/tst-system.c
|
||||||
|
+++ b/stdlib/tst-system.c
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
#include <support/check.h>
|
||||||
|
#include <support/temp_file.h>
|
||||||
|
#include <support/support.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
#include <support/xunistd.h>
|
||||||
|
|
||||||
|
static char *tmpdir;
|
||||||
|
@@ -72,6 +73,20 @@ call_system (void *closure)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void *
|
||||||
|
+sleep_and_check_sigchld (void *closure)
|
||||||
|
+{
|
||||||
|
+ double *seconds = (double *) closure;
|
||||||
|
+ char cmd[namemax];
|
||||||
|
+ sprintf (cmd, "sleep %lf" , *seconds);
|
||||||
|
+ TEST_COMPARE (system (cmd), 0);
|
||||||
|
+
|
||||||
|
+ sigset_t blocked = {0};
|
||||||
|
+ TEST_COMPARE (sigprocmask (SIG_BLOCK, NULL, &blocked), 0);
|
||||||
|
+ TEST_COMPARE (sigismember (&blocked, SIGCHLD), 0);
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
@@ -155,6 +170,17 @@ do_test (void)
|
||||||
|
xchmod (_PATH_BSHELL, st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ {
|
||||||
|
+ pthread_t long_sleep_thread = xpthread_create (NULL,
|
||||||
|
+ sleep_and_check_sigchld,
|
||||||
|
+ &(double) { 0.2 });
|
||||||
|
+ pthread_t short_sleep_thread = xpthread_create (NULL,
|
||||||
|
+ sleep_and_check_sigchld,
|
||||||
|
+ &(double) { 0.1 });
|
||||||
|
+ xpthread_join (short_sleep_thread);
|
||||||
|
+ xpthread_join (long_sleep_thread);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
TEST_COMPARE (system (""), 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
diff --git a/support/Makefile b/support/Makefile
|
||||||
|
index 724ae6d7..936af554 100644
|
||||||
|
--- a/support/Makefile
|
||||||
|
+++ b/support/Makefile
|
||||||
|
@@ -32,6 +32,8 @@ libsupport-routines = \
|
||||||
|
check_hostent \
|
||||||
|
check_netent \
|
||||||
|
delayed_exit \
|
||||||
|
+ dtotimespec \
|
||||||
|
+ dtotimespec-time64 \
|
||||||
|
ignore_stderr \
|
||||||
|
next_to_fault \
|
||||||
|
oom_error \
|
||||||
|
diff --git a/support/dtotimespec-time64.c b/support/dtotimespec-time64.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..b3d5e351
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/support/dtotimespec-time64.c
|
||||||
|
@@ -0,0 +1,27 @@
|
||||||
|
+/* Convert double to timespec. 64-bit time support.
|
||||||
|
+ Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library and is also part of gnulib.
|
||||||
|
+ Patches to this file should be submitted to both projects.
|
||||||
|
+
|
||||||
|
+ 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
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <time.h>
|
||||||
|
+
|
||||||
|
+#if __TIMESIZE != 64
|
||||||
|
+# define timespec __timespec64
|
||||||
|
+# define time_t __time64_t
|
||||||
|
+# define dtotimespec dtotimespec_time64
|
||||||
|
+# include "dtotimespec.c"
|
||||||
|
+#endif
|
||||||
|
diff --git a/support/dtotimespec.c b/support/dtotimespec.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..cde5b4d7
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/support/dtotimespec.c
|
||||||
|
@@ -0,0 +1,50 @@
|
||||||
|
+/* Convert double to timespec.
|
||||||
|
+ Copyright (C) 2011-2023 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library and is also part of gnulib.
|
||||||
|
+ Patches to this file should be submitted to both projects.
|
||||||
|
+
|
||||||
|
+ 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
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+/* Convert the double value SEC to a struct timespec. Round toward
|
||||||
|
+ positive infinity. On overflow, return an extremal value. */
|
||||||
|
+
|
||||||
|
+#include <support/timespec.h>
|
||||||
|
+#include <intprops.h>
|
||||||
|
+
|
||||||
|
+struct timespec
|
||||||
|
+dtotimespec (double sec)
|
||||||
|
+{
|
||||||
|
+ if (sec <= TYPE_MINIMUM (time_t))
|
||||||
|
+ return make_timespec (TYPE_MINIMUM (time_t), 0);
|
||||||
|
+ else if (sec >= 1.0 + TYPE_MAXIMUM (time_t))
|
||||||
|
+ return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_HZ - 1);
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ time_t s = sec;
|
||||||
|
+ double frac = TIMESPEC_HZ * (sec - s);
|
||||||
|
+ long ns = frac;
|
||||||
|
+ ns += ns < frac;
|
||||||
|
+ s += ns / TIMESPEC_HZ;
|
||||||
|
+ ns %= TIMESPEC_HZ;
|
||||||
|
+
|
||||||
|
+ if (ns < 0)
|
||||||
|
+ {
|
||||||
|
+ s--;
|
||||||
|
+ ns += TIMESPEC_HZ;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return make_timespec (s, ns);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/support/shell-container.c b/support/shell-container.c
|
||||||
|
index b2a4324d..6fe925dc 100644
|
||||||
|
--- a/support/shell-container.c
|
||||||
|
+++ b/support/shell-container.c
|
||||||
|
@@ -39,6 +39,7 @@
|
||||||
|
#include <error.h>
|
||||||
|
|
||||||
|
#include <support/support.h>
|
||||||
|
+#include <support/timespec.h>
|
||||||
|
|
||||||
|
/* Design considerations
|
||||||
|
|
||||||
|
@@ -171,6 +172,32 @@ kill_func (char **argv)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Emulate the "/bin/sleep" command. No suffix support. Options are
|
||||||
|
+ ignored. */
|
||||||
|
+static int
|
||||||
|
+sleep_func (char **argv)
|
||||||
|
+{
|
||||||
|
+ if (argv[0] == NULL)
|
||||||
|
+ {
|
||||||
|
+ fprintf (stderr, "sleep: missing operand\n");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ char *endptr = NULL;
|
||||||
|
+ double sec = strtod (argv[0], &endptr);
|
||||||
|
+ if (endptr == argv[0] || errno == ERANGE || sec < 0)
|
||||||
|
+ {
|
||||||
|
+ fprintf (stderr, "sleep: invalid time interval '%s'\n", argv[0]);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ struct timespec ts = dtotimespec (sec);
|
||||||
|
+ if (nanosleep (&ts, NULL) < 0)
|
||||||
|
+ {
|
||||||
|
+ fprintf (stderr, "sleep: failed to nanosleep: %s\n", strerror (errno));
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* This is a list of all the built-in commands we understand. */
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
@@ -181,6 +208,7 @@ static struct {
|
||||||
|
{ "cp", copy_func },
|
||||||
|
{ "exit", exit_func },
|
||||||
|
{ "kill", kill_func },
|
||||||
|
+ { "sleep", sleep_func },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/support/timespec.h b/support/timespec.h
|
||||||
|
index 0478aef5..843a90d6 100644
|
||||||
|
--- a/support/timespec.h
|
||||||
|
+++ b/support/timespec.h
|
||||||
|
@@ -57,6 +57,8 @@ int support_timespec_check_in_range (struct timespec expected,
|
||||||
|
struct timespec observed,
|
||||||
|
double lower_bound, double upper_bound);
|
||||||
|
|
||||||
|
+struct timespec dtotimespec (double sec) __attribute__((const));
|
||||||
|
+
|
||||||
|
#else
|
||||||
|
struct timespec __REDIRECT (timespec_add, (struct timespec, struct timespec),
|
||||||
|
timespec_add_time64);
|
||||||
|
@@ -82,6 +84,8 @@ int __REDIRECT (support_timespec_check_in_range, (struct timespec expected,
|
||||||
|
double lower_bound,
|
||||||
|
double upper_bound),
|
||||||
|
support_timespec_check_in_range_time64);
|
||||||
|
+
|
||||||
|
+struct timespec __REDIRECT (dtotimespec, (double sec), dtotimespec_time64);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check that the timespec on the left represents a time before the
|
||||||
|
diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
|
||||||
|
index 48668fb3..b9676abb 100644
|
||||||
|
--- a/sysdeps/posix/system.c
|
||||||
|
+++ b/sysdeps/posix/system.c
|
||||||
|
@@ -179,16 +179,16 @@ do_system (const char *line)
|
||||||
|
as if the shell had terminated using _exit(127). */
|
||||||
|
status = W_EXITCODE (127, 0);
|
||||||
|
|
||||||
|
+ /* sigaction can not fail with SIGINT/SIGQUIT used with old
|
||||||
|
+ disposition. Same applies for sigprocmask. */
|
||||||
|
DO_LOCK ();
|
||||||
|
if (SUB_REF () == 0)
|
||||||
|
{
|
||||||
|
- /* sigaction can not fail with SIGINT/SIGQUIT used with old
|
||||||
|
- disposition. Same applies for sigprocmask. */
|
||||||
|
__sigaction (SIGINT, &intr, NULL);
|
||||||
|
__sigaction (SIGQUIT, &quit, NULL);
|
||||||
|
- __sigprocmask (SIG_SETMASK, &omask, NULL);
|
||||||
|
}
|
||||||
|
DO_UNLOCK ();
|
||||||
|
+ __sigprocmask (SIG_SETMASK, &omask, NULL);
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
__set_errno (ret);
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,140 @@
|
|||||||
|
From fd78cfa72ea2bab30fdb4e1e0672b34471426c05 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Vitaly Buka <vitalybuka@google.com>
|
||||||
|
Date: Sat, 18 Feb 2023 12:53:41 -0800
|
||||||
|
Subject: [PATCH] stdlib: Undo post review change to 16adc58e73f3 [BZ #27749]
|
||||||
|
|
||||||
|
Post review removal of "goto restart" from
|
||||||
|
https://sourceware.org/pipermail/libc-alpha/2021-April/125470.html
|
||||||
|
introduced a bug when some atexit handers skipped.
|
||||||
|
|
||||||
|
Signed-off-by: Vitaly Buka <vitalybuka@google.com>
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
---
|
||||||
|
stdlib/Makefile | 1 +
|
||||||
|
stdlib/exit.c | 7 +++-
|
||||||
|
stdlib/test-atexit-recursive.c | 75 ++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 81 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 stdlib/test-atexit-recursive.c
|
||||||
|
|
||||||
|
diff --git a/stdlib/Makefile b/stdlib/Makefile
|
||||||
|
index a4ac30d1..73cd3370 100644
|
||||||
|
--- a/stdlib/Makefile
|
||||||
|
+++ b/stdlib/Makefile
|
||||||
|
@@ -73,6 +73,7 @@ tests := \
|
||||||
|
test-a64l \
|
||||||
|
test-at_quick_exit-race \
|
||||||
|
test-atexit-race \
|
||||||
|
+ test-atexit-recursive \
|
||||||
|
test-bz22786 \
|
||||||
|
test-canon \
|
||||||
|
test-canon2 \
|
||||||
|
diff --git a/stdlib/exit.c b/stdlib/exit.c
|
||||||
|
index 453eb85b..546343f7 100644
|
||||||
|
--- a/stdlib/exit.c
|
||||||
|
+++ b/stdlib/exit.c
|
||||||
|
@@ -53,7 +53,10 @@ __run_exit_handlers (int status, struct exit_function_list **listp,
|
||||||
|
exit (). */
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
- struct exit_function_list *cur = *listp;
|
||||||
|
+ struct exit_function_list *cur;
|
||||||
|
+
|
||||||
|
+ restart:
|
||||||
|
+ cur = *listp;
|
||||||
|
|
||||||
|
if (cur == NULL)
|
||||||
|
{
|
||||||
|
@@ -118,7 +121,7 @@ __run_exit_handlers (int status, struct exit_function_list **listp,
|
||||||
|
if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called))
|
||||||
|
/* The last exit function, or another thread, has registered
|
||||||
|
more exit functions. Start the loop over. */
|
||||||
|
- continue;
|
||||||
|
+ goto restart;
|
||||||
|
}
|
||||||
|
|
||||||
|
*listp = cur->next;
|
||||||
|
diff --git a/stdlib/test-atexit-recursive.c b/stdlib/test-atexit-recursive.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..0596b976
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/stdlib/test-atexit-recursive.c
|
||||||
|
@@ -0,0 +1,75 @@
|
||||||
|
+/* Support file for atexit/exit, etc. race tests (BZ #27749).
|
||||||
|
+ Copyright (C) 2023 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
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+/* Check that atexit handler registed from another handler still called. */
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xunistd.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+atexit_cb (void)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+atexit_last (void)
|
||||||
|
+{
|
||||||
|
+ _exit (1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+atexit_recursive (void)
|
||||||
|
+{
|
||||||
|
+ atexit (&atexit_cb);
|
||||||
|
+ atexit (&atexit_last);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+_Noreturn static void
|
||||||
|
+test_and_exit (int count)
|
||||||
|
+{
|
||||||
|
+ for (int i = 0; i < count; ++i)
|
||||||
|
+ atexit (&atexit_cb);
|
||||||
|
+ atexit (&atexit_recursive);
|
||||||
|
+ exit (0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ for (int i = 0; i < 100; ++i)
|
||||||
|
+ if (xfork () == 0)
|
||||||
|
+ test_and_exit (i);
|
||||||
|
+
|
||||||
|
+ for (int i = 0; i < 100; ++i)
|
||||||
|
+ {
|
||||||
|
+ int status;
|
||||||
|
+ xwaitpid (0, &status, 0);
|
||||||
|
+ if (!WIFEXITED (status))
|
||||||
|
+ FAIL_EXIT1 ("Failed iterations %d", i);
|
||||||
|
+ TEST_COMPARE (WEXITSTATUS (status), 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION do_test
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
14
glibc.spec
14
glibc.spec
@ -66,7 +66,7 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
Name: glibc
|
Name: glibc
|
||||||
Version: 2.34
|
Version: 2.34
|
||||||
Release: 114
|
Release: 115
|
||||||
Summary: The GNU libc libraries
|
Summary: The GNU libc libraries
|
||||||
License: %{all_license}
|
License: %{all_license}
|
||||||
URL: http://www.gnu.org/software/glibc/
|
URL: http://www.gnu.org/software/glibc/
|
||||||
@ -247,6 +247,11 @@ Patch159: io-Fix-use-after-free-in-ftw-BZ-26779.patch
|
|||||||
Patch160: backport-x86-Fix-wcsnlen-avx2-page-cross-length-comparison-BZ.patch
|
Patch160: backport-x86-Fix-wcsnlen-avx2-page-cross-length-comparison-BZ.patch
|
||||||
Patch161: gmon-Fix-allocated-buffer-overflow-bug-29444.patch
|
Patch161: gmon-Fix-allocated-buffer-overflow-bug-29444.patch
|
||||||
Patch162: malloc-Fix-transposed-arguments-in-sysmalloc_mmap_fa.patch
|
Patch162: malloc-Fix-transposed-arguments-in-sysmalloc_mmap_fa.patch
|
||||||
|
Patch163: backport-Avoid-use-of-atoi-in-some-places-in-libc.patch
|
||||||
|
Patch164: backport-stdlib-Undo-post-review-change-to-16adc58e73f3-BZ-27.patch
|
||||||
|
patch165: backport-gmon-improve-mcount-overflow-handling-BZ-27576.patch
|
||||||
|
Patch166: backport-gmon-fix-memory-corruption-issues-BZ-30101.patch
|
||||||
|
Patch167: backport-posix-Fix-system-blocks-SIGCHLD-erroneously-BZ-30163.patch
|
||||||
|
|
||||||
Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
|
Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
|
||||||
Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch
|
Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch
|
||||||
@ -1453,6 +1458,13 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Mar 27 2023 shixuantong <shixuantong1@huawei.com> - 2.34-115
|
||||||
|
- Avoid use of atoi in some places in libc
|
||||||
|
- stdlib: Undo post review change to 16adc58e73f3
|
||||||
|
- gmon: improve mcount overflow handling
|
||||||
|
- gmon: fix memory corruption issues
|
||||||
|
- posix: Fix system blocks SIGCHLD erroneously
|
||||||
|
|
||||||
* Sat Mar 25 2023 Chen Ziyang<chenziyang4@huawei.com> - 2.34-114
|
* Sat Mar 25 2023 Chen Ziyang<chenziyang4@huawei.com> - 2.34-114
|
||||||
- elf/ld.so: fix 2 bugs in ld.so mmap shared object use hugepage
|
- elf/ld.so: fix 2 bugs in ld.so mmap shared object use hugepage
|
||||||
- bugfix: ld.so mmap now first mmap 2MB continuous memory by MAP_NORESERVE flag because we do not want to revert to 4KB when 2MB resources is smaller then entire so. We want to check resources happend in later _mmap_segment_filesz function
|
- bugfix: ld.so mmap now first mmap 2MB continuous memory by MAP_NORESERVE flag because we do not want to revert to 4KB when 2MB resources is smaller then entire so. We want to check resources happend in later _mmap_segment_filesz function
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user