summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Newton <will.newton@linaro.org>2014-02-25 14:29:32 +0000
committerWill Newton <will.newton@linaro.org>2014-04-17 11:39:50 +0100
commite04a4e9d2e639a7770e1c0d24ecbcf92abf6bba8 (patch)
treedc57034fa71ff8f0701d8a1f4ad9a584f2ae0c77
parent37d350073888887637aa67dddf988d9c4b226032 (diff)
downloadglibc-e04a4e9d2e639a7770e1c0d24ecbcf92abf6bba8.tar.gz
stdlib/tst-setcontext.c: Check for clobbering of signal stack
On aarch64 calling swapcontext clobbers the state of the signal stack (BZ #16629). Check that the address and size of the signal stack before and after the call to swapcontext remains the same. ChangeLog: 2014-04-17 Will Newton <will.newton@linaro.org> [BZ #16629] * stdlib/tst-setcontext.c: Include signal.h. (main): Check that the signal stack before and after swapcontext is the same.
-rw-r--r--ChangeLog4
-rw-r--r--stdlib/tst-setcontext.c21
2 files changed, 25 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 55dcc2b652..1dd40fcf2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,10 @@
2014-04-17 Will Newton <will.newton@linaro.org>
[BZ #16629]
+ * stdlib/tst-setcontext.c: Include signal.h.
+ (main): Check that the signal stack before and
+ after swapcontext is the same.
+
* sysdeps/unix/sysv/linux/aarch64/setcontext.S (__setcontext):
Re-implement to restore registers in user code and avoid
rt_sigreturn system call.
diff --git a/stdlib/tst-setcontext.c b/stdlib/tst-setcontext.c
index ac9deb1b4f..55984a4642 100644
--- a/stdlib/tst-setcontext.c
+++ b/stdlib/tst-setcontext.c
@@ -16,6 +16,7 @@
<http://www.gnu.org/licenses/>. */
#include <errno.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -144,6 +145,9 @@ main (void)
atexit (check_called);
char st1[32768];
+ stack_t stack_before, stack_after;
+
+ sigaltstack(NULL, &stack_before);
puts ("making contexts");
if (getcontext (&ctx[1]) != 0)
@@ -207,6 +211,8 @@ main (void)
puts ("back at main program");
back_in_main = 1;
+ sigaltstack(NULL, &stack_after);
+
if (was_in_f1 == 0)
{
puts ("didn't reach f1");
@@ -218,6 +224,21 @@ main (void)
exit (1);
}
+ /* Check sigaltstack state is not clobbered as in BZ #16629. */
+ if (stack_before.ss_sp != stack_after.ss_sp)
+ {
+ printf ("stack ss_sp mismatch: %p %p\n",
+ stack_before.ss_sp, stack_after.ss_sp);
+ exit (1);
+ }
+
+ if (stack_before.ss_size != stack_after.ss_size)
+ {
+ printf ("stack ss_size mismatch: %zd %zd\n",
+ stack_before.ss_size, stack_after.ss_size);
+ exit (1);
+ }
+
puts ("test succeeded");
return 0;
}