about summary refs log tree commit diff
path: root/stdlib/tst-setcontext.c
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 /stdlib/tst-setcontext.c
parent37d350073888887637aa67dddf988d9c4b226032 (diff)
downloadglibc-e04a4e9d2e639a7770e1c0d24ecbcf92abf6bba8.tar.gz
glibc-e04a4e9d2e639a7770e1c0d24ecbcf92abf6bba8.tar.xz
glibc-e04a4e9d2e639a7770e1c0d24ecbcf92abf6bba8.zip
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.
Diffstat (limited to 'stdlib/tst-setcontext.c')
-rw-r--r--stdlib/tst-setcontext.c21
1 files changed, 21 insertions, 0 deletions
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;
 }