This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.26.9000-1070-g8a5df95


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  8a5df95ffa83f525a4f638ead743f4fa2b7fe45a (commit)
      from  82eef55f8fad3e00c53050de5d6ebea08df488b3 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8a5df95ffa83f525a4f638ead743f4fa2b7fe45a

commit 8a5df95ffa83f525a4f638ead743f4fa2b7fe45a
Author: Florian Weimer <fweimer@redhat.com>
Date:   Thu Jan 4 18:00:05 2018 +0100

    i386: In makecontext, align the stack before calling exit [BZ #22667]
    
    Before this change, if glibc was compiled with SSE instructions and a
    sufficiently recent GCC, an unaligned stack access in
    __run_exit_handlers would cause stdlib/tst-makecontext to crash.

diff --git a/ChangeLog b/ChangeLog
index 7f0c2eb..5be91cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2018-01-04  Florian Weimer  <fweimer@redhat.com>
 
+	[BZ #22667]
+	* sysdeps/unix/sysv/linux/i386/makecontext.S (__makecontext):
+	Align the stack before calling exit.
+	* stdlib/tst-makecontext-align.c: New file.
+	* stdlib/Makefile (tests): Add tst-makecontext-align.
+
+2018-01-04  Florian Weimer  <fweimer@redhat.com>
+
 	Add support for calling dlvsym from libc.so.
 	* include/dlfcn.h (__libc_dlvsym): Declare.
 	* elf/Makefile (tests-static-internal): Add
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 691325b..7c363a6 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -83,7 +83,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   tst-getrandom tst-atexit tst-at_quick_exit 		    \
 		   tst-cxa_atexit tst-on_exit test-atexit-race 		    \
 		   test-at_quick_exit-race test-cxa_atexit-race             \
-		   test-on_exit-race test-dlclose-exit-race
+		   test-on_exit-race test-dlclose-exit-race 		    \
+		   tst-makecontext-align
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-makecontext-align.c b/stdlib/tst-makecontext-align.c
new file mode 100644
index 0000000..82394b4
--- /dev/null
+++ b/stdlib/tst-makecontext-align.c
@@ -0,0 +1,241 @@
+/* Check stack alignment provided by makecontext.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/xunistd.h>
+#include <sys/mman.h>
+#include <ucontext.h>
+
+/* Used for error reporting.  */
+static const char *context;
+
+/* Check that ADDRESS is aligned to ALIGNMENT bytes, behind a compiler
+   barrier.  */
+__attribute__ ((noinline, noclone, weak))
+void
+check_align (void *address, size_t alignment)
+{
+  uintptr_t uaddress = (uintptr_t) address;
+  if ((uaddress % alignment) != 0)
+    {
+      support_record_failure ();
+      printf ("error: %s: object at address %p is not aligned to %zu bytes\n",
+              context, address, alignment);
+    }
+}
+
+/* Various alignment checking functions.  */
+
+__attribute__ ((noinline, noclone, weak))
+void
+check_align_int (void)
+{
+  int a;
+  check_align (&a, __alignof__ (a));
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+check_align_long (void)
+{
+  long a;
+  check_align (&a, __alignof__ (a));
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+check_align_long_long (void)
+{
+  long long a;
+  check_align (&a, __alignof__ (a));
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+check_align_double (void)
+{
+  double a;
+  check_align (&a, __alignof__ (a));
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+check_align_4 (void)
+{
+  int a __attribute__ ((aligned (4)));
+  check_align (&a, 4);
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+check_align_8 (void)
+{
+  double a __attribute__ ((aligned (8)));
+  check_align (&a, 8);
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+check_align_16 (void)
+{
+  struct aligned
+  {
+    double x0  __attribute__ ((aligned (16)));
+    double x1;
+  } a;
+  check_align (&a, 16);
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+check_align_32 (void)
+{
+  struct aligned
+  {
+    double x0  __attribute__ ((aligned (32)));
+    double x1;
+    double x2;
+    double x3;
+  } a;
+  check_align (&a, 32);
+}
+
+/* Call all the alignment checking functions.  */
+__attribute__ ((noinline, noclone, weak))
+void
+check_alignments (void)
+{
+  check_align_int ();
+  check_align_long ();
+  check_align_long_long ();
+  check_align_double ();
+  check_align_4 ();
+  check_align_8 ();
+  check_align_16 ();
+  check_align_32 ();
+}
+
+/* Callback functions for makecontext and their invokers (to be used
+   with support_isolate_in_subprocess).  */
+
+static ucontext_t ucp;
+
+static void
+callback_0 (void)
+{
+  context = "callback_0";
+  check_alignments ();
+  context = "after return from callback_0";
+}
+
+static void
+invoke_callback_0 (void *closure)
+{
+  makecontext (&ucp, (void *) callback_0, 0);
+  if (setcontext (&ucp) != 0)
+    FAIL_EXIT1 ("setcontext");
+  FAIL_EXIT1 ("setcontext returned");
+}
+
+static void
+callback_1 (int arg1)
+{
+  context = "callback_1";
+  check_alignments ();
+  TEST_COMPARE (arg1, 101);
+  context = "after return from callback_1";
+}
+
+static void
+invoke_callback_1 (void *closure)
+{
+  makecontext (&ucp, (void *) callback_1, 1, 101);
+  if (setcontext (&ucp) != 0)
+    FAIL_EXIT1 ("setcontext");
+  FAIL_EXIT1 ("setcontext returned");
+}
+
+static void
+callback_2 (int arg1, int arg2)
+{
+  context = "callback_2";
+  check_alignments ();
+  TEST_COMPARE (arg1, 201);
+  TEST_COMPARE (arg2, 202);
+  context = "after return from callback_2";
+}
+
+static void
+invoke_callback_2 (void *closure)
+{
+  makecontext (&ucp, (void *) callback_2, 2, 201, 202);
+  if (setcontext (&ucp) != 0)
+    FAIL_EXIT1 ("setcontext");
+  FAIL_EXIT1 ("setcontext returned");
+}
+
+static void
+callback_3 (int arg1, int arg2, int arg3)
+{
+  context = "callback_3";
+  check_alignments ();
+  TEST_COMPARE (arg1, 301);
+  TEST_COMPARE (arg2, 302);
+  TEST_COMPARE (arg3, 303);
+  context = "after return from callback_3";
+}
+
+static void
+invoke_callback_3 (void *closure)
+{
+  makecontext (&ucp, (void *) callback_3, 3, 301, 302, 303);
+  if (setcontext (&ucp) != 0)
+    FAIL_EXIT1 ("setcontext");
+  FAIL_EXIT1 ("setcontext returned");
+}
+
+static int
+do_test (void)
+{
+  context = "direct call";
+  check_alignments ();
+
+  atexit (check_alignments);
+
+  if (getcontext (&ucp) != 0)
+    FAIL_UNSUPPORTED ("getcontext");
+
+  ucp.uc_link = NULL;
+  ucp.uc_stack.ss_size = 512 * 1024;
+  ucp.uc_stack.ss_sp = xmmap (NULL, ucp.uc_stack.ss_size,
+                              PROT_READ | PROT_WRITE,
+                              MAP_PRIVATE | MAP_ANONYMOUS, -1);
+
+  support_isolate_in_subprocess (invoke_callback_0, NULL);
+  support_isolate_in_subprocess (invoke_callback_1, NULL);
+  support_isolate_in_subprocess (invoke_callback_2, NULL);
+  support_isolate_in_subprocess (invoke_callback_3, NULL);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/i386/makecontext.S b/sysdeps/unix/sysv/linux/i386/makecontext.S
index efa4955..e3ca3dc 100644
--- a/sysdeps/unix/sysv/linux/i386/makecontext.S
+++ b/sysdeps/unix/sysv/linux/i386/makecontext.S
@@ -108,9 +108,19 @@ L(exitcode):
 	call	HIDDEN_JUMPTARGET(__setcontext)
 	/* If this returns (which can happen if the syscall fails) we'll
 	   exit the program with the return error value (-1).  */
+	jmp L(call_exit)
 
-	movl	%eax, (%esp)
-2:	call	HIDDEN_JUMPTARGET(exit)
+2:
+	/* Exit with status 0.  */
+	xorl	%eax, %eax
+
+L(call_exit):
+	/* Align the stack and pass the exit code (from %eax).  */
+	andl	$0xfffffff0, %esp
+	subl	$12, %esp
+	pushl	%eax
+
+	call	HIDDEN_JUMPTARGET(exit)
 	/* The 'exit' call should never return.  In case it does cause
 	   the process to terminate.  */
 	hlt

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                  |    8 +
 stdlib/Makefile                            |    3 +-
 stdlib/tst-makecontext-align.c             |  241 ++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/i386/makecontext.S |   14 ++-
 4 files changed, 263 insertions(+), 3 deletions(-)
 create mode 100644 stdlib/tst-makecontext-align.c


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]