Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > bee470e21a8ce2cdd844d7d805aa403d > files > 69

glibc-2.5-49.el5_5.6.src.rpm

2008-01-09  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/i386/makecontext.S (__makecontext): Avoid
	clobbering memory at or above uc_stack.ss_sp + uc_stack.ss_size.
	* stdlib/Makefile: Add rules to build and run tst-makecontext2.
	* stdlib/tst-makecontext2.c: New test.

2007-12-03  Ulrich Drepper  <drepper@redhat.com>

	[BZ #5435]
	* sysdeps/unix/sysv/linux/i386/makecontext.S: Align stack.

	* stdlib/tst-setcontext.c: Catch the case where the links gets
	messed up and we do not reach main again.

--- libc/sysdeps/unix/sysv/linux/i386/makecontext.S	26 May 2005 14:30:47 -0000	1.7
+++ libc/sysdeps/unix/sysv/linux/i386/makecontext.S	9 Jan 2008 19:35:15 -0000	1.9
@@ -35,24 +35,32 @@
 	movl	%ecx, oEIP(%eax)
 	addl	oSS_SIZE(%eax), %edx
 
-	/* Put the next context on the new stack (from the uc_link
-	   element).  */
-	movl	oLINK(%eax), %ecx
-	movl	%ecx, -4(%edx)
-
 	/* Remember the number of parameters for the exit handler since
 	   it has to remove them.  We store the number in the EBX register
 	   which the function we will call must preserve.  */
 	movl	12(%esp), %ecx
 	movl	%ecx, oEBX(%eax)
 
-	/* Make room on the new stack for the parameters.  */
+	/* Make room on the new stack for the parameters.
+	   Room for the arguments, return address (== L(exitcode)) and
+	   oLINK pointer is needed.  One of the pointer sizes is subtracted
+	   after aligning the stack.  */
 	negl	%ecx
-	leal	-8(%edx,%ecx,4), %edx
+	leal	-4(%edx,%ecx,4), %edx
 	negl	%ecx
+
+	/* Align the stack.  */
+	andl	$0xfffffff0, %edx
+	subl	$4, %edx
+
 	/* Store the future stack pointer.  */
 	movl	%edx, oESP(%eax)
 
+	/* Put the next context on the new stack (from the uc_link
+	   element).  */
+	movl	oLINK(%eax), %eax
+	movl	%eax, 4(%edx,%ecx,4)
+
 	/* Copy all the parameters.  */
 	jecxz	2f
 1:	movl	12(%esp,%ecx,4), %eax
--- libc/stdlib/tst-setcontext.c	3 Mar 2006 11:51:31 -0000	1.8
+++ libc/stdlib/tst-setcontext.c	3 Dec 2007 04:11:25 -0000	1.9
@@ -123,9 +123,26 @@ test_stack(volatile int a, volatile int 
 
 volatile int global;
 
+
+static int back_in_main;
+
+
+static void
+check_called (void)
+{
+  if (back_in_main == 0)
+    {
+      puts ("program did no reach main again");
+      _exit (1);
+    }
+}
+
+
 int
 main (void)
 {
+  atexit (check_called);
+
   char st1[32768];
 
   puts ("making contexts");
@@ -185,6 +202,7 @@ main (void)
       exit (1);
     }
   puts ("back at main program");
+  back_in_main = 1;
 
   if (was_in_f1 == 0)
     {
--- libc/stdlib/Makefile	5 Oct 2007 06:50:27 -0000	1.119
+++ libc/stdlib/Makefile	9 Jan 2008 19:34:59 -0000	1.120
@@ -68,7 +68,7 @@ tests		:= tst-strtol tst-strtod testmb t
 		   tst-limits tst-rand48 bug-strtod tst-setcontext	    \
 		   test-a64l tst-qsort tst-system testmb2 bug-strtod2	    \
 		   tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
-		   tst-makecontext tst-strtod4 tst-strtod5
+		   tst-makecontext tst-strtod4 tst-strtod5 tst-makecontext2
 
 include ../Makeconfig
 
@@ -110,6 +110,7 @@ endif
 
 CFLAGS-tst-bsearch.c = $(stack-align-test-flags)
 CFLAGS-tst-qsort.c = $(stack-align-test-flags)
+CFLAGS-tst-makecontext2.c = $(stack-align-test-flags)
 
 include ../Rules
 
--- libc/stdlib/tst-makecontext2.c	1 Jan 1970 00:00:00 -0000
+++ libc/stdlib/tst-makecontext2.c	9 Jan 2008 19:34:46 -0000	1.1
@@ -0,0 +1,80 @@
+/* Copyright (C) 2008 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ucontext.h>
+#include <tst-stack-align.h>
+
+ucontext_t ucp, ucp2;
+char st1[262144] __attribute__((aligned (16)));
+
+void
+cf (int i, int j)
+{
+  if (i != 78 || j != 274)
+    {
+      printf ("i %d j %d\n", i, j);
+      exit (1);
+    }
+  else if (TEST_STACK_ALIGN ())
+    {
+      puts ("insufficiently aligned stack");
+      exit (2);
+    }
+}
+
+int
+do_test (void)
+{
+  for (size_t j = 32; j < 64; j += sizeof (long))
+    {
+      if (getcontext (&ucp) != 0)
+	{
+	  if (errno == ENOSYS)
+	    {
+	      puts ("context handling not supported");
+	      return 0;
+	    }
+
+	  puts ("getcontext failed");
+	  return 1;
+	}
+      ucp.uc_link = &ucp2;
+      ucp.uc_stack.ss_sp = st1;
+      ucp.uc_stack.ss_size = sizeof (st1) - j;
+      memset (&st1[sizeof (st1) - j], 0x55, j);
+      makecontext (&ucp, (void (*) (void)) cf, 2, 78, 274);
+      if (swapcontext (&ucp2, &ucp) != 0)
+	{
+	  puts ("setcontext failed");
+	  return 1;
+	}
+
+      for (size_t i = j; i > 0; i--)
+	if (st1[sizeof (st1) - j + i - 1] != 0x55)
+	  { printf ("fail %zd %zd\n", i, j); break; }
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"