stdlib/tst-setcontext9 test suite failure (#1623519)
This commit is contained in:
parent
dc43d3ff16
commit
b972da9df0
100
glibc-rh1623519.patch
Normal file
100
glibc-rh1623519.patch
Normal file
@ -0,0 +1,100 @@
|
||||
commit a55e109709af55e6ed67d3f9536cac5d929c982e
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Wed Sep 5 01:16:42 2018 -0400
|
||||
|
||||
Fix tst-setcontext9 for optimized small stacks.
|
||||
|
||||
If the compiler reduces the stack usage in function f1 before calling
|
||||
into function f2, then when we swapcontext back to f1 and continue
|
||||
execution we may overwrite registers that were spilled to the stack
|
||||
while f2 was executing. Later when we return to f2 the corrupt
|
||||
registers will be reloaded from the stack and the test will crash. This
|
||||
was most commonly observed on i686 with __x86.get_pc_thunk.dx and
|
||||
needing to save and restore $edx. Overall i686 has few registers and
|
||||
the spilling to the stack is bound to happen, therefore the solution to
|
||||
making this test robust is to split function f1 into two parts f1a and
|
||||
f1b, and allocate f1b it's own stack such that subsequent execution does
|
||||
not overwrite the stack in use by function f2.
|
||||
|
||||
Tested on i686 and x86_64.
|
||||
|
||||
Signed-off-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit 791b350dc725545e3f9b5db0f97ebdbc60c9735f)
|
||||
|
||||
diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
|
||||
index 4636ce9030fa38a7..db8355766ca7b906 100644
|
||||
--- a/stdlib/tst-setcontext9.c
|
||||
+++ b/stdlib/tst-setcontext9.c
|
||||
@@ -41,26 +41,55 @@ f2 (void)
|
||||
}
|
||||
|
||||
static void
|
||||
-f1 (void)
|
||||
+f1b (void)
|
||||
{
|
||||
- puts ("start f1");
|
||||
- if (getcontext (&ctx[2]) != 0)
|
||||
- {
|
||||
- printf ("%s: getcontext: %m\n", __FUNCTION__);
|
||||
- exit (EXIT_FAILURE);
|
||||
- }
|
||||
if (done)
|
||||
{
|
||||
- puts ("set context in f1");
|
||||
+ puts ("set context in f1b");
|
||||
if (setcontext (&ctx[3]) != 0)
|
||||
{
|
||||
printf ("%s: setcontext: %m\n", __FUNCTION__);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
+ exit (EXIT_FAILURE);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+f1a (void)
|
||||
+{
|
||||
+ char st2[32768];
|
||||
+ puts ("start f1a");
|
||||
+ if (getcontext (&ctx[2]) != 0)
|
||||
+ {
|
||||
+ printf ("%s: getcontext: %m\n", __FUNCTION__);
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ ctx[2].uc_stack.ss_sp = st2;
|
||||
+ ctx[2].uc_stack.ss_size = sizeof st2;
|
||||
+ ctx[2].uc_link = &ctx[0];
|
||||
+ makecontext (&ctx[2], (void (*) (void)) f1b, 0);
|
||||
f2 ();
|
||||
}
|
||||
|
||||
+/* The execution path through the test looks like this:
|
||||
+ do_test (call)
|
||||
+ -> "making contexts"
|
||||
+ -> "swap contexts"
|
||||
+ f1a (via swapcontext to ctx[1], with alternate stack)
|
||||
+ -> "start f1a"
|
||||
+ f2 (call)
|
||||
+ -> "swap contexts in f2"
|
||||
+ f1b (via swapcontext to ctx[2], with alternate stack)
|
||||
+ -> "set context in f1b"
|
||||
+ do_test (via setcontext to ctx[3], main stack)
|
||||
+ -> "setcontext"
|
||||
+ f2 (via setcontext to ctx[4], with alternate stack)
|
||||
+ -> "end f2"
|
||||
+
|
||||
+ We must use an alternate stack for f1b, because if we don't then the
|
||||
+ result of executing an earlier caller may overwrite registers
|
||||
+ spilled to the stack in f2. */
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
@@ -79,7 +108,7 @@ do_test (void)
|
||||
ctx[1].uc_stack.ss_sp = st1;
|
||||
ctx[1].uc_stack.ss_size = sizeof st1;
|
||||
ctx[1].uc_link = &ctx[0];
|
||||
- makecontext (&ctx[1], (void (*) (void)) f1, 0);
|
||||
+ makecontext (&ctx[1], (void (*) (void)) f1a, 0);
|
||||
puts ("swap contexts");
|
||||
if (swapcontext (&ctx[3], &ctx[1]) != 0)
|
||||
{
|
@ -1,6 +1,6 @@
|
||||
%define glibcsrcdir glibc-2.28
|
||||
%define glibcversion 2.28
|
||||
%define glibcrelease 12%{?dist}
|
||||
%define glibcrelease 13%{?dist}
|
||||
# Pre-release tarballs are pulled in from git using a command that is
|
||||
# effectively:
|
||||
#
|
||||
@ -169,6 +169,7 @@ Patch33: glibc-1622674-1.patch
|
||||
Patch34: glibc-1622674-2.patch
|
||||
Patch35: glibc-rh1631338-1.patch
|
||||
Patch36: glibc-rh1631338-2.patch
|
||||
Patch37: glibc-rh1623519.patch
|
||||
|
||||
##############################################################################
|
||||
# Continued list of core "glibc" package information:
|
||||
@ -1910,6 +1911,9 @@ fi
|
||||
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
||||
|
||||
%changelog
|
||||
* Wed Sep 26 2018 Florian Weimer <fweimer@redhat.com> - 2.28-13
|
||||
- stdlib/tst-setcontext9 test suite failure (#1623519)
|
||||
|
||||
* Wed Sep 26 2018 Florian Weimer <fweimer@redhat.com> - 2.28-12
|
||||
- gethostid: Missing NULL check for gethostbyname_r result (#1631338)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user