public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 08/12] Add a test for swapcontext with a wrapper
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (5 preceding siblings ...)
  2018-07-21 14:20 ` [PATCH 07/12] x86/CET: Add tests with legacy non-CET shared objects H.J. Lu
@ 2018-07-21 14:20 ` H.J. Lu
  2018-07-25  3:27   ` Carlos O'Donell
  2018-07-21 14:21 ` [PATCH 05/12] x86: Rename __glibc_reserved2 to ssp_base in tcbhead_t H.J. Lu
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:20 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

Check swapcontext works with a wrapper.

	* stdlib/Makefile (tests): Add tst-swapcontext1.
	* stdlib/tst-swapcontext1.c: New test.
---
 stdlib/Makefile           |  3 +-
 stdlib/tst-swapcontext1.c | 92 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-swapcontext1.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index b5e55b0a55..bc8929f2b9 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -84,7 +84,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   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 		    \
-		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign
+		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
+		   tst-swapcontext1
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-swapcontext1.c b/stdlib/tst-swapcontext1.c
new file mode 100644
index 0000000000..6dd52f22a6
--- /dev/null
+++ b/stdlib/tst-swapcontext1.c
@@ -0,0 +1,92 @@
+/* Check swapcontext wrapper.
+   Modified from c-c++-common/asan/swapcontext-test-1.c in GCC testsuite.
+   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 <stdio.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+__attribute__((noinline, noclone))
+__INDIRECT_RETURN
+int
+myswapcontext (ucontext_t *oucp, ucontext_t *ucp)
+{
+  int res = swapcontext (oucp, ucp);
+  return res;
+}
+
+ucontext_t orig_context;
+ucontext_t child_context;
+
+void
+Child (int mode)
+{
+  char x[32] = {0};  /* Stack gets poisoned. */
+  printf("Child: %p\n", x);
+  /* (a) Do nothing, just return to parent function.
+     (b) Jump into the original function. Stack remains poisoned unless we do
+     something. */
+  if (mode == 1)
+    {
+      if (myswapcontext (&child_context, &orig_context) < 0)
+	{
+	  perror ("swapcontext");
+	  _exit (0);
+	}
+    }
+}
+
+int
+Run (int arg, int mode)
+{
+  int i;
+  const int kStackSize = 1 << 20;
+  char child_stack[kStackSize + 1];
+  printf ("Child stack: %p\n", child_stack);
+  /* Setup child context. */
+  getcontext (&child_context);
+  child_context.uc_stack.ss_sp = child_stack;
+  child_context.uc_stack.ss_size = kStackSize / 2;
+  if (mode == 0)
+    child_context.uc_link = &orig_context;
+  makecontext (&child_context, (void (*)(void))Child, 1, mode);
+  if (myswapcontext (&orig_context, &child_context) < 0)
+    {
+      perror("swapcontext");
+      return 0;
+    }
+  /* Touch childs's stack to make sure it's unpoisoned. */
+  for (i = 0; i < kStackSize; i++)
+    child_stack[i] = i;
+  return child_stack[arg];
+}
+
+volatile int zero = 0;
+
+static int
+do_test (void)
+{
+  int ret = 0;
+  ret += Run (zero, 0);
+  fprintf (stderr, "Test1 passed\n");
+  ret += Run (zero, 1);
+  fprintf (stderr, "Test2 passed\n");
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 10/12] Add another test for setcontext
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (2 preceding siblings ...)
  2018-07-21 14:20 ` [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control H.J. Lu
@ 2018-07-21 14:20 ` H.J. Lu
  2018-07-25  3:36   ` Carlos O'Donell
  2018-07-25 16:21   ` Florian Weimer
  2018-07-21 14:20 ` [PATCH 12/12] Add tests for setcontext on the context from makecontext H.J. Lu
                   ` (9 subsequent siblings)
  13 siblings, 2 replies; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:20 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

	* stdlib/Makefile (tests): Add tst-setcontext4.
	* stdlib/tst-setcontext4.c: New file.
---
 stdlib/Makefile          |   2 +-
 stdlib/tst-setcontext4.c | 217 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 218 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-setcontext4.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index 40d07ade20..73d0e7c2a2 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -85,7 +85,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   test-at_quick_exit-race test-cxa_atexit-race             \
 		   test-on_exit-race test-dlclose-exit-race 		    \
 		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
-		   tst-swapcontext1 tst-swapcontext2
+		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-setcontext4.c b/stdlib/tst-setcontext4.c
new file mode 100644
index 0000000000..64d3fc9137
--- /dev/null
+++ b/stdlib/tst-setcontext4.c
@@ -0,0 +1,217 @@
+/* Testcase checks, if setcontext(), swapcontext() restores signal-mask
+   and if pending signals are delivered after those calls.
+   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 <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+volatile int global;
+volatile sig_atomic_t handlerCalled;
+
+static void
+check (const char *funcName)
+{
+  sigset_t set;
+
+  /* check if SIGUSR2 is unblocked after setcontext-call.  */
+  sigprocmask (SIG_BLOCK, NULL, &set);
+
+  if (sigismember (&set, SIGUSR2) != 0)
+    {
+      printf ("FAIL: SIGUSR2 is blocked after %s.\n", funcName);
+      exit (1);
+    }
+
+  if (sigismember (&set, SIGUSR1) != 1)
+    {
+      printf ("FAIL: SIGUSR1 is not blocked after %s.\n", funcName);
+      exit (1);
+    }
+}
+
+static void
+signalmask (int how, int signum)
+{
+  sigset_t set;
+  sigemptyset (&set);
+  sigaddset (&set, signum);
+  if (sigprocmask (how, &set, NULL) != 0)
+    {
+      printf ("FAIL: sigprocmaks (%d, %d, NULL): %m\n", how, signum);
+      exit (1);
+    }
+}
+
+static void
+signalpending (int signum, const char *msg)
+{
+  sigset_t set;
+  sigemptyset (&set);
+  if (sigpending (&set) != 0)
+    {
+      printf ("FAIL: sigpending: %m\n");
+      exit (1);
+    }
+  if (sigismember (&set, SIGUSR2) != 1)
+    {
+      printf ("FAIL: Signal %d is not pending %s\n", signum, msg);
+      exit (1);
+    }
+}
+
+static void
+handler (int __attribute__ ((unused)) signum)
+{
+  handlerCalled ++;
+}
+
+static int
+do_test (void)
+{
+  ucontext_t ctx, oldctx;
+  struct sigaction action;
+  pid_t pid;
+
+  pid = getpid ();
+
+  /* unblock SIGUSR2 */
+  signalmask (SIG_UNBLOCK, SIGUSR2);
+
+  /* block SIGUSR1 */
+  signalmask (SIG_BLOCK, SIGUSR1);
+
+  /* register handler for SIGUSR2  */
+  action.sa_flags = 0;
+  action.sa_handler = handler;
+  sigemptyset (&action.sa_mask);
+  sigaction (SIGUSR2, &action, NULL);
+
+  if (getcontext (&ctx) != 0)
+    {
+      printf ("FAIL: getcontext: %m\n");
+      exit (1);
+    }
+
+  global++;
+
+  if (global == 1)
+    {
+      puts ("after getcontext");
+
+      /* block SIGUSR2  */
+      signalmask (SIG_BLOCK, SIGUSR2);
+
+      /* send SIGUSR2 to me  */
+      handlerCalled = 0;
+      kill (pid, SIGUSR2);
+
+      /* was SIGUSR2 handler called?  */
+      if (handlerCalled != 0)
+	{
+	  puts ("FAIL: signal handler was called, but signal was blocked.");
+	  exit (1);
+	}
+
+      /* is SIGUSR2 pending?  */
+      signalpending (SIGUSR2, "before setcontext");
+
+      /* SIGUSR2 will be unblocked by setcontext-call.  */
+      if (setcontext (&ctx) != 0)
+	{
+	  printf ("FAIL: setcontext: %m\n");
+	  exit (1);
+	}
+    }
+  else if (global == 2)
+    {
+      puts ("after setcontext");
+
+      /* check SIGUSR1/2  */
+      check ("setcontext");
+
+      /* was SIGUSR2 handler called? */
+      if (handlerCalled != 1)
+	{
+	  puts ("FAIL: signal handler was not called after setcontext.");
+	  exit (1);
+	}
+
+      /* block SIGUSR2 */
+      signalmask (SIG_BLOCK, SIGUSR2);
+
+      /* send SIGUSR2 to me  */
+      handlerCalled = 0;
+      kill (pid, SIGUSR2);
+
+      /* was SIGUSR2 handler called?  */
+      if (handlerCalled != 0)
+	{
+	  puts ("FAIL: signal handler was called, but signal was blocked.");
+	  exit (1);
+	}
+
+      /* is SIGUSR2 pending?  */
+      signalpending (SIGUSR2, "before swapcontext");
+
+      if (swapcontext (&oldctx, &ctx) != 0)
+	{
+	  printf ("FAIL: swapcontext: %m\n");
+	  exit (1);
+	}
+
+      puts ("FAIL: returned from (&oldctx, &ctx)");
+      exit (1);
+    }
+  else if ( global != 3 )
+    {
+      puts ("FAIL: 'global' not incremented three times");
+      exit (1);
+    }
+
+  puts ("after swapcontext");
+  /* check SIGUSR1/2  */
+  check ("swapcontext");
+
+  /* was SIGUSR2 handler called? */
+  if (handlerCalled != 1)
+    {
+      puts ("FAIL: signal handler was not called after swapcontext.");
+      exit (1);
+    }
+
+  /* check sigmask in old context of swapcontext-call  */
+  if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1)
+    {
+      puts ("FAIL: SIGUSR2 is not blocked in oldctx.uc_sigmask.");
+      exit (1);
+    }
+
+  if (sigismember (&oldctx.uc_sigmask, SIGUSR1) != 1)
+    {
+      puts ("FAIL: SIGUSR1 is not blocked in oldctx.uc_sigmaks.");
+      exit (1);
+    }
+
+  return 0;
+}
+
+#include <support/test-driver.c>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
@ 2018-07-21 14:20 H.J. Lu
  2018-07-21 14:20 ` [PATCH 09/12] Add a test for multiple makecontext calls H.J. Lu
                   ` (13 more replies)
  0 siblings, 14 replies; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:20 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

These are the last 12 patches to enable Intel CET.  Tested by

1. build-many-glibcs.py.
2. With --enable-cet and without --enable-cet for i686, x86-64 and x32
on non-CET x86-64 processors.
3. With --enable-cet for x86-64 and x32 on CET SDV using the CET kernel
from cet branch at:

https://github.com/yyu168/linux_cet/tree/cet

When the shadow stack (SHSTK) is enabled, makecontext needs to allocate
a new shadow stack to go with the new stack allocated by the caller.
setcontext and swapcontext must properly handle the corresponding shadow
stack when the stack is switched.  Add more tests for user context
functions to provide more coverage for the shadow stack support.

H.J. Lu (12):
  x86: Update vfork to pop shadow stack
  x86-64: Add endbr64 to tst-quadmod[12].S
  Add <bits/indirect-return.h>
  x86/CET: Extend arch_prctl syscall for CET control
  x86: Rename __glibc_reserved2 to ssp_base in tcbhead_t
  x86-64/CET: Extend ucontext_t to save shadow stack
  x86/CET: Add tests with legacy non-CET shared objects
  Add a test for swapcontext with a wrapper
  Add a test for multiple makecontext calls
  Add another test for setcontext
  Add a test for multiple setcontext calls
  Add tests for setcontext on the context from makecontext

 bits/indirect-return.h                        |  25 ++
 misc/sys/cdefs.h                              |   6 +
 stdlib/Makefile                               |   7 +-
 stdlib/tst-setcontext4.c                      | 217 ++++++++++++++++++
 stdlib/tst-setcontext5.c                      |  88 +++++++
 stdlib/tst-setcontext6.c                      |  76 ++++++
 stdlib/tst-setcontext7.c                      |  96 ++++++++
 stdlib/tst-setcontext8.c                      |  81 +++++++
 stdlib/tst-setcontext9.c                      | 100 ++++++++
 stdlib/tst-swapcontext1.c                     |  92 ++++++++
 stdlib/tst-swapcontext2.c                     | 108 +++++++++
 stdlib/ucontext.h                             |   6 +-
 string/tst-xbzero-opt.c                       |  10 +-
 sysdeps/i386/nptl/tcb-offsets.sym             |   1 +
 sysdeps/i386/nptl/tls.h                       |   3 +-
 sysdeps/unix/sysv/linux/Makefile              |   3 +-
 sysdeps/unix/sysv/linux/bits/prctl.h          |  21 ++
 sysdeps/unix/sysv/linux/i386/vfork.S          |  54 +++++
 sysdeps/unix/sysv/linux/sys/prctl.h           |   1 +
 sysdeps/unix/sysv/linux/x86/bits/prctl.h      |  48 ++++
 sysdeps/unix/sysv/linux/x86/cpu-features.c    |   7 +
 sysdeps/unix/sysv/linux/x86/dl-cet.h          |  29 ++-
 sysdeps/unix/sysv/linux/x86/sys/ucontext.h    |   2 +
 .../unix/sysv/linux/x86_64/__start_context.S  |  75 ++++++
 sysdeps/unix/sysv/linux/x86_64/getcontext.S   |  17 ++
 sysdeps/unix/sysv/linux/x86_64/makecontext.c  |  56 ++++-
 sysdeps/unix/sysv/linux/x86_64/setcontext.S   | 139 +++++++++++
 sysdeps/unix/sysv/linux/x86_64/swapcontext.S  | 150 ++++++++++++
 sysdeps/unix/sysv/linux/x86_64/sysdep.h       |   5 +
 sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym |   1 +
 sysdeps/unix/sysv/linux/x86_64/vfork.S        |  35 +++
 sysdeps/x86/Makefile                          |  38 +++
 sysdeps/x86/bits/indirect-return.h            |  35 +++
 sysdeps/x86/libc-start.c                      |   3 +
 sysdeps/x86/tst-cet-legacy-1.c                |  44 ++++
 sysdeps/x86/tst-cet-legacy-2.c                |  64 ++++++
 sysdeps/x86/tst-cet-legacy-2a.c               |   1 +
 sysdeps/x86/tst-cet-legacy-3.c                |  88 +++++++
 sysdeps/x86/tst-cet-legacy-4.c                |  56 +++++
 sysdeps/x86/tst-cet-legacy-4a.c               |   1 +
 sysdeps/x86/tst-cet-legacy-4b.c               |   1 +
 sysdeps/x86/tst-cet-legacy-4c.c               |   1 +
 sysdeps/x86/tst-cet-legacy-mod-1.c            |  24 ++
 sysdeps/x86/tst-cet-legacy-mod-2.c            |  24 ++
 sysdeps/x86/tst-cet-legacy-mod-4.c            |   2 +
 sysdeps/x86_64/nptl/tcb-offsets.sym           |   1 +
 sysdeps/x86_64/nptl/tls.h                     |  10 +-
 sysdeps/x86_64/tst-quadmod1.S                 |   6 +
 sysdeps/x86_64/tst-quadmod2.S                 |   6 +
 49 files changed, 1950 insertions(+), 14 deletions(-)
 create mode 100644 bits/indirect-return.h
 create mode 100644 stdlib/tst-setcontext4.c
 create mode 100644 stdlib/tst-setcontext5.c
 create mode 100644 stdlib/tst-setcontext6.c
 create mode 100644 stdlib/tst-setcontext7.c
 create mode 100644 stdlib/tst-setcontext8.c
 create mode 100644 stdlib/tst-setcontext9.c
 create mode 100644 stdlib/tst-swapcontext1.c
 create mode 100644 stdlib/tst-swapcontext2.c
 create mode 100644 sysdeps/unix/sysv/linux/bits/prctl.h
 create mode 100644 sysdeps/unix/sysv/linux/x86/bits/prctl.h
 create mode 100644 sysdeps/x86/bits/indirect-return.h
 create mode 100644 sysdeps/x86/tst-cet-legacy-1.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-2.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-2a.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-3.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4a.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4b.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4c.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-mod-1.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-mod-2.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-mod-4.c

-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 09/12] Add a test for multiple makecontext calls
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
@ 2018-07-21 14:20 ` H.J. Lu
  2018-07-25  3:31   ` Carlos O'Donell
  2018-07-21 14:20 ` [PATCH 02/12] x86-64: Add endbr64 to tst-quadmod[12].S H.J. Lu
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:20 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

Check multiple makecontext calls.

	* stdlib/Makefile (tests): Add tst-swapcontext2.
	* stdlib/tst-swapcontext2.c: New test.
---
 stdlib/Makefile           |   2 +-
 stdlib/tst-swapcontext2.c | 108 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-swapcontext2.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index bc8929f2b9..40d07ade20 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -85,7 +85,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   test-at_quick_exit-race test-cxa_atexit-race             \
 		   test-on_exit-race test-dlclose-exit-race 		    \
 		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
-		   tst-swapcontext1
+		   tst-swapcontext1 tst-swapcontext2
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-swapcontext2.c b/stdlib/tst-swapcontext2.c
new file mode 100644
index 0000000000..7802df4868
--- /dev/null
+++ b/stdlib/tst-swapcontext2.c
@@ -0,0 +1,108 @@
+/* Check multiple makecontext calls.
+   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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+
+static ucontext_t uctx_main, uctx_func1, uctx_func2;
+const char *str1 = "\e[31mswapcontext(&uctx_func1, &uctx_main)\e[0m";
+const char *str2 = "\e[34mswapcontext(&uctx_func2, &uctx_main)\e[0m";
+const char *fmt1 = "\e[31m";
+const char *fmt2 = "\e[34m";
+
+#define handle_error(msg) \
+  do { perror(msg); exit(EXIT_FAILURE); } while (0)
+
+__attribute__((noinline, noclone))
+static void
+func4(ucontext_t *uocp, ucontext_t *ucp, const char *str, const char *fmt)
+{
+  printf("      %sfunc4: %s\e[0m\n", fmt, str);
+  if (swapcontext(uocp, ucp) == -1)
+    handle_error("swapcontext");
+  printf("      %sfunc4: returning\e[0m\n", fmt);
+}
+
+__attribute__((noinline, noclone))
+static void
+func3(ucontext_t *uocp, ucontext_t *ucp, const char *str, const char *fmt)
+{
+  printf("    %sfunc3: func4(uocp, ucp, str)\e[0m\n", fmt);
+  func4(uocp, ucp, str, fmt);
+  printf("    %sfunc3: returning\e[0m\n", fmt);
+}
+
+__attribute__((noinline, noclone))
+static void
+func1(void)
+{
+  while ( 1 )
+    {
+      printf("  \e[31mfunc1: func3(&uctx_func1, &uctx_main, str1)\e[0m\n");
+      func3( &uctx_func1, &uctx_main, str1, fmt1);
+    }
+}
+
+__attribute__((noinline, noclone))
+static void
+func2(void)
+{
+  while ( 1 )
+    {
+      printf("  \e[34mfunc2: func3(&uctx_func2, &uctx_main, str2)\e[0m\n");
+      func3(&uctx_func2, &uctx_main, str2, fmt2);
+    }
+}
+
+static int
+do_test (void)
+{
+  char func1_stack[16384];
+  char func2_stack[16384];
+  int i;
+
+  if (getcontext(&uctx_func1) == -1)
+    handle_error("getcontext");
+  uctx_func1.uc_stack.ss_sp = func1_stack;
+  uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
+  uctx_func1.uc_link = &uctx_main;
+  makecontext(&uctx_func1, func1, 0);
+
+  if (getcontext(&uctx_func2) == -1)
+    handle_error("getcontext");
+  uctx_func2.uc_stack.ss_sp = func2_stack;
+  uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
+  uctx_func2.uc_link = &uctx_func1;
+  makecontext(&uctx_func2, func2, 0);
+
+  for ( i = 0; i < 4; i++ )
+    {
+      if (swapcontext(&uctx_main, &uctx_func1) == -1)
+	handle_error("swapcontext");
+      printf("        \e[35mmain: swapcontext(&uctx_main, &uctx_func2)\n\e[0m");
+      if (swapcontext(&uctx_main, &uctx_func2) == -1)
+	handle_error("swapcontext");
+      printf("        \e[35mmain: swapcontext(&uctx_main, &uctx_func1)\n\e[0m");
+    }
+
+  printf("main: exiting\n");
+  exit(EXIT_SUCCESS);
+}
+
+#include <support/test-driver.c>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
  2018-07-21 14:20 ` [PATCH 09/12] Add a test for multiple makecontext calls H.J. Lu
  2018-07-21 14:20 ` [PATCH 02/12] x86-64: Add endbr64 to tst-quadmod[12].S H.J. Lu
@ 2018-07-21 14:20 ` H.J. Lu
  2018-07-24  3:05   ` Carlos O'Donell
  2018-07-21 14:20 ` [PATCH 10/12] Add another test for setcontext H.J. Lu
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:20 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

 /* CET features:
    IBT:   GNU_PROPERTY_X86_FEATURE_1_IBT
    SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
  */

 /* Return CET features in unsigned long long *addr:
      features: addr[0].
      shadow stack base address: addr[1].
      shadow stack size: addr[2].
  */
 # define ARCH_CET_STATUS		0x3001
 /* Disable CET features in unsigned int features.  */
 # define ARCH_CET_DISABLE		0x3002
 /* Lock all CET features.  */
 # define ARCH_CET_LOCK			0x3003
 /* Allocate a new shadow stack with unsigned long long *addr:
      IN: requested shadow stack size: *addr.
      OUT: allocated shadow stack address: *addr.
  */
 # define ARCH_CET_ALLOC_SHSTK		0x3004
 /* Return legacy region bitmap info in unsigned long long *addr:
     address: addr[0].
     size: addr[1].
  */
 # define ARCH_CET_LEGACY_BITMAP	0x3005

	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
	bits/prctl.h.
	* sysdeps/unix/sysv/linux/bits/prctl.h: New file.
	* sysdeps/unix/sysv/linux/x86/bits/prctl.h: Likewise.
	* sysdeps/unix/sysv/linux/sys/prctl.h: Include <bits/prctl.h>.
	* sysdeps/unix/sysv/linux/x86/cpu-features.c: Include
	<sys/prctl.h>.
	(get_cet_status): Call arch_prctl with ARCH_CET_STATUS.
	* sysdeps/unix/sysv/linux/x86/dl-cet.h: Include  <sys/prctl.h>.
	(dl_cet_allocate_legacy_bitmap): Call arch_prctl with
	ARCH_CET_LEGACY_BITMAP.
	(dl_cet_disable_cet): Call arch_prctl with ARCH_CET_DISABLE.
	(dl_cet_lock_cet): Call arch_prctl with ARCH_CET_LOCK.
	* sysdeps/x86/libc-start.c: Include <startup.h>.
---
 sysdeps/unix/sysv/linux/Makefile           |  3 +-
 sysdeps/unix/sysv/linux/bits/prctl.h       | 21 ++++++++++
 sysdeps/unix/sysv/linux/sys/prctl.h        |  1 +
 sysdeps/unix/sysv/linux/x86/bits/prctl.h   | 48 ++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86/cpu-features.c |  7 ++++
 sysdeps/unix/sysv/linux/x86/dl-cet.h       | 29 ++++++++++---
 sysdeps/x86/libc-start.c                   |  3 ++
 7 files changed, 105 insertions(+), 7 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/bits/prctl.h
 create mode 100644 sysdeps/unix/sysv/linux/x86/bits/prctl.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index f71cc39c7e..0bcc5287d9 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -40,7 +40,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 		  bits/signalfd.h bits/timerfd.h bits/epoll.h \
 		  bits/socket_type.h bits/syscall.h bits/sysctl.h \
 		  bits/mman-linux.h bits/mman-shared.h bits/ptrace-shared.h \
-		  bits/siginfo-arch.h bits/siginfo-consts-arch.h
+		  bits/siginfo-arch.h bits/siginfo-consts-arch.h \
+		  bits/prctl.h
 
 tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
 	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
diff --git a/sysdeps/unix/sysv/linux/bits/prctl.h b/sysdeps/unix/sysv/linux/bits/prctl.h
new file mode 100644
index 0000000000..be96218066
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/prctl.h
@@ -0,0 +1,21 @@
+/* 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/>.  */
+
+#ifndef _BITS_PRCTL_H
+#define _BITS_PRCTL_H	1
+
+#endif  /* bits/prctl.h */
diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h
index 683d16748f..6c4f643c75 100644
--- a/sysdeps/unix/sysv/linux/sys/prctl.h
+++ b/sysdeps/unix/sysv/linux/sys/prctl.h
@@ -20,6 +20,7 @@
 
 #include <features.h>
 #include <linux/prctl.h>  /*  The magic values come from here  */
+#include <bits/prctl.h>
 
 __BEGIN_DECLS
 
diff --git a/sysdeps/unix/sysv/linux/x86/bits/prctl.h b/sysdeps/unix/sysv/linux/x86/bits/prctl.h
new file mode 100644
index 0000000000..37e5fc8212
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/bits/prctl.h
@@ -0,0 +1,48 @@
+/* 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/>.  */
+
+#ifndef _BITS_PRCTL_H
+#define _BITS_PRCTL_H	1
+
+#ifndef ARCH_CET_STATUS
+/* CET features:
+   IBT:   GNU_PROPERTY_X86_FEATURE_1_IBT
+   SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
+ */
+/* Return CET features in unsigned long long *addr:
+     features: addr[0].
+     shadow stack base address: addr[1].
+     shadow stack size: addr[2].
+ */
+# define ARCH_CET_STATUS	0x3001
+/* Disable CET features in unsigned int features.  */
+# define ARCH_CET_DISABLE	0x3002
+/* Lock all CET features.  */
+# define ARCH_CET_LOCK		0x3003
+/* Allocate a new shadow stack with unsigned long long *addr:
+     IN: requested shadow stack size: *addr.
+     OUT: allocated shadow stack address: *addr.
+ */
+# define ARCH_CET_ALLOC_SHSTK	0x3004
+/* Return legacy region bitmap info in unsigned long long *addr:
+     address: addr[0].
+     size: addr[1].
+ */
+# define ARCH_CET_LEGACY_BITMAP	0x3005
+#endif /* ARCH_CET_STATUS */
+
+#endif  /* bits/prctl.h */
diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c
index 7c9df9b794..c7c59055dc 100644
--- a/sysdeps/unix/sysv/linux/x86/cpu-features.c
+++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c
@@ -17,9 +17,16 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if CET_ENABLED
+# include <sys/prctl.h>
+
 static inline int __attribute__ ((always_inline))
 get_cet_status (void)
 {
+  unsigned long long cet_status[3];
+  INTERNAL_SYSCALL_DECL (err);
+  if (INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_STATUS,
+			cet_status) == 0)
+    return cet_status[0];
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h
index ae81e2f2ca..787368292d 100644
--- a/sysdeps/unix/sysv/linux/x86/dl-cet.h
+++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h
@@ -15,23 +15,40 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <sys/prctl.h>
+
 static inline int __attribute__ ((always_inline))
 dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap)
 {
-  /* FIXME: Need syscall support.  */
-  return -1;
+  /* Allocate legacy bitmap.  */
+  INTERNAL_SYSCALL_DECL (err);
+#ifdef __LP64__
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
+				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap);
+#else
+  unsigned long long legacy_bitmap_u64[2];
+  int res = INTERNAL_SYSCALL (arch_prctl, err, 2,
+			      ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
+  if (res == 0)
+    {
+      legacy_bitmap[0] = legacy_bitmap_u64[0];
+      legacy_bitmap[1] = legacy_bitmap_u64[1];
+    }
+  return res;
+#endif
 }
 
 static inline int __attribute__ ((always_inline))
 dl_cet_disable_cet (unsigned int cet_feature)
 {
-  /* FIXME: Need syscall support.  */
-  return -1;
+  INTERNAL_SYSCALL_DECL (err);
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_DISABLE,
+				 cet_feature);
 }
 
 static inline int __attribute__ ((always_inline))
 dl_cet_lock_cet (void)
 {
-  /* FIXME: Need syscall support.  */
-  return -1;
+  INTERNAL_SYSCALL_DECL (err);
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_LOCK, 0);
 }
diff --git a/sysdeps/x86/libc-start.c b/sysdeps/x86/libc-start.c
index 43aba9d061..eb5335c154 100644
--- a/sysdeps/x86/libc-start.c
+++ b/sysdeps/x86/libc-start.c
@@ -16,6 +16,9 @@
    <http://www.gnu.org/licenses/>.  */
 
 #ifndef SHARED
+/* Define I386_USE_SYSENTER to support syscall during startup in static
+   PIE.  */
+# include <startup.h>
 # include <ldsodefs.h>
 # include <cpu-features.h>
 # include <cpu-features.c>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 07/12] x86/CET: Add tests with legacy non-CET shared objects
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (4 preceding siblings ...)
  2018-07-21 14:20 ` [PATCH 12/12] Add tests for setcontext on the context from makecontext H.J. Lu
@ 2018-07-21 14:20 ` H.J. Lu
  2018-07-25  3:21   ` Carlos O'Donell
  2018-07-21 14:20 ` [PATCH 08/12] Add a test for swapcontext with a wrapper H.J. Lu
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:20 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

Check binary compatibility of CET-enabled executables:

1. When CET-enabled executable is used with legacy non-CET shared object
at run-time, ld.so should disable SHSTK and put legacy non-CET shared
objects in legacy bitmap.
2. When IBT-enabled executable dlopens legacy non-CET shared object,
ld.so should put legacy shared object in legacy bitmap.
3. Use GLIBC_TUNABLES=glibc.tune.x86_shstk=[on|off|permissive] to
control how SHSTK is enabled.

	* sysdeps/x86/Makefile (tests): Add tst-cet-legacy-1,
	tst-cet-legacy-2, tst-cet-legacy-2a, tst-cet-legacy-3,
	tst-cet-legacy-4, tst-cet-legacy-4a, tst-cet-legacy-4b
	and tst-cet-legacy-4c.
	(modules-names): Add tst-cet-legacy-mod-1, tst-cet-legacy-mod-2
	and tst-cet-legacy-mod-4.
	(CFLAGS-tst-cet-legacy-2.c): New.
	(CFLAGS-tst-cet-legacy-mod-1.c): Likewise.
	(CFLAGS-tst-cet-legacy-mod-2.c): Likewise.
	(CFLAGS-tst-cet-legacy-3.c): Likewise.
	(CFLAGS-tst-cet-legacy-4.c): Likewise.
	(CFLAGS-tst-cet-legacy-mod-4.c): Likewise.
	($(objpfx)tst-cet-legacy-1): Likewise.
	($(objpfx)tst-cet-legacy-2): Likewise.
	($(objpfx)tst-cet-legacy-2.out): Likewise.
	($(objpfx)tst-cet-legacy-2a): Likewise.
	($(objpfx)tst-cet-legacy-2a.out): Likewise.
	($(objpfx)tst-cet-legacy-4): Likewise.
	($(objpfx)tst-cet-legacy-4.out): Likewise.
	($(objpfx)tst-cet-legacy-4a): Likewise.
	($(objpfx)tst-cet-legacy-4a.out): Likewise.
	(tst-cet-legacy-4a-ENV): Likewise.
	($(objpfx)tst-cet-legacy-4b): Likewise.
	($(objpfx)tst-cet-legacy-4b.out): Likewise.
	(tst-cet-legacy-4b-ENV): Likewise.
	($(objpfx)tst-cet-legacy-4c): Likewise.
	($(objpfx)tst-cet-legacy-4c.out): Likewise.
	(tst-cet-legacy-4c-ENV): Likewise.
	* sysdeps/x86/tst-cet-legacy-1.c: New file.
	* sysdeps/x86/tst-cet-legacy-2.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-2a.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-3.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-4.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-4a.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-4b.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-4c.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-mod-1.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-mod-2.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-mod-4.c: Likewise.
---
 sysdeps/x86/Makefile               | 38 +++++++++++++
 sysdeps/x86/tst-cet-legacy-1.c     | 44 +++++++++++++++
 sysdeps/x86/tst-cet-legacy-2.c     | 64 ++++++++++++++++++++++
 sysdeps/x86/tst-cet-legacy-2a.c    |  1 +
 sysdeps/x86/tst-cet-legacy-3.c     | 88 ++++++++++++++++++++++++++++++
 sysdeps/x86/tst-cet-legacy-4.c     | 56 +++++++++++++++++++
 sysdeps/x86/tst-cet-legacy-4a.c    |  1 +
 sysdeps/x86/tst-cet-legacy-4b.c    |  1 +
 sysdeps/x86/tst-cet-legacy-4c.c    |  1 +
 sysdeps/x86/tst-cet-legacy-mod-1.c | 24 ++++++++
 sysdeps/x86/tst-cet-legacy-mod-2.c | 24 ++++++++
 sysdeps/x86/tst-cet-legacy-mod-4.c |  2 +
 12 files changed, 344 insertions(+)
 create mode 100644 sysdeps/x86/tst-cet-legacy-1.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-2.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-2a.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-3.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4a.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4b.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4c.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-mod-1.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-mod-2.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-mod-4.c

diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
index e9b2d0b35d..672bb19489 100644
--- a/sysdeps/x86/Makefile
+++ b/sysdeps/x86/Makefile
@@ -17,6 +17,44 @@ endif
 ifeq ($(enable-cet),yes)
 ifeq ($(subdir),elf)
 sysdep-dl-routines += dl-cet
+
+tests += tst-cet-legacy-1 tst-cet-legacy-2 tst-cet-legacy-2a \
+	 tst-cet-legacy-3 tst-cet-legacy-4
+ifneq (no,$(have-tunables))
+tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c
+endif
+modules-names += tst-cet-legacy-mod-1 tst-cet-legacy-mod-2 \
+		 tst-cet-legacy-mod-4
+
+CFLAGS-tst-cet-legacy-2.c += -fcf-protection=branch
+CFLAGS-tst-cet-legacy-2a.c += -fcf-protection
+CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-4.c += -fcf-protection=branch
+CFLAGS-tst-cet-legacy-4a.c += -fcf-protection
+CFLAGS-tst-cet-legacy-4b.c += -fcf-protection
+CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none
+
+$(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \
+		       $(objpfx)tst-cet-legacy-mod-2.so
+$(objpfx)tst-cet-legacy-2: $(objpfx)tst-cet-legacy-mod-2.so $(libdl)
+$(objpfx)tst-cet-legacy-2.out: $(objpfx)tst-cet-legacy-mod-1.so
+$(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so $(libdl)
+$(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so
+$(objpfx)tst-cet-legacy-4: $(libdl)
+$(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so
+ifneq (no,$(have-tunables))
+$(objpfx)tst-cet-legacy-4a: $(libdl)
+$(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so
+tst-cet-legacy-4a-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=permissive
+$(objpfx)tst-cet-legacy-4b: $(libdl)
+$(objpfx)tst-cet-legacy-4b.out: $(objpfx)tst-cet-legacy-mod-4.so
+tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=on
+$(objpfx)tst-cet-legacy-4c: $(libdl)
+$(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so
+tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=off
+endif
 endif
 
 # Add -fcf-protection to CFLAGS when CET is enabled.
diff --git a/sysdeps/x86/tst-cet-legacy-1.c b/sysdeps/x86/tst-cet-legacy-1.c
new file mode 100644
index 0000000000..861c09a26e
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-1.c
@@ -0,0 +1,44 @@
+/* Check compatibility of CET-enabled executable linked with legacy
+   shared object.
+   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 <stdio.h>
+#include <stdlib.h>
+
+extern int in_dso_1 (void);
+extern int in_dso_2 (void);
+
+static int
+do_test (void)
+{
+  if (in_dso_1 () != 0x1234678)
+    {
+      puts ("in_dso_1 () != 0x1234678");
+      exit (1);
+    }
+
+  if (in_dso_2 () != 0xbadbeef)
+    {
+      puts ("in_dso_2 () != 0xbadbeef");
+      exit (1);
+    }
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86/tst-cet-legacy-2.c b/sysdeps/x86/tst-cet-legacy-2.c
new file mode 100644
index 0000000000..e039a16797
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-2.c
@@ -0,0 +1,64 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   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 <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int in_dso_2 (void);
+
+static int
+do_test (void)
+{
+  static const char modname[] = "tst-cet-legacy-mod-1.so";
+  int (*fp) (void);
+  void *h;
+
+  h = dlopen (modname, RTLD_LAZY);
+  if (h == NULL)
+    {
+      printf ("cannot open '%s': %s\n", modname, dlerror ());
+      exit (1);
+    }
+
+  fp = dlsym (h, "in_dso_1");
+  if (fp == NULL)
+    {
+      printf ("cannot get symbol 'in_dso': %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (fp () != 0x1234678)
+    {
+      puts ("in_dso_1 () != 0x1234678");
+      exit (1);
+    }
+
+  if (in_dso_2 () != 0xbadbeef)
+    {
+      puts ("in_dso_2 () != 0xbadbeef");
+      exit (1);
+    }
+
+  dlclose (h);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86/tst-cet-legacy-2a.c b/sysdeps/x86/tst-cet-legacy-2a.c
new file mode 100644
index 0000000000..d5aead4303
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-2a.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-2.c"
diff --git a/sysdeps/x86/tst-cet-legacy-3.c b/sysdeps/x86/tst-cet-legacy-3.c
new file mode 100644
index 0000000000..7bf0e656b1
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-3.c
@@ -0,0 +1,88 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.  Copied from gcc.target/i386/pr81128.c in GCC testsuite.
+   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 <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+int resolver_fn = 0;
+int resolved_fn = 0;
+
+static inline void
+do_it_right_at_runtime_A (void)
+{
+  resolved_fn++;
+}
+
+static inline void
+do_it_right_at_runtime_B (void)
+{
+  resolved_fn++;
+}
+
+static inline void do_it_right_at_runtime (void);
+
+void do_it_right_at_runtime (void)
+  __attribute__ ((ifunc ("resolve_do_it_right_at_runtime")));
+
+static void (*resolve_do_it_right_at_runtime (void)) (void)
+{
+  srand (time (NULL));
+  int r = rand ();
+  resolver_fn++;
+
+  /* Use intermediate variable to get a warning for non-matching
+   * prototype. */
+  typeof(do_it_right_at_runtime) *func;
+  if (r & 1)
+    func = do_it_right_at_runtime_A;
+  else
+    func = do_it_right_at_runtime_B;
+
+  return (void *) func;
+}
+
+int
+test (void)
+{
+  const unsigned int ITERS = 10;
+
+  for (int i = ITERS; i > 0; i--)
+    {
+      do_it_right_at_runtime ();
+    }
+
+  if (resolver_fn != 1)
+    __builtin_abort ();
+
+  if (resolved_fn != 10)
+    __builtin_abort ();
+
+  return 0;
+}
+
+#ifndef TEST_MODULE
+static int
+do_test (void)
+{
+  return test ();
+}
+
+#include <support/test-driver.c>
+#endif
diff --git a/sysdeps/x86/tst-cet-legacy-4.c b/sysdeps/x86/tst-cet-legacy-4.c
new file mode 100644
index 0000000000..3ead63dd24
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-4.c
@@ -0,0 +1,56 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   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 <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int
+do_test (void)
+{
+  static const char modname[] = "tst-cet-legacy-mod-4.so";
+  int (*fp) (void);
+  void *h;
+
+  h = dlopen (modname, RTLD_LAZY);
+  if (h == NULL)
+    {
+      printf ("cannot open '%s': %s\n", modname, dlerror ());
+      exit (1);
+    }
+
+  fp = dlsym (h, "test");
+  if (fp == NULL)
+    {
+      printf ("cannot get symbol 'test': %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (fp () != 0)
+    {
+      puts ("test () != 0");
+      exit (1);
+    }
+
+  dlclose (h);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86/tst-cet-legacy-4a.c b/sysdeps/x86/tst-cet-legacy-4a.c
new file mode 100644
index 0000000000..b9bb18c36b
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-4a.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-4.c"
diff --git a/sysdeps/x86/tst-cet-legacy-4b.c b/sysdeps/x86/tst-cet-legacy-4b.c
new file mode 100644
index 0000000000..b9bb18c36b
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-4b.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-4.c"
diff --git a/sysdeps/x86/tst-cet-legacy-4c.c b/sysdeps/x86/tst-cet-legacy-4c.c
new file mode 100644
index 0000000000..b9bb18c36b
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-4c.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-4.c"
diff --git a/sysdeps/x86/tst-cet-legacy-mod-1.c b/sysdeps/x86/tst-cet-legacy-mod-1.c
new file mode 100644
index 0000000000..09762bce13
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-mod-1.c
@@ -0,0 +1,24 @@
+/* Check compatibility of CET-enabled executable with legacy shared
+   object.
+   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/>.  */
+
+int
+in_dso_1 (void)
+{
+  return 0x1234678;
+}
diff --git a/sysdeps/x86/tst-cet-legacy-mod-2.c b/sysdeps/x86/tst-cet-legacy-mod-2.c
new file mode 100644
index 0000000000..1c8de443f6
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-mod-2.c
@@ -0,0 +1,24 @@
+/* Check compatibility of CET-enabled executable with legacy shared
+   object.
+   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/>.  */
+
+int
+in_dso_2 (void)
+{
+  return 0xbadbeef;
+}
diff --git a/sysdeps/x86/tst-cet-legacy-mod-4.c b/sysdeps/x86/tst-cet-legacy-mod-4.c
new file mode 100644
index 0000000000..a93c2fe4a7
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-mod-4.c
@@ -0,0 +1,2 @@
+#define TEST_MODULE
+#include "tst-cet-legacy-3.c"
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 12/12] Add tests for setcontext on the context from makecontext
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (3 preceding siblings ...)
  2018-07-21 14:20 ` [PATCH 10/12] Add another test for setcontext H.J. Lu
@ 2018-07-21 14:20 ` H.J. Lu
  2018-07-25  3:51   ` Carlos O'Donell
  2018-07-21 14:20 ` [PATCH 07/12] x86/CET: Add tests with legacy non-CET shared objects H.J. Lu
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:20 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

	* stdlib/Makefile ((tests): Add tst-setcontext6, tst-setcontext7,
	tst-setcontext8 and tst-setcontext9.
	* stdlib/tst-setcontext6.c: New file.
	* stdlib/tst-setcontext7.c: Likewise.
	* stdlib/tst-setcontext8.c: Likewise.
	* stdlib/tst-setcontext9.c: Likewise.
---
 stdlib/Makefile          |   3 +-
 stdlib/tst-setcontext6.c |  76 +++++++++++++++++++++++++++++
 stdlib/tst-setcontext7.c |  96 +++++++++++++++++++++++++++++++++++++
 stdlib/tst-setcontext8.c |  81 +++++++++++++++++++++++++++++++
 stdlib/tst-setcontext9.c | 100 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 355 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-setcontext6.c
 create mode 100644 stdlib/tst-setcontext7.c
 create mode 100644 stdlib/tst-setcontext8.c
 create mode 100644 stdlib/tst-setcontext9.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index 8db4f1d35a..638306bb5c 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -86,7 +86,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   test-on_exit-race test-dlclose-exit-race 		    \
 		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
 		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4 \
-		   tst-setcontext5
+		   tst-setcontext5 tst-setcontext6 tst-setcontext7 \
+		   tst-setcontext8 tst-setcontext9
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-setcontext6.c b/stdlib/tst-setcontext6.c
new file mode 100644
index 0000000000..c719e2d678
--- /dev/null
+++ b/stdlib/tst-setcontext6.c
@@ -0,0 +1,76 @@
+/* Check getcontext and setcontext on the context from 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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static ucontext_t ctx[3];
+static volatile int done;
+
+static void
+f1 (void)
+{
+  printf ("start f1\n");
+  if (!done)
+    {
+      if (getcontext (&ctx[2]) != 0)
+	{
+	  printf ("%s: getcontext: %m\n", __FUNCTION__);
+	  exit (EXIT_FAILURE);
+	}
+      if (done)
+	exit (EXIT_SUCCESS);
+    }
+  done++;
+  if (setcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  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);
+  if (setcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
diff --git a/stdlib/tst-setcontext7.c b/stdlib/tst-setcontext7.c
new file mode 100644
index 0000000000..e331e511ef
--- /dev/null
+++ b/stdlib/tst-setcontext7.c
@@ -0,0 +1,96 @@
+/* Check setcontext on the context from 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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static ucontext_t ctx[5];
+static volatile int done;
+
+static void
+f1 (void)
+{
+  puts ("start f1");
+  if (!done)
+    {
+      if (getcontext (&ctx[2]) != 0)
+	{
+	  printf ("%s: getcontext: %m\n", __FUNCTION__);
+	  exit (EXIT_FAILURE);
+	}
+      if (done)
+	{
+	  puts ("set context in f1");
+	  if (setcontext (&ctx[3]) != 0)
+	    {
+	      printf ("%s: setcontext: %m\n", __FUNCTION__);
+	      exit (EXIT_FAILURE);
+	    }
+	}
+    }
+  done++;
+  puts ("swap contexts in f1");
+  if (swapcontext (&ctx[4], &ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  puts ("end f1");
+  exit (done == 2 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  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);
+  puts ("swap contexts");
+  if (swapcontext (&ctx[3], &ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (done != 1)
+    exit (EXIT_FAILURE);
+  done++;
+  puts ("set context");
+  if (setcontext (&ctx[4]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
diff --git a/stdlib/tst-setcontext8.c b/stdlib/tst-setcontext8.c
new file mode 100644
index 0000000000..a7febf6c67
--- /dev/null
+++ b/stdlib/tst-setcontext8.c
@@ -0,0 +1,81 @@
+/* Check getcontext and setcontext on the context from 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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static ucontext_t ctx[3];
+static volatile int done;
+
+static void
+__attribute__((noinline, noclone))
+f2 (void)
+{
+  printf ("start f2\n");
+  done++;
+  if (setcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+}
+
+static void
+f1 (void)
+{
+  printf ("start f1\n");
+  if (getcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (done)
+    exit (EXIT_SUCCESS);
+  f2 ();
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  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);
+  if (setcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
new file mode 100644
index 0000000000..53609d4b10
--- /dev/null
+++ b/stdlib/tst-setcontext9.c
@@ -0,0 +1,100 @@
+/* Check setcontext on the context from 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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static ucontext_t ctx[5];
+static volatile int done;
+
+static void
+__attribute__((noinline, noclone))
+f2 (void)
+{
+  done++;
+  puts ("swap contexts in f2");
+  if (swapcontext (&ctx[4], &ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  puts ("end f2");
+  exit (done == 2 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+static void
+f1 (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");
+      if (setcontext (&ctx[3]) != 0)
+	{
+	  printf ("%s: setcontext: %m\n", __FUNCTION__);
+	  exit (EXIT_FAILURE);
+	}
+    }
+  f2 ();
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  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);
+  puts ("swap contexts");
+  if (swapcontext (&ctx[3], &ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (done != 1)
+    exit (EXIT_FAILURE);
+  done++;
+  puts ("set context");
+  if (setcontext (&ctx[4]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 02/12] x86-64: Add endbr64 to tst-quadmod[12].S
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
  2018-07-21 14:20 ` [PATCH 09/12] Add a test for multiple makecontext calls H.J. Lu
@ 2018-07-21 14:20 ` H.J. Lu
  2018-07-24  2:53   ` Carlos O'Donell
  2018-07-21 14:20 ` [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control H.J. Lu
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:20 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

Add endbr64 to tst-quadmod1.S and tst-quadmod2.S so that func and foo
can be called indirectly.

	* sysdeps/x86_64/tst-quadmod1.S (func): Add endbr64 if IBT is
	enabled.
	(foo): Likewise.
	* sysdeps/x86_64/tst-quadmod2.S (func) : Likewise.
	(foo): Likewise.
---
 sysdeps/x86_64/tst-quadmod1.S | 6 ++++++
 sysdeps/x86_64/tst-quadmod2.S | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/sysdeps/x86_64/tst-quadmod1.S b/sysdeps/x86_64/tst-quadmod1.S
index 26f2f1b599..c60f9dc89d 100644
--- a/sysdeps/x86_64/tst-quadmod1.S
+++ b/sysdeps/x86_64/tst-quadmod1.S
@@ -28,6 +28,9 @@
 	.type	func, @function
 func:
 	.cfi_startproc
+#if defined __CET__ && (__CET__ & 1) != 0
+	endbr64
+#endif
 	xorl	%edi, %edi
 	jmp	exit@PLT
 	.cfi_endproc
@@ -37,6 +40,9 @@ func:
 foo:
 	.cfi_startproc
 	.cfi_def_cfa_register 6
+#if defined __CET__ && (__CET__ & 1) != 0
+	endbr64
+#endif
 	movq	.Ljmp(%rip), %rax
 	subq	$BIAS, %rax
 	jmp	*%rax
diff --git a/sysdeps/x86_64/tst-quadmod2.S b/sysdeps/x86_64/tst-quadmod2.S
index e923adf672..af03444d4f 100644
--- a/sysdeps/x86_64/tst-quadmod2.S
+++ b/sysdeps/x86_64/tst-quadmod2.S
@@ -27,6 +27,9 @@
 	.type	func, @function
 func:
 	.cfi_startproc
+#if defined __CET__ && (__CET__ & 1) != 0
+	endbr64
+#endif
 	xorl	%edi, %edi
 	jmp	exit@PLT
 	.cfi_endproc
@@ -36,6 +39,9 @@ func:
 foo:
 	.cfi_startproc
 	.cfi_def_cfa_register 6
+#if defined __CET__ && (__CET__ & 1) != 0
+	endbr64
+#endif
 	movq	.Ljmp(%rip), %rax
 	subq	$BIAS, %rax
 	jmp	*%rax
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 03/12] Add <bits/indirect-return.h>
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (8 preceding siblings ...)
  2018-07-21 14:21 ` [PATCH 06/12] x86-64/CET: Extend ucontext_t to save shadow stack H.J. Lu
@ 2018-07-21 14:21 ` H.J. Lu
  2018-07-24 12:57   ` Carlos O'Donell
  2018-07-21 14:21 ` [PATCH 11/12] Add a test for multiple setcontext calls H.J. Lu
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:21 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

Add <bits/indirect-return.h> and include it in <ucontext.h>.
__INDIRECT_RETURN defined in <bits/indirect-return.h> indicates if
swapcontext requires special compiler treatment.  The default
__INDIRECT_RETURN is empty.

On x86, when shadow stack is enabled, __INDIRECT_RETURN is defined
with indirect_return attribute, which has been added to GCC 9, to
indicate that swapcontext returns via indirect branch.  Otherwise
__INDIRECT_RETURN is defined with returns_twice attribute.

When shadow stack is enabled, remove always_inline attribute from
prepare_test_buffer in string/tst-xbzero-opt.c to avoid:

tst-xbzero-opt.c: In function ‘prepare_test_buffer’:
tst-xbzero-opt.c:105:1: error: function ‘prepare_test_buffer’ can never be inlined because it uses setjmp
 prepare_test_buffer (unsigned char *buf)

when indirect_return attribute isn't available.

	* bits/indirect-return.h: New file.
	* misc/sys/cdefs.h (__glibc_has_attribute): New.
	* sysdeps/x86/bits/indirect-return.h: Likewise.
	* stdlib/Makefile (headers): Add bits/indirect-return.h.
	* stdlib/ucontext.h: Include <bits/indirect-return.h>.
	(swapcontext): Add __INDIRECT_RETURN.
	* string/tst-xbzero-opt.c (ALWAYS_INLINE): New.
	(prepare_test_buffer): Use it.
---
 bits/indirect-return.h             | 25 +++++++++++++++++++++
 misc/sys/cdefs.h                   |  6 +++++
 stdlib/Makefile                    |  2 +-
 stdlib/ucontext.h                  |  6 ++++-
 string/tst-xbzero-opt.c            | 10 ++++++++-
 sysdeps/x86/bits/indirect-return.h | 35 ++++++++++++++++++++++++++++++
 6 files changed, 81 insertions(+), 3 deletions(-)
 create mode 100644 bits/indirect-return.h
 create mode 100644 sysdeps/x86/bits/indirect-return.h

diff --git a/bits/indirect-return.h b/bits/indirect-return.h
new file mode 100644
index 0000000000..47f6f15a6e
--- /dev/null
+++ b/bits/indirect-return.h
@@ -0,0 +1,25 @@
+/* Definition of __INDIRECT_RETURN.  Generic version.
+   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/>.  */
+
+#ifndef _UCONTEXT_H
+# error "Never include <bits/indirect-return.h> directly; use <ucontext.h> instead."
+#endif
+
+/* __INDIRECT_RETURN is used on swapcontext to indicate if it requires
+   special compiler treatment.  */
+#define __INDIRECT_RETURN
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index e80a45ca68..3f6fe3cc85 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -406,6 +406,12 @@
 # define __glibc_likely(cond)	(cond)
 #endif
 
+#ifdef __has_attribute
+# define __glibc_has_attribute(attr)	__has_attribute (attr)
+#else
+# define __glibc_has_attribute(attr)	0
+#endif
+
 #if (!defined _Noreturn \
      && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
      &&  !__GNUC_PREREQ (4,7))
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 808a8ceab7..b5e55b0a55 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -26,7 +26,7 @@ headers	:= stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h      \
 	   monetary.h bits/monetary-ldbl.h				      \
 	   inttypes.h stdint.h bits/wordsize.h				      \
 	   errno.h sys/errno.h bits/errno.h bits/types/error_t.h	      \
-	   ucontext.h sys/ucontext.h					      \
+	   ucontext.h sys/ucontext.h bits/indirect-return.h		      \
 	   alloca.h fmtmsg.h						      \
 	   bits/stdlib-bsearch.h sys/random.h bits/stdint-intn.h	      \
 	   bits/stdint-uintn.h
diff --git a/stdlib/ucontext.h b/stdlib/ucontext.h
index eec7611631..ec630038f6 100644
--- a/stdlib/ucontext.h
+++ b/stdlib/ucontext.h
@@ -22,6 +22,9 @@
 
 #include <features.h>
 
+/* Get definition of __INDIRECT_RETURN.  */
+#include <bits/indirect-return.h>
+
 /* Get machine dependent definition of data structures.  */
 #include <sys/ucontext.h>
 
@@ -36,7 +39,8 @@ extern int setcontext (const ucontext_t *__ucp) __THROWNL;
 /* Save current context in context variable pointed to by OUCP and set
    context from variable pointed to by UCP.  */
 extern int swapcontext (ucontext_t *__restrict __oucp,
-			const ucontext_t *__restrict __ucp) __THROWNL;
+			const ucontext_t *__restrict __ucp)
+  __THROWNL __INDIRECT_RETURN;
 
 /* Manipulate user context UCP to continue with calling functions FUNC
    and the ARGC-1 parameters following ARGC when the context is used
diff --git a/string/tst-xbzero-opt.c b/string/tst-xbzero-opt.c
index cf7041f37a..aab4a7f715 100644
--- a/string/tst-xbzero-opt.c
+++ b/string/tst-xbzero-opt.c
@@ -100,7 +100,15 @@ static ucontext_t uc_main, uc_co;
 /* Always check the test buffer immediately after filling it; this
    makes externally visible side effects depend on the buffer existing
    and having been filled in.  */
-static inline __attribute__  ((always_inline)) void
+#if defined __CET__ && !__glibc_has_attribute (__indirect_return__)
+/* Note: swapcontext returns via indirect branch when SHSTK is enabled.
+   Without indirect_return attribute, swapcontext is marked with
+   returns_twice attribute, which prevents always_inline to work.  */
+# define ALWAYS_INLINE
+#else
+# define ALWAYS_INLINE	__attribute__ ((always_inline))
+#endif
+static inline ALWAYS_INLINE void
 prepare_test_buffer (unsigned char *buf)
 {
   for (unsigned int i = 0; i < PATTERN_REPS; i++)
diff --git a/sysdeps/x86/bits/indirect-return.h b/sysdeps/x86/bits/indirect-return.h
new file mode 100644
index 0000000000..0587e687ac
--- /dev/null
+++ b/sysdeps/x86/bits/indirect-return.h
@@ -0,0 +1,35 @@
+/* Definition of __INDIRECT_RETURN.  x86 version.
+   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/>.  */
+
+#ifndef _UCONTEXT_H
+# error "Never include <bits/indirect-return.h> directly; use <ucontext.h> instead."
+#endif
+
+/* On x86, swapcontext returns via indirect branch when the shadow stack
+   is enabled.  Define __INDIRECT_RETURN to indicate whether swapcontext
+   returns via indirect branch.  */
+#if defined __CET__ && (__CET__ & 2) != 0
+# if __glibc_has_attribute (__indirect_return__)
+#  define __INDIRECT_RETURN __attribute__ ((__indirect_return__))
+# else
+/* Without indirect_return attribute, use returns_twice attribute.  */
+#  define __INDIRECT_RETURN __attribute__ ((__returns_twice__))
+# endif
+#else
+# define __INDIRECT_RETURN
+#endif
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 01/12] x86: Update vfork to pop shadow stack
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (10 preceding siblings ...)
  2018-07-21 14:21 ` [PATCH 11/12] Add a test for multiple setcontext calls H.J. Lu
@ 2018-07-21 14:21 ` H.J. Lu
  2018-07-24  2:47   ` Carlos O'Donell
  2018-07-24  1:41 ` [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET Carlos O'Donell
  2018-07-26 11:17 ` Florian Weimer
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:21 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

Since we can't change return address on shadow stack, if shadow stack
is in use, we need to pop shadow stack and jump back to caller directly.

	* sysdeps/unix/sysv/linux/i386/vfork.S (SYSCALL_ERROR_HANDLER):
	Redefine if shadow stack is enabled.
	(SYSCALL_ERROR_LABEL): Likewise.
	(__vfork): Pop shadow stack and jump back to to caller directly
	when shadow stack is in use.
	* sysdeps/unix/sysv/linux/x86_64/vfork.S (SYSCALL_ERROR_HANDLER):
	Redefine if shadow stack is enabled.
	(SYSCALL_ERROR_LABEL): Likewise.
	(__vfork): Pop shadow stack and jump back to to caller directly
	when shadow stack is in use.
---
 sysdeps/unix/sysv/linux/i386/vfork.S   | 54 ++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/vfork.S | 35 +++++++++++++++++
 2 files changed, 89 insertions(+)

diff --git a/sysdeps/unix/sysv/linux/i386/vfork.S b/sysdeps/unix/sysv/linux/i386/vfork.S
index 8f40d02d09..a75436157e 100644
--- a/sysdeps/unix/sysv/linux/i386/vfork.S
+++ b/sysdeps/unix/sysv/linux/i386/vfork.S
@@ -21,6 +21,35 @@
 #include <bits/errno.h>
 #include <tcb-offsets.h>
 
+#if SHSTK_ENABLED
+/* When shadow stack is in use, we need to pop shadow stack and jump
+   back to caller directly.   */
+# undef SYSCALL_ERROR_HANDLER
+# ifdef PIC
+#  define SYSCALL_ERROR_HANDLER				\
+0:							\
+  calll .L1;						\
+.L1:							\
+  popl %edx;						\
+.L2:							\
+  addl $_GLOBAL_OFFSET_TABLE_ + (.L2 - .L1), %edx;	\
+  movl __libc_errno@gotntpoff(%edx), %edx;		\
+  negl %eax;						\
+  movl %eax, %gs:(%edx);				\
+  orl $-1, %eax;					\
+  jmp 1b;
+# else
+#  define SYSCALL_ERROR_HANDLER				\
+0:							\
+  movl __libc_errno@indntpoff, %edx;			\
+  negl %eax;						\
+  movl %eax, %gs:(%edx);				\
+  orl $-1, %eax;					\
+  jmp 1b;
+# endif
+# undef SYSCALL_ERROR_LABEL
+# define SYSCALL_ERROR_LABEL 0f
+#endif
 
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
@@ -38,16 +67,41 @@ ENTRY (__vfork)
 	movl	$SYS_ify (vfork), %eax
 	int	$0x80
 
+#if !SHSTK_ENABLED
 	/* Jump to the return PC.  Don't jump directly since this
 	   disturbs the branch target cache.  Instead push the return
 	   address back on the stack.  */
 	pushl	%ecx
 	cfi_adjust_cfa_offset (4)
+#endif
 
 	cmpl	$-4095, %eax
 	/* Branch forward if it failed.  */
 	jae	SYSCALL_ERROR_LABEL
 
+#if SHSTK_ENABLED
+1:
+	/* Check if shadow stack is in use.  */
+	xorl	%edx, %edx
+	rdsspd	%edx
+	testl	%edx, %edx
+	/* Normal return if shadow stack isn't in use.  */
+	je	L(no_shstk)
+
+	/* Pop return address from shadow stack and jump back to caller
+	   directly.  */
+	movl	$1, %edx
+	incsspd	%edx
+	jmp	*%ecx
+
+L(no_shstk):
+	/* Jump to the return PC.  Don't jump directly since this
+	   disturbs the branch target cache.  Instead push the return
+	   address back on the stack.  */
+	pushl	%ecx
+	cfi_adjust_cfa_offset (4)
+#endif
+
 	ret
 
 PSEUDO_END (__vfork)
diff --git a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S
index e4c8269e3d..a6d6280bd2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/vfork.S
+++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S
@@ -20,6 +20,18 @@
 #include <bits/errno.h>
 #include <tcb-offsets.h>
 
+#if SHSTK_ENABLED
+/* When shadow stack is in use, we need to pop shadow stack and jump
+   back to caller directly.   */
+# undef SYSCALL_ERROR_HANDLER
+# define SYSCALL_ERROR_HANDLER			\
+0:						\
+  SYSCALL_SET_ERRNO;				\
+  or $-1, %RAX_LP;				\
+  jmp 1b;
+# undef SYSCALL_ERROR_LABEL
+# define SYSCALL_ERROR_LABEL 0f
+#endif
 
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
@@ -38,13 +50,36 @@ ENTRY (__vfork)
 	movl	$SYS_ify (vfork), %eax
 	syscall
 
+#if !SHSTK_ENABLED
 	/* Push back the return PC.  */
 	pushq	%rdi
 	cfi_adjust_cfa_offset(8)
+#endif
 
 	cmpl	$-4095, %eax
 	jae SYSCALL_ERROR_LABEL		/* Branch forward if it failed.  */
 
+#if SHSTK_ENABLED
+1:
+	/* Check if shadow stack is in use.  */
+	xorl	%esi, %esi
+	rdsspq	%rsi
+	testq	%rsi, %rsi
+	/* Normal return if shadow stack isn't in use.  */
+	je	L(no_shstk)
+
+	/* Pop return address from shadow stack and jump back to caller
+	   directly.  */
+	movl	$1, %esi
+	incsspq	%rsi
+	jmp	*%rdi
+
+L(no_shstk):
+	/* Push back the return PC.  */
+	pushq	%rdi
+	cfi_adjust_cfa_offset(8)
+#endif
+
 	/* Normal return.  */
 	ret
 
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 06/12] x86-64/CET: Extend ucontext_t to save shadow stack
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (7 preceding siblings ...)
  2018-07-21 14:21 ` [PATCH 05/12] x86: Rename __glibc_reserved2 to ssp_base in tcbhead_t H.J. Lu
@ 2018-07-21 14:21 ` H.J. Lu
  2018-07-24 20:49   ` Carlos O'Donell
  2018-07-21 14:21 ` [PATCH 03/12] Add <bits/indirect-return.h> H.J. Lu
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:21 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

This patch adds a field to ucontext_t to save shadow stack:

1. getcontext and swapcontext are updated to save the caller's shadow
stack pointer and return addresses.
2. setcontext and swapcontext are updated to restore shadow stack and
jump to new context directly.
3. makecontext is updated to allocate a new shadow stack and set the
caller's return address to __start_context.

Since makecontext allocates a new shadow stack when making a new
context and kernel allocates a new shadow stack for clone/fork/vfork
syscalls, we keep track the lowest shadow stack base.  In setcontext
and swapcontext, when searching for shadow stack restore token, if the
lowest shadow stack base is reached, we assume both the current and
target shadow stack pointers are on the same shadow stack.

We enable shadow stack at run-time only if program and all used shared
objects, including dlopened ones, are shadow stack enabled, which means
that they must be compiled with GCC 8 or above and glibc 2.28 or above.
We need to save and restore shadow stack only if shadow stack is enabled.
When caller of getcontext, setcontext, swapcontext and makecontext is
compiled with smaller ucontext_t, shadow stack won't be enabled at
run-time.  We check if shadow stack is enabled before accessing the
extended field in ucontext_t.

2018-05-21  Vedvyas Shanbhogue  <vedvyas.shanbhogue@intel.com>
	    H.J. Lu  <hongjiu.lu@intel.com>

	* sysdeps/unix/sysv/linux/x86/sys/ucontext.h (ucontext_t): Add
	__ssp.
	* sysdeps/unix/sysv/linux/x86_64/__start_context.S: Include
	<bits/prctl.h> and "ucontext_i.h" when shadow stack is enabled.
	(__push___start_context): New.
	* sysdeps/unix/sysv/linux/x86_64/getcontext.S (__getcontext):
	Save the caller's shadow stack pointer when shadow stack is in
	use.
	* sysdeps/unix/sysv/linux/x86_64/makecontext.c Include
	<pthread.h>, <libc-pointer-arith.h> and <sys/prctl.h>.
	(__push___start_context): New prototype.
	(__makecontext): Call __push___start_context to allocate a new
	shadow stack, push __start_context onto the new stack as well
	as the new shadow stack.  Set the lowest shadow stack base.
	* sysdeps/unix/sysv/linux/x86_64/setcontext.S: Include
	<bits/prctl.h>.
	(__setcontext): Use the restore token to restore shadow stack
	if available.  Otherwise unwind shadow stack.  Check if the
	target shadow stack pointer came from __push___start_context.
	Don't search for shadow stack restore token below the lowest
	shadow stack base.
	* sysdeps/unix/sysv/linux/x86_64/swapcontext.S: Include
	<bits/prctl.h>.
	(__swapcontext): Save the current shadow stack pointer.
	Use the restore token to restore shadow stack if available.
	Otherwise unwind shadow stack.  Check if the target shadow
	stack pointer came from __push___start_context.  Don't search
	for shadow stack restore token below the lowest shadow stack
	base.
	* sysdeps/unix/sysv/linux/x86_64/sysdep.h
	(STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT): New.
	* sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym (oSSP): New.
---
 sysdeps/unix/sysv/linux/x86/sys/ucontext.h    |   2 +
 .../unix/sysv/linux/x86_64/__start_context.S  |  75 +++++++++
 sysdeps/unix/sysv/linux/x86_64/getcontext.S   |  17 ++
 sysdeps/unix/sysv/linux/x86_64/makecontext.c  |  56 ++++++-
 sysdeps/unix/sysv/linux/x86_64/setcontext.S   | 139 ++++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/swapcontext.S  | 150 ++++++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/sysdep.h       |   5 +
 sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym |   1 +
 8 files changed, 444 insertions(+), 1 deletion(-)

diff --git a/sysdeps/unix/sysv/linux/x86/sys/ucontext.h b/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
index afb7c181bf..7367726a50 100644
--- a/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
+++ b/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
@@ -147,6 +147,7 @@ typedef struct ucontext_t
     mcontext_t uc_mcontext;
     sigset_t uc_sigmask;
     struct _libc_fpstate __fpregs_mem;
+    __extension__ unsigned long long int __ssp[4];
   } ucontext_t;
 
 #else /* !__x86_64__ */
@@ -251,6 +252,7 @@ typedef struct ucontext_t
     mcontext_t uc_mcontext;
     sigset_t uc_sigmask;
     struct _libc_fpstate __fpregs_mem;
+    unsigned long int __ssp[4];
   } ucontext_t;
 
 #endif /* !__x86_64__ */
diff --git a/sysdeps/unix/sysv/linux/x86_64/__start_context.S b/sysdeps/unix/sysv/linux/x86_64/__start_context.S
index 0bfde5fc31..01e672c09b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/__start_context.S
+++ b/sysdeps/unix/sysv/linux/x86_64/__start_context.S
@@ -18,6 +18,80 @@
 
 #include <sysdep.h>
 
+#if SHSTK_ENABLED
+# include <bits/prctl.h>
+# include "ucontext_i.h"
+
+/* Use CALL to push __start_context onto the new stack as well as the new
+   shadow stack.  RDI points to ucontext:
+   Incoming:
+     __ssp[0]: The original caller's shadow stack pointer.
+     __ssp[1]: The size of the new shadow stack.
+     __ssp[2]: The size of the new shadow stack.
+   Outgoing:
+     __ssp[0]: The new shadow stack pointer.
+     __ssp[1]: The base address of the new shadow stack.
+     __ssp[2]: The size of the new shadow stack.
+ */
+
+ENTRY(__push___start_context)
+	/* Save the pointer to ucontext.  */
+	movq	%rdi, %r9
+	/* Get the original shadow stack pointer.  */
+	rdsspq	%r8
+	/* Save the original stack pointer.  */
+	movq	%rsp, %rdx
+	/* Load the top of the new stack into RSI.  */
+	movq 	oRSP(%rdi), %rsi
+	/* Add 8 bytes to RSI since CALL will push the 8-byte return
+	   address onto stack.  */
+	leaq	8(%rsi), %rsp
+	/* Allocate the new shadow stack.  The size of the new shadow
+	   stack is passed in __ssp[1].  */
+	lea	(oSSP + 8)(%rdi), %RSI_LP
+	movl	$ARCH_CET_ALLOC_SHSTK, %edi
+	movl	$__NR_arch_prctl, %eax
+	/* The new shadow stack base is returned in __ssp[1].  */
+	syscall
+	testq	%rax, %rax
+	jne	L(hlt)		/* This should never happen.  */
+
+	/* Get the size of the new shadow stack.  */
+	movq	8(%rsi), %rdi
+
+	/* Get the base address of the new shadow stack.  */
+	movq	(%rsi), %rsi
+
+	/* Use the restore stoken to restore the new shadow stack.  */
+	rstorssp -8(%rsi, %rdi)
+
+	/* Save the restore token on the original shadow stack.  */
+	saveprevssp
+
+	/* Push the address of "jmp __start_context" onto the new stack
+	   as well as the new shadow stack.  */
+	call	1f
+	jmp	__start_context
+1:
+
+	/* Get the new shadow stack pointer.  */
+	rdsspq	%rdi
+
+	/* Use the restore stoken to restore the original shadow stack.  */
+	rstorssp -8(%r8)
+
+	/* Save the restore token on the new shadow stack.  */
+	saveprevssp
+
+	/* Store the new shadow stack pointer in __ssp[0].  */
+	movq	%rdi, oSSP(%r9)
+
+	/* Restore the original stack.  */
+	mov	%rdx, %rsp
+	ret
+END(__push___start_context)
+#endif
+
 /* This is the helper code which gets called if a function which is
    registered with 'makecontext' returns.  In this case we have to
    install the context listed in the uc_link element of the context
@@ -45,5 +119,6 @@ ENTRY(__start_context)
 	call	HIDDEN_JUMPTARGET(exit)
 	/* The 'exit' call should never return.  In case it does cause
 	   the process to terminate.  */
+L(hlt):
 	hlt
 END(__start_context)
diff --git a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
index 33347bc02e..cbbe4cc9fc 100644
--- a/sysdeps/unix/sysv/linux/x86_64/getcontext.S
+++ b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
@@ -53,6 +53,23 @@ ENTRY(__getcontext)
 	leaq	8(%rsp), %rcx		/* Exclude the return address.  */
 	movq	%rcx, oRSP(%rdi)
 
+#if SHSTK_ENABLED
+	/* Check if shadow stack is enabled.  */
+	testl	$X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
+	jz	L(no_shstk)
+
+	/* Get the current shadow stack pointer.  */
+	rdsspq	%rax
+	/* NB: Save the caller's shadow stack so that we can jump back
+	   to the caller directly.  */
+	addq	$8, %rax
+	movq	%rax, oSSP(%rdi)
+	xorl	%edx, %edx
+	movq	%rdx, (oSSP + 8)(%rdi)
+	movq	%rdx, (oSSP + 16)(%rdi)
+
+L(no_shstk):
+#endif
 	/* We have separate floating-point register content memory on the
 	   stack.  We use the __fpregs_mem block in the context.  Set the
 	   links up correctly.  */
diff --git a/sysdeps/unix/sysv/linux/x86_64/makecontext.c b/sysdeps/unix/sysv/linux/x86_64/makecontext.c
index 0d0802bf43..97f9bbbd2d 100644
--- a/sysdeps/unix/sysv/linux/x86_64/makecontext.c
+++ b/sysdeps/unix/sysv/linux/x86_64/makecontext.c
@@ -21,6 +21,11 @@
 #include <stdarg.h>
 #include <stdint.h>
 #include <ucontext.h>
+#if SHSTK_ENABLED
+# include <pthread.h>
+# include <libc-pointer-arith.h>
+# include <sys/prctl.h>
+#endif
 
 #include "ucontext_i.h"
 
@@ -52,6 +57,8 @@ void
 __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
 {
   extern void __start_context (void) attribute_hidden;
+  extern void __push___start_context (ucontext_t *)
+    attribute_hidden;
   greg_t *sp;
   unsigned int idx_uc_link;
   va_list ap;
@@ -74,7 +81,54 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
   ucp->uc_mcontext.gregs[REG_RSP] = (uintptr_t) sp;
 
   /* Setup stack.  */
-  sp[0] = (uintptr_t) &__start_context;
+#if SHSTK_ENABLED
+  struct pthread *self = THREAD_SELF;
+  unsigned int feature_1 = THREAD_GETMEM (self, header.feature_1);
+  /* NB: We must check feature_1 before accessing __ssp since caller
+	 may be compiled against ucontext_t without __ssp.  */
+  if ((feature_1 & X86_FEATURE_1_SHSTK) != 0)
+    {
+      /* Shadow stack is enabled.  We need to allocate a new shadow
+         stack.  */
+      unsigned long ssp_size = (((uintptr_t) sp
+				 - (uintptr_t) ucp->uc_stack.ss_sp)
+				>> STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT);
+      /* Align shadow stack to 8 bytes.  */
+      ssp_size = ALIGN_UP (ssp_size, 8);
+
+      ucp->__ssp[1] = ssp_size;
+      ucp->__ssp[2] = ssp_size;
+
+      /* Call __push___start_context to allocate a new shadow stack,
+	 push __start_context onto the new stack as well as the new
+	 shadow stack.  NB: After __push___start_context returns,
+	   ucp->__ssp[0]: The new shadow stack pointer.
+	   ucp->__ssp[1]: The base address of the new shadow stack.
+	   ucp->__ssp[2]: The size of the new shadow stack.
+       */
+      __push___start_context (ucp);
+
+      /* Update the lowest shadow stack base.  NB: Since a new shadow
+         stack may be switch by clone syscall, we need to get the
+	 current default shadow stack base via ARCH_CET_STATUS.  */
+      unsigned long long cet_status[3];
+      INTERNAL_SYSCALL_DECL (err);
+      if (INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_STATUS,
+			    cet_status) == 0)
+	{
+	  unsigned long long new_ssp_base = ucp->__ssp[1];
+	  if (new_ssp_base > cet_status[1])
+	    new_ssp_base = cet_status[1];
+
+	  unsigned long long current_ssp_base
+	    = THREAD_GETMEM (self, header.ssp_base);
+	  if (!current_ssp_base || current_ssp_base > new_ssp_base)
+	    THREAD_SETMEM (self, header.ssp_base, new_ssp_base);
+	}
+    }
+  else
+#endif
+    sp[0] = (uintptr_t) &__start_context;
   sp[idx_uc_link] = (uintptr_t) ucp->uc_link;
 
   va_start (ap, argc);
diff --git a/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
index b42af8e291..88c4df5e45 100644
--- a/sysdeps/unix/sysv/linux/x86_64/setcontext.S
+++ b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
@@ -18,6 +18,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
+#include <bits/prctl.h>
 
 #include "ucontext_i.h"
 
@@ -79,6 +80,144 @@ ENTRY(__setcontext)
 	movq	oR14(%rdx), %r14
 	movq	oR15(%rdx), %r15
 
+#if SHSTK_ENABLED
+	/* Check if shadow stack is enabled.  */
+	testl	$X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
+	jz	L(no_shstk)
+
+	/* Get the base address and size of the default shadow stack.
+	   NB: We can't cache them since CLONE syscall switches the
+	   default shadow stack.  */
+	sub	$24, %RSP_LP
+	mov	%RSP_LP, %RSI_LP
+	movl	$ARCH_CET_STATUS, %edi
+	movl	$__NR_arch_prctl, %eax
+	syscall
+	testq	%rax, %rax
+	jne	L(hlt)      /* This should never happen.  */
+
+	/* Get the current shadow stack pointer.  */
+	rdsspq	%rcx
+
+	/* NB: If both the target shadow stack pointer and the current
+	   shadow stack pointer are on the original shadow stack, we
+	   can unwind the stack.  Otherwise, find the restore token
+	   pushed by rstorssp and saveprevssp to restore the target
+	   shadow stack.  */
+	movq	oSSP(%rdx), %rdi
+	movq	%rdi, %rsi
+	subq	8(%rsp), %rsi
+	jb	L(find_restore_token)
+	cmpq	16(%rsp), %rsi
+	jae	L(find_restore_token)
+
+	/* Check if both shadow stack pointers are on the original
+	   shadow stack.  */
+	movq	%rcx, %rsi
+	subq	8(%rsp), %rsi
+	jb	L(find_restore_token)
+	cmpq	16(%rsp), %rsi
+	jae	L(find_restore_token)
+
+	jmp	L(unwind_shadow_stack)
+
+L(find_restore_token):
+	/* Save the target shadow stack pointer.  */
+	movq	%rdi, %rsi
+
+	/* Check if the target shadow stack pointer came from
+	   __push___start_context.  */
+	movq	(%rsi), %rax
+	andq	$-8, %rax
+	leaq	8(%rsi), %r8
+	cmpq	%r8, %rax
+	jne	L(skip_restore_shadow_stack_special)
+
+	/* Pop return address from the shadow stack since setcontext
+	   will not return.   */
+	movq	$1, %rax
+	incsspq	%rax
+
+	/* Use the restore stoken to restore the target shadow stack.  */
+	rstorssp (%rsi)
+
+	jmp	L(unwind_shadow_stack_special)
+
+L(skip_restore_shadow_stack_special):
+	movq	%fs:SSP_BASE_OFFSET, %r8
+L(find_restore_token_loop):
+	/* Check if there is a restore token.  */
+	movq	-8(%rsi), %rax
+	andq	$-8, %rax
+	cmpq	%rsi, %rax
+	je	L(restore_shadow_stack)
+
+	/* Try the next slot.  */
+	subq	$8, %rsi
+
+	/* Don't check restore token below the lowest shadow stack
+	   base.  */
+	cmpq	%r8, %rsi
+	ja	L(find_restore_token_loop)
+
+	jmp	L(unwind_shadow_stack)
+
+L(restore_shadow_stack):
+	/* Pop return address from the shadow stack since setcontext
+	   will not return.   */
+	movq	$1, %rax
+	incsspq	%rax
+
+	/* Use the restore stoken to restore the target shadow stack.  */
+	rstorssp -8(%rsi)
+
+	/* Save the restore token on the old shadow stack.  NB: This
+	   restore token may be checked by setcontext or swapcontext
+	   later.  */
+	saveprevssp
+
+L(unwind_shadow_stack_special):
+	/* Get the current shadow stack.  */
+	rdsspq	%rcx
+
+L(unwind_shadow_stack):
+	add	$24, %RSP_LP
+	/* Unwind the shadow stack.  */
+	subq	%rdi, %rcx
+	je	L(skip_unwind_shadow_stack)
+	negq	%rcx
+	shrq	$3, %rcx
+	movl	$255, %esi
+L(loop):
+	cmpq	%rsi, %rcx
+	cmovb	%rcx, %rsi
+	incsspq	%rsi
+	subq	%rsi, %rcx
+	ja	L(loop)
+
+L(skip_unwind_shadow_stack):
+	movq	oRSI(%rdx), %rsi
+	movq	oRDI(%rdx), %rdi
+	movq	oRCX(%rdx), %rcx
+	movq	oR8(%rdx), %r8
+	movq	oR9(%rdx), %r9
+
+	/* Get the return address set with getcontext.  */
+	movq	oRIP(%rdx), %r10
+
+	/* Setup finally %rdx.  */
+	movq	oRDX(%rdx), %rdx
+
+	/* Clear rax to indicate success.  */
+	xorl	%eax, %eax
+	/* Jump to the new context directly.  */
+	jmp	*%r10
+
+L(hlt):
+	hlt
+
+L(no_shstk):
+#endif
 	/* The following ret should return to the address set with
 	getcontext.  Therefore push the address on the stack.  */
 	movq	oRIP(%rdx), %rcx
diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
index 1110c479fa..7a47275727 100644
--- a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
@@ -18,6 +18,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
+#include <bits/prctl.h>
 
 #include "ucontext_i.h"
 
@@ -67,6 +68,7 @@ ENTRY(__swapcontext)
 
 	/* The syscall destroys some registers, save them.  */
 	movq	%rsi, %r12
+	movq	%rdi, %r9
 
 	/* Save the current signal mask and install the new one with
 	   rt_sigprocmask (SIG_BLOCK, newset, oldset,_NSIG/8).  */
@@ -99,6 +101,154 @@ ENTRY(__swapcontext)
 	movq	oR14(%rdx), %r14
 	movq	oR15(%rdx), %r15
 
+#if SHSTK_ENABLED
+	/* Check if shadow stack is enabled.  */
+	testl	$X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
+	jz	L(no_shstk)
+
+	/* Get the base address and size of the default shadow stack.
+	   NB: We can't cache them since CLONE syscall switches the
+	   default shadow stack.  */
+	sub	$24, %RSP_LP
+	mov	%RSP_LP, %RSI_LP
+	movl	$ARCH_CET_STATUS, %edi
+	movl	$__NR_arch_prctl, %eax
+	syscall
+	testq	%rax, %rax
+	jne	L(hlt)      /* This should never happen.  */
+
+	/* Get the current shadow stack pointer.  */
+	rdsspq	%rcx
+
+	/* On the original shadow stack, save the caller's shadow
+	   stack so that we can jump back to the caller directly.  */
+	leaq	8(%rcx), %rsi
+
+	/* Save the current shadow stack pointer in __ssp[0].  */
+	movq	%rsi, oSSP(%r9)
+
+	/* NB: If both the target shadow stack pointer and the current
+	   shadow stack pointer are on the original shadow stack, we
+	   can unwind the stack.  Otherwise, find the restore token
+	   pushed by rstorssp and saveprevssp to restore the target
+	   shadow stack.  */
+	movq	oSSP(%rdx), %rdi
+	movq	%rdi, %rsi
+	subq	8(%rsp), %rsi
+	jb	L(find_restore_token)
+	cmpq	16(%rsp), %rsi
+	jae	L(find_restore_token)
+
+	/* Check if both shadow stack pointers are on the original
+	   shadow stack.  */
+	movq	%rcx, %rsi
+	subq	8(%rsp), %rsi
+	jb	L(find_restore_token)
+	cmpq	16(%rsp), %rsi
+	jae	L(find_restore_token)
+
+	jmp	L(unwind_shadow_stack)
+
+L(find_restore_token):
+	/* Save the target shadow stack pointer.  */
+	movq	%rdi, %rsi
+
+	/* Check if the target shadow stack pointer came from
+	   __push___start_context.  */
+	movq	(%rsi), %rax
+	andq	$-8, %rax
+	leaq	8(%rsi), %r8
+	cmpq	%r8, %rax
+	jne	L(skip_restore_shadow_stack_special)
+
+	/* Pop return address from the shadow stack since setcontext
+	   will not return.   */
+	movq	$1, %rax
+	incsspq	%rax
+
+	/* Use the restore stoken to restore the target shadow stack.  */
+	rstorssp (%rsi)
+
+	jmp	L(unwind_shadow_stack_special)
+
+L(skip_restore_shadow_stack_special):
+	movq	%fs:SSP_BASE_OFFSET, %r8
+L(find_restore_token_loop):
+	/* Check if there is a restore token.  */
+	movq	-8(%rsi), %rax
+	andq	$-8, %rax
+	cmpq	%rsi, %rax
+	je	L(restore_shadow_stack)
+
+	/* Try the next slot.  */
+	subq	$8, %rsi
+
+	/* Don't check restore token below the lowest shadow stack
+	   base.  */
+	cmpq	%r8, %rsi
+	ja	L(find_restore_token_loop)
+
+	jmp	L(unwind_shadow_stack)
+
+L(restore_shadow_stack):
+	/* Pop return address from the shadow stack since setcontext
+	   will not return.   */
+	movq	$1, %rax
+	incsspq	%rax
+
+	/* Restore the target shadow stack.  */
+	rstorssp -8(%rsi)
+
+L(unwind_shadow_stack_special):
+	/* Save restore token on the old shadow stack.  */
+	saveprevssp
+
+	/* Get the current shadow stack.  */
+	rdsspq	%rcx
+
+L(unwind_shadow_stack):
+	add	$24, %RSP_LP
+	/* Unwind the shadow stack.  */
+	subq	%rdi, %rcx
+	je	L(skip_unwind_shadow_stack)
+	negq	%rcx
+	shrq	$3, %rcx
+	movl	$255, %esi
+L(loop):
+	cmpq	%rsi, %rcx
+	cmovb	%rcx, %rsi
+	incsspq	%rsi
+	subq	%rsi, %rcx
+	ja	L(loop)
+
+L(skip_unwind_shadow_stack):
+	xorl	%eax, %eax
+	movq	%rax, (oSSP + 8)(%r9)
+	movq	%rax, (oSSP + 16)(%r9)
+
+	/* Setup registers used for passing args.  */
+	movq	oRDI(%rdx), %rdi
+	movq	oRSI(%rdx), %rsi
+	movq	oRCX(%rdx), %rcx
+	movq	oR8(%rdx), %r8
+	movq	oR9(%rdx), %r9
+
+	/* Get the return address set with getcontext.  */
+	movq	oRIP(%rdx), %r10
+
+	/* Setup finally %rdx.  */
+	movq	oRDX(%rdx), %rdx
+
+	/* Clear rax to indicate success.  */
+	xorl	%eax, %eax
+	/* Jump to the new context directly.  */
+	jmp	*%r10
+
+L(hlt):
+	hlt
+
+L(no_shstk):
+#endif
 	/* The following ret should return to the address set with
 	getcontext.  Therefore push the address on the stack.  */
 	movq	oRIP(%rdx), %rcx
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index 1ef0f742ae..f07eb04962 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -423,4 +423,9 @@
 #undef LO_HI_LONG
 #define LO_HI_LONG(val) (val), 0
 
+/* Each shadow stack slot takes 8 bytes.  Assuming that each stack
+   frame takes 256 bytes, this is used to compute shadow stack size
+   from stack size.  */
+#define STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT 5
+
 #endif /* linux/x86_64/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
index af3e0e544b..c08b3b8b47 100644
--- a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
+++ b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
@@ -35,3 +35,4 @@ oFPREGS		mcontext (fpregs)
 oSIGMASK	ucontext (uc_sigmask)
 oFPREGSMEM	ucontext (__fpregs_mem)
 oMXCSR		ucontext (__fpregs_mem.mxcsr)
+oSSP		ucontext (__ssp)
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 11/12] Add a test for multiple setcontext calls
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (9 preceding siblings ...)
  2018-07-21 14:21 ` [PATCH 03/12] Add <bits/indirect-return.h> H.J. Lu
@ 2018-07-21 14:21 ` H.J. Lu
  2018-07-25  3:38   ` Carlos O'Donell
  2018-07-21 14:21 ` [PATCH 01/12] x86: Update vfork to pop shadow stack H.J. Lu
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:21 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

Check multiple setcontext calls.

	* stdlib/Makefile ((tests): Add tst-setcontext5.
	* stdlib/tst-setcontext5.c: New file.
---
 stdlib/Makefile          |  3 +-
 stdlib/tst-setcontext5.c | 88 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-setcontext5.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index 73d0e7c2a2..8db4f1d35a 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -85,7 +85,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   test-at_quick_exit-race test-cxa_atexit-race             \
 		   test-on_exit-race test-dlclose-exit-race 		    \
 		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
-		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4
+		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4 \
+		   tst-setcontext5
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-setcontext5.c b/stdlib/tst-setcontext5.c
new file mode 100644
index 0000000000..7dcc15cb8e
--- /dev/null
+++ b/stdlib/tst-setcontext5.c
@@ -0,0 +1,88 @@
+/* Check multiple setcontext calls.
+   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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static ucontext_t ctx[2];
+static volatile int done;
+
+static void f2 (void);
+
+static void
+__attribute__ ((noinline, noclone))
+f1 (void)
+{
+  printf ("start f1\n");
+  f2 ();
+}
+
+static void
+__attribute__ ((noinline, noclone))
+f2 (void)
+{
+  printf ("start f2\n");
+  if (setcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+}
+
+static void
+f3 (void)
+{
+  printf ("start f3\n");
+  if (done)
+    exit (EXIT_SUCCESS);
+  done = 1;
+  if (setcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  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)) f3, 0);
+  f1 ();
+  puts ("FAIL: returned from f1 ()");
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* [PATCH 05/12] x86: Rename __glibc_reserved2 to ssp_base in tcbhead_t
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (6 preceding siblings ...)
  2018-07-21 14:20 ` [PATCH 08/12] Add a test for swapcontext with a wrapper H.J. Lu
@ 2018-07-21 14:21 ` H.J. Lu
  2018-07-24 20:49   ` Carlos O'Donell
  2018-07-21 14:21 ` [PATCH 06/12] x86-64/CET: Extend ucontext_t to save shadow stack H.J. Lu
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-21 14:21 UTC (permalink / raw)
  To: libc-alpha; +Cc: Carlos O'Donell

This will be used to implement shadow stack switching by getcontext,
makecontext, setcontext and swapcontext.

	* sysdeps/i386/nptl/tcb-offsets.sym (SSP_BASE_OFFSET): New.
	* sysdeps/i386/nptl/tls.h (tcbhead_t): Replace __glibc_reserved2
	with ssp_base.
	* sysdeps/x86_64/nptl/tcb-offsets.sym (SSP_BASE_OFFSET): New.
	* sysdeps/x86_64/nptl/tls.h (tcbhead_t): Replace __glibc_reserved2
	with ssp_base.
---
 sysdeps/i386/nptl/tcb-offsets.sym   |  1 +
 sysdeps/i386/nptl/tls.h             |  3 ++-
 sysdeps/x86_64/nptl/tcb-offsets.sym |  1 +
 sysdeps/x86_64/nptl/tls.h           | 10 +++++++++-
 4 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/sysdeps/i386/nptl/tcb-offsets.sym b/sysdeps/i386/nptl/tcb-offsets.sym
index fbac241c45..2ec9e787c1 100644
--- a/sysdeps/i386/nptl/tcb-offsets.sym
+++ b/sysdeps/i386/nptl/tcb-offsets.sym
@@ -13,3 +13,4 @@ CLEANUP_PREV		offsetof (struct _pthread_cleanup_buffer, __prev)
 MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
 POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
 FEATURE_1_OFFSET	offsetof (tcbhead_t, feature_1)
+SSP_BASE_OFFSET		offsetof (tcbhead_t, ssp_base)
diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
index 21e23cd809..12285d3217 100644
--- a/sysdeps/i386/nptl/tls.h
+++ b/sysdeps/i386/nptl/tls.h
@@ -49,7 +49,8 @@ typedef struct
   void *__private_tm[3];
   /* GCC split stack support.  */
   void *__private_ss;
-  void *__glibc_reserved2;
+  /* The lowest address of shadow stack,  */
+  unsigned long ssp_base;
 } tcbhead_t;
 
 /* morestack.S in libgcc uses offset 0x30 to access __private_ss,   */
diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym
index 387621e88c..ae8034743b 100644
--- a/sysdeps/x86_64/nptl/tcb-offsets.sym
+++ b/sysdeps/x86_64/nptl/tcb-offsets.sym
@@ -13,6 +13,7 @@ MULTIPLE_THREADS_OFFSET	offsetof (tcbhead_t, multiple_threads)
 POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
 VGETCPU_CACHE_OFFSET	offsetof (tcbhead_t, vgetcpu_cache)
 FEATURE_1_OFFSET	offsetof (tcbhead_t, feature_1)
+SSP_BASE_OFFSET		offsetof (tcbhead_t, ssp_base)
 
 -- Not strictly offsets, but these values are also used in the TCB.
 TCB_CANCELSTATE_BITMASK	 CANCELSTATE_BITMASK
diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
index f042a0250a..e88561c934 100644
--- a/sysdeps/x86_64/nptl/tls.h
+++ b/sysdeps/x86_64/nptl/tls.h
@@ -60,7 +60,8 @@ typedef struct
   void *__private_tm[4];
   /* GCC split stack support.  */
   void *__private_ss;
-  long int __glibc_reserved2;
+  /* The lowest address of shadow stack,  */
+  unsigned long long int ssp_base;
   /* Must be kept even if it is no longer used by glibc since programs,
      like AddressSanitizer, depend on the size of tcbhead_t.  */
   __128bits __glibc_unused2[8][4] __attribute__ ((aligned (32)));
@@ -72,10 +73,17 @@ typedef struct
 /* morestack.S in libgcc uses offset 0x40 to access __private_ss,   */
 _Static_assert (offsetof (tcbhead_t, __private_ss) == 0x40,
 		"offset of __private_ss != 0x40");
+/* NB: ssp_base used to be "long int __glibc_reserved2", which was
+   changed from 32 bits to 64 bits.  Make sure that the offset of the
+   next field, __glibc_unused2, is unchanged.  */
+_Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x60,
+		"offset of __glibc_unused2 != 0x60");
 # else
 /* morestack.S in libgcc uses offset 0x70 to access __private_ss,   */
 _Static_assert (offsetof (tcbhead_t, __private_ss) == 0x70,
 		"offset of __private_ss != 0x70");
+_Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
+		"offset of __glibc_unused2 != 0x80");
 # endif
 
 #else /* __ASSEMBLER__ */
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (11 preceding siblings ...)
  2018-07-21 14:21 ` [PATCH 01/12] x86: Update vfork to pop shadow stack H.J. Lu
@ 2018-07-24  1:41 ` Carlos O'Donell
  2018-07-26 11:17 ` Florian Weimer
  13 siblings, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24  1:41 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> These are the last 12 patches to enable Intel CET.  Tested by
> 
> 1. build-many-glibcs.py.
> 2. With --enable-cet and without --enable-cet for i686, x86-64 and x32
> on non-CET x86-64 processors.
> 3. With --enable-cet for x86-64 and x32 on CET SDV using the CET kernel
> from cet branch at:
> 
> https://github.com/yyu168/linux_cet/tree/cet
> 
> When the shadow stack (SHSTK) is enabled, makecontext needs to allocate
> a new shadow stack to go with the new stack allocated by the caller.
> setcontext and swapcontext must properly handle the corresponding shadow
> stack when the stack is switched.  Add more tests for user context
> functions to provide more coverage for the shadow stack support.

Thanks for putting this together for review.

Again, I think this should be ready for inclusion in 2.28.

We have spent a lot of time discussing CET and how it should be
handled. While I wanted to avoid a flag change, I know we can't
if we want to support *context() and that's OK.

At a high level we could still backport CET into various distributions,
but enabling it would disable *context() (because of the ABI change),
and that might be an OK position to take.

Cheers,
Carlos.
 
> H.J. Lu (12):
>   x86: Update vfork to pop shadow stack
>   x86-64: Add endbr64 to tst-quadmod[12].S
>   Add <bits/indirect-return.h>
>   x86/CET: Extend arch_prctl syscall for CET control
>   x86: Rename __glibc_reserved2 to ssp_base in tcbhead_t
>   x86-64/CET: Extend ucontext_t to save shadow stack
>   x86/CET: Add tests with legacy non-CET shared objects
>   Add a test for swapcontext with a wrapper
>   Add a test for multiple makecontext calls
>   Add another test for setcontext
>   Add a test for multiple setcontext calls
>   Add tests for setcontext on the context from makecontext
> 
>  bits/indirect-return.h                        |  25 ++
>  misc/sys/cdefs.h                              |   6 +
>  stdlib/Makefile                               |   7 +-
>  stdlib/tst-setcontext4.c                      | 217 ++++++++++++++++++
>  stdlib/tst-setcontext5.c                      |  88 +++++++
>  stdlib/tst-setcontext6.c                      |  76 ++++++
>  stdlib/tst-setcontext7.c                      |  96 ++++++++
>  stdlib/tst-setcontext8.c                      |  81 +++++++
>  stdlib/tst-setcontext9.c                      | 100 ++++++++
>  stdlib/tst-swapcontext1.c                     |  92 ++++++++
>  stdlib/tst-swapcontext2.c                     | 108 +++++++++
>  stdlib/ucontext.h                             |   6 +-
>  string/tst-xbzero-opt.c                       |  10 +-
>  sysdeps/i386/nptl/tcb-offsets.sym             |   1 +
>  sysdeps/i386/nptl/tls.h                       |   3 +-
>  sysdeps/unix/sysv/linux/Makefile              |   3 +-
>  sysdeps/unix/sysv/linux/bits/prctl.h          |  21 ++
>  sysdeps/unix/sysv/linux/i386/vfork.S          |  54 +++++
>  sysdeps/unix/sysv/linux/sys/prctl.h           |   1 +
>  sysdeps/unix/sysv/linux/x86/bits/prctl.h      |  48 ++++
>  sysdeps/unix/sysv/linux/x86/cpu-features.c    |   7 +
>  sysdeps/unix/sysv/linux/x86/dl-cet.h          |  29 ++-
>  sysdeps/unix/sysv/linux/x86/sys/ucontext.h    |   2 +
>  .../unix/sysv/linux/x86_64/__start_context.S  |  75 ++++++
>  sysdeps/unix/sysv/linux/x86_64/getcontext.S   |  17 ++
>  sysdeps/unix/sysv/linux/x86_64/makecontext.c  |  56 ++++-
>  sysdeps/unix/sysv/linux/x86_64/setcontext.S   | 139 +++++++++++
>  sysdeps/unix/sysv/linux/x86_64/swapcontext.S  | 150 ++++++++++++
>  sysdeps/unix/sysv/linux/x86_64/sysdep.h       |   5 +
>  sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym |   1 +
>  sysdeps/unix/sysv/linux/x86_64/vfork.S        |  35 +++
>  sysdeps/x86/Makefile                          |  38 +++
>  sysdeps/x86/bits/indirect-return.h            |  35 +++
>  sysdeps/x86/libc-start.c                      |   3 +
>  sysdeps/x86/tst-cet-legacy-1.c                |  44 ++++
>  sysdeps/x86/tst-cet-legacy-2.c                |  64 ++++++
>  sysdeps/x86/tst-cet-legacy-2a.c               |   1 +
>  sysdeps/x86/tst-cet-legacy-3.c                |  88 +++++++
>  sysdeps/x86/tst-cet-legacy-4.c                |  56 +++++
>  sysdeps/x86/tst-cet-legacy-4a.c               |   1 +
>  sysdeps/x86/tst-cet-legacy-4b.c               |   1 +
>  sysdeps/x86/tst-cet-legacy-4c.c               |   1 +
>  sysdeps/x86/tst-cet-legacy-mod-1.c            |  24 ++
>  sysdeps/x86/tst-cet-legacy-mod-2.c            |  24 ++
>  sysdeps/x86/tst-cet-legacy-mod-4.c            |   2 +
>  sysdeps/x86_64/nptl/tcb-offsets.sym           |   1 +
>  sysdeps/x86_64/nptl/tls.h                     |  10 +-
>  sysdeps/x86_64/tst-quadmod1.S                 |   6 +
>  sysdeps/x86_64/tst-quadmod2.S                 |   6 +
>  49 files changed, 1950 insertions(+), 14 deletions(-)
>  create mode 100644 bits/indirect-return.h
>  create mode 100644 stdlib/tst-setcontext4.c
>  create mode 100644 stdlib/tst-setcontext5.c
>  create mode 100644 stdlib/tst-setcontext6.c
>  create mode 100644 stdlib/tst-setcontext7.c
>  create mode 100644 stdlib/tst-setcontext8.c
>  create mode 100644 stdlib/tst-setcontext9.c
>  create mode 100644 stdlib/tst-swapcontext1.c
>  create mode 100644 stdlib/tst-swapcontext2.c
>  create mode 100644 sysdeps/unix/sysv/linux/bits/prctl.h
>  create mode 100644 sysdeps/unix/sysv/linux/x86/bits/prctl.h
>  create mode 100644 sysdeps/x86/bits/indirect-return.h
>  create mode 100644 sysdeps/x86/tst-cet-legacy-1.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-2.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-2a.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-3.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-4.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-4a.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-4b.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-4c.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-1.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-2.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-4.c
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/12] x86: Update vfork to pop shadow stack
  2018-07-21 14:21 ` [PATCH 01/12] x86: Update vfork to pop shadow stack H.J. Lu
@ 2018-07-24  2:47   ` Carlos O'Donell
  2018-07-24 12:25     ` H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24  2:47 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> Since we can't change return address on shadow stack, if shadow stack
> is in use, we need to pop shadow stack and jump back to caller directly.
> 
> 	* sysdeps/unix/sysv/linux/i386/vfork.S (SYSCALL_ERROR_HANDLER):
> 	Redefine if shadow stack is enabled.
> 	(SYSCALL_ERROR_LABEL): Likewise.
> 	(__vfork): Pop shadow stack and jump back to to caller directly
> 	when shadow stack is in use.
> 	* sysdeps/unix/sysv/linux/x86_64/vfork.S (SYSCALL_ERROR_HANDLER):
> 	Redefine if shadow stack is enabled.
> 	(SYSCALL_ERROR_LABEL): Likewise.
> 	(__vfork): Pop shadow stack and jump back to to caller directly
> 	when shadow stack is in use.
> ---
>  sysdeps/unix/sysv/linux/i386/vfork.S   | 54 ++++++++++++++++++++++++++
>  sysdeps/unix/sysv/linux/x86_64/vfork.S | 35 +++++++++++++++++
>  2 files changed, 89 insertions(+)

OK with comment suggestion.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
 
> diff --git a/sysdeps/unix/sysv/linux/i386/vfork.S b/sysdeps/unix/sysv/linux/i386/vfork.S
> index 8f40d02d09..a75436157e 100644
> --- a/sysdeps/unix/sysv/linux/i386/vfork.S
> +++ b/sysdeps/unix/sysv/linux/i386/vfork.S
> @@ -21,6 +21,35 @@
>  #include <bits/errno.h>
>  #include <tcb-offsets.h>
>  
> +#if SHSTK_ENABLED
> +/* When shadow stack is in use, we need to pop shadow stack and jump
> +   back to caller directly.   */

Suggest:
/* The shadow stack prevents us from pushing the saved return PC
   onto the stack and returning normally.  Instead we pop the shadow
   stack and return directly.  This is the safest way to return
   and ensures any stack manipulations done by the vfork'd child
   doesn't cause the parent to terminate when CET is enabled.  */

> +# undef SYSCALL_ERROR_HANDLER
> +# ifdef PIC
> +#  define SYSCALL_ERROR_HANDLER				\
> +0:							\
> +  calll .L1;						\
> +.L1:							\
> +  popl %edx;						\
> +.L2:							\
> +  addl $_GLOBAL_OFFSET_TABLE_ + (.L2 - .L1), %edx;	\
> +  movl __libc_errno@gotntpoff(%edx), %edx;		\
> +  negl %eax;						\
> +  movl %eax, %gs:(%edx);				\
> +  orl $-1, %eax;					\
> +  jmp 1b;
> +# else
> +#  define SYSCALL_ERROR_HANDLER				\
> +0:							\
> +  movl __libc_errno@indntpoff, %edx;			\
> +  negl %eax;						\
> +  movl %eax, %gs:(%edx);				\
> +  orl $-1, %eax;					\
> +  jmp 1b;
> +# endif
> +# undef SYSCALL_ERROR_LABEL
> +# define SYSCALL_ERROR_LABEL 0f
> +#endif
>  
>  /* Clone the calling process, but without copying the whole address space.
>     The calling process is suspended until the new process exits or is
> @@ -38,16 +67,41 @@ ENTRY (__vfork)
>  	movl	$SYS_ify (vfork), %eax
>  	int	$0x80
>  
> +#if !SHSTK_ENABLED
>  	/* Jump to the return PC.  Don't jump directly since this
>  	   disturbs the branch target cache.  Instead push the return
>  	   address back on the stack.  */
>  	pushl	%ecx
>  	cfi_adjust_cfa_offset (4)
> +#endif

OK.

>  
>  	cmpl	$-4095, %eax
>  	/* Branch forward if it failed.  */
>  	jae	SYSCALL_ERROR_LABEL
>  
> +#if SHSTK_ENABLED
> +1:
> +	/* Check if shadow stack is in use.  */
> +	xorl	%edx, %edx
> +	rdsspd	%edx
> +	testl	%edx, %edx
> +	/* Normal return if shadow stack isn't in use.  */
> +	je	L(no_shstk)

OK.

> +
> +	/* Pop return address from shadow stack and jump back to caller
> +	   directly.  */
> +	movl	$1, %edx
> +	incsspd	%edx
> +	jmp	*%ecx

OK.

> +
> +L(no_shstk):
> +	/* Jump to the return PC.  Don't jump directly since this
> +	   disturbs the branch target cache.  Instead push the return
> +	   address back on the stack.  */
> +	pushl	%ecx
> +	cfi_adjust_cfa_offset (4)
> +#endif
> +
>  	ret
>  
>  PSEUDO_END (__vfork)
> diff --git a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S
> index e4c8269e3d..a6d6280bd2 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/vfork.S
> +++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S
> @@ -20,6 +20,18 @@
>  #include <bits/errno.h>
>  #include <tcb-offsets.h>
>  
> +#if SHSTK_ENABLED
> +/* When shadow stack is in use, we need to pop shadow stack and jump
> +   back to caller directly.   */

Likewise.

> +# undef SYSCALL_ERROR_HANDLER
> +# define SYSCALL_ERROR_HANDLER			\
> +0:						\
> +  SYSCALL_SET_ERRNO;				\
> +  or $-1, %RAX_LP;				\
> +  jmp 1b;
> +# undef SYSCALL_ERROR_LABEL
> +# define SYSCALL_ERROR_LABEL 0f
> +#endif
>  
>  /* Clone the calling process, but without copying the whole address space.
>     The calling process is suspended until the new process exits or is
> @@ -38,13 +50,36 @@ ENTRY (__vfork)
>  	movl	$SYS_ify (vfork), %eax
>  	syscall
>  
> +#if !SHSTK_ENABLED
>  	/* Push back the return PC.  */
>  	pushq	%rdi
>  	cfi_adjust_cfa_offset(8)
> +#endif
>  
>  	cmpl	$-4095, %eax
>  	jae SYSCALL_ERROR_LABEL		/* Branch forward if it failed.  */
>  
> +#if SHSTK_ENABLED
> +1:
> +	/* Check if shadow stack is in use.  */
> +	xorl	%esi, %esi
> +	rdsspq	%rsi
> +	testq	%rsi, %rsi
> +	/* Normal return if shadow stack isn't in use.  */
> +	je	L(no_shstk)

OK.

> +
> +	/* Pop return address from shadow stack and jump back to caller
> +	   directly.  */
> +	movl	$1, %esi
> +	incsspq	%rsi
> +	jmp	*%rdi
> +
> +L(no_shstk):
> +	/* Push back the return PC.  */
> +	pushq	%rdi
> +	cfi_adjust_cfa_offset(8)
> +#endif
> +

OK.

>  	/* Normal return.  */
>  	ret
>  
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 02/12] x86-64: Add endbr64 to tst-quadmod[12].S
  2018-07-21 14:20 ` [PATCH 02/12] x86-64: Add endbr64 to tst-quadmod[12].S H.J. Lu
@ 2018-07-24  2:53   ` Carlos O'Donell
  2018-07-24 11:58     ` H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24  2:53 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> Add endbr64 to tst-quadmod1.S and tst-quadmod2.S so that func and foo
> can be called indirectly.
> 
> 	* sysdeps/x86_64/tst-quadmod1.S (func): Add endbr64 if IBT is
> 	enabled.
> 	(foo): Likewise.
> 	* sysdeps/x86_64/tst-quadmod2.S (func) : Likewise.
> 	(foo): Likewise.
> ---
>  sysdeps/x86_64/tst-quadmod1.S | 6 ++++++
>  sysdeps/x86_64/tst-quadmod2.S | 6 ++++++
>  2 files changed, 12 insertions(+)

This is OK as-is, but marking foo with enbr64 seems
beyond what is needed. Only foo calls func directly,
so I would expect only func needing markup. If you can
tighten this up it would be better.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> 
> diff --git a/sysdeps/x86_64/tst-quadmod1.S b/sysdeps/x86_64/tst-quadmod1.S
> index 26f2f1b599..c60f9dc89d 100644
> --- a/sysdeps/x86_64/tst-quadmod1.S
> +++ b/sysdeps/x86_64/tst-quadmod1.S
> @@ -28,6 +28,9 @@
>  	.type	func, @function
>  func:
>  	.cfi_startproc
> +#if defined __CET__ && (__CET__ & 1) != 0
> +	endbr64
> +#endif

OK.

>  	xorl	%edi, %edi
>  	jmp	exit@PLT
>  	.cfi_endproc
> @@ -37,6 +40,9 @@ func:
>  foo:
>  	.cfi_startproc
>  	.cfi_def_cfa_register 6
> +#if defined __CET__ && (__CET__ & 1) != 0
> +	endbr64

OK.

> +#endif
>  	movq	.Ljmp(%rip), %rax
>  	subq	$BIAS, %rax
>  	jmp	*%rax
> diff --git a/sysdeps/x86_64/tst-quadmod2.S b/sysdeps/x86_64/tst-quadmod2.S
> index e923adf672..af03444d4f 100644
> --- a/sysdeps/x86_64/tst-quadmod2.S
> +++ b/sysdeps/x86_64/tst-quadmod2.S
> @@ -27,6 +27,9 @@
>  	.type	func, @function
>  func:
>  	.cfi_startproc
> +#if defined __CET__ && (__CET__ & 1) != 0
> +	endbr64

OK. Foo calls func directly.

> +#endif
>  	xorl	%edi, %edi
>  	jmp	exit@PLT
>  	.cfi_endproc
> @@ -36,6 +39,9 @@ func:
>  foo:
>  	.cfi_startproc
>  	.cfi_def_cfa_register 6
> +#if defined __CET__ && (__CET__ & 1) != 0
> +	endbr64
> +#endif
>  	movq	.Ljmp(%rip), %rax
>  	subq	$BIAS, %rax
>  	jmp	*%rax
> 

OK.

c.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control
  2018-07-21 14:20 ` [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control H.J. Lu
@ 2018-07-24  3:05   ` Carlos O'Donell
  2018-07-24 13:24     ` V2 " H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24  3:05 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
>  /* CET features:
>     IBT:   GNU_PROPERTY_X86_FEATURE_1_IBT
>     SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
>   */
> 
>  /* Return CET features in unsigned long long *addr:
>       features: addr[0].
>       shadow stack base address: addr[1].
>       shadow stack size: addr[2].
>   */
>  # define ARCH_CET_STATUS		0x3001
>  /* Disable CET features in unsigned int features.  */
>  # define ARCH_CET_DISABLE		0x3002
>  /* Lock all CET features.  */
>  # define ARCH_CET_LOCK			0x3003
>  /* Allocate a new shadow stack with unsigned long long *addr:
>       IN: requested shadow stack size: *addr.
>       OUT: allocated shadow stack address: *addr.
>   */
>  # define ARCH_CET_ALLOC_SHSTK		0x3004
>  /* Return legacy region bitmap info in unsigned long long *addr:
>      address: addr[0].
>      size: addr[1].
>   */
>  # define ARCH_CET_LEGACY_BITMAP	0x3005
> 
> 	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
> 	bits/prctl.h.
> 	* sysdeps/unix/sysv/linux/bits/prctl.h: New file.
> 	* sysdeps/unix/sysv/linux/x86/bits/prctl.h: Likewise.
> 	* sysdeps/unix/sysv/linux/sys/prctl.h: Include <bits/prctl.h>.
> 	* sysdeps/unix/sysv/linux/x86/cpu-features.c: Include
> 	<sys/prctl.h>.
> 	(get_cet_status): Call arch_prctl with ARCH_CET_STATUS.
> 	* sysdeps/unix/sysv/linux/x86/dl-cet.h: Include  <sys/prctl.h>.
> 	(dl_cet_allocate_legacy_bitmap): Call arch_prctl with
> 	ARCH_CET_LEGACY_BITMAP.
> 	(dl_cet_disable_cet): Call arch_prctl with ARCH_CET_DISABLE.
> 	(dl_cet_lock_cet): Call arch_prctl with ARCH_CET_LOCK.
> 	* sysdeps/x86/libc-start.c: Include <startup.h>.
> ---

The prctl.h values don't appear in any published kernel.

What's the status for these?

We can't ship them in the public prctl.h header unless they are already
in a public kernel or committed and basically ready to go out in a public
kernel.

You could rework this to only use the values internally and that would
be OK, since no user needs these yet, we are the primary CET user for
now.

>  sysdeps/unix/sysv/linux/Makefile           |  3 +-
>  sysdeps/unix/sysv/linux/bits/prctl.h       | 21 ++++++++++
>  sysdeps/unix/sysv/linux/sys/prctl.h        |  1 +
>  sysdeps/unix/sysv/linux/x86/bits/prctl.h   | 48 ++++++++++++++++++++++
>  sysdeps/unix/sysv/linux/x86/cpu-features.c |  7 ++++
>  sysdeps/unix/sysv/linux/x86/dl-cet.h       | 29 ++++++++++---
>  sysdeps/x86/libc-start.c                   |  3 ++
>  7 files changed, 105 insertions(+), 7 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/bits/prctl.h
>  create mode 100644 sysdeps/unix/sysv/linux/x86/bits/prctl.h
> 
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index f71cc39c7e..0bcc5287d9 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -40,7 +40,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
>  		  bits/signalfd.h bits/timerfd.h bits/epoll.h \
>  		  bits/socket_type.h bits/syscall.h bits/sysctl.h \
>  		  bits/mman-linux.h bits/mman-shared.h bits/ptrace-shared.h \
> -		  bits/siginfo-arch.h bits/siginfo-consts-arch.h
> +		  bits/siginfo-arch.h bits/siginfo-consts-arch.h \
> +		  bits/prctl.h

OK.

>  
>  tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
>  	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
> diff --git a/sysdeps/unix/sysv/linux/bits/prctl.h b/sysdeps/unix/sysv/linux/bits/prctl.h
> new file mode 100644
> index 0000000000..be96218066
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/prctl.h
> @@ -0,0 +1,21 @@
> +/* 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/>.  */
> +
> +#ifndef _BITS_PRCTL_H
> +#define _BITS_PRCTL_H	1
> +
> +#endif  /* bits/prctl.h */

OK, add generic empty header.

> diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h
> index 683d16748f..6c4f643c75 100644
> --- a/sysdeps/unix/sysv/linux/sys/prctl.h
> +++ b/sysdeps/unix/sysv/linux/sys/prctl.h
> @@ -20,6 +20,7 @@
>  
>  #include <features.h>
>  #include <linux/prctl.h>  /*  The magic values come from here  */
> +#include <bits/prctl.h>

OK, include it.

>  
>  __BEGIN_DECLS
>  
> diff --git a/sysdeps/unix/sysv/linux/x86/bits/prctl.h b/sysdeps/unix/sysv/linux/x86/bits/prctl.h
> new file mode 100644
> index 0000000000..37e5fc8212
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/bits/prctl.h
> @@ -0,0 +1,48 @@
> +/* 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/>.  */
> +
> +#ifndef _BITS_PRCTL_H
> +#define _BITS_PRCTL_H	1
> +
> +#ifndef ARCH_CET_STATUS
> +/* CET features:
> +   IBT:   GNU_PROPERTY_X86_FEATURE_1_IBT
> +   SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
> + */
> +/* Return CET features in unsigned long long *addr:
> +     features: addr[0].
> +     shadow stack base address: addr[1].
> +     shadow stack size: addr[2].
> + */
> +# define ARCH_CET_STATUS	0x3001

OK.

> +/* Disable CET features in unsigned int features.  */
> +# define ARCH_CET_DISABLE	0x3002

OK.

> +/* Lock all CET features.  */
> +# define ARCH_CET_LOCK		0x3003'

OK.

> +/* Allocate a new shadow stack with unsigned long long *addr:
> +     IN: requested shadow stack size: *addr.
> +     OUT: allocated shadow stack address: *addr.
> + */
> +# define ARCH_CET_ALLOC_SHSTK	0x3004

OK.

> +/* Return legacy region bitmap info in unsigned long long *addr:
> +     address: addr[0].
> +     size: addr[1].
> + */
> +# define ARCH_CET_LEGACY_BITMAP	0x3005

OK.

> +#endif /* ARCH_CET_STATUS */
> +
> +#endif  /* bits/prctl.h */
> diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c
> index 7c9df9b794..c7c59055dc 100644
> --- a/sysdeps/unix/sysv/linux/x86/cpu-features.c
> +++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c
> @@ -17,9 +17,16 @@
>     <http://www.gnu.org/licenses/>.  */
>  
>  #if CET_ENABLED
> +# include <sys/prctl.h>
> +
>  static inline int __attribute__ ((always_inline))
>  get_cet_status (void)
>  {
> +  unsigned long long cet_status[3];
> +  INTERNAL_SYSCALL_DECL (err);
> +  if (INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_STATUS,
> +			cet_status) == 0)
> +    return cet_status[0];

OK.

>    return 0;
>  }
>  
> diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h
> index ae81e2f2ca..787368292d 100644
> --- a/sysdeps/unix/sysv/linux/x86/dl-cet.h
> +++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h
> @@ -15,23 +15,40 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#include <sys/prctl.h>
> +
>  static inline int __attribute__ ((always_inline))
>  dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap)
>  {
> -  /* FIXME: Need syscall support.  */
> -  return -1;
> +  /* Allocate legacy bitmap.  */
> +  INTERNAL_SYSCALL_DECL (err);
> +#ifdef __LP64__
> +  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
> +				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap);
> +#else
> +  unsigned long long legacy_bitmap_u64[2];
> +  int res = INTERNAL_SYSCALL (arch_prctl, err, 2,
> +			      ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
> +  if (res == 0)
> +    {
> +      legacy_bitmap[0] = legacy_bitmap_u64[0];
> +      legacy_bitmap[1] = legacy_bitmap_u64[1];
> +    }
> +  return res;

OK.

> +#endif
>  }
>  
>  static inline int __attribute__ ((always_inline))
>  dl_cet_disable_cet (unsigned int cet_feature)
>  {
> -  /* FIXME: Need syscall support.  */
> -  return -1;
> +  INTERNAL_SYSCALL_DECL (err);
> +  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_DISABLE,
> +				 cet_feature);

OK.

>  }
>  
>  static inline int __attribute__ ((always_inline))
>  dl_cet_lock_cet (void)
>  {
> -  /* FIXME: Need syscall support.  */
> -  return -1;
> +  INTERNAL_SYSCALL_DECL (err);
> +  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_LOCK, 0);

OK.

>  }
> diff --git a/sysdeps/x86/libc-start.c b/sysdeps/x86/libc-start.c
> index 43aba9d061..eb5335c154 100644
> --- a/sysdeps/x86/libc-start.c
> +++ b/sysdeps/x86/libc-start.c
> @@ -16,6 +16,9 @@
>     <http://www.gnu.org/licenses/>.  */
>  
>  #ifndef SHARED
> +/* Define I386_USE_SYSENTER to support syscall during startup in static
> +   PIE.  */
> +# include <startup.h>

OK.

>  # include <ldsodefs.h>
>  # include <cpu-features.h>
>  # include <cpu-features.c>
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 02/12] x86-64: Add endbr64 to tst-quadmod[12].S
  2018-07-24  2:53   ` Carlos O'Donell
@ 2018-07-24 11:58     ` H.J. Lu
  2018-07-24 12:27       ` Carlos O'Donell
  0 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-24 11:58 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: GNU C Library

On Mon, Jul 23, 2018 at 7:53 PM, Carlos O'Donell <carlos@redhat.com> wrote:
> On 07/21/2018 10:20 AM, H.J. Lu wrote:
>> Add endbr64 to tst-quadmod1.S and tst-quadmod2.S so that func and foo
>> can be called indirectly.
>>
>>       * sysdeps/x86_64/tst-quadmod1.S (func): Add endbr64 if IBT is
>>       enabled.
>>       (foo): Likewise.
>>       * sysdeps/x86_64/tst-quadmod2.S (func) : Likewise.
>>       (foo): Likewise.
>> ---
>>  sysdeps/x86_64/tst-quadmod1.S | 6 ++++++
>>  sysdeps/x86_64/tst-quadmod2.S | 6 ++++++
>>  2 files changed, 12 insertions(+)
>
> This is OK as-is, but marking foo with enbr64 seems
> beyond what is needed. Only foo calls func directly,

Both func and foo needs ENDBR64.   All global functions
may be called indirectly via PLT:

[hjl@gnu-cet-2 build-x86_64-linux]$ readelf -rW elf/tst-quad1

Relocation section '.rela.dyn' at offset 0x7f0 contains 2 entries:
    Offset             Info             Type               Symbol's
Value  Symbol's Name + Addend
0000000000403ff0  0000000100000006 R_X86_64_GLOB_DAT
0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
0000000000403ff8  0000000200000006 R_X86_64_GLOB_DAT
0000000000000000 __gmon_start__ + 0

Relocation section '.rela.plt' at offset 0x820 contains 1 entry:
    Offset             Info             Type               Symbol's
Value  Symbol's Name + Addend
0000000000404018  0000000300000007 R_X86_64_JUMP_SLOT
0000000000000000 foo + 0
[hjl@gnu-cet-2 build-x86_64-linux]$

Without ENDBR64, I got

(gdb) r --direct
Starting program:
/export/build/gnu/tools-build/glibc-cet/build-x86_64-linux/elf/tst-quad1
--direct

Program received signal SIGSEGV, Segmentation fault.
foo () at ../sysdeps/x86_64/tst-quadmod1.S:43
43 movq .Ljmp(%rip), %rax
(gdb)

I will check it as-is.

> so I would expect only func needing markup. If you can
> tighten this up it would be better.
>
> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
>
>>
>> diff --git a/sysdeps/x86_64/tst-quadmod1.S b/sysdeps/x86_64/tst-quadmod1.S
>> index 26f2f1b599..c60f9dc89d 100644
>> --- a/sysdeps/x86_64/tst-quadmod1.S
>> +++ b/sysdeps/x86_64/tst-quadmod1.S
>> @@ -28,6 +28,9 @@
>>       .type   func, @function
>>  func:
>>       .cfi_startproc
>> +#if defined __CET__ && (__CET__ & 1) != 0
>> +     endbr64
>> +#endif
>
> OK.
>
>>       xorl    %edi, %edi
>>       jmp     exit@PLT
>>       .cfi_endproc
>> @@ -37,6 +40,9 @@ func:
>>  foo:
>>       .cfi_startproc
>>       .cfi_def_cfa_register 6
>> +#if defined __CET__ && (__CET__ & 1) != 0
>> +     endbr64
>
> OK.
>
>> +#endif
>>       movq    .Ljmp(%rip), %rax
>>       subq    $BIAS, %rax
>>       jmp     *%rax
>> diff --git a/sysdeps/x86_64/tst-quadmod2.S b/sysdeps/x86_64/tst-quadmod2.S
>> index e923adf672..af03444d4f 100644
>> --- a/sysdeps/x86_64/tst-quadmod2.S
>> +++ b/sysdeps/x86_64/tst-quadmod2.S
>> @@ -27,6 +27,9 @@
>>       .type   func, @function
>>  func:
>>       .cfi_startproc
>> +#if defined __CET__ && (__CET__ & 1) != 0
>> +     endbr64
>
> OK. Foo calls func directly.
>
>> +#endif
>>       xorl    %edi, %edi
>>       jmp     exit@PLT
>>       .cfi_endproc
>> @@ -36,6 +39,9 @@ func:
>>  foo:
>>       .cfi_startproc
>>       .cfi_def_cfa_register 6
>> +#if defined __CET__ && (__CET__ & 1) != 0
>> +     endbr64
>> +#endif
>>       movq    .Ljmp(%rip), %rax
>>       subq    $BIAS, %rax
>>       jmp     *%rax
>>
>
> OK.
>
> c.



-- 
H.J.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/12] x86: Update vfork to pop shadow stack
  2018-07-24  2:47   ` Carlos O'Donell
@ 2018-07-24 12:25     ` H.J. Lu
  2018-07-24 12:32       ` Carlos O'Donell
  0 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-24 12:25 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: GNU C Library

[-- Attachment #1: Type: text/plain, Size: 1135 bytes --]

On Mon, Jul 23, 2018 at 7:47 PM, Carlos O'Donell <carlos@redhat.com> wrote:
> On 07/21/2018 10:20 AM, H.J. Lu wrote:
>> Since we can't change return address on shadow stack, if shadow stack
>> is in use, we need to pop shadow stack and jump back to caller directly.
>>
>>       * sysdeps/unix/sysv/linux/i386/vfork.S (SYSCALL_ERROR_HANDLER):
>>       Redefine if shadow stack is enabled.
>>       (SYSCALL_ERROR_LABEL): Likewise.
>>       (__vfork): Pop shadow stack and jump back to to caller directly
>>       when shadow stack is in use.
>>       * sysdeps/unix/sysv/linux/x86_64/vfork.S (SYSCALL_ERROR_HANDLER):
>>       Redefine if shadow stack is enabled.
>>       (SYSCALL_ERROR_LABEL): Likewise.
>>       (__vfork): Pop shadow stack and jump back to to caller directly
>>       when shadow stack is in use.
>> ---
>>  sysdeps/unix/sysv/linux/i386/vfork.S   | 54 ++++++++++++++++++++++++++
>>  sysdeps/unix/sysv/linux/x86_64/vfork.S | 35 +++++++++++++++++
>>  2 files changed, 89 insertions(+)
>
> OK with comment suggestion.
>
> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
>

This is what I checked in.

Thanks.

-- 
H.J.

[-- Attachment #2: 0001-Add-bits-indirect-return.h.patch --]
[-- Type: text/x-patch, Size: 7917 bytes --]

From 2f165ed718036e91a798a657dc00101393692208 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 7 Jun 2018 20:50:11 -0700
Subject: [PATCH] Add <bits/indirect-return.h>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add <bits/indirect-return.h> and include it in <ucontext.h>.
__INDIRECT_RETURN defined in <bits/indirect-return.h> indicates if
swapcontext requires special compiler treatment.  The default
__INDIRECT_RETURN is empty.

On x86, when shadow stack is enabled, __INDIRECT_RETURN is defined
with indirect_return attribute, which has been added to GCC 9, to
indicate that swapcontext returns via indirect branch.  Otherwise
__INDIRECT_RETURN is defined with returns_twice attribute.

When shadow stack is enabled, remove always_inline attribute from
prepare_test_buffer in string/tst-xbzero-opt.c to avoid:

tst-xbzero-opt.c: In function ‘prepare_test_buffer’:
tst-xbzero-opt.c:105:1: error: function ‘prepare_test_buffer’ can never be inlined because it uses setjmp
 prepare_test_buffer (unsigned char *buf)

when indirect_return attribute isn't available.

	* bits/indirect-return.h: New file.
	* misc/sys/cdefs.h (__glibc_has_attribute): New.
	* sysdeps/x86/bits/indirect-return.h: Likewise.
	* stdlib/Makefile (headers): Add bits/indirect-return.h.
	* stdlib/ucontext.h: Include <bits/indirect-return.h>.
	(swapcontext): Add __INDIRECT_RETURN.
	* string/tst-xbzero-opt.c (ALWAYS_INLINE): New.
	(prepare_test_buffer): Use it.
---
 bits/indirect-return.h             | 25 +++++++++++++++++++++
 misc/sys/cdefs.h                   |  6 +++++
 stdlib/Makefile                    |  2 +-
 stdlib/ucontext.h                  |  6 ++++-
 string/tst-xbzero-opt.c            | 10 ++++++++-
 sysdeps/x86/bits/indirect-return.h | 35 ++++++++++++++++++++++++++++++
 6 files changed, 81 insertions(+), 3 deletions(-)
 create mode 100644 bits/indirect-return.h
 create mode 100644 sysdeps/x86/bits/indirect-return.h

diff --git a/bits/indirect-return.h b/bits/indirect-return.h
new file mode 100644
index 0000000000..47f6f15a6e
--- /dev/null
+++ b/bits/indirect-return.h
@@ -0,0 +1,25 @@
+/* Definition of __INDIRECT_RETURN.  Generic version.
+   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/>.  */
+
+#ifndef _UCONTEXT_H
+# error "Never include <bits/indirect-return.h> directly; use <ucontext.h> instead."
+#endif
+
+/* __INDIRECT_RETURN is used on swapcontext to indicate if it requires
+   special compiler treatment.  */
+#define __INDIRECT_RETURN
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index e80a45ca68..3f6fe3cc85 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -406,6 +406,12 @@
 # define __glibc_likely(cond)	(cond)
 #endif
 
+#ifdef __has_attribute
+# define __glibc_has_attribute(attr)	__has_attribute (attr)
+#else
+# define __glibc_has_attribute(attr)	0
+#endif
+
 #if (!defined _Noreturn \
      && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
      &&  !__GNUC_PREREQ (4,7))
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 808a8ceab7..b5e55b0a55 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -26,7 +26,7 @@ headers	:= stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h      \
 	   monetary.h bits/monetary-ldbl.h				      \
 	   inttypes.h stdint.h bits/wordsize.h				      \
 	   errno.h sys/errno.h bits/errno.h bits/types/error_t.h	      \
-	   ucontext.h sys/ucontext.h					      \
+	   ucontext.h sys/ucontext.h bits/indirect-return.h		      \
 	   alloca.h fmtmsg.h						      \
 	   bits/stdlib-bsearch.h sys/random.h bits/stdint-intn.h	      \
 	   bits/stdint-uintn.h
diff --git a/stdlib/ucontext.h b/stdlib/ucontext.h
index eec7611631..ec630038f6 100644
--- a/stdlib/ucontext.h
+++ b/stdlib/ucontext.h
@@ -22,6 +22,9 @@
 
 #include <features.h>
 
+/* Get definition of __INDIRECT_RETURN.  */
+#include <bits/indirect-return.h>
+
 /* Get machine dependent definition of data structures.  */
 #include <sys/ucontext.h>
 
@@ -36,7 +39,8 @@ extern int setcontext (const ucontext_t *__ucp) __THROWNL;
 /* Save current context in context variable pointed to by OUCP and set
    context from variable pointed to by UCP.  */
 extern int swapcontext (ucontext_t *__restrict __oucp,
-			const ucontext_t *__restrict __ucp) __THROWNL;
+			const ucontext_t *__restrict __ucp)
+  __THROWNL __INDIRECT_RETURN;
 
 /* Manipulate user context UCP to continue with calling functions FUNC
    and the ARGC-1 parameters following ARGC when the context is used
diff --git a/string/tst-xbzero-opt.c b/string/tst-xbzero-opt.c
index cf7041f37a..aab4a7f715 100644
--- a/string/tst-xbzero-opt.c
+++ b/string/tst-xbzero-opt.c
@@ -100,7 +100,15 @@ static ucontext_t uc_main, uc_co;
 /* Always check the test buffer immediately after filling it; this
    makes externally visible side effects depend on the buffer existing
    and having been filled in.  */
-static inline __attribute__  ((always_inline)) void
+#if defined __CET__ && !__glibc_has_attribute (__indirect_return__)
+/* Note: swapcontext returns via indirect branch when SHSTK is enabled.
+   Without indirect_return attribute, swapcontext is marked with
+   returns_twice attribute, which prevents always_inline to work.  */
+# define ALWAYS_INLINE
+#else
+# define ALWAYS_INLINE	__attribute__ ((always_inline))
+#endif
+static inline ALWAYS_INLINE void
 prepare_test_buffer (unsigned char *buf)
 {
   for (unsigned int i = 0; i < PATTERN_REPS; i++)
diff --git a/sysdeps/x86/bits/indirect-return.h b/sysdeps/x86/bits/indirect-return.h
new file mode 100644
index 0000000000..0587e687ac
--- /dev/null
+++ b/sysdeps/x86/bits/indirect-return.h
@@ -0,0 +1,35 @@
+/* Definition of __INDIRECT_RETURN.  x86 version.
+   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/>.  */
+
+#ifndef _UCONTEXT_H
+# error "Never include <bits/indirect-return.h> directly; use <ucontext.h> instead."
+#endif
+
+/* On x86, swapcontext returns via indirect branch when the shadow stack
+   is enabled.  Define __INDIRECT_RETURN to indicate whether swapcontext
+   returns via indirect branch.  */
+#if defined __CET__ && (__CET__ & 2) != 0
+# if __glibc_has_attribute (__indirect_return__)
+#  define __INDIRECT_RETURN __attribute__ ((__indirect_return__))
+# else
+/* Without indirect_return attribute, use returns_twice attribute.  */
+#  define __INDIRECT_RETURN __attribute__ ((__returns_twice__))
+# endif
+#else
+# define __INDIRECT_RETURN
+#endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 02/12] x86-64: Add endbr64 to tst-quadmod[12].S
  2018-07-24 11:58     ` H.J. Lu
@ 2018-07-24 12:27       ` Carlos O'Donell
  0 siblings, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24 12:27 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

On 07/24/2018 07:58 AM, H.J. Lu wrote:
> On Mon, Jul 23, 2018 at 7:53 PM, Carlos O'Donell <carlos@redhat.com> wrote:
>> On 07/21/2018 10:20 AM, H.J. Lu wrote:
>>> Add endbr64 to tst-quadmod1.S and tst-quadmod2.S so that func and foo
>>> can be called indirectly.
>>>
>>>       * sysdeps/x86_64/tst-quadmod1.S (func): Add endbr64 if IBT is
>>>       enabled.
>>>       (foo): Likewise.
>>>       * sysdeps/x86_64/tst-quadmod2.S (func) : Likewise.
>>>       (foo): Likewise.
>>> ---
>>>  sysdeps/x86_64/tst-quadmod1.S | 6 ++++++
>>>  sysdeps/x86_64/tst-quadmod2.S | 6 ++++++
>>>  2 files changed, 12 insertions(+)
>>
>> This is OK as-is, but marking foo with enbr64 seems
>> beyond what is needed. Only foo calls func directly,
> 
> Both func and foo needs ENDBR64.   All global functions
> may be called indirectly via PLT:

Sorry, you are correct. I wasn't thinking about the fact that the
main program calls via the PLT and we need an ENBR to continue the
CET state machine or the process will be terminated.

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/12] x86: Update vfork to pop shadow stack
  2018-07-24 12:25     ` H.J. Lu
@ 2018-07-24 12:32       ` Carlos O'Donell
  2018-07-24 13:17         ` H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24 12:32 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

On 07/24/2018 08:25 AM, H.J. Lu wrote:
> On Mon, Jul 23, 2018 at 7:47 PM, Carlos O'Donell <carlos@redhat.com> wrote:
>> On 07/21/2018 10:20 AM, H.J. Lu wrote:
>>> Since we can't change return address on shadow stack, if shadow stack
>>> is in use, we need to pop shadow stack and jump back to caller directly.
>>>
>>>       * sysdeps/unix/sysv/linux/i386/vfork.S (SYSCALL_ERROR_HANDLER):
>>>       Redefine if shadow stack is enabled.
>>>       (SYSCALL_ERROR_LABEL): Likewise.
>>>       (__vfork): Pop shadow stack and jump back to to caller directly
>>>       when shadow stack is in use.
>>>       * sysdeps/unix/sysv/linux/x86_64/vfork.S (SYSCALL_ERROR_HANDLER):
>>>       Redefine if shadow stack is enabled.
>>>       (SYSCALL_ERROR_LABEL): Likewise.
>>>       (__vfork): Pop shadow stack and jump back to to caller directly
>>>       when shadow stack is in use.
>>> ---
>>>  sysdeps/unix/sysv/linux/i386/vfork.S   | 54 ++++++++++++++++++++++++++
>>>  sysdeps/unix/sysv/linux/x86_64/vfork.S | 35 +++++++++++++++++
>>>  2 files changed, 89 insertions(+)
>>
>> OK with comment suggestion.
>>
>> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
>>
> 
> This is what I checked in.
> 
> Thanks.
> 

Wrong patch?

c.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 03/12] Add <bits/indirect-return.h>
  2018-07-21 14:21 ` [PATCH 03/12] Add <bits/indirect-return.h> H.J. Lu
@ 2018-07-24 12:57   ` Carlos O'Donell
  2018-07-24 13:52     ` V2 " H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24 12:57 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> Add <bits/indirect-return.h> and include it in <ucontext.h>.
> __INDIRECT_RETURN defined in <bits/indirect-return.h> indicates if
> swapcontext requires special compiler treatment.  The default
> __INDIRECT_RETURN is empty.
> 
> On x86, when shadow stack is enabled, __INDIRECT_RETURN is defined
> with indirect_return attribute, which has been added to GCC 9, to
> indicate that swapcontext returns via indirect branch.  Otherwise
> __INDIRECT_RETURN is defined with returns_twice attribute.

I saw this discussion and I think a returns_twice is the right solution
for older compilers since it removes possibly incorrect optimizations.

> When shadow stack is enabled, remove always_inline attribute from
> prepare_test_buffer in string/tst-xbzero-opt.c to avoid:
> 
> tst-xbzero-opt.c: In function ‘prepare_test_buffer’:
> tst-xbzero-opt.c:105:1: error: function ‘prepare_test_buffer’ can never be inlined because it uses setjmp
>  prepare_test_buffer (unsigned char *buf)

OK.

> when indirect_return attribute isn't available.
> 
> 	* bits/indirect-return.h: New file.
> 	* misc/sys/cdefs.h (__glibc_has_attribute): New.
> 	* sysdeps/x86/bits/indirect-return.h: Likewise.
> 	* stdlib/Makefile (headers): Add bits/indirect-return.h.
> 	* stdlib/ucontext.h: Include <bits/indirect-return.h>.
> 	(swapcontext): Add __INDIRECT_RETURN.
> 	* string/tst-xbzero-opt.c (ALWAYS_INLINE): New.
> 	(prepare_test_buffer): Use it.

OK with suggestion.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  bits/indirect-return.h             | 25 +++++++++++++++++++++
>  misc/sys/cdefs.h                   |  6 +++++
>  stdlib/Makefile                    |  2 +-
>  stdlib/ucontext.h                  |  6 ++++-
>  string/tst-xbzero-opt.c            | 10 ++++++++-
>  sysdeps/x86/bits/indirect-return.h | 35 ++++++++++++++++++++++++++++++
>  6 files changed, 81 insertions(+), 3 deletions(-)
>  create mode 100644 bits/indirect-return.h
>  create mode 100644 sysdeps/x86/bits/indirect-return.h
> 
> diff --git a/bits/indirect-return.h b/bits/indirect-return.h
> new file mode 100644
> index 0000000000..47f6f15a6e
> --- /dev/null
> +++ b/bits/indirect-return.h
> @@ -0,0 +1,25 @@
> +/* Definition of __INDIRECT_RETURN.  Generic version.
> +   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/>.  */
> +
> +#ifndef _UCONTEXT_H
> +# error "Never include <bits/indirect-return.h> directly; use <ucontext.h> instead."
> +#endif
> +
> +/* __INDIRECT_RETURN is used on swapcontext to indicate if it requires
> +   special compiler treatment.  */
> +#define __INDIRECT_RETURN

OK. Does nothing.

> diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
> index e80a45ca68..3f6fe3cc85 100644
> --- a/misc/sys/cdefs.h
> +++ b/misc/sys/cdefs.h
> @@ -406,6 +406,12 @@
>  # define __glibc_likely(cond)	(cond)
>  #endif
>  
> +#ifdef __has_attribute
> +# define __glibc_has_attribute(attr)	__has_attribute (attr)
> +#else
> +# define __glibc_has_attribute(attr)	0
> +#endif

OK. In gcc < 5 which lacks __has_attribute this will resolve to 0,
and with that we will get returns_twice attribute being used, and
that's fine.

> +
>  #if (!defined _Noreturn \
>       && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
>       &&  !__GNUC_PREREQ (4,7))
> diff --git a/stdlib/Makefile b/stdlib/Makefile
> index 808a8ceab7..b5e55b0a55 100644
> --- a/stdlib/Makefile
> +++ b/stdlib/Makefile
> @@ -26,7 +26,7 @@ headers	:= stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h      \
>  	   monetary.h bits/monetary-ldbl.h				      \
>  	   inttypes.h stdint.h bits/wordsize.h				      \
>  	   errno.h sys/errno.h bits/errno.h bits/types/error_t.h	      \
> -	   ucontext.h sys/ucontext.h					      \
> +	   ucontext.h sys/ucontext.h bits/indirect-return.h		      \

OK.

>  	   alloca.h fmtmsg.h						      \
>  	   bits/stdlib-bsearch.h sys/random.h bits/stdint-intn.h	      \
>  	   bits/stdint-uintn.h
> diff --git a/stdlib/ucontext.h b/stdlib/ucontext.h
> index eec7611631..ec630038f6 100644
> --- a/stdlib/ucontext.h
> +++ b/stdlib/ucontext.h
> @@ -22,6 +22,9 @@
>  
>  #include <features.h>
>  
> +/* Get definition of __INDIRECT_RETURN.  */
> +#include <bits/indirect-return.h>

OK.

> +
>  /* Get machine dependent definition of data structures.  */
>  #include <sys/ucontext.h>
>  
> @@ -36,7 +39,8 @@ extern int setcontext (const ucontext_t *__ucp) __THROWNL;
>  /* Save current context in context variable pointed to by OUCP and set
>     context from variable pointed to by UCP.  */
>  extern int swapcontext (ucontext_t *__restrict __oucp,
> -			const ucontext_t *__restrict __ucp) __THROWNL;
> +			const ucontext_t *__restrict __ucp)
> +  __THROWNL __INDIRECT_RETURN;

OK.

>  
>  /* Manipulate user context UCP to continue with calling functions FUNC
>     and the ARGC-1 parameters following ARGC when the context is used
> diff --git a/string/tst-xbzero-opt.c b/string/tst-xbzero-opt.c
> index cf7041f37a..aab4a7f715 100644
> --- a/string/tst-xbzero-opt.c
> +++ b/string/tst-xbzero-opt.c
> @@ -100,7 +100,15 @@ static ucontext_t uc_main, uc_co;
>  /* Always check the test buffer immediately after filling it; this
>     makes externally visible side effects depend on the buffer existing
>     and having been filled in.  */
> -static inline __attribute__  ((always_inline)) void
> +#if defined __CET__ && !__glibc_has_attribute (__indirect_return__)
> +/* Note: swapcontext returns via indirect branch when SHSTK is enabled.
> +   Without indirect_return attribute, swapcontext is marked with
> +   returns_twice attribute, which prevents always_inline to work.  */
> +# define ALWAYS_INLINE
> +#else
> +# define ALWAYS_INLINE	__attribute__ ((always_inline))
> +#endif
> +static inline ALWAYS_INLINE void

OK. I don't think this will impact the semantics of the test, the compiler
should still be able to see the local call and carry out any optimizations
it needs to do.

>  prepare_test_buffer (unsigned char *buf)
>  {
>    for (unsigned int i = 0; i < PATTERN_REPS; i++)
> diff --git a/sysdeps/x86/bits/indirect-return.h b/sysdeps/x86/bits/indirect-return.h
> new file mode 100644
> index 0000000000..0587e687ac
> --- /dev/null
> +++ b/sysdeps/x86/bits/indirect-return.h
> @@ -0,0 +1,35 @@
> +/* Definition of __INDIRECT_RETURN.  x86 version.
> +   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/>.  */
> +
> +#ifndef _UCONTEXT_H
> +# error "Never include <bits/indirect-return.h> directly; use <ucontext.h> instead."
> +#endif
> +
> +/* On x86, swapcontext returns via indirect branch when the shadow stack
> +   is enabled.  Define __INDIRECT_RETURN to indicate whether swapcontext
> +   returns via indirect branch.  */
> +#if defined __CET__ && (__CET__ & 2) != 0
> +# if __glibc_has_attribute (__indirect_return__)
> +#  define __INDIRECT_RETURN __attribute__ ((__indirect_return__))
> +# else
> +/* Without indirect_return attribute, use returns_twice attribute.  */

Suggest:

/* Newer compilers provide the indirect_return attribute, but without
   it we can use returns_twice to affect the optimizer in the same
   way and avoid unsafe optimizations.  */

> +#  define __INDIRECT_RETURN __attribute__ ((__returns_twice__))
> +# endif
> +#else
> +# define __INDIRECT_RETURN
> +#endif
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/12] x86: Update vfork to pop shadow stack
  2018-07-24 12:32       ` Carlos O'Donell
@ 2018-07-24 13:17         ` H.J. Lu
  0 siblings, 0 replies; 70+ messages in thread
From: H.J. Lu @ 2018-07-24 13:17 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: GNU C Library

[-- Attachment #1: Type: text/plain, Size: 1364 bytes --]

On Tue, Jul 24, 2018 at 5:32 AM, Carlos O'Donell <carlos@redhat.com> wrote:
> On 07/24/2018 08:25 AM, H.J. Lu wrote:
>> On Mon, Jul 23, 2018 at 7:47 PM, Carlos O'Donell <carlos@redhat.com> wrote:
>>> On 07/21/2018 10:20 AM, H.J. Lu wrote:
>>>> Since we can't change return address on shadow stack, if shadow stack
>>>> is in use, we need to pop shadow stack and jump back to caller directly.
>>>>
>>>>       * sysdeps/unix/sysv/linux/i386/vfork.S (SYSCALL_ERROR_HANDLER):
>>>>       Redefine if shadow stack is enabled.
>>>>       (SYSCALL_ERROR_LABEL): Likewise.
>>>>       (__vfork): Pop shadow stack and jump back to to caller directly
>>>>       when shadow stack is in use.
>>>>       * sysdeps/unix/sysv/linux/x86_64/vfork.S (SYSCALL_ERROR_HANDLER):
>>>>       Redefine if shadow stack is enabled.
>>>>       (SYSCALL_ERROR_LABEL): Likewise.
>>>>       (__vfork): Pop shadow stack and jump back to to caller directly
>>>>       when shadow stack is in use.
>>>> ---
>>>>  sysdeps/unix/sysv/linux/i386/vfork.S   | 54 ++++++++++++++++++++++++++
>>>>  sysdeps/unix/sysv/linux/x86_64/vfork.S | 35 +++++++++++++++++
>>>>  2 files changed, 89 insertions(+)
>>>
>>> OK with comment suggestion.
>>>
>>> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
>>>
>>
>> This is what I checked in.
>>
>> Thanks.
>>
>
> Wrong patch?
>

Oops.  Here is the right one.

-- 
H.J.

[-- Attachment #2: 0001-x86-Update-vfork-to-pop-shadow-stack.patch --]
[-- Type: text/x-patch, Size: 6118 bytes --]

From 3650e1d9284926be67e368707a9a2276fb77a167 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 24 Jul 2018 05:20:48 -0700
Subject: [PATCH] x86: Update vfork to pop shadow stack

The shadow stack prevents us from pushing the saved return PC onto
the stack and returning normally.  Instead we pop the shadow stack
and return directly.  This is the safest way to return and ensures
any stack manipulations done by the vfork'd child doesn't cause the
parent to terminate when CET is enabled.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

	* sysdeps/unix/sysv/linux/i386/vfork.S (SYSCALL_ERROR_HANDLER):
	Redefine if shadow stack is enabled.
	(SYSCALL_ERROR_LABEL): Likewise.
	(__vfork): Pop shadow stack and jump back to to caller directly
	when shadow stack is in use.
	* sysdeps/unix/sysv/linux/x86_64/vfork.S (SYSCALL_ERROR_HANDLER):
	Redefine if shadow stack is enabled.
	(SYSCALL_ERROR_LABEL): Likewise.
	(__vfork): Pop shadow stack and jump back to to caller directly
	when shadow stack is in use.
---
 ChangeLog                              | 13 ++++++
 sysdeps/unix/sysv/linux/i386/vfork.S   | 57 ++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86_64/vfork.S | 38 +++++++++++++++++
 3 files changed, 108 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 2a1a53d9df..8b892eb686 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2018-07-24  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* sysdeps/unix/sysv/linux/i386/vfork.S (SYSCALL_ERROR_HANDLER):
+	Redefine if shadow stack is enabled.
+	(SYSCALL_ERROR_LABEL): Likewise.
+	(__vfork): Pop shadow stack and jump back to to caller directly
+	when shadow stack is in use.
+	* sysdeps/unix/sysv/linux/x86_64/vfork.S (SYSCALL_ERROR_HANDLER):
+	Redefine if shadow stack is enabled.
+	(SYSCALL_ERROR_LABEL): Likewise.
+	(__vfork): Pop shadow stack and jump back to to caller directly
+	when shadow stack is in use.
+
 2018-07-24  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* sysdeps/x86_64/tst-quadmod1.S (func): Add endbr64 if IBT is
diff --git a/sysdeps/unix/sysv/linux/i386/vfork.S b/sysdeps/unix/sysv/linux/i386/vfork.S
index 8f40d02d09..ce6dbfac48 100644
--- a/sysdeps/unix/sysv/linux/i386/vfork.S
+++ b/sysdeps/unix/sysv/linux/i386/vfork.S
@@ -21,6 +21,38 @@
 #include <bits/errno.h>
 #include <tcb-offsets.h>
 
+#if SHSTK_ENABLED
+/* The shadow stack prevents us from pushing the saved return PC onto
+   the stack and returning normally.  Instead we pop the shadow stack
+   and return directly.  This is the safest way to return and ensures
+   any stack manipulations done by the vfork'd child doesn't cause the
+   parent to terminate when CET is enabled.  */
+# undef SYSCALL_ERROR_HANDLER
+# ifdef PIC
+#  define SYSCALL_ERROR_HANDLER				\
+0:							\
+  calll .L1;						\
+.L1:							\
+  popl %edx;						\
+.L2:							\
+  addl $_GLOBAL_OFFSET_TABLE_ + (.L2 - .L1), %edx;	\
+  movl __libc_errno@gotntpoff(%edx), %edx;		\
+  negl %eax;						\
+  movl %eax, %gs:(%edx);				\
+  orl $-1, %eax;					\
+  jmp 1b;
+# else
+#  define SYSCALL_ERROR_HANDLER				\
+0:							\
+  movl __libc_errno@indntpoff, %edx;			\
+  negl %eax;						\
+  movl %eax, %gs:(%edx);				\
+  orl $-1, %eax;					\
+  jmp 1b;
+# endif
+# undef SYSCALL_ERROR_LABEL
+# define SYSCALL_ERROR_LABEL 0f
+#endif
 
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
@@ -38,16 +70,41 @@ ENTRY (__vfork)
 	movl	$SYS_ify (vfork), %eax
 	int	$0x80
 
+#if !SHSTK_ENABLED
 	/* Jump to the return PC.  Don't jump directly since this
 	   disturbs the branch target cache.  Instead push the return
 	   address back on the stack.  */
 	pushl	%ecx
 	cfi_adjust_cfa_offset (4)
+#endif
 
 	cmpl	$-4095, %eax
 	/* Branch forward if it failed.  */
 	jae	SYSCALL_ERROR_LABEL
 
+#if SHSTK_ENABLED
+1:
+	/* Check if shadow stack is in use.  */
+	xorl	%edx, %edx
+	rdsspd	%edx
+	testl	%edx, %edx
+	/* Normal return if shadow stack isn't in use.  */
+	je	L(no_shstk)
+
+	/* Pop return address from shadow stack and jump back to caller
+	   directly.  */
+	movl	$1, %edx
+	incsspd	%edx
+	jmp	*%ecx
+
+L(no_shstk):
+	/* Jump to the return PC.  Don't jump directly since this
+	   disturbs the branch target cache.  Instead push the return
+	   address back on the stack.  */
+	pushl	%ecx
+	cfi_adjust_cfa_offset (4)
+#endif
+
 	ret
 
 PSEUDO_END (__vfork)
diff --git a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S
index e4c8269e3d..8f1ca9f836 100644
--- a/sysdeps/unix/sysv/linux/x86_64/vfork.S
+++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S
@@ -20,6 +20,21 @@
 #include <bits/errno.h>
 #include <tcb-offsets.h>
 
+#if SHSTK_ENABLED
+/* The shadow stack prevents us from pushing the saved return PC onto
+   the stack and returning normally.  Instead we pop the shadow stack
+   and return directly.  This is the safest way to return and ensures
+   any stack manipulations done by the vfork'd child doesn't cause the
+   parent to terminate when CET is enabled.  */
+# undef SYSCALL_ERROR_HANDLER
+# define SYSCALL_ERROR_HANDLER			\
+0:						\
+  SYSCALL_SET_ERRNO;				\
+  or $-1, %RAX_LP;				\
+  jmp 1b;
+# undef SYSCALL_ERROR_LABEL
+# define SYSCALL_ERROR_LABEL 0f
+#endif
 
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
@@ -38,13 +53,36 @@ ENTRY (__vfork)
 	movl	$SYS_ify (vfork), %eax
 	syscall
 
+#if !SHSTK_ENABLED
 	/* Push back the return PC.  */
 	pushq	%rdi
 	cfi_adjust_cfa_offset(8)
+#endif
 
 	cmpl	$-4095, %eax
 	jae SYSCALL_ERROR_LABEL		/* Branch forward if it failed.  */
 
+#if SHSTK_ENABLED
+1:
+	/* Check if shadow stack is in use.  */
+	xorl	%esi, %esi
+	rdsspq	%rsi
+	testq	%rsi, %rsi
+	/* Normal return if shadow stack isn't in use.  */
+	je	L(no_shstk)
+
+	/* Pop return address from shadow stack and jump back to caller
+	   directly.  */
+	movl	$1, %esi
+	incsspq	%rsi
+	jmp	*%rdi
+
+L(no_shstk):
+	/* Push back the return PC.  */
+	pushq	%rdi
+	cfi_adjust_cfa_offset(8)
+#endif
+
 	/* Normal return.  */
 	ret
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 70+ messages in thread

* V2 [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control
  2018-07-24  3:05   ` Carlos O'Donell
@ 2018-07-24 13:24     ` H.J. Lu
  2018-07-24 13:49       ` Carlos O'Donell
  2018-07-24 14:28       ` Joseph Myers
  0 siblings, 2 replies; 70+ messages in thread
From: H.J. Lu @ 2018-07-24 13:24 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: libc-alpha

On Mon, Jul 23, 2018 at 11:05:15PM -0400, Carlos O'Donell wrote:
> On 07/21/2018 10:20 AM, H.J. Lu wrote:
> >  /* CET features:
> >     IBT:   GNU_PROPERTY_X86_FEATURE_1_IBT
> >     SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
> >   */
> > 
> >  /* Return CET features in unsigned long long *addr:
> >       features: addr[0].
> >       shadow stack base address: addr[1].
> >       shadow stack size: addr[2].
> >   */
> >  # define ARCH_CET_STATUS		0x3001
> >  /* Disable CET features in unsigned int features.  */
> >  # define ARCH_CET_DISABLE		0x3002
> >  /* Lock all CET features.  */
> >  # define ARCH_CET_LOCK			0x3003
> >  /* Allocate a new shadow stack with unsigned long long *addr:
> >       IN: requested shadow stack size: *addr.
> >       OUT: allocated shadow stack address: *addr.
> >   */
> >  # define ARCH_CET_ALLOC_SHSTK		0x3004
> >  /* Return legacy region bitmap info in unsigned long long *addr:
> >      address: addr[0].
> >      size: addr[1].
> >   */
> >  # define ARCH_CET_LEGACY_BITMAP	0x3005
> > 
> > 	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
> > 	bits/prctl.h.
> > 	* sysdeps/unix/sysv/linux/bits/prctl.h: New file.
> > 	* sysdeps/unix/sysv/linux/x86/bits/prctl.h: Likewise.
> > 	* sysdeps/unix/sysv/linux/sys/prctl.h: Include <bits/prctl.h>.
> > 	* sysdeps/unix/sysv/linux/x86/cpu-features.c: Include
> > 	<sys/prctl.h>.
> > 	(get_cet_status): Call arch_prctl with ARCH_CET_STATUS.
> > 	* sysdeps/unix/sysv/linux/x86/dl-cet.h: Include  <sys/prctl.h>.
> > 	(dl_cet_allocate_legacy_bitmap): Call arch_prctl with
> > 	ARCH_CET_LEGACY_BITMAP.
> > 	(dl_cet_disable_cet): Call arch_prctl with ARCH_CET_DISABLE.
> > 	(dl_cet_lock_cet): Call arch_prctl with ARCH_CET_LOCK.
> > 	* sysdeps/x86/libc-start.c: Include <startup.h>.
> > ---
> 
> The prctl.h values don't appear in any published kernel.
> 
> What's the status for these?

The CET kernel changes have been submitted and under discussion.  We
believe that this is the final CET kernel interface.

> 
> We can't ship them in the public prctl.h header unless they are already
> in a public kernel or committed and basically ready to go out in a public
> kernel.
> 
> You could rework this to only use the values internally and that would
> be OK, since no user needs these yet, we are the primary CET user for
> now.
> 

Like this?


H.J.
---
 /* CET features:
    IBT:   GNU_PROPERTY_X86_FEATURE_1_IBT
    SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
  */

 /* Return CET features in unsigned long long *addr:
      features: addr[0].
      shadow stack base address: addr[1].
      shadow stack size: addr[2].
  */
 # define ARCH_CET_STATUS		0x3001
 /* Disable CET features in unsigned int features.  */
 # define ARCH_CET_DISABLE		0x3002
 /* Lock all CET features.  */
 # define ARCH_CET_LOCK			0x3003
 /* Allocate a new shadow stack with unsigned long long *addr:
      IN: requested shadow stack size: *addr.
      OUT: allocated shadow stack address: *addr.
  */
 # define ARCH_CET_ALLOC_SHSTK		0x3004
 /* Return legacy region bitmap info in unsigned long long *addr:
     address: addr[0].
     size: addr[1].
  */
 # define ARCH_CET_LEGACY_BITMAP	0x3005

Note: sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h should be
renamed to sysdeps/unix/sysv/linux/x86/bits/prctl.h after the CET
kernel interface has been committed into the public kernel.

	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
	bits/prctl.h.
	* sysdeps/unix/sysv/linux/bits/prctl.h: New file.
	* sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h: Likewise.
	* sysdeps/unix/sysv/linux/sys/prctl.h: Include <bits/prctl.h>.
	* sysdeps/unix/sysv/linux/x86/cpu-features.c: Include
	<sys/prctl.h> and <bits/prctl-internal.h>.
	(get_cet_status): Call arch_prctl with ARCH_CET_STATUS.
	* sysdeps/unix/sysv/linux/x86/dl-cet.h: Include <sys/prctl.h>
	and <bits/prctl-internal.h>.
	(dl_cet_allocate_legacy_bitmap): Call arch_prctl with
	ARCH_CET_LEGACY_BITMAP.
	(dl_cet_disable_cet): Call arch_prctl with ARCH_CET_DISABLE.
	(dl_cet_lock_cet): Call arch_prctl with ARCH_CET_LOCK.
	* sysdeps/x86/libc-start.c: Include <startup.h>.
---
 sysdeps/unix/sysv/linux/Makefile              |  3 +-
 sysdeps/unix/sysv/linux/bits/prctl.h          | 21 ++++++++
 sysdeps/unix/sysv/linux/sys/prctl.h           |  1 +
 .../unix/sysv/linux/x86/bits/prctl-internal.h | 52 +++++++++++++++++++
 sysdeps/unix/sysv/linux/x86/cpu-features.c    | 10 ++++
 sysdeps/unix/sysv/linux/x86/dl-cet.h          | 32 +++++++++---
 sysdeps/x86/libc-start.c                      |  3 ++
 7 files changed, 115 insertions(+), 7 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/bits/prctl.h
 create mode 100644 sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index f71cc39c7e..0bcc5287d9 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -40,7 +40,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 		  bits/signalfd.h bits/timerfd.h bits/epoll.h \
 		  bits/socket_type.h bits/syscall.h bits/sysctl.h \
 		  bits/mman-linux.h bits/mman-shared.h bits/ptrace-shared.h \
-		  bits/siginfo-arch.h bits/siginfo-consts-arch.h
+		  bits/siginfo-arch.h bits/siginfo-consts-arch.h \
+		  bits/prctl.h
 
 tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
 	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
diff --git a/sysdeps/unix/sysv/linux/bits/prctl.h b/sysdeps/unix/sysv/linux/bits/prctl.h
new file mode 100644
index 0000000000..be96218066
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/prctl.h
@@ -0,0 +1,21 @@
+/* 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/>.  */
+
+#ifndef _BITS_PRCTL_H
+#define _BITS_PRCTL_H	1
+
+#endif  /* bits/prctl.h */
diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h
index 683d16748f..6c4f643c75 100644
--- a/sysdeps/unix/sysv/linux/sys/prctl.h
+++ b/sysdeps/unix/sysv/linux/sys/prctl.h
@@ -20,6 +20,7 @@
 
 #include <features.h>
 #include <linux/prctl.h>  /*  The magic values come from here  */
+#include <bits/prctl.h>
 
 __BEGIN_DECLS
 
diff --git a/sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h b/sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h
new file mode 100644
index 0000000000..08408d5b88
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h
@@ -0,0 +1,52 @@
+/* FIXME: Rename this file to prctl.h after the CET kernel interface
+   has been committed into the public kernel.  */
+#undef _BITS_PRCTL_H
+
+/* 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/>.  */
+
+#ifndef _BITS_PRCTL_H
+#define _BITS_PRCTL_H	1
+
+#ifndef ARCH_CET_STATUS
+/* CET features:
+   IBT:   GNU_PROPERTY_X86_FEATURE_1_IBT
+   SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
+ */
+/* Return CET features in unsigned long long *addr:
+     features: addr[0].
+     shadow stack base address: addr[1].
+     shadow stack size: addr[2].
+ */
+# define ARCH_CET_STATUS	0x3001
+/* Disable CET features in unsigned int features.  */
+# define ARCH_CET_DISABLE	0x3002
+/* Lock all CET features.  */
+# define ARCH_CET_LOCK		0x3003
+/* Allocate a new shadow stack with unsigned long long *addr:
+     IN: requested shadow stack size: *addr.
+     OUT: allocated shadow stack address: *addr.
+ */
+# define ARCH_CET_ALLOC_SHSTK	0x3004
+/* Return legacy region bitmap info in unsigned long long *addr:
+     address: addr[0].
+     size: addr[1].
+ */
+# define ARCH_CET_LEGACY_BITMAP	0x3005
+#endif /* ARCH_CET_STATUS */
+
+#endif  /* bits/prctl.h */
diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c
index 7c9df9b794..c042783ae9 100644
--- a/sysdeps/unix/sysv/linux/x86/cpu-features.c
+++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c
@@ -17,9 +17,19 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if CET_ENABLED
+# include <sys/prctl.h>
+/* FIXME: Remove this after <bits/prctl-internal.h> has been renamed to
+   <bits/prctl.h>.  */
+# include <bits/prctl-internal.h>
+
 static inline int __attribute__ ((always_inline))
 get_cet_status (void)
 {
+  unsigned long long cet_status[3];
+  INTERNAL_SYSCALL_DECL (err);
+  if (INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_STATUS,
+			cet_status) == 0)
+    return cet_status[0];
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h
index ae81e2f2ca..edf8cd7394 100644
--- a/sysdeps/unix/sysv/linux/x86/dl-cet.h
+++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h
@@ -15,23 +15,43 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <sys/prctl.h>
+/* FIXME: Remove this after <bits/prctl-internal.h> has been renamed to
+   <bits/prctl.h>.  */
+#include <bits/prctl-internal.h>
+
 static inline int __attribute__ ((always_inline))
 dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap)
 {
-  /* FIXME: Need syscall support.  */
-  return -1;
+  /* Allocate legacy bitmap.  */
+  INTERNAL_SYSCALL_DECL (err);
+#ifdef __LP64__
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
+				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap);
+#else
+  unsigned long long legacy_bitmap_u64[2];
+  int res = INTERNAL_SYSCALL (arch_prctl, err, 2,
+			      ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
+  if (res == 0)
+    {
+      legacy_bitmap[0] = legacy_bitmap_u64[0];
+      legacy_bitmap[1] = legacy_bitmap_u64[1];
+    }
+  return res;
+#endif
 }
 
 static inline int __attribute__ ((always_inline))
 dl_cet_disable_cet (unsigned int cet_feature)
 {
-  /* FIXME: Need syscall support.  */
-  return -1;
+  INTERNAL_SYSCALL_DECL (err);
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_DISABLE,
+				 cet_feature);
 }
 
 static inline int __attribute__ ((always_inline))
 dl_cet_lock_cet (void)
 {
-  /* FIXME: Need syscall support.  */
-  return -1;
+  INTERNAL_SYSCALL_DECL (err);
+  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_LOCK, 0);
 }
diff --git a/sysdeps/x86/libc-start.c b/sysdeps/x86/libc-start.c
index 43aba9d061..eb5335c154 100644
--- a/sysdeps/x86/libc-start.c
+++ b/sysdeps/x86/libc-start.c
@@ -16,6 +16,9 @@
    <http://www.gnu.org/licenses/>.  */
 
 #ifndef SHARED
+/* Define I386_USE_SYSENTER to support syscall during startup in static
+   PIE.  */
+# include <startup.h>
 # include <ldsodefs.h>
 # include <cpu-features.h>
 # include <cpu-features.c>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: V2 [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control
  2018-07-24 13:24     ` V2 " H.J. Lu
@ 2018-07-24 13:49       ` Carlos O'Donell
  2018-07-24 14:28       ` Joseph Myers
  1 sibling, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24 13:49 UTC (permalink / raw)
  To: H.J. Lu; +Cc: libc-alpha

On 07/24/2018 09:24 AM, H.J. Lu wrote:
> On Mon, Jul 23, 2018 at 11:05:15PM -0400, Carlos O'Donell wrote:
>> On 07/21/2018 10:20 AM, H.J. Lu wrote:
>>>  /* CET features:
>>>     IBT:   GNU_PROPERTY_X86_FEATURE_1_IBT
>>>     SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
>>>   */
>>>
>>>  /* Return CET features in unsigned long long *addr:
>>>       features: addr[0].
>>>       shadow stack base address: addr[1].
>>>       shadow stack size: addr[2].
>>>   */
>>>  # define ARCH_CET_STATUS		0x3001
>>>  /* Disable CET features in unsigned int features.  */
>>>  # define ARCH_CET_DISABLE		0x3002
>>>  /* Lock all CET features.  */
>>>  # define ARCH_CET_LOCK			0x3003
>>>  /* Allocate a new shadow stack with unsigned long long *addr:
>>>       IN: requested shadow stack size: *addr.
>>>       OUT: allocated shadow stack address: *addr.
>>>   */
>>>  # define ARCH_CET_ALLOC_SHSTK		0x3004
>>>  /* Return legacy region bitmap info in unsigned long long *addr:
>>>      address: addr[0].
>>>      size: addr[1].
>>>   */
>>>  # define ARCH_CET_LEGACY_BITMAP	0x3005
>>>
>>> 	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
>>> 	bits/prctl.h.
>>> 	* sysdeps/unix/sysv/linux/bits/prctl.h: New file.
>>> 	* sysdeps/unix/sysv/linux/x86/bits/prctl.h: Likewise.
>>> 	* sysdeps/unix/sysv/linux/sys/prctl.h: Include <bits/prctl.h>.
>>> 	* sysdeps/unix/sysv/linux/x86/cpu-features.c: Include
>>> 	<sys/prctl.h>.
>>> 	(get_cet_status): Call arch_prctl with ARCH_CET_STATUS.
>>> 	* sysdeps/unix/sysv/linux/x86/dl-cet.h: Include  <sys/prctl.h>.
>>> 	(dl_cet_allocate_legacy_bitmap): Call arch_prctl with
>>> 	ARCH_CET_LEGACY_BITMAP.
>>> 	(dl_cet_disable_cet): Call arch_prctl with ARCH_CET_DISABLE.
>>> 	(dl_cet_lock_cet): Call arch_prctl with ARCH_CET_LOCK.
>>> 	* sysdeps/x86/libc-start.c: Include <startup.h>.
>>> ---
>>
>> The prctl.h values don't appear in any published kernel.
>>
>> What's the status for these?
> 
> The CET kernel changes have been submitted and under discussion.  We
> believe that this is the final CET kernel interface.

OK, so this can't be a published public header then. Thank you for
reworking this.
 
>>
>> We can't ship them in the public prctl.h header unless they are already
>> in a public kernel or committed and basically ready to go out in a public
>> kernel.
>>
>> You could rework this to only use the values internally and that would
>> be OK, since no user needs these yet, we are the primary CET user for
>> now.
>>
> 
> Like this?
> 
> 
> H.J.
> ---
>  /* CET features:
>     IBT:   GNU_PROPERTY_X86_FEATURE_1_IBT
>     SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
>   */
> 
>  /* Return CET features in unsigned long long *addr:
>       features: addr[0].
>       shadow stack base address: addr[1].
>       shadow stack size: addr[2].
>   */
>  # define ARCH_CET_STATUS		0x3001
>  /* Disable CET features in unsigned int features.  */
>  # define ARCH_CET_DISABLE		0x3002
>  /* Lock all CET features.  */
>  # define ARCH_CET_LOCK			0x3003
>  /* Allocate a new shadow stack with unsigned long long *addr:
>       IN: requested shadow stack size: *addr.
>       OUT: allocated shadow stack address: *addr.
>   */
>  # define ARCH_CET_ALLOC_SHSTK		0x3004
>  /* Return legacy region bitmap info in unsigned long long *addr:
>      address: addr[0].
>      size: addr[1].
>   */
>  # define ARCH_CET_LEGACY_BITMAP	0x3005
> 
> Note: sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h should be
> renamed to sysdeps/unix/sysv/linux/x86/bits/prctl.h after the CET
> kernel interface has been committed into the public kernel.
> 
> 	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
> 	bits/prctl.h.
> 	* sysdeps/unix/sysv/linux/bits/prctl.h: New file.
> 	* sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h: Likewise.
> 	* sysdeps/unix/sysv/linux/sys/prctl.h: Include <bits/prctl.h>.
> 	* sysdeps/unix/sysv/linux/x86/cpu-features.c: Include
> 	<sys/prctl.h> and <bits/prctl-internal.h>.
> 	(get_cet_status): Call arch_prctl with ARCH_CET_STATUS.
> 	* sysdeps/unix/sysv/linux/x86/dl-cet.h: Include <sys/prctl.h>
> 	and <bits/prctl-internal.h>.
> 	(dl_cet_allocate_legacy_bitmap): Call arch_prctl with
> 	ARCH_CET_LEGACY_BITMAP.
> 	(dl_cet_disable_cet): Call arch_prctl with ARCH_CET_DISABLE.
> 	(dl_cet_lock_cet): Call arch_prctl with ARCH_CET_LOCK.
> 	* sysdeps/x86/libc-start.c: Include <startup.h>.

OK to commit, with the prctl-internal.h hack (staging for released
kernel), so long as you confirm the installed prctl.h is empty and
doesn't cause any problems with a build-many-glibcs.sh run.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  sysdeps/unix/sysv/linux/Makefile              |  3 +-
>  sysdeps/unix/sysv/linux/bits/prctl.h          | 21 ++++++++
>  sysdeps/unix/sysv/linux/sys/prctl.h           |  1 +
>  .../unix/sysv/linux/x86/bits/prctl-internal.h | 52 +++++++++++++++++++
>  sysdeps/unix/sysv/linux/x86/cpu-features.c    | 10 ++++
>  sysdeps/unix/sysv/linux/x86/dl-cet.h          | 32 +++++++++---
>  sysdeps/x86/libc-start.c                      |  3 ++
>  7 files changed, 115 insertions(+), 7 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/bits/prctl.h
>  create mode 100644 sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h
> 
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index f71cc39c7e..0bcc5287d9 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -40,7 +40,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
>  		  bits/signalfd.h bits/timerfd.h bits/epoll.h \
>  		  bits/socket_type.h bits/syscall.h bits/sysctl.h \
>  		  bits/mman-linux.h bits/mman-shared.h bits/ptrace-shared.h \
> -		  bits/siginfo-arch.h bits/siginfo-consts-arch.h
> +		  bits/siginfo-arch.h bits/siginfo-consts-arch.h \
> +		  bits/prctl.h

OK.

>  
>  tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
>  	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
> diff --git a/sysdeps/unix/sysv/linux/bits/prctl.h b/sysdeps/unix/sysv/linux/bits/prctl.h
> new file mode 100644
> index 0000000000..be96218066
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/prctl.h
> @@ -0,0 +1,21 @@
> +/* 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/>.  */
> +
> +#ifndef _BITS_PRCTL_H
> +#define _BITS_PRCTL_H	1
> +
> +#endif  /* bits/prctl.h */

OK.

> diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h
> index 683d16748f..6c4f643c75 100644
> --- a/sysdeps/unix/sysv/linux/sys/prctl.h
> +++ b/sysdeps/unix/sysv/linux/sys/prctl.h
> @@ -20,6 +20,7 @@
>  
>  #include <features.h>
>  #include <linux/prctl.h>  /*  The magic values come from here  */
> +#include <bits/prctl.h>
>  
>  __BEGIN_DECLS
>  
> diff --git a/sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h b/sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h
> new file mode 100644
> index 0000000000..08408d5b88
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h
> @@ -0,0 +1,52 @@
> +/* FIXME: Rename this file to prctl.h after the CET kernel interface
> +   has been committed into the public kernel.  */

OK. It's a hack, but we know why, and I'm not ashamed of it, we need ways
to stage work pending kernel releases. Adding constants to a header is an
OK thing to do for a released ABI if needed.

> +#undef _BITS_PRCTL_H
> +
> +/* 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/>.  */
> +
> +#ifndef _BITS_PRCTL_H
> +#define _BITS_PRCTL_H	1
> +
> +#ifndef ARCH_CET_STATUS
> +/* CET features:
> +   IBT:   GNU_PROPERTY_X86_FEATURE_1_IBT
> +   SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK
> + */
> +/* Return CET features in unsigned long long *addr:
> +     features: addr[0].
> +     shadow stack base address: addr[1].
> +     shadow stack size: addr[2].
> + */
> +# define ARCH_CET_STATUS	0x3001
> +/* Disable CET features in unsigned int features.  */
> +# define ARCH_CET_DISABLE	0x3002
> +/* Lock all CET features.  */
> +# define ARCH_CET_LOCK		0x3003
> +/* Allocate a new shadow stack with unsigned long long *addr:
> +     IN: requested shadow stack size: *addr.
> +     OUT: allocated shadow stack address: *addr.
> + */
> +# define ARCH_CET_ALLOC_SHSTK	0x3004
> +/* Return legacy region bitmap info in unsigned long long *addr:
> +     address: addr[0].
> +     size: addr[1].
> + */
> +# define ARCH_CET_LEGACY_BITMAP	0x3005
> +#endif /* ARCH_CET_STATUS */
> +
> +#endif  /* bits/prctl.h */

OK.

> diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/unix/sysv/linux/x86/cpu-features.c
> index 7c9df9b794..c042783ae9 100644
> --- a/sysdeps/unix/sysv/linux/x86/cpu-features.c
> +++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c
> @@ -17,9 +17,19 @@
>     <http://www.gnu.org/licenses/>.  */
>  
>  #if CET_ENABLED
> +# include <sys/prctl.h>
> +/* FIXME: Remove this after <bits/prctl-internal.h> has been renamed to
> +   <bits/prctl.h>.  */
> +# include <bits/prctl-internal.h>

OK.

> +
>  static inline int __attribute__ ((always_inline))
>  get_cet_status (void)
>  {
> +  unsigned long long cet_status[3];
> +  INTERNAL_SYSCALL_DECL (err);
> +  if (INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_STATUS,
> +			cet_status) == 0)
> +    return cet_status[0];

OK.

>    return 0;
>  }
>  
> diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sysv/linux/x86/dl-cet.h
> index ae81e2f2ca..edf8cd7394 100644
> --- a/sysdeps/unix/sysv/linux/x86/dl-cet.h
> +++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h
> @@ -15,23 +15,43 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#include <sys/prctl.h>
> +/* FIXME: Remove this after <bits/prctl-internal.h> has been renamed to
> +   <bits/prctl.h>.  */
> +#include <bits/prctl-internal.h>
> +

OK.

>  static inline int __attribute__ ((always_inline))
>  dl_cet_allocate_legacy_bitmap (unsigned long *legacy_bitmap)
>  {
> -  /* FIXME: Need syscall support.  */
> -  return -1;
> +  /* Allocate legacy bitmap.  */
> +  INTERNAL_SYSCALL_DECL (err);
> +#ifdef __LP64__
> +  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2,
> +				 ARCH_CET_LEGACY_BITMAP, legacy_bitmap);
> +#else
> +  unsigned long long legacy_bitmap_u64[2];
> +  int res = INTERNAL_SYSCALL (arch_prctl, err, 2,
> +			      ARCH_CET_LEGACY_BITMAP, legacy_bitmap_u64);
> +  if (res == 0)
> +    {
> +      legacy_bitmap[0] = legacy_bitmap_u64[0];
> +      legacy_bitmap[1] = legacy_bitmap_u64[1];
> +    }
> +  return res;
> +#endif

OK.

>  }
>  
>  static inline int __attribute__ ((always_inline))
>  dl_cet_disable_cet (unsigned int cet_feature)
>  {
> -  /* FIXME: Need syscall support.  */
> -  return -1;
> +  INTERNAL_SYSCALL_DECL (err);
> +  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_DISABLE,
> +				 cet_feature);
>  }
>  

OK.

>  static inline int __attribute__ ((always_inline))
>  dl_cet_lock_cet (void)
>  {
> -  /* FIXME: Need syscall support.  */
> -  return -1;
> +  INTERNAL_SYSCALL_DECL (err);
> +  return (int) INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_LOCK, 0);

OK.

>  }
> diff --git a/sysdeps/x86/libc-start.c b/sysdeps/x86/libc-start.c
> index 43aba9d061..eb5335c154 100644
> --- a/sysdeps/x86/libc-start.c
> +++ b/sysdeps/x86/libc-start.c
> @@ -16,6 +16,9 @@
>     <http://www.gnu.org/licenses/>.  */
>  
>  #ifndef SHARED
> +/* Define I386_USE_SYSENTER to support syscall during startup in static
> +   PIE.  */
> +# include <startup.h>

OK.

>  # include <ldsodefs.h>
>  # include <cpu-features.h>
>  # include <cpu-features.c>
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* V2 [PATCH 03/12] Add <bits/indirect-return.h>
  2018-07-24 12:57   ` Carlos O'Donell
@ 2018-07-24 13:52     ` H.J. Lu
  0 siblings, 0 replies; 70+ messages in thread
From: H.J. Lu @ 2018-07-24 13:52 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: libc-alpha

On Tue, Jul 24, 2018 at 08:57:17AM -0400, Carlos O'Donell wrote:
> On 07/21/2018 10:20 AM, H.J. Lu wrote:
> > Add <bits/indirect-return.h> and include it in <ucontext.h>.
> > __INDIRECT_RETURN defined in <bits/indirect-return.h> indicates if
> > swapcontext requires special compiler treatment.  The default
> > __INDIRECT_RETURN is empty.
> > 
> > On x86, when shadow stack is enabled, __INDIRECT_RETURN is defined
> > with indirect_return attribute, which has been added to GCC 9, to
> > indicate that swapcontext returns via indirect branch.  Otherwise
> > __INDIRECT_RETURN is defined with returns_twice attribute.
> 
> I saw this discussion and I think a returns_twice is the right solution
> for older compilers since it removes possibly incorrect optimizations.
> 
> > When shadow stack is enabled, remove always_inline attribute from
> > prepare_test_buffer in string/tst-xbzero-opt.c to avoid:
> > 
> > tst-xbzero-opt.c: In function ‘prepare_test_buffer’:
> > tst-xbzero-opt.c:105:1: error: function ‘prepare_test_buffer’ can never be inlined because it uses setjmp
> >  prepare_test_buffer (unsigned char *buf)
> 
> OK.
> 
> > when indirect_return attribute isn't available.
> > 
> > 	* bits/indirect-return.h: New file.
> > 	* misc/sys/cdefs.h (__glibc_has_attribute): New.
> > 	* sysdeps/x86/bits/indirect-return.h: Likewise.
> > 	* stdlib/Makefile (headers): Add bits/indirect-return.h.
> > 	* stdlib/ucontext.h: Include <bits/indirect-return.h>.
> > 	(swapcontext): Add __INDIRECT_RETURN.
> > 	* string/tst-xbzero-opt.c (ALWAYS_INLINE): New.
> > 	(prepare_test_buffer): Use it.
> 
> OK with suggestion.
> 
> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
> 
> Suggest:
> 
> /* Newer compilers provide the indirect_return attribute, but without
>    it we can use returns_twice to affect the optimizer in the same
>    way and avoid unsafe optimizations.  */
> 
> > +#  define __INDIRECT_RETURN __attribute__ ((__returns_twice__))
> > +# endif
> > +#else
> > +# define __INDIRECT_RETURN
> > +#endif
> > 
> 

This is the patch I am going to check in.

Thanks.

H.J.
---
Add <bits/indirect-return.h> and include it in <ucontext.h>.
__INDIRECT_RETURN defined in <bits/indirect-return.h> indicates if
swapcontext requires special compiler treatment.  The default
__INDIRECT_RETURN is empty.

On x86, when shadow stack is enabled, __INDIRECT_RETURN is defined
with indirect_return attribute, which has been added to GCC 9, to
indicate that swapcontext returns via indirect branch.  Otherwise
__INDIRECT_RETURN is defined with returns_twice attribute.

When shadow stack is enabled, remove always_inline attribute from
prepare_test_buffer in string/tst-xbzero-opt.c to avoid:

tst-xbzero-opt.c: In function ‘prepare_test_buffer’:
tst-xbzero-opt.c:105:1: error: function ‘prepare_test_buffer’ can never be inlined because it uses setjmp
 prepare_test_buffer (unsigned char *buf)

when indirect_return attribute isn't available.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

	* bits/indirect-return.h: New file.
	* misc/sys/cdefs.h (__glibc_has_attribute): New.
	* sysdeps/x86/bits/indirect-return.h: Likewise.
	* stdlib/Makefile (headers): Add bits/indirect-return.h.
	* stdlib/ucontext.h: Include <bits/indirect-return.h>.
	(swapcontext): Add __INDIRECT_RETURN.
	* string/tst-xbzero-opt.c (ALWAYS_INLINE): New.
	(prepare_test_buffer): Use it.
---
 bits/indirect-return.h             | 25 ++++++++++++++++++++
 misc/sys/cdefs.h                   |  6 +++++
 stdlib/Makefile                    |  2 +-
 stdlib/ucontext.h                  |  6 ++++-
 string/tst-xbzero-opt.c            | 10 +++++++-
 sysdeps/x86/bits/indirect-return.h | 37 ++++++++++++++++++++++++++++++
 6 files changed, 83 insertions(+), 3 deletions(-)
 create mode 100644 bits/indirect-return.h
 create mode 100644 sysdeps/x86/bits/indirect-return.h

diff --git a/bits/indirect-return.h b/bits/indirect-return.h
new file mode 100644
index 0000000000..47f6f15a6e
--- /dev/null
+++ b/bits/indirect-return.h
@@ -0,0 +1,25 @@
+/* Definition of __INDIRECT_RETURN.  Generic version.
+   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/>.  */
+
+#ifndef _UCONTEXT_H
+# error "Never include <bits/indirect-return.h> directly; use <ucontext.h> instead."
+#endif
+
+/* __INDIRECT_RETURN is used on swapcontext to indicate if it requires
+   special compiler treatment.  */
+#define __INDIRECT_RETURN
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index e80a45ca68..3f6fe3cc85 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -406,6 +406,12 @@
 # define __glibc_likely(cond)	(cond)
 #endif
 
+#ifdef __has_attribute
+# define __glibc_has_attribute(attr)	__has_attribute (attr)
+#else
+# define __glibc_has_attribute(attr)	0
+#endif
+
 #if (!defined _Noreturn \
      && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
      &&  !__GNUC_PREREQ (4,7))
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 808a8ceab7..b5e55b0a55 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -26,7 +26,7 @@ headers	:= stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h      \
 	   monetary.h bits/monetary-ldbl.h				      \
 	   inttypes.h stdint.h bits/wordsize.h				      \
 	   errno.h sys/errno.h bits/errno.h bits/types/error_t.h	      \
-	   ucontext.h sys/ucontext.h					      \
+	   ucontext.h sys/ucontext.h bits/indirect-return.h		      \
 	   alloca.h fmtmsg.h						      \
 	   bits/stdlib-bsearch.h sys/random.h bits/stdint-intn.h	      \
 	   bits/stdint-uintn.h
diff --git a/stdlib/ucontext.h b/stdlib/ucontext.h
index eec7611631..ec630038f6 100644
--- a/stdlib/ucontext.h
+++ b/stdlib/ucontext.h
@@ -22,6 +22,9 @@
 
 #include <features.h>
 
+/* Get definition of __INDIRECT_RETURN.  */
+#include <bits/indirect-return.h>
+
 /* Get machine dependent definition of data structures.  */
 #include <sys/ucontext.h>
 
@@ -36,7 +39,8 @@ extern int setcontext (const ucontext_t *__ucp) __THROWNL;
 /* Save current context in context variable pointed to by OUCP and set
    context from variable pointed to by UCP.  */
 extern int swapcontext (ucontext_t *__restrict __oucp,
-			const ucontext_t *__restrict __ucp) __THROWNL;
+			const ucontext_t *__restrict __ucp)
+  __THROWNL __INDIRECT_RETURN;
 
 /* Manipulate user context UCP to continue with calling functions FUNC
    and the ARGC-1 parameters following ARGC when the context is used
diff --git a/string/tst-xbzero-opt.c b/string/tst-xbzero-opt.c
index cf7041f37a..aab4a7f715 100644
--- a/string/tst-xbzero-opt.c
+++ b/string/tst-xbzero-opt.c
@@ -100,7 +100,15 @@ static ucontext_t uc_main, uc_co;
 /* Always check the test buffer immediately after filling it; this
    makes externally visible side effects depend on the buffer existing
    and having been filled in.  */
-static inline __attribute__  ((always_inline)) void
+#if defined __CET__ && !__glibc_has_attribute (__indirect_return__)
+/* Note: swapcontext returns via indirect branch when SHSTK is enabled.
+   Without indirect_return attribute, swapcontext is marked with
+   returns_twice attribute, which prevents always_inline to work.  */
+# define ALWAYS_INLINE
+#else
+# define ALWAYS_INLINE	__attribute__ ((always_inline))
+#endif
+static inline ALWAYS_INLINE void
 prepare_test_buffer (unsigned char *buf)
 {
   for (unsigned int i = 0; i < PATTERN_REPS; i++)
diff --git a/sysdeps/x86/bits/indirect-return.h b/sysdeps/x86/bits/indirect-return.h
new file mode 100644
index 0000000000..d1acaca3b9
--- /dev/null
+++ b/sysdeps/x86/bits/indirect-return.h
@@ -0,0 +1,37 @@
+/* Definition of __INDIRECT_RETURN.  x86 version.
+   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/>.  */
+
+#ifndef _UCONTEXT_H
+# error "Never include <bits/indirect-return.h> directly; use <ucontext.h> instead."
+#endif
+
+/* On x86, swapcontext returns via indirect branch when the shadow stack
+   is enabled.  Define __INDIRECT_RETURN to indicate whether swapcontext
+   returns via indirect branch.  */
+#if defined __CET__ && (__CET__ & 2) != 0
+# if __glibc_has_attribute (__indirect_return__)
+#  define __INDIRECT_RETURN __attribute__ ((__indirect_return__))
+# else
+/* Newer compilers provide the indirect_return attribute, but without
+   it we can use returns_twice to affect the optimizer in the same
+   way and avoid unsafe optimizations.  */
+#  define __INDIRECT_RETURN __attribute__ ((__returns_twice__))
+# endif
+#else
+# define __INDIRECT_RETURN
+#endif
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: V2 [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control
  2018-07-24 13:24     ` V2 " H.J. Lu
  2018-07-24 13:49       ` Carlos O'Donell
@ 2018-07-24 14:28       ` Joseph Myers
  2018-07-24 15:29         ` Carlos O'Donell
  1 sibling, 1 reply; 70+ messages in thread
From: Joseph Myers @ 2018-07-24 14:28 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Carlos O'Donell, libc-alpha

On Tue, 24 Jul 2018, H.J. Lu wrote:

> Note: sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h should be
> renamed to sysdeps/unix/sysv/linux/x86/bits/prctl.h after the CET
> kernel interface has been committed into the public kernel.

bits/ should not be used for any internal headers; it's purely a naming 
convention for public headers.  So there should be no 
bits/prctl-internal.h header.

I don't think there should be bits/prctl.h at all either.  Not with this 
patch (because there isn't anything for it to do), and not once the 
interface is in the kernel (because existing practice is that we rely on 
the include of <linux/prctl.h> from <sys/prctl.h> to provide the values to 
users of glibc).

Rather, for the uses of these constants within glibc, to avoid relying on 
new kernel headers, provide an x86 include/sys/prctl.h that does 
#include_next <sys/prctl.h> and then defines these constants if not 
already defined.  And make sure that header gets a prominent comment 
naming the upstream kernel version with the constants (once they are 
upstream), so it's obvious at what point we can remove that header.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: V2 [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control
  2018-07-24 14:28       ` Joseph Myers
@ 2018-07-24 15:29         ` Carlos O'Donell
  0 siblings, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24 15:29 UTC (permalink / raw)
  To: Joseph Myers, H.J. Lu; +Cc: libc-alpha

On 07/24/2018 10:28 AM, Joseph Myers wrote:
> On Tue, 24 Jul 2018, H.J. Lu wrote:
> 
>> Note: sysdeps/unix/sysv/linux/x86/bits/prctl-internal.h should be
>> renamed to sysdeps/unix/sysv/linux/x86/bits/prctl.h after the CET
>> kernel interface has been committed into the public kernel.
> 
> bits/ should not be used for any internal headers; it's purely a naming 
> convention for public headers.  So there should be no 
> bits/prctl-internal.h header.

OK.

> I don't think there should be bits/prctl.h at all either.  Not with this 
> patch (because there isn't anything for it to do), and not once the 
> interface is in the kernel (because existing practice is that we rely on 
> the include of <linux/prctl.h> from <sys/prctl.h> to provide the values to 
> users of glibc).

Good point.
 
> Rather, for the uses of these constants within glibc, to avoid relying on 
> new kernel headers, provide an x86 include/sys/prctl.h that does 
> #include_next <sys/prctl.h> and then defines these constants if not 
> already defined.  And make sure that header gets a prominent comment 
> naming the upstream kernel version with the constants (once they are 
> upstream), so it's obvious at what point we can remove that header.

OK, that makes sense, so a purely internal header via include/ wrapping
with the constants there.

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 05/12] x86: Rename __glibc_reserved2 to ssp_base in tcbhead_t
  2018-07-21 14:21 ` [PATCH 05/12] x86: Rename __glibc_reserved2 to ssp_base in tcbhead_t H.J. Lu
@ 2018-07-24 20:49   ` Carlos O'Donell
  0 siblings, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24 20:49 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> This will be used to implement shadow stack switching by getcontext,
> makecontext, setcontext and swapcontext.
> 
> 	* sysdeps/i386/nptl/tcb-offsets.sym (SSP_BASE_OFFSET): New.
> 	* sysdeps/i386/nptl/tls.h (tcbhead_t): Replace __glibc_reserved2
> 	with ssp_base.
> 	* sysdeps/x86_64/nptl/tcb-offsets.sym (SSP_BASE_OFFSET): New.
> 	* sysdeps/x86_64/nptl/tls.h (tcbhead_t): Replace __glibc_reserved2
> 	with ssp_base.

Looks good to me.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  sysdeps/i386/nptl/tcb-offsets.sym   |  1 +
>  sysdeps/i386/nptl/tls.h             |  3 ++-
>  sysdeps/x86_64/nptl/tcb-offsets.sym |  1 +
>  sysdeps/x86_64/nptl/tls.h           | 10 +++++++++-
>  4 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/sysdeps/i386/nptl/tcb-offsets.sym b/sysdeps/i386/nptl/tcb-offsets.sym
> index fbac241c45..2ec9e787c1 100644
> --- a/sysdeps/i386/nptl/tcb-offsets.sym
> +++ b/sysdeps/i386/nptl/tcb-offsets.sym
> @@ -13,3 +13,4 @@ CLEANUP_PREV		offsetof (struct _pthread_cleanup_buffer, __prev)
>  MUTEX_FUTEX		offsetof (pthread_mutex_t, __data.__lock)
>  POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
>  FEATURE_1_OFFSET	offsetof (tcbhead_t, feature_1)
> +SSP_BASE_OFFSET		offsetof (tcbhead_t, ssp_base)

OK.

> diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
> index 21e23cd809..12285d3217 100644
> --- a/sysdeps/i386/nptl/tls.h
> +++ b/sysdeps/i386/nptl/tls.h
> @@ -49,7 +49,8 @@ typedef struct
>    void *__private_tm[3];
>    /* GCC split stack support.  */
>    void *__private_ss;
> -  void *__glibc_reserved2;
> +  /* The lowest address of shadow stack,  */
> +  unsigned long ssp_base;

OK.

>  } tcbhead_t;
>  
>  /* morestack.S in libgcc uses offset 0x30 to access __private_ss,   */
> diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym
> index 387621e88c..ae8034743b 100644
> --- a/sysdeps/x86_64/nptl/tcb-offsets.sym
> +++ b/sysdeps/x86_64/nptl/tcb-offsets.sym
> @@ -13,6 +13,7 @@ MULTIPLE_THREADS_OFFSET	offsetof (tcbhead_t, multiple_threads)
>  POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)
>  VGETCPU_CACHE_OFFSET	offsetof (tcbhead_t, vgetcpu_cache)
>  FEATURE_1_OFFSET	offsetof (tcbhead_t, feature_1)
> +SSP_BASE_OFFSET		offsetof (tcbhead_t, ssp_base)

OK.

>  
>  -- Not strictly offsets, but these values are also used in the TCB.
>  TCB_CANCELSTATE_BITMASK	 CANCELSTATE_BITMASK
> diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
> index f042a0250a..e88561c934 100644
> --- a/sysdeps/x86_64/nptl/tls.h
> +++ b/sysdeps/x86_64/nptl/tls.h
> @@ -60,7 +60,8 @@ typedef struct
>    void *__private_tm[4];
>    /* GCC split stack support.  */
>    void *__private_ss;
> -  long int __glibc_reserved2;
> +  /* The lowest address of shadow stack,  */
> +  unsigned long long int ssp_base;

OK.

>    /* Must be kept even if it is no longer used by glibc since programs,
>       like AddressSanitizer, depend on the size of tcbhead_t.  */
>    __128bits __glibc_unused2[8][4] __attribute__ ((aligned (32)));
> @@ -72,10 +73,17 @@ typedef struct
>  /* morestack.S in libgcc uses offset 0x40 to access __private_ss,   */
>  _Static_assert (offsetof (tcbhead_t, __private_ss) == 0x40,
>  		"offset of __private_ss != 0x40");
> +/* NB: ssp_base used to be "long int __glibc_reserved2", which was
> +   changed from 32 bits to 64 bits.  Make sure that the offset of the
> +   next field, __glibc_unused2, is unchanged.  */
> +_Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x60,
> +		"offset of __glibc_unused2 != 0x60");

OK.

>  # else
>  /* morestack.S in libgcc uses offset 0x70 to access __private_ss,   */
>  _Static_assert (offsetof (tcbhead_t, __private_ss) == 0x70,
>  		"offset of __private_ss != 0x70");
> +_Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
> +		"offset of __glibc_unused2 != 0x80");

OK.

>  # endif
>  
>  #else /* __ASSEMBLER__ */
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 06/12] x86-64/CET: Extend ucontext_t to save shadow stack
  2018-07-21 14:21 ` [PATCH 06/12] x86-64/CET: Extend ucontext_t to save shadow stack H.J. Lu
@ 2018-07-24 20:49   ` Carlos O'Donell
  0 siblings, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-24 20:49 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> This patch adds a field to ucontext_t to save shadow stack:
> 
> 1. getcontext and swapcontext are updated to save the caller's shadow
> stack pointer and return addresses.
> 2. setcontext and swapcontext are updated to restore shadow stack and
> jump to new context directly.
> 3. makecontext is updated to allocate a new shadow stack and set the
> caller's return address to __start_context.
> 
> Since makecontext allocates a new shadow stack when making a new
> context and kernel allocates a new shadow stack for clone/fork/vfork
> syscalls, we keep track the lowest shadow stack base.  In setcontext
> and swapcontext, when searching for shadow stack restore token, if the
> lowest shadow stack base is reached, we assume both the current and
> target shadow stack pointers are on the same shadow stack.
> 
> We enable shadow stack at run-time only if program and all used shared
> objects, including dlopened ones, are shadow stack enabled, which means
> that they must be compiled with GCC 8 or above and glibc 2.28 or above.
> We need to save and restore shadow stack only if shadow stack is enabled.
> When caller of getcontext, setcontext, swapcontext and makecontext is
> compiled with smaller ucontext_t, shadow stack won't be enabled at
> run-time.  We check if shadow stack is enabled before accessing the
> extended field in ucontext_t.
> 

Right, this is a flag day ABI change.

> 2018-05-21  Vedvyas Shanbhogue  <vedvyas.shanbhogue@intel.com>
> 	    H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* sysdeps/unix/sysv/linux/x86/sys/ucontext.h (ucontext_t): Add
> 	__ssp.
> 	* sysdeps/unix/sysv/linux/x86_64/__start_context.S: Include
> 	<bits/prctl.h> and "ucontext_i.h" when shadow stack is enabled.
> 	(__push___start_context): New.
> 	* sysdeps/unix/sysv/linux/x86_64/getcontext.S (__getcontext):
> 	Save the caller's shadow stack pointer when shadow stack is in
> 	use.
> 	* sysdeps/unix/sysv/linux/x86_64/makecontext.c Include
> 	<pthread.h>, <libc-pointer-arith.h> and <sys/prctl.h>.
> 	(__push___start_context): New prototype.
> 	(__makecontext): Call __push___start_context to allocate a new
> 	shadow stack, push __start_context onto the new stack as well
> 	as the new shadow stack.  Set the lowest shadow stack base.
> 	* sysdeps/unix/sysv/linux/x86_64/setcontext.S: Include
> 	<bits/prctl.h>.
> 	(__setcontext): Use the restore token to restore shadow stack
> 	if available.  Otherwise unwind shadow stack.  Check if the
> 	target shadow stack pointer came from __push___start_context.
> 	Don't search for shadow stack restore token below the lowest
> 	shadow stack base.
> 	* sysdeps/unix/sysv/linux/x86_64/swapcontext.S: Include
> 	<bits/prctl.h>.
> 	(__swapcontext): Save the current shadow stack pointer.
> 	Use the restore token to restore shadow stack if available.
> 	Otherwise unwind shadow stack.  Check if the target shadow
> 	stack pointer came from __push___start_context.  Don't search
> 	for shadow stack restore token below the lowest shadow stack
> 	base.
> 	* sysdeps/unix/sysv/linux/x86_64/sysdep.h
> 	(STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT): New.
> 	* sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym (oSSP): New.
> ---

OK for 2.28, but should we increase the size we allocate in the 
new structure?

The hardest part to review was the CET token save/restore state
transitions between context changes and for example I still don't
clearly understand why we need to check if the restored state is
on the same shadow stack and unwind? Is this because we are trying
to unwind the shadow stack as often as possible to avoid overflow
(as we do in the unwind_shadow_stack/loop sequence). Why do we do
this unwind process?

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

>  sysdeps/unix/sysv/linux/x86/sys/ucontext.h    |   2 +
>  .../unix/sysv/linux/x86_64/__start_context.S  |  75 +++++++++
>  sysdeps/unix/sysv/linux/x86_64/getcontext.S   |  17 ++
>  sysdeps/unix/sysv/linux/x86_64/makecontext.c  |  56 ++++++-
>  sysdeps/unix/sysv/linux/x86_64/setcontext.S   | 139 ++++++++++++++++
>  sysdeps/unix/sysv/linux/x86_64/swapcontext.S  | 150 ++++++++++++++++++
>  sysdeps/unix/sysv/linux/x86_64/sysdep.h       |   5 +
>  sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym |   1 +
>  8 files changed, 444 insertions(+), 1 deletion(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/x86/sys/ucontext.h b/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
> index afb7c181bf..7367726a50 100644
> --- a/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
> +++ b/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
> @@ -147,6 +147,7 @@ typedef struct ucontext_t
>      mcontext_t uc_mcontext;
>      sigset_t uc_sigmask;
>      struct _libc_fpstate __fpregs_mem;
> +    __extension__ unsigned long long int __ssp[4];

This is an ABI change, is this enough space for future changes also?

Should we extend this to have some more space?

>    } ucontext_t;
>  
>  #else /* !__x86_64__ */
> @@ -251,6 +252,7 @@ typedef struct ucontext_t
>      mcontext_t uc_mcontext;
>      sigset_t uc_sigmask;
>      struct _libc_fpstate __fpregs_mem;
> +    unsigned long int __ssp[4];

Likewise.

>    } ucontext_t;
>  
>  #endif /* !__x86_64__ */
> diff --git a/sysdeps/unix/sysv/linux/x86_64/__start_context.S b/sysdeps/unix/sysv/linux/x86_64/__start_context.S
> index 0bfde5fc31..01e672c09b 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/__start_context.S
> +++ b/sysdeps/unix/sysv/linux/x86_64/__start_context.S
> @@ -18,6 +18,80 @@
>  
>  #include <sysdep.h>
>  
> +#if SHSTK_ENABLED
> +# include <bits/prctl.h>
> +# include "ucontext_i.h"
> +
> +/* Use CALL to push __start_context onto the new stack as well as the new
> +   shadow stack.  RDI points to ucontext:
> +   Incoming:
> +     __ssp[0]: The original caller's shadow stack pointer.
> +     __ssp[1]: The size of the new shadow stack.
> +     __ssp[2]: The size of the new shadow stack.
> +   Outgoing:
> +     __ssp[0]: The new shadow stack pointer.
> +     __ssp[1]: The base address of the new shadow stack.
> +     __ssp[2]: The size of the new shadow stack.

OK.

> + */

OK.

> +
> +ENTRY(__push___start_context)
> +	/* Save the pointer to ucontext.  */
> +	movq	%rdi, %r9
> +	/* Get the original shadow stack pointer.  */
> +	rdsspq	%r8
> +	/* Save the original stack pointer.  */
> +	movq	%rsp, %rdx
> +	/* Load the top of the new stack into RSI.  */
> +	movq 	oRSP(%rdi), %rsi
> +	/* Add 8 bytes to RSI since CALL will push the 8-byte return
> +	   address onto stack.  */
> +	leaq	8(%rsi), %rsp
> +	/* Allocate the new shadow stack.  The size of the new shadow
> +	   stack is passed in __ssp[1].  */
> +	lea	(oSSP + 8)(%rdi), %RSI_LP
> +	movl	$ARCH_CET_ALLOC_SHSTK, %edi
> +	movl	$__NR_arch_prctl, %eax

OK.

> +	/* The new shadow stack base is returned in __ssp[1].  */
> +	syscall
> +	testq	%rax, %rax
> +	jne	L(hlt)		/* This should never happen.  */
> +
> +	/* Get the size of the new shadow stack.  */
> +	movq	8(%rsi), %rdi
> +
> +	/* Get the base address of the new shadow stack.  */
> +	movq	(%rsi), %rsi
> +
> +	/* Use the restore stoken to restore the new shadow stack.  */
> +	rstorssp -8(%rsi, %rdi)

OK.

> +
> +	/* Save the restore token on the original shadow stack.  */
> +	saveprevssp
> +
> +	/* Push the address of "jmp __start_context" onto the new stack
> +	   as well as the new shadow stack.  */
> +	call	1f
> +	jmp	__start_context

OK.

> +1:
> +
> +	/* Get the new shadow stack pointer.  */
> +	rdsspq	%rdi
> +
> +	/* Use the restore stoken to restore the original shadow stack.  */
> +	rstorssp -8(%r8)
> +
> +	/* Save the restore token on the new shadow stack.  */
> +	saveprevssp
> +
> +	/* Store the new shadow stack pointer in __ssp[0].  */
> +	movq	%rdi, oSSP(%r9)
> +
> +	/* Restore the original stack.  */
> +	mov	%rdx, %rsp
> +	ret

OK.

> +END(__push___start_context)
> +#endif
> +
>  /* This is the helper code which gets called if a function which is
>     registered with 'makecontext' returns.  In this case we have to
>     install the context listed in the uc_link element of the context
> @@ -45,5 +119,6 @@ ENTRY(__start_context)
>  	call	HIDDEN_JUMPTARGET(exit)
>  	/* The 'exit' call should never return.  In case it does cause
>  	   the process to terminate.  */
> +L(hlt):

OK.

>  	hlt
>  END(__start_context)
> diff --git a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
> index 33347bc02e..cbbe4cc9fc 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/getcontext.S
> +++ b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
> @@ -53,6 +53,23 @@ ENTRY(__getcontext)
>  	leaq	8(%rsp), %rcx		/* Exclude the return address.  */
>  	movq	%rcx, oRSP(%rdi)
>  
> +#if SHSTK_ENABLED
> +	/* Check if shadow stack is enabled.  */
> +	testl	$X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
> +	jz	L(no_shstk)
> +
> +	/* Get the current shadow stack pointer.  */
> +	rdsspq	%rax
> +	/* NB: Save the caller's shadow stack so that we can jump back
> +	   to the caller directly.  */
> +	addq	$8, %rax
> +	movq	%rax, oSSP(%rdi)
> +	xorl	%edx, %edx
> +	movq	%rdx, (oSSP + 8)(%rdi)
> +	movq	%rdx, (oSSP + 16)(%rdi)

OK, Save it.

> +
> +L(no_shstk):
> +#endif
>  	/* We have separate floating-point register content memory on the
>  	   stack.  We use the __fpregs_mem block in the context.  Set the
>  	   links up correctly.  */
> diff --git a/sysdeps/unix/sysv/linux/x86_64/makecontext.c b/sysdeps/unix/sysv/linux/x86_64/makecontext.c
> index 0d0802bf43..97f9bbbd2d 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/makecontext.c
> +++ b/sysdeps/unix/sysv/linux/x86_64/makecontext.c
> @@ -21,6 +21,11 @@
>  #include <stdarg.h>
>  #include <stdint.h>
>  #include <ucontext.h>
> +#if SHSTK_ENABLED
> +# include <pthread.h>
> +# include <libc-pointer-arith.h>
> +# include <sys/prctl.h>
> +#endif

OK (with prctl.h changes proposed by Joseph).

>  
>  #include "ucontext_i.h"
>  
> @@ -52,6 +57,8 @@ void
>  __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
>  {
>    extern void __start_context (void) attribute_hidden;
> +  extern void __push___start_context (ucontext_t *)
> +    attribute_hidden;

OK.

>    greg_t *sp;
>    unsigned int idx_uc_link;
>    va_list ap;
> @@ -74,7 +81,54 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
>    ucp->uc_mcontext.gregs[REG_RSP] = (uintptr_t) sp;
>  
>    /* Setup stack.  */
> -  sp[0] = (uintptr_t) &__start_context;
> +#if SHSTK_ENABLED
> +  struct pthread *self = THREAD_SELF;
> +  unsigned int feature_1 = THREAD_GETMEM (self, header.feature_1);
> +  /* NB: We must check feature_1 before accessing __ssp since caller
> +	 may be compiled against ucontext_t without __ssp.  */

OK. Correct, don't touch elements potentially outside of the ABI.

> +  if ((feature_1 & X86_FEATURE_1_SHSTK) != 0)
> +    {
> +      /* Shadow stack is enabled.  We need to allocate a new shadow
> +         stack.  */
> +      unsigned long ssp_size = (((uintptr_t) sp
> +				 - (uintptr_t) ucp->uc_stack.ss_sp)
> +				>> STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT);
> +      /* Align shadow stack to 8 bytes.  */
> +      ssp_size = ALIGN_UP (ssp_size, 8);

OK.

> +
> +      ucp->__ssp[1] = ssp_size;
> +      ucp->__ssp[2] = ssp_size;

OK.

> +
> +      /* Call __push___start_context to allocate a new shadow stack,
> +	 push __start_context onto the new stack as well as the new
> +	 shadow stack.  NB: After __push___start_context returns,
> +	   ucp->__ssp[0]: The new shadow stack pointer.
> +	   ucp->__ssp[1]: The base address of the new shadow stack.
> +	   ucp->__ssp[2]: The size of the new shadow stack.
> +       */
> +      __push___start_context (ucp);

OK.

> +
> +      /* Update the lowest shadow stack base.  NB: Since a new shadow
> +         stack may be switch by clone syscall, we need to get the

s/switch by clone/switched by the/g

> +	 current default shadow stack base via ARCH_CET_STATUS.  */
> +      unsigned long long cet_status[3];
> +      INTERNAL_SYSCALL_DECL (err);
> +      if (INTERNAL_SYSCALL (arch_prctl, err, 2, ARCH_CET_STATUS,
> +			    cet_status) == 0)
> +	{
> +	  unsigned long long new_ssp_base = ucp->__ssp[1];
> +	  if (new_ssp_base > cet_status[1])
> +	    new_ssp_base = cet_status[1];
> +
> +	  unsigned long long current_ssp_base
> +	    = THREAD_GETMEM (self, header.ssp_base);
> +	  if (!current_ssp_base || current_ssp_base > new_ssp_base)
> +	    THREAD_SETMEM (self, header.ssp_base, new_ssp_base);
> +	}

OK.

> +    }
> +  else
> +#endif
> +    sp[0] = (uintptr_t) &__start_context;

OK.

>    sp[idx_uc_link] = (uintptr_t) ucp->uc_link;
>  
>    va_start (ap, argc);
> diff --git a/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
> index b42af8e291..88c4df5e45 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/setcontext.S
> +++ b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
> @@ -18,6 +18,7 @@
>     <http://www.gnu.org/licenses/>.  */
>  
>  #include <sysdep.h>
> +#include <bits/prctl.h>

OK, though this changes with Joseph's recommendations.

>  
>  #include "ucontext_i.h"
>  
> @@ -79,6 +80,144 @@ ENTRY(__setcontext)
>  	movq	oR14(%rdx), %r14
>  	movq	oR15(%rdx), %r15
>  
> +#if SHSTK_ENABLED
> +	/* Check if shadow stack is enabled.  */
> +	testl	$X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
> +	jz	L(no_shstk)
> +

OK.

> +	/* Get the base address and size of the default shadow stack.
> +	   NB: We can't cache them since CLONE syscall switches the
> +	   default shadow stack.  */
> +	sub	$24, %RSP_LP
> +	mov	%RSP_LP, %RSI_LP
> +	movl	$ARCH_CET_STATUS, %edi
> +	movl	$__NR_arch_prctl, %eax
> +	syscall
> +	testq	%rax, %rax
> +	jne	L(hlt)      /* This should never happen.  */

OK.

> +
> +	/* Get the current shadow stack pointer.  */
> +	rdsspq	%rcx
> +

OK.

> +	/* NB: If both the target shadow stack pointer and the current
> +	   shadow stack pointer are on the original shadow stack, we
> +	   can unwind the stack.  Otherwise, find the restore token
> +	   pushed by rstorssp and saveprevssp to restore the target
> +	   shadow stack.  */
> +	movq	oSSP(%rdx), %rdi
> +	movq	%rdi, %rsi
> +	subq	8(%rsp), %rsi
> +	jb	L(find_restore_token)
> +	cmpq	16(%rsp), %rsi
> +	jae	L(find_restore_token)

OK.

> +
> +	/* Check if both shadow stack pointers are on the original
> +	   shadow stack.  */
> +	movq	%rcx, %rsi
> +	subq	8(%rsp), %rsi
> +	jb	L(find_restore_token)
> +	cmpq	16(%rsp), %rsi
> +	jae	L(find_restore_token)
> +
> +	jmp	L(unwind_shadow_stack)
> +

OK.

> +L(find_restore_token):
> +	/* Save the target shadow stack pointer.  */
> +	movq	%rdi, %rsi
> +
> +	/* Check if the target shadow stack pointer came from
> +	   __push___start_context.  */
> +	movq	(%rsi), %rax
> +	andq	$-8, %rax
> +	leaq	8(%rsi), %r8
> +	cmpq	%r8, %rax
> +	jne	L(skip_restore_shadow_stack_special)

OK.

> +
> +	/* Pop return address from the shadow stack since setcontext
> +	   will not return.   */
> +	movq	$1, %rax
> +	incsspq	%rax
> +
> +	/* Use the restore stoken to restore the target shadow stack.  */
> +	rstorssp (%rsi)

OK.

> +
> +	jmp	L(unwind_shadow_stack_special)
> +
> +L(skip_restore_shadow_stack_special):
> +	movq	%fs:SSP_BASE_OFFSET, %r8
> +L(find_restore_token_loop):
> +	/* Check if there is a restore token.  */
> +	movq	-8(%rsi), %rax
> +	andq	$-8, %rax
> +	cmpq	%rsi, %rax
> +	je	L(restore_shadow_stack)
> +
> +	/* Try the next slot.  */
> +	subq	$8, %rsi
> +
> +	/* Don't check restore token below the lowest shadow stack
> +	   base.  */
> +	cmpq	%r8, %rsi
> +	ja	L(find_restore_token_loop)

OK.

> +
> +	jmp	L(unwind_shadow_stack)
> +
> +L(restore_shadow_stack):
> +	/* Pop return address from the shadow stack since setcontext
> +	   will not return.   */
> +	movq	$1, %rax
> +	incsspq	%rax
> +
> +	/* Use the restore stoken to restore the target shadow stack.  */
> +	rstorssp -8(%rsi)
> +
> +	/* Save the restore token on the old shadow stack.  NB: This
> +	   restore token may be checked by setcontext or swapcontext
> +	   later.  */
> +	saveprevssp

OK.

> +
> +L(unwind_shadow_stack_special):
> +	/* Get the current shadow stack.  */
> +	rdsspq	%rcx
> +
> +L(unwind_shadow_stack):
> +	add	$24, %RSP_LP
> +	/* Unwind the shadow stack.  */
> +	subq	%rdi, %rcx
> +	je	L(skip_unwind_shadow_stack)
> +	negq	%rcx
> +	shrq	$3, %rcx
> +	movl	$255, %esi
> +L(loop):
> +	cmpq	%rsi, %rcx
> +	cmovb	%rcx, %rsi
> +	incsspq	%rsi
> +	subq	%rsi, %rcx
> +	ja	L(loop)

Unwind the shadow stack.

> +
> +L(skip_unwind_shadow_stack):
> +	movq	oRSI(%rdx), %rsi
> +	movq	oRDI(%rdx), %rdi
> +	movq	oRCX(%rdx), %rcx
> +	movq	oR8(%rdx), %r8
> +	movq	oR9(%rdx), %r9
> +
> +	/* Get the return address set with getcontext.  */
> +	movq	oRIP(%rdx), %r10
> +
> +	/* Setup finally %rdx.  */
> +	movq	oRDX(%rdx), %rdx
> +
> +	/* Clear rax to indicate success.  */
> +	xorl	%eax, %eax
> +	/* Jump to the new context directly.  */
> +	jmp	*%r10
> +
> +L(hlt):
> +	hlt
> +
> +L(no_shstk):

OK.

> +#endif
>  	/* The following ret should return to the address set with
>  	getcontext.  Therefore push the address on the stack.  */
>  	movq	oRIP(%rdx), %rcx
> diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
> index 1110c479fa..7a47275727 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
> +++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
> @@ -18,6 +18,7 @@
>     <http://www.gnu.org/licenses/>.  */
>  
>  #include <sysdep.h>
> +#include <bits/prctl.h>

OK (modulo name change).

>  
>  #include "ucontext_i.h"
>  
> @@ -67,6 +68,7 @@ ENTRY(__swapcontext)
>  
>  	/* The syscall destroys some registers, save them.  */
>  	movq	%rsi, %r12
> +	movq	%rdi, %r9

OK.

>  
>  	/* Save the current signal mask and install the new one with
>  	   rt_sigprocmask (SIG_BLOCK, newset, oldset,_NSIG/8).  */
> @@ -99,6 +101,154 @@ ENTRY(__swapcontext)
>  	movq	oR14(%rdx), %r14
>  	movq	oR15(%rdx), %r15
>  
> +#if SHSTK_ENABLED
> +	/* Check if shadow stack is enabled.  */
> +	testl	$X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET
> +	jz	L(no_shstk)

OK.

> +
> +	/* Get the base address and size of the default shadow stack.
> +	   NB: We can't cache them since CLONE syscall switches the
> +	   default shadow stack.  */
> +	sub	$24, %RSP_LP
> +	mov	%RSP_LP, %RSI_LP
> +	movl	$ARCH_CET_STATUS, %edi
> +	movl	$__NR_arch_prctl, %eax
> +	syscall
> +	testq	%rax, %rax
> +	jne	L(hlt)      /* This should never happen.  */

OK.

> +
> +	/* Get the current shadow stack pointer.  */
> +	rdsspq	%rcx
> +
> +	/* On the original shadow stack, save the caller's shadow
> +	   stack so that we can jump back to the caller directly.  */
> +	leaq	8(%rcx), %rsi
> +
> +	/* Save the current shadow stack pointer in __ssp[0].  */
> +	movq	%rsi, oSSP(%r9)
> +
> +	/* NB: If both the target shadow stack pointer and the current
> +	   shadow stack pointer are on the original shadow stack, we
> +	   can unwind the stack.  Otherwise, find the restore token
> +	   pushed by rstorssp and saveprevssp to restore the target
> +	   shadow stack.  */

OK.

> +	movq	oSSP(%rdx), %rdi
> +	movq	%rdi, %rsi
> +	subq	8(%rsp), %rsi
> +	jb	L(find_restore_token)
> +	cmpq	16(%rsp), %rsi
> +	jae	L(find_restore_token)
> +
> +	/* Check if both shadow stack pointers are on the original
> +	   shadow stack.  */
> +	movq	%rcx, %rsi
> +	subq	8(%rsp), %rsi
> +	jb	L(find_restore_token)
> +	cmpq	16(%rsp), %rsi
> +	jae	L(find_restore_token)
> +
> +	jmp	L(unwind_shadow_stack)
> +
> +L(find_restore_token):
> +	/* Save the target shadow stack pointer.  */
> +	movq	%rdi, %rsi
> +
> +	/* Check if the target shadow stack pointer came from
> +	   __push___start_context.  */
> +	movq	(%rsi), %rax
> +	andq	$-8, %rax
> +	leaq	8(%rsi), %r8
> +	cmpq	%r8, %rax
> +	jne	L(skip_restore_shadow_stack_special)
> +
> +	/* Pop return address from the shadow stack since setcontext
> +	   will not return.   */
> +	movq	$1, %rax
> +	incsspq	%rax

OK.

> +
> +	/* Use the restore stoken to restore the target shadow stack.  */
> +	rstorssp (%rsi)

OK.

> +
> +	jmp	L(unwind_shadow_stack_special)
> +
> +L(skip_restore_shadow_stack_special):
> +	movq	%fs:SSP_BASE_OFFSET, %r8

OK.

> +L(find_restore_token_loop):
> +	/* Check if there is a restore token.  */
> +	movq	-8(%rsi), %rax
> +	andq	$-8, %rax
> +	cmpq	%rsi, %rax
> +	je	L(restore_shadow_stack)
> +
> +	/* Try the next slot.  */
> +	subq	$8, %rsi
> +
> +	/* Don't check restore token below the lowest shadow stack
> +	   base.  */
> +	cmpq	%r8, %rsi
> +	ja	L(find_restore_token_loop)
> +
> +	jmp	L(unwind_shadow_stack)
> +
> +L(restore_shadow_stack):
> +	/* Pop return address from the shadow stack since setcontext
> +	   will not return.   */
> +	movq	$1, %rax
> +	incsspq	%rax
> +
> +	/* Restore the target shadow stack.  */
> +	rstorssp -8(%rsi)
> +
> +L(unwind_shadow_stack_special):
> +	/* Save restore token on the old shadow stack.  */
> +	saveprevssp
> +
> +	/* Get the current shadow stack.  */
> +	rdsspq	%rcx
> +
> +L(unwind_shadow_stack):
> +	add	$24, %RSP_LP
> +	/* Unwind the shadow stack.  */
> +	subq	%rdi, %rcx
> +	je	L(skip_unwind_shadow_stack)
> +	negq	%rcx
> +	shrq	$3, %rcx
> +	movl	$255, %esi

OK.

> +L(loop):
> +	cmpq	%rsi, %rcx
> +	cmovb	%rcx, %rsi
> +	incsspq	%rsi
> +	subq	%rsi, %rcx
> +	ja	L(loop)

OK. Unwind and keep unwinding.

> +
> +L(skip_unwind_shadow_stack):
> +	xorl	%eax, %eax
> +	movq	%rax, (oSSP + 8)(%r9)
> +	movq	%rax, (oSSP + 16)(%r9)
> +
> +	/* Setup registers used for passing args.  */
> +	movq	oRDI(%rdx), %rdi
> +	movq	oRSI(%rdx), %rsi
> +	movq	oRCX(%rdx), %rcx
> +	movq	oR8(%rdx), %r8
> +	movq	oR9(%rdx), %r9
> +
> +	/* Get the return address set with getcontext.  */
> +	movq	oRIP(%rdx), %r10
> +
> +	/* Setup finally %rdx.  */
> +	movq	oRDX(%rdx), %rdx
> +
> +	/* Clear rax to indicate success.  */
> +	xorl	%eax, %eax
> +	/* Jump to the new context directly.  */
> +	jmp	*%r10

OK.

> +
> +L(hlt):
> +	hlt
> +
> +L(no_shstk):
> +#endif
>  	/* The following ret should return to the address set with
>  	getcontext.  Therefore push the address on the stack.  */
>  	movq	oRIP(%rdx), %rcx
> diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
> index 1ef0f742ae..f07eb04962 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
> +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
> @@ -423,4 +423,9 @@
>  #undef LO_HI_LONG
>  #define LO_HI_LONG(val) (val), 0
>  
> +/* Each shadow stack slot takes 8 bytes.  Assuming that each stack
> +   frame takes 256 bytes, this is used to compute shadow stack size
> +   from stack size.  */
> +#define STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT 5

OK.

> +
>  #endif /* linux/x86_64/sysdep.h */
> diff --git a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
> index af3e0e544b..c08b3b8b47 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
> +++ b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
> @@ -35,3 +35,4 @@ oFPREGS		mcontext (fpregs)
>  oSIGMASK	ucontext (uc_sigmask)
>  oFPREGSMEM	ucontext (__fpregs_mem)
>  oMXCSR		ucontext (__fpregs_mem.mxcsr)
> +oSSP		ucontext (__ssp)

OK.

> 

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 07/12] x86/CET: Add tests with legacy non-CET shared objects
  2018-07-21 14:20 ` [PATCH 07/12] x86/CET: Add tests with legacy non-CET shared objects H.J. Lu
@ 2018-07-25  3:21   ` Carlos O'Donell
  2018-07-25  3:22     ` Carlos O'Donell
  2018-07-25 11:46     ` H.J. Lu
  0 siblings, 2 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25  3:21 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> Check binary compatibility of CET-enabled executables:
> 

OK for 2.28.

Gold star for always enabling the tests and having them 

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> 1. When CET-enabled executable is used with legacy non-CET shared object
> at run-time, ld.so should disable SHSTK and put legacy non-CET shared
> objects in legacy bitmap.

OK.

> 2. When IBT-enabled executable dlopens legacy non-CET shared object,
> ld.so should put legacy shared object in legacy bitmap.

OK.

> 3. Use GLIBC_TUNABLES=glibc.tune.x86_shstk=[on|off|permissive] to
> control how SHSTK is enabled.

OK.

> 
> 	* sysdeps/x86/Makefile (tests): Add tst-cet-legacy-1,
> 	tst-cet-legacy-2, tst-cet-legacy-2a, tst-cet-legacy-3,
> 	tst-cet-legacy-4, tst-cet-legacy-4a, tst-cet-legacy-4b
> 	and tst-cet-legacy-4c.
> 	(modules-names): Add tst-cet-legacy-mod-1, tst-cet-legacy-mod-2
> 	and tst-cet-legacy-mod-4.
> 	(CFLAGS-tst-cet-legacy-2.c): New.
> 	(CFLAGS-tst-cet-legacy-mod-1.c): Likewise.
> 	(CFLAGS-tst-cet-legacy-mod-2.c): Likewise.
> 	(CFLAGS-tst-cet-legacy-3.c): Likewise.
> 	(CFLAGS-tst-cet-legacy-4.c): Likewise.
> 	(CFLAGS-tst-cet-legacy-mod-4.c): Likewise.
> 	($(objpfx)tst-cet-legacy-1): Likewise.
> 	($(objpfx)tst-cet-legacy-2): Likewise.
> 	($(objpfx)tst-cet-legacy-2.out): Likewise.
> 	($(objpfx)tst-cet-legacy-2a): Likewise.
> 	($(objpfx)tst-cet-legacy-2a.out): Likewise.
> 	($(objpfx)tst-cet-legacy-4): Likewise.
> 	($(objpfx)tst-cet-legacy-4.out): Likewise.
> 	($(objpfx)tst-cet-legacy-4a): Likewise.
> 	($(objpfx)tst-cet-legacy-4a.out): Likewise.
> 	(tst-cet-legacy-4a-ENV): Likewise.
> 	($(objpfx)tst-cet-legacy-4b): Likewise.
> 	($(objpfx)tst-cet-legacy-4b.out): Likewise.
> 	(tst-cet-legacy-4b-ENV): Likewise.
> 	($(objpfx)tst-cet-legacy-4c): Likewise.
> 	($(objpfx)tst-cet-legacy-4c.out): Likewise.
> 	(tst-cet-legacy-4c-ENV): Likewise.
> 	* sysdeps/x86/tst-cet-legacy-1.c: New file.
> 	* sysdeps/x86/tst-cet-legacy-2.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-2a.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-3.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-4.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-4a.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-4b.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-4c.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-mod-1.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-mod-2.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-mod-4.c: Likewise.
> ---
>  sysdeps/x86/Makefile               | 38 +++++++++++++
>  sysdeps/x86/tst-cet-legacy-1.c     | 44 +++++++++++++++
>  sysdeps/x86/tst-cet-legacy-2.c     | 64 ++++++++++++++++++++++
>  sysdeps/x86/tst-cet-legacy-2a.c    |  1 +
>  sysdeps/x86/tst-cet-legacy-3.c     | 88 ++++++++++++++++++++++++++++++
>  sysdeps/x86/tst-cet-legacy-4.c     | 56 +++++++++++++++++++
>  sysdeps/x86/tst-cet-legacy-4a.c    |  1 +
>  sysdeps/x86/tst-cet-legacy-4b.c    |  1 +
>  sysdeps/x86/tst-cet-legacy-4c.c    |  1 +
>  sysdeps/x86/tst-cet-legacy-mod-1.c | 24 ++++++++
>  sysdeps/x86/tst-cet-legacy-mod-2.c | 24 ++++++++
>  sysdeps/x86/tst-cet-legacy-mod-4.c |  2 +
>  12 files changed, 344 insertions(+)
>  create mode 100644 sysdeps/x86/tst-cet-legacy-1.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-2.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-2a.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-3.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-4.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-4a.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-4b.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-4c.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-1.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-2.c
>  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-4.c
> 
> diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
> index e9b2d0b35d..672bb19489 100644
> --- a/sysdeps/x86/Makefile
> +++ b/sysdeps/x86/Makefile
> @@ -17,6 +17,44 @@ endif
>  ifeq ($(enable-cet),yes)
>  ifeq ($(subdir),elf)
>  sysdep-dl-routines += dl-cet
> +
> +tests += tst-cet-legacy-1 tst-cet-legacy-2 tst-cet-legacy-2a \
> +	 tst-cet-legacy-3 tst-cet-legacy-4

OK.

> +ifneq (no,$(have-tunables))
> +tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c

OK.

> +endif
> +modules-names += tst-cet-legacy-mod-1 tst-cet-legacy-mod-2 \
> +		 tst-cet-legacy-mod-4
> +
> +CFLAGS-tst-cet-legacy-2.c += -fcf-protection=branch
> +CFLAGS-tst-cet-legacy-2a.c += -fcf-protection
> +CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none
> +CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none
> +CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none
> +CFLAGS-tst-cet-legacy-4.c += -fcf-protection=branch
> +CFLAGS-tst-cet-legacy-4a.c += -fcf-protection
> +CFLAGS-tst-cet-legacy-4b.c += -fcf-protection
> +CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none

OK, but I'm slightly disappointed that we can't have all tests
enabled and just have these return UNSUPPORTED. These tests are
effectively hidden behind the enable-cet check and could bitrot
because we aren't compiling them.

> +
> +$(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \
> +		       $(objpfx)tst-cet-legacy-mod-2.so
> +$(objpfx)tst-cet-legacy-2: $(objpfx)tst-cet-legacy-mod-2.so $(libdl)
> +$(objpfx)tst-cet-legacy-2.out: $(objpfx)tst-cet-legacy-mod-1.so
> +$(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so $(libdl)
> +$(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so
> +$(objpfx)tst-cet-legacy-4: $(libdl)
> +$(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so
> +ifneq (no,$(have-tunables))
> +$(objpfx)tst-cet-legacy-4a: $(libdl)
> +$(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so
> +tst-cet-legacy-4a-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=permissive

OK.

> +$(objpfx)tst-cet-legacy-4b: $(libdl)
> +$(objpfx)tst-cet-legacy-4b.out: $(objpfx)tst-cet-legacy-mod-4.so
> +tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=on

OK.

> +$(objpfx)tst-cet-legacy-4c: $(libdl)
> +$(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so
> +tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=off

OK.

> +endif
>  endif
>  
>  # Add -fcf-protection to CFLAGS when CET is enabled.
> diff --git a/sysdeps/x86/tst-cet-legacy-1.c b/sysdeps/x86/tst-cet-legacy-1.c
> new file mode 100644
> index 0000000000..861c09a26e
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-1.c
> @@ -0,0 +1,44 @@
> +/* Check compatibility of CET-enabled executable linked with legacy
> +   shared object.
> +   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 <stdio.h>
> +#include <stdlib.h>
> +
> +extern int in_dso_1 (void);
> +extern int in_dso_2 (void);
> +
> +static int
> +do_test (void)
> +{
> +  if (in_dso_1 () != 0x1234678)
> +    {
> +      puts ("in_dso_1 () != 0x1234678");
> +      exit (1);
> +    }
> +
> +  if (in_dso_2 () != 0xbadbeef)
> +    {
> +      puts ("in_dso_2 () != 0xbadbeef");
> +      exit (1);
> +    }
> +
> +  return 0;
> +}

OK.

> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/x86/tst-cet-legacy-2.c b/sysdeps/x86/tst-cet-legacy-2.c
> new file mode 100644
> index 0000000000..e039a16797
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-2.c
> @@ -0,0 +1,64 @@
> +/* Check compatibility of CET-enabled executable with dlopened legacy
> +   shared object.
> +   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 <dlfcn.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +extern int in_dso_2 (void);
> +
> +static int
> +do_test (void)
> +{
> +  static const char modname[] = "tst-cet-legacy-mod-1.so";
> +  int (*fp) (void);
> +  void *h;
> +
> +  h = dlopen (modname, RTLD_LAZY);
> +  if (h == NULL)
> +    {
> +      printf ("cannot open '%s': %s\n", modname, dlerror ());
> +      exit (1);
> +    }
> +
> +  fp = dlsym (h, "in_dso_1");
> +  if (fp == NULL)
> +    {
> +      printf ("cannot get symbol 'in_dso': %s\n", dlerror ());
> +      exit (1);
> +    }
> +
> +  if (fp () != 0x1234678)
> +    {
> +      puts ("in_dso_1 () != 0x1234678");
> +      exit (1);
> +    }
> +
> +  if (in_dso_2 () != 0xbadbeef)
> +    {
> +      puts ("in_dso_2 () != 0xbadbeef");
> +      exit (1);
> +    }
> +
> +  dlclose (h);
> +
> +  return 0;

OK.

> +}
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/x86/tst-cet-legacy-2a.c b/sysdeps/x86/tst-cet-legacy-2a.c
> new file mode 100644
> index 0000000000..d5aead4303
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-2a.c
> @@ -0,0 +1 @@
> +#include "tst-cet-legacy-2.c"
> diff --git a/sysdeps/x86/tst-cet-legacy-3.c b/sysdeps/x86/tst-cet-legacy-3.c
> new file mode 100644
> index 0000000000..7bf0e656b1
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-3.c
> @@ -0,0 +1,88 @@
> +/* Check compatibility of CET-enabled executable with dlopened legacy
> +   shared object.  Copied from gcc.target/i386/pr81128.c in GCC testsuite.

You cannot copy from GCC and relicense from GPLv3 to GPLv2.1 unless you
owned the original code.

> +   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 <stdio.h>
> +#include <stdlib.h>
> +#include <time.h>
> +
> +int resolver_fn = 0;
> +int resolved_fn = 0;
> +
> +static inline void
> +do_it_right_at_runtime_A (void)
> +{
> +  resolved_fn++;
> +}
> +
> +static inline void
> +do_it_right_at_runtime_B (void)
> +{
> +  resolved_fn++;
> +}
> +
> +static inline void do_it_right_at_runtime (void);
> +
> +void do_it_right_at_runtime (void)
> +  __attribute__ ((ifunc ("resolve_do_it_right_at_runtime")));
> +
> +static void (*resolve_do_it_right_at_runtime (void)) (void)
> +{
> +  srand (time (NULL));
> +  int r = rand ();
> +  resolver_fn++;
> +
> +  /* Use intermediate variable to get a warning for non-matching
> +   * prototype. */
> +  typeof(do_it_right_at_runtime) *func;
> +  if (r & 1)
> +    func = do_it_right_at_runtime_A;
> +  else
> +    func = do_it_right_at_runtime_B;
> +
> +  return (void *) func;
> +}
> +
> +int
> +test (void)
> +{
> +  const unsigned int ITERS = 10;
> +
> +  for (int i = ITERS; i > 0; i--)
> +    {
> +      do_it_right_at_runtime ();
> +    }
> +
> +  if (resolver_fn != 1)
> +    __builtin_abort ();
> +
> +  if (resolved_fn != 10)
> +    __builtin_abort ();
> +
> +  return 0;
> +}
> +
> +#ifndef TEST_MODULE
> +static int
> +do_test (void)
> +{
> +  return test ();
> +}
> +
> +#include <support/test-driver.c>
> +#endif
> diff --git a/sysdeps/x86/tst-cet-legacy-4.c b/sysdeps/x86/tst-cet-legacy-4.c
> new file mode 100644
> index 0000000000..3ead63dd24
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-4.c
> @@ -0,0 +1,56 @@
> +/* Check compatibility of CET-enabled executable with dlopened legacy
> +   shared object.

OK.

> +   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 <dlfcn.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +static int
> +do_test (void)
> +{
> +  static const char modname[] = "tst-cet-legacy-mod-4.so";
> +  int (*fp) (void);
> +  void *h;
> +
> +  h = dlopen (modname, RTLD_LAZY);
> +  if (h == NULL)
> +    {
> +      printf ("cannot open '%s': %s\n", modname, dlerror ());
> +      exit (1);
> +    }
> +
> +  fp = dlsym (h, "test");
> +  if (fp == NULL)
> +    {
> +      printf ("cannot get symbol 'test': %s\n", dlerror ());
> +      exit (1);
> +    }
> +
> +  if (fp () != 0)

OK.

> +    {
> +      puts ("test () != 0");
> +      exit (1);
> +    }
> +
> +  dlclose (h);

OK.

> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/x86/tst-cet-legacy-4a.c b/sysdeps/x86/tst-cet-legacy-4a.c
> new file mode 100644
> index 0000000000..b9bb18c36b
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-4a.c
> @@ -0,0 +1 @@
> +#include "tst-cet-legacy-4.c"

OK.

> diff --git a/sysdeps/x86/tst-cet-legacy-4b.c b/sysdeps/x86/tst-cet-legacy-4b.c
> new file mode 100644
> index 0000000000..b9bb18c36b
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-4b.c
> @@ -0,0 +1 @@
> +#include "tst-cet-legacy-4.c"

Ok.

> diff --git a/sysdeps/x86/tst-cet-legacy-4c.c b/sysdeps/x86/tst-cet-legacy-4c.c
> new file mode 100644
> index 0000000000..b9bb18c36b
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-4c.c
> @@ -0,0 +1 @@
> +#include "tst-cet-legacy-4.c"

OK.

> diff --git a/sysdeps/x86/tst-cet-legacy-mod-1.c b/sysdeps/x86/tst-cet-legacy-mod-1.c
> new file mode 100644
> index 0000000000..09762bce13
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-mod-1.c
> @@ -0,0 +1,24 @@
> +/* Check compatibility of CET-enabled executable with legacy shared
> +   object.
> +   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/>.  */
> +
> +int
> +in_dso_1 (void)
> +{
> +  return 0x1234678;
> +}
> diff --git a/sysdeps/x86/tst-cet-legacy-mod-2.c b/sysdeps/x86/tst-cet-legacy-mod-2.c
> new file mode 100644
> index 0000000000..1c8de443f6
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-mod-2.c
> @@ -0,0 +1,24 @@
> +/* Check compatibility of CET-enabled executable with legacy shared
> +   object.
> +   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/>.  */
> +
> +int
> +in_dso_2 (void)
> +{
> +  return 0xbadbeef;
> +}

OK.

> diff --git a/sysdeps/x86/tst-cet-legacy-mod-4.c b/sysdeps/x86/tst-cet-legacy-mod-4.c
> new file mode 100644
> index 0000000000..a93c2fe4a7
> --- /dev/null
> +++ b/sysdeps/x86/tst-cet-legacy-mod-4.c
> @@ -0,0 +1,2 @@
> +#define TEST_MODULE
> +#include "tst-cet-legacy-3.c"

OK.

> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 07/12] x86/CET: Add tests with legacy non-CET shared objects
  2018-07-25  3:21   ` Carlos O'Donell
@ 2018-07-25  3:22     ` Carlos O'Donell
  2018-07-25 11:46     ` H.J. Lu
  1 sibling, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25  3:22 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/24/2018 11:21 PM, Carlos O'Donell wrote:
> On 07/21/2018 10:20 AM, H.J. Lu wrote:
>> Check binary compatibility of CET-enabled executables:
>>
> 
> OK for 2.28.
> 
> Gold star for always enabling the tests and having them 

... run and return UNSUPPORTED.

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 08/12] Add a test for swapcontext with a wrapper
  2018-07-21 14:20 ` [PATCH 08/12] Add a test for swapcontext with a wrapper H.J. Lu
@ 2018-07-25  3:27   ` Carlos O'Donell
  2018-07-25 11:50     ` H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25  3:27 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> Check swapcontext works with a wrapper.
> 
> 	* stdlib/Makefile (tests): Add tst-swapcontext1.
> 	* stdlib/tst-swapcontext1.c: New test.

OK for 2.28 if you can answer the licensing question.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  stdlib/Makefile           |  3 +-
>  stdlib/tst-swapcontext1.c | 92 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 94 insertions(+), 1 deletion(-)
>  create mode 100644 stdlib/tst-swapcontext1.c
> 
> diff --git a/stdlib/Makefile b/stdlib/Makefile
> index b5e55b0a55..bc8929f2b9 100644
> --- a/stdlib/Makefile
> +++ b/stdlib/Makefile
> @@ -84,7 +84,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
>  		   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 		    \
> -		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign
> +		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
> +		   tst-swapcontext1

OK.

>  
>  tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
>  		   tst-tls-atexit tst-tls-atexit-nodelete
> diff --git a/stdlib/tst-swapcontext1.c b/stdlib/tst-swapcontext1.c
> new file mode 100644
> index 0000000000..6dd52f22a6
> --- /dev/null
> +++ b/stdlib/tst-swapcontext1.c
> @@ -0,0 +1,92 @@
> +/* Check swapcontext wrapper.
> +   Modified from c-c++-common/asan/swapcontext-test-1.c in GCC testsuite.

I'm not sure we can relicense a test like this or copy the test.

> +   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 <stdio.h>
> +#include <ucontext.h>
> +#include <unistd.h>
> +
> +__attribute__((noinline, noclone))
> +__INDIRECT_RETURN
> +int
> +myswapcontext (ucontext_t *oucp, ucontext_t *ucp)
> +{
> +  int res = swapcontext (oucp, ucp);
> +  return res;
> +}
> +
> +ucontext_t orig_context;
> +ucontext_t child_context;
> +
> +void
> +Child (int mode)
> +{
> +  char x[32] = {0};  /* Stack gets poisoned. */
> +  printf("Child: %p\n", x);
> +  /* (a) Do nothing, just return to parent function.
> +     (b) Jump into the original function. Stack remains poisoned unless we do
> +     something. */
> +  if (mode == 1)
> +    {
> +      if (myswapcontext (&child_context, &orig_context) < 0)
> +	{
> +	  perror ("swapcontext");
> +	  _exit (0);
> +	}
> +    }

OK.

> +}
> +
> +int
> +Run (int arg, int mode)
> +{
> +  int i;
> +  const int kStackSize = 1 << 20;
> +  char child_stack[kStackSize + 1];
> +  printf ("Child stack: %p\n", child_stack);
> +  /* Setup child context. */
> +  getcontext (&child_context);
> +  child_context.uc_stack.ss_sp = child_stack;
> +  child_context.uc_stack.ss_size = kStackSize / 2;
> +  if (mode == 0)
> +    child_context.uc_link = &orig_context;
> +  makecontext (&child_context, (void (*)(void))Child, 1, mode);
> +  if (myswapcontext (&orig_context, &child_context) < 0)
> +    {
> +      perror("swapcontext");
> +      return 0;
> +    }
> +  /* Touch childs's stack to make sure it's unpoisoned. */
> +  for (i = 0; i < kStackSize; i++)
> +    child_stack[i] = i;
> +  return child_stack[arg];

OK.

> +}
> +
> +volatile int zero = 0;
> +
> +static int
> +do_test (void)
> +{
> +  int ret = 0;
> +  ret += Run (zero, 0);
> +  fprintf (stderr, "Test1 passed\n");
> +  ret += Run (zero, 1);
> +  fprintf (stderr, "Test2 passed\n");
> +  return ret;
> +}

OK.

> +
> +#include <support/test-driver.c>
> 

OK.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/12] Add a test for multiple makecontext calls
  2018-07-21 14:20 ` [PATCH 09/12] Add a test for multiple makecontext calls H.J. Lu
@ 2018-07-25  3:31   ` Carlos O'Donell
  2018-07-25 11:55     ` H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25  3:31 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> Check multiple makecontext calls.
> 
> 	* stdlib/Makefile (tests): Add tst-swapcontext2.
> 	* stdlib/tst-swapcontext2.c: New test.

OK for 2.28.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  stdlib/Makefile           |   2 +-
>  stdlib/tst-swapcontext2.c | 108 ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 109 insertions(+), 1 deletion(-)
>  create mode 100644 stdlib/tst-swapcontext2.c
> 
> diff --git a/stdlib/Makefile b/stdlib/Makefile
> index bc8929f2b9..40d07ade20 100644
> --- a/stdlib/Makefile
> +++ b/stdlib/Makefile
> @@ -85,7 +85,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
>  		   test-at_quick_exit-race test-cxa_atexit-race             \
>  		   test-on_exit-race test-dlclose-exit-race 		    \
>  		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
> -		   tst-swapcontext1
> +		   tst-swapcontext1 tst-swapcontext2

OK.

>  
>  tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
>  		   tst-tls-atexit tst-tls-atexit-nodelete
> diff --git a/stdlib/tst-swapcontext2.c b/stdlib/tst-swapcontext2.c
> new file mode 100644
> index 0000000000..7802df4868
> --- /dev/null
> +++ b/stdlib/tst-swapcontext2.c
> @@ -0,0 +1,108 @@
> +/* Check multiple makecontext calls.
> +   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 <stdio.h>
> +#include <stdlib.h>
> +#include <ucontext.h>
> +
> +static ucontext_t uctx_main, uctx_func1, uctx_func2;
> +const char *str1 = "\e[31mswapcontext(&uctx_func1, &uctx_main)\e[0m";
> +const char *str2 = "\e[34mswapcontext(&uctx_func2, &uctx_main)\e[0m";
> +const char *fmt1 = "\e[31m";
> +const char *fmt2 = "\e[34m";
> 

OK.

> +#define handle_error(msg) \
> +  do { perror(msg); exit(EXIT_FAILURE); } while (0)
> +
> +__attribute__((noinline, noclone))
> +static void
> +func4(ucontext_t *uocp, ucontext_t *ucp, const char *str, const char *fmt)
> +{
> +  printf("      %sfunc4: %s\e[0m\n", fmt, str);
> +  if (swapcontext(uocp, ucp) == -1)
> +    handle_error("swapcontext");
> +  printf("      %sfunc4: returning\e[0m\n", fmt);
> +}
> +

OK.

> +__attribute__((noinline, noclone))
> +static void
> +func3(ucontext_t *uocp, ucontext_t *ucp, const char *str, const char *fmt)
> +{
> +  printf("    %sfunc3: func4(uocp, ucp, str)\e[0m\n", fmt);
> +  func4(uocp, ucp, str, fmt);
> +  printf("    %sfunc3: returning\e[0m\n", fmt);
> +}
> +

OK.

> +__attribute__((noinline, noclone))
> +static void
> +func1(void)
> +{
> +  while ( 1 )
> +    {
> +      printf("  \e[31mfunc1: func3(&uctx_func1, &uctx_main, str1)\e[0m\n");
> +      func3( &uctx_func1, &uctx_main, str1, fmt1);
> +    }
> +}
> +

OK.

> +__attribute__((noinline, noclone))
> +static void
> +func2(void)
> +{
> +  while ( 1 )
> +    {
> +      printf("  \e[34mfunc2: func3(&uctx_func2, &uctx_main, str2)\e[0m\n");
> +      func3(&uctx_func2, &uctx_main, str2, fmt2);
> +    }
> +}

OK.

> +
> +static int
> +do_test (void)
> +{
> +  char func1_stack[16384];
> +  char func2_stack[16384];
> +  int i;
> +
> +  if (getcontext(&uctx_func1) == -1)
> +    handle_error("getcontext");
> +  uctx_func1.uc_stack.ss_sp = func1_stack;
> +  uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
> +  uctx_func1.uc_link = &uctx_main;
> +  makecontext(&uctx_func1, func1, 0);

OK.

> +
> +  if (getcontext(&uctx_func2) == -1)
> +    handle_error("getcontext");
> +  uctx_func2.uc_stack.ss_sp = func2_stack;
> +  uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
> +  uctx_func2.uc_link = &uctx_func1;
> +  makecontext(&uctx_func2, func2, 0);

OK.

> +
> +  for ( i = 0; i < 4; i++ )
> +    {
> +      if (swapcontext(&uctx_main, &uctx_func1) == -1)
> +	handle_error("swapcontext");
> +      printf("        \e[35mmain: swapcontext(&uctx_main, &uctx_func2)\n\e[0m");
> +      if (swapcontext(&uctx_main, &uctx_func2) == -1)
> +	handle_error("swapcontext");
> +      printf("        \e[35mmain: swapcontext(&uctx_main, &uctx_func1)\n\e[0m");

OK.

> +    }
> +
> +  printf("main: exiting\n");
> +  exit(EXIT_SUCCESS);
> +}
> +
> +#include <support/test-driver.c>
> 

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-21 14:20 ` [PATCH 10/12] Add another test for setcontext H.J. Lu
@ 2018-07-25  3:36   ` Carlos O'Donell
  2018-07-25 16:21   ` Florian Weimer
  1 sibling, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25  3:36 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> 	* stdlib/Makefile (tests): Add tst-setcontext4.
> 	* stdlib/tst-setcontext4.c: New file.

OK for 2.28.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  stdlib/Makefile          |   2 +-
>  stdlib/tst-setcontext4.c | 217 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 218 insertions(+), 1 deletion(-)
>  create mode 100644 stdlib/tst-setcontext4.c
> 
> diff --git a/stdlib/Makefile b/stdlib/Makefile
> index 40d07ade20..73d0e7c2a2 100644
> --- a/stdlib/Makefile
> +++ b/stdlib/Makefile
> @@ -85,7 +85,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
>  		   test-at_quick_exit-race test-cxa_atexit-race             \
>  		   test-on_exit-race test-dlclose-exit-race 		    \
>  		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
> -		   tst-swapcontext1 tst-swapcontext2
> +		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4

OK.

>  
>  tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
>  		   tst-tls-atexit tst-tls-atexit-nodelete
> diff --git a/stdlib/tst-setcontext4.c b/stdlib/tst-setcontext4.c
> new file mode 100644
> index 0000000000..64d3fc9137
> --- /dev/null
> +++ b/stdlib/tst-setcontext4.c
> @@ -0,0 +1,217 @@
> +/* Testcase checks, if setcontext(), swapcontext() restores signal-mask
> +   and if pending signals are delivered after those calls.

OK.

> +   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 <stdio.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <signal.h>
> +#include <ucontext.h>
> +#include <unistd.h>
> +
> +volatile int global;
> +volatile sig_atomic_t handlerCalled;
> +
> +static void
> +check (const char *funcName)
> +{
> +  sigset_t set;
> +
> +  /* check if SIGUSR2 is unblocked after setcontext-call.  */
> +  sigprocmask (SIG_BLOCK, NULL, &set);
> +
> +  if (sigismember (&set, SIGUSR2) != 0)
> +    {
> +      printf ("FAIL: SIGUSR2 is blocked after %s.\n", funcName);
> +      exit (1);

OK.

> +    }
> +
> +  if (sigismember (&set, SIGUSR1) != 1)
> +    {
> +      printf ("FAIL: SIGUSR1 is not blocked after %s.\n", funcName);
> +      exit (1);

OK.

> +    }
> +}
> +
> +static void
> +signalmask (int how, int signum)
> +{
> +  sigset_t set;
> +  sigemptyset (&set);
> +  sigaddset (&set, signum);
> +  if (sigprocmask (how, &set, NULL) != 0)
> +    {
> +      printf ("FAIL: sigprocmaks (%d, %d, NULL): %m\n", how, signum);
> +      exit (1);
> +    }
> +}
> +
> +static void
> +signalpending (int signum, const char *msg)
> +{
> +  sigset_t set;
> +  sigemptyset (&set);
> +  if (sigpending (&set) != 0)
> +    {
> +      printf ("FAIL: sigpending: %m\n");
> +      exit (1);
> +    }
> +  if (sigismember (&set, SIGUSR2) != 1)
> +    {
> +      printf ("FAIL: Signal %d is not pending %s\n", signum, msg);
> +      exit (1);
> +    }
> +}
> +
> +static void
> +handler (int __attribute__ ((unused)) signum)
> +{
> +  handlerCalled ++;
> +}
> +

OK.

> +static int
> +do_test (void)
> +{
> +  ucontext_t ctx, oldctx;
> +  struct sigaction action;
> +  pid_t pid;
> +
> +  pid = getpid ();
> +
> +  /* unblock SIGUSR2 */
> +  signalmask (SIG_UNBLOCK, SIGUSR2);
> +
> +  /* block SIGUSR1 */
> +  signalmask (SIG_BLOCK, SIGUSR1);
> +
> +  /* register handler for SIGUSR2  */
> +  action.sa_flags = 0;
> +  action.sa_handler = handler;
> +  sigemptyset (&action.sa_mask);
> +  sigaction (SIGUSR2, &action, NULL);

OK.

> +
> +  if (getcontext (&ctx) != 0)
> +    {
> +      printf ("FAIL: getcontext: %m\n");
> +      exit (1);
> +    }
> +

OK.

> +  global++;
> +
> +  if (global == 1)
> +    {
> +      puts ("after getcontext");
> +
> +      /* block SIGUSR2  */
> +      signalmask (SIG_BLOCK, SIGUSR2);
> +
> +      /* send SIGUSR2 to me  */
> +      handlerCalled = 0;
> +      kill (pid, SIGUSR2);
> +
> +      /* was SIGUSR2 handler called?  */
> +      if (handlerCalled != 0)
> +	{
> +	  puts ("FAIL: signal handler was called, but signal was blocked.");
> +	  exit (1);
> +	}
> +
> +      /* is SIGUSR2 pending?  */
> +      signalpending (SIGUSR2, "before setcontext");
> +
> +      /* SIGUSR2 will be unblocked by setcontext-call.  */
> +      if (setcontext (&ctx) != 0)
> +	{
> +	  printf ("FAIL: setcontext: %m\n");
> +	  exit (1);
> +	}

OK.

> +    }
> +  else if (global == 2)
> +    {
> +      puts ("after setcontext");
> +
> +      /* check SIGUSR1/2  */
> +      check ("setcontext");
> +
> +      /* was SIGUSR2 handler called? */
> +      if (handlerCalled != 1)
> +	{
> +	  puts ("FAIL: signal handler was not called after setcontext.");
> +	  exit (1);
> +	}

OK.

> +
> +      /* block SIGUSR2 */
> +      signalmask (SIG_BLOCK, SIGUSR2);
> +
> +      /* send SIGUSR2 to me  */
> +      handlerCalled = 0;
> +      kill (pid, SIGUSR2);
> +
> +      /* was SIGUSR2 handler called?  */
> +      if (handlerCalled != 0)
> +	{
> +	  puts ("FAIL: signal handler was called, but signal was blocked.");
> +	  exit (1);
> +	}
> +
> +      /* is SIGUSR2 pending?  */
> +      signalpending (SIGUSR2, "before swapcontext");
> +
> +      if (swapcontext (&oldctx, &ctx) != 0)
> +	{
> +	  printf ("FAIL: swapcontext: %m\n");
> +	  exit (1);
> +	}
> +
> +      puts ("FAIL: returned from (&oldctx, &ctx)");
> +      exit (1);
> +    }
> +  else if ( global != 3 )
> +    {
> +      puts ("FAIL: 'global' not incremented three times");
> +      exit (1);

OK.

> +    }
> +
> +  puts ("after swapcontext");
> +  /* check SIGUSR1/2  */
> +  check ("swapcontext");
> +
> +  /* was SIGUSR2 handler called? */
> +  if (handlerCalled != 1)
> +    {
> +      puts ("FAIL: signal handler was not called after swapcontext.");
> +      exit (1);
> +    }
> +
> +  /* check sigmask in old context of swapcontext-call  */
> +  if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1)
> +    {
> +      puts ("FAIL: SIGUSR2 is not blocked in oldctx.uc_sigmask.");
> +      exit (1);
> +    }
> +
> +  if (sigismember (&oldctx.uc_sigmask, SIGUSR1) != 1)
> +    {
> +      puts ("FAIL: SIGUSR1 is not blocked in oldctx.uc_sigmaks.");
> +      exit (1);
> +    }
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> 

OK.

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 11/12] Add a test for multiple setcontext calls
  2018-07-21 14:21 ` [PATCH 11/12] Add a test for multiple setcontext calls H.J. Lu
@ 2018-07-25  3:38   ` Carlos O'Donell
  0 siblings, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25  3:38 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> Check multiple setcontext calls.
> 
> 	* stdlib/Makefile ((tests): Add tst-setcontext5.
> 	* stdlib/tst-setcontext5.c: New file.

OK for 2.28.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>.


> ---
>  stdlib/Makefile          |  3 +-
>  stdlib/tst-setcontext5.c | 88 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 90 insertions(+), 1 deletion(-)
>  create mode 100644 stdlib/tst-setcontext5.c
> 
> diff --git a/stdlib/Makefile b/stdlib/Makefile
> index 73d0e7c2a2..8db4f1d35a 100644
> --- a/stdlib/Makefile
> +++ b/stdlib/Makefile
> @@ -85,7 +85,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
>  		   test-at_quick_exit-race test-cxa_atexit-race             \
>  		   test-on_exit-race test-dlclose-exit-race 		    \
>  		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
> -		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4
> +		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4 \
> +		   tst-setcontext5

OK.

>  
>  tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
>  		   tst-tls-atexit tst-tls-atexit-nodelete
> diff --git a/stdlib/tst-setcontext5.c b/stdlib/tst-setcontext5.c
> new file mode 100644
> index 0000000000..7dcc15cb8e
> --- /dev/null
> +++ b/stdlib/tst-setcontext5.c
> @@ -0,0 +1,88 @@
> +/* Check multiple setcontext calls.

OK.

> +   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 <stdio.h>
> +#include <stdlib.h>
> +#include <ucontext.h>
> +#include <unistd.h>
> +
> +static ucontext_t ctx[2];
> +static volatile int done;
> +
> +static void f2 (void);
> +
> +static void
> +__attribute__ ((noinline, noclone))
> +f1 (void)
> +{
> +  printf ("start f1\n");
> +  f2 ();
> +}

OK.

> +
> +static void
> +__attribute__ ((noinline, noclone))
> +f2 (void)
> +{
> +  printf ("start f2\n");
> +  if (setcontext (&ctx[1]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +}

OK.

> +
> +static void
> +f3 (void)
> +{
> +  printf ("start f3\n");
> +  if (done)
> +    exit (EXIT_SUCCESS);
> +  done = 1;
> +  if (setcontext (&ctx[0]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +}

OK.

> +
> +static int
> +do_test (void)
> +{
> +  char st1[32768];
> +
> +  puts ("making contexts");
> +  if (getcontext (&ctx[0]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  if (getcontext (&ctx[1]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  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)) f3, 0);
> +  f1 ();
> +  puts ("FAIL: returned from f1 ()");
> +  exit (EXIT_FAILURE);
> +}
> +
> +#include <support/test-driver.c>

OK.

> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 12/12] Add tests for setcontext on the context from makecontext
  2018-07-21 14:20 ` [PATCH 12/12] Add tests for setcontext on the context from makecontext H.J. Lu
@ 2018-07-25  3:51   ` Carlos O'Donell
  2018-07-25 12:14     ` H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25  3:51 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha

On 07/21/2018 10:20 AM, H.J. Lu wrote:
> 	* stdlib/Makefile ((tests): Add tst-setcontext6, tst-setcontext7,
> 	tst-setcontext8 and tst-setcontext9.
> 	* stdlib/tst-setcontext6.c: New file.
> 	* stdlib/tst-setcontext7.c: Likewise.
> 	* stdlib/tst-setcontext8.c: Likewise.
> 	* stdlib/tst-setcontext9.c: Likewise.

OK for 2.28 if you use atomics instead of volatile int.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  stdlib/Makefile          |   3 +-
>  stdlib/tst-setcontext6.c |  76 +++++++++++++++++++++++++++++
>  stdlib/tst-setcontext7.c |  96 +++++++++++++++++++++++++++++++++++++
>  stdlib/tst-setcontext8.c |  81 +++++++++++++++++++++++++++++++
>  stdlib/tst-setcontext9.c | 100 +++++++++++++++++++++++++++++++++++++++
>  5 files changed, 355 insertions(+), 1 deletion(-)
>  create mode 100644 stdlib/tst-setcontext6.c
>  create mode 100644 stdlib/tst-setcontext7.c
>  create mode 100644 stdlib/tst-setcontext8.c
>  create mode 100644 stdlib/tst-setcontext9.c
> 
> diff --git a/stdlib/Makefile b/stdlib/Makefile
> index 8db4f1d35a..638306bb5c 100644
> --- a/stdlib/Makefile
> +++ b/stdlib/Makefile
> @@ -86,7 +86,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
>  		   test-on_exit-race test-dlclose-exit-race 		    \
>  		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
>  		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4 \
> -		   tst-setcontext5
> +		   tst-setcontext5 tst-setcontext6 tst-setcontext7 \
> +		   tst-setcontext8 tst-setcontext9

OK.

>  
>  tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
>  		   tst-tls-atexit tst-tls-atexit-nodelete
> diff --git a/stdlib/tst-setcontext6.c b/stdlib/tst-setcontext6.c
> new file mode 100644
> index 0000000000..c719e2d678
> --- /dev/null
> +++ b/stdlib/tst-setcontext6.c
> @@ -0,0 +1,76 @@
> +/* Check getcontext and setcontext on the context from makecontext.

OK.

> +   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 <stdio.h>
> +#include <stdlib.h>
> +#include <ucontext.h>
> +#include <unistd.h>
> +
> +static ucontext_t ctx[3];
> +static volatile int done;

OK, but I'd prefer a way around this needing to be volatile, like using atomics.

> +
> +static void
> +f1 (void)
> +{
> +  printf ("start f1\n");
> +  if (!done)
> +    {
> +      if (getcontext (&ctx[2]) != 0)
> +	{
> +	  printf ("%s: getcontext: %m\n", __FUNCTION__);
> +	  exit (EXIT_FAILURE);
> +	}
> +      if (done)
> +	exit (EXIT_SUCCESS);
> +    }
> +  done++;
> +  if (setcontext (&ctx[2]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +}
> +
> +static int
> +do_test (void)
> +{
> +  char st1[32768];
> +  puts ("making contexts");
> +  if (getcontext (&ctx[0]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  if (getcontext (&ctx[1]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);

OK.

> +    }
> +  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);
> +  if (setcontext (&ctx[1]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }

OK.

> +  exit (EXIT_FAILURE);
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/stdlib/tst-setcontext7.c b/stdlib/tst-setcontext7.c
> new file mode 100644
> index 0000000000..e331e511ef
> --- /dev/null
> +++ b/stdlib/tst-setcontext7.c
> @@ -0,0 +1,96 @@
> +/* Check setcontext on the context from makecontext.

OK.

> +   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 <stdio.h>
> +#include <stdlib.h>
> +#include <ucontext.h>
> +#include <unistd.h>
> +
> +static ucontext_t ctx[5];
> +static volatile int done;

Likewise (see above).

> +
> +static void
> +f1 (void)
> +{
> +  puts ("start f1");
> +  if (!done)
> +    {
> +      if (getcontext (&ctx[2]) != 0)
> +	{
> +	  printf ("%s: getcontext: %m\n", __FUNCTION__);
> +	  exit (EXIT_FAILURE);
> +	}
> +      if (done)
> +	{
> +	  puts ("set context in f1");
> +	  if (setcontext (&ctx[3]) != 0)
> +	    {
> +	      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +	      exit (EXIT_FAILURE);
> +	    }
> +	}

OK.

> +    }
> +  done++;
> +  puts ("swap contexts in f1");
> +  if (swapcontext (&ctx[4], &ctx[2]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  puts ("end f1");
> +  exit (done == 2 ? EXIT_SUCCESS : EXIT_FAILURE);

OK.

> +}
> +
> +static int
> +do_test (void)
> +{
> +  char st1[32768];
> +  puts ("making contexts");
> +  if (getcontext (&ctx[0]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  if (getcontext (&ctx[1]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  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);
> +  puts ("swap contexts");
> +  if (swapcontext (&ctx[3], &ctx[1]) != 0)

OK.

> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  if (done != 1)
> +    exit (EXIT_FAILURE);
> +  done++;
> +  puts ("set context");
> +  if (setcontext (&ctx[4]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  exit (EXIT_FAILURE);
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/stdlib/tst-setcontext8.c b/stdlib/tst-setcontext8.c
> new file mode 100644
> index 0000000000..a7febf6c67
> --- /dev/null
> +++ b/stdlib/tst-setcontext8.c
> @@ -0,0 +1,81 @@
> +/* Check getcontext and setcontext on the context from makecontext.

OK.

> +   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 <stdio.h>
> +#include <stdlib.h>
> +#include <ucontext.h>
> +#include <unistd.h>
> +
> +static ucontext_t ctx[3];
> +static volatile int done;
> +
> +static void
> +__attribute__((noinline, noclone))
> +f2 (void)
> +{
> +  printf ("start f2\n");
> +  done++;
> +  if (setcontext (&ctx[2]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +}
> +
> +static void
> +f1 (void)
> +{
> +  printf ("start f1\n");
> +  if (getcontext (&ctx[2]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  if (done)
> +    exit (EXIT_SUCCESS);
> +  f2 ();
> +}
> +

OK.

> +static int
> +do_test (void)
> +{
> +  char st1[32768];
> +  puts ("making contexts");
> +  if (getcontext (&ctx[0]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  if (getcontext (&ctx[1]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  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);

OK.

> +  if (setcontext (&ctx[1]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  exit (EXIT_FAILURE);
> +}
> +
> +#include <support/test-driver.c>

OK. Similar to the original one.

> diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
> new file mode 100644
> index 0000000000..53609d4b10
> --- /dev/null
> +++ b/stdlib/tst-setcontext9.c
> @@ -0,0 +1,100 @@
> +/* Check setcontext on the context from 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 <stdio.h>
> +#include <stdlib.h>
> +#include <ucontext.h>
> +#include <unistd.h>
> +
> +static ucontext_t ctx[5];
> +static volatile int done;
> +
> +static void
> +__attribute__((noinline, noclone))
> +f2 (void)
> +{
> +  done++;
> +  puts ("swap contexts in f2");
> +  if (swapcontext (&ctx[4], &ctx[2]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  puts ("end f2");
> +  exit (done == 2 ? EXIT_SUCCESS : EXIT_FAILURE);
> +}
> +
> +static void
> +f1 (void)
> +{
> +  puts ("start f1");
> +  if (getcontext (&ctx[2]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  if (done)

OK.

> +    {
> +      puts ("set context in f1");
> +      if (setcontext (&ctx[3]) != 0)
> +	{
> +	  printf ("%s: setcontext: %m\n", __FUNCTION__);
> +	  exit (EXIT_FAILURE);
> +	}
> +    }
> +  f2 ();
> +}
> +
> +static int
> +do_test (void)
> +{
> +  char st1[32768];
> +  puts ("making contexts");
> +  if (getcontext (&ctx[0]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  if (getcontext (&ctx[1]) != 0)
> +    {
> +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  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);
> +  puts ("swap contexts");
> +  if (swapcontext (&ctx[3], &ctx[1]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  if (done != 1)
> +    exit (EXIT_FAILURE);
> +  done++;
> +  puts ("set context");
> +  if (setcontext (&ctx[4]) != 0)
> +    {
> +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> +      exit (EXIT_FAILURE);
> +    }
> +  exit (EXIT_FAILURE);
> +}
> +
> +#include <support/test-driver.c>
> 

OK.

Cheers,Carlos.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 07/12] x86/CET: Add tests with legacy non-CET shared objects
  2018-07-25  3:21   ` Carlos O'Donell
  2018-07-25  3:22     ` Carlos O'Donell
@ 2018-07-25 11:46     ` H.J. Lu
  2018-07-25 14:28       ` Carlos O'Donell
  1 sibling, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-25 11:46 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: libc-alpha

On Tue, Jul 24, 2018 at 11:21:22PM -0400, Carlos O'Donell wrote:
> On 07/21/2018 10:20 AM, H.J. Lu wrote:
> > Check binary compatibility of CET-enabled executables:
> > 
> 
> OK for 2.28.
> 
> Gold star for always enabling the tests and having them 
> 
> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
> 
> > 1. When CET-enabled executable is used with legacy non-CET shared object
> > at run-time, ld.so should disable SHSTK and put legacy non-CET shared
> > objects in legacy bitmap.
> 
> OK.
> 
> > 2. When IBT-enabled executable dlopens legacy non-CET shared object,
> > ld.so should put legacy shared object in legacy bitmap.
> 
> OK.
> 
> > 3. Use GLIBC_TUNABLES=glibc.tune.x86_shstk=[on|off|permissive] to
> > control how SHSTK is enabled.
> 
> OK.
> 
> > 
> > 	* sysdeps/x86/Makefile (tests): Add tst-cet-legacy-1,
> > 	tst-cet-legacy-2, tst-cet-legacy-2a, tst-cet-legacy-3,
> > 	tst-cet-legacy-4, tst-cet-legacy-4a, tst-cet-legacy-4b
> > 	and tst-cet-legacy-4c.
> > 	(modules-names): Add tst-cet-legacy-mod-1, tst-cet-legacy-mod-2
> > 	and tst-cet-legacy-mod-4.
> > 	(CFLAGS-tst-cet-legacy-2.c): New.
> > 	(CFLAGS-tst-cet-legacy-mod-1.c): Likewise.
> > 	(CFLAGS-tst-cet-legacy-mod-2.c): Likewise.
> > 	(CFLAGS-tst-cet-legacy-3.c): Likewise.
> > 	(CFLAGS-tst-cet-legacy-4.c): Likewise.
> > 	(CFLAGS-tst-cet-legacy-mod-4.c): Likewise.
> > 	($(objpfx)tst-cet-legacy-1): Likewise.
> > 	($(objpfx)tst-cet-legacy-2): Likewise.
> > 	($(objpfx)tst-cet-legacy-2.out): Likewise.
> > 	($(objpfx)tst-cet-legacy-2a): Likewise.
> > 	($(objpfx)tst-cet-legacy-2a.out): Likewise.
> > 	($(objpfx)tst-cet-legacy-4): Likewise.
> > 	($(objpfx)tst-cet-legacy-4.out): Likewise.
> > 	($(objpfx)tst-cet-legacy-4a): Likewise.
> > 	($(objpfx)tst-cet-legacy-4a.out): Likewise.
> > 	(tst-cet-legacy-4a-ENV): Likewise.
> > 	($(objpfx)tst-cet-legacy-4b): Likewise.
> > 	($(objpfx)tst-cet-legacy-4b.out): Likewise.
> > 	(tst-cet-legacy-4b-ENV): Likewise.
> > 	($(objpfx)tst-cet-legacy-4c): Likewise.
> > 	($(objpfx)tst-cet-legacy-4c.out): Likewise.
> > 	(tst-cet-legacy-4c-ENV): Likewise.
> > 	* sysdeps/x86/tst-cet-legacy-1.c: New file.
> > 	* sysdeps/x86/tst-cet-legacy-2.c: Likewise.
> > 	* sysdeps/x86/tst-cet-legacy-2a.c: Likewise.
> > 	* sysdeps/x86/tst-cet-legacy-3.c: Likewise.
> > 	* sysdeps/x86/tst-cet-legacy-4.c: Likewise.
> > 	* sysdeps/x86/tst-cet-legacy-4a.c: Likewise.
> > 	* sysdeps/x86/tst-cet-legacy-4b.c: Likewise.
> > 	* sysdeps/x86/tst-cet-legacy-4c.c: Likewise.
> > 	* sysdeps/x86/tst-cet-legacy-mod-1.c: Likewise.
> > 	* sysdeps/x86/tst-cet-legacy-mod-2.c: Likewise.
> > 	* sysdeps/x86/tst-cet-legacy-mod-4.c: Likewise.
> > ---
> >  sysdeps/x86/Makefile               | 38 +++++++++++++
> >  sysdeps/x86/tst-cet-legacy-1.c     | 44 +++++++++++++++
> >  sysdeps/x86/tst-cet-legacy-2.c     | 64 ++++++++++++++++++++++
> >  sysdeps/x86/tst-cet-legacy-2a.c    |  1 +
> >  sysdeps/x86/tst-cet-legacy-3.c     | 88 ++++++++++++++++++++++++++++++
> >  sysdeps/x86/tst-cet-legacy-4.c     | 56 +++++++++++++++++++
> >  sysdeps/x86/tst-cet-legacy-4a.c    |  1 +
> >  sysdeps/x86/tst-cet-legacy-4b.c    |  1 +
> >  sysdeps/x86/tst-cet-legacy-4c.c    |  1 +
> >  sysdeps/x86/tst-cet-legacy-mod-1.c | 24 ++++++++
> >  sysdeps/x86/tst-cet-legacy-mod-2.c | 24 ++++++++
> >  sysdeps/x86/tst-cet-legacy-mod-4.c |  2 +
> >  12 files changed, 344 insertions(+)
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-1.c
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-2.c
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-2a.c
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-3.c
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-4.c
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-4a.c
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-4b.c
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-4c.c
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-1.c
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-2.c
> >  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-4.c
> > 
> > diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
> > index e9b2d0b35d..672bb19489 100644
> > --- a/sysdeps/x86/Makefile
> > +++ b/sysdeps/x86/Makefile
> > @@ -17,6 +17,44 @@ endif
> >  ifeq ($(enable-cet),yes)
> >  ifeq ($(subdir),elf)
> >  sysdep-dl-routines += dl-cet
> > +
> > +tests += tst-cet-legacy-1 tst-cet-legacy-2 tst-cet-legacy-2a \
> > +	 tst-cet-legacy-3 tst-cet-legacy-4
> 
> OK.
> 
> > +ifneq (no,$(have-tunables))
> > +tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c
> 
> OK.
> 
> > +endif
> > +modules-names += tst-cet-legacy-mod-1 tst-cet-legacy-mod-2 \
> > +		 tst-cet-legacy-mod-4
> > +
> > +CFLAGS-tst-cet-legacy-2.c += -fcf-protection=branch
> > +CFLAGS-tst-cet-legacy-2a.c += -fcf-protection
> > +CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none
> > +CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none
> > +CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none
> > +CFLAGS-tst-cet-legacy-4.c += -fcf-protection=branch
> > +CFLAGS-tst-cet-legacy-4a.c += -fcf-protection
> > +CFLAGS-tst-cet-legacy-4b.c += -fcf-protection
> > +CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none
> 
> OK, but I'm slightly disappointed that we can't have all tests
> enabled and just have these return UNSUPPORTED. These tests are
> effectively hidden behind the enable-cet check and could bitrot
> because we aren't compiling them.
> 
> > +
> > +$(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \
> > +		       $(objpfx)tst-cet-legacy-mod-2.so
> > +$(objpfx)tst-cet-legacy-2: $(objpfx)tst-cet-legacy-mod-2.so $(libdl)
> > +$(objpfx)tst-cet-legacy-2.out: $(objpfx)tst-cet-legacy-mod-1.so
> > +$(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so $(libdl)
> > +$(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so
> > +$(objpfx)tst-cet-legacy-4: $(libdl)
> > +$(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so
> > +ifneq (no,$(have-tunables))
> > +$(objpfx)tst-cet-legacy-4a: $(libdl)
> > +$(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so
> > +tst-cet-legacy-4a-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=permissive
> 
> OK.
> 
> > +$(objpfx)tst-cet-legacy-4b: $(libdl)
> > +$(objpfx)tst-cet-legacy-4b.out: $(objpfx)tst-cet-legacy-mod-4.so
> > +tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=on
> 
> OK.
> 
> > +$(objpfx)tst-cet-legacy-4c: $(libdl)
> > +$(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so
> > +tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=off
> 
> OK.
> 
> > +endif
> >  endif
> >  
...
> > diff --git a/sysdeps/x86/tst-cet-legacy-3.c b/sysdeps/x86/tst-cet-legacy-3.c
> > new file mode 100644
> > index 0000000000..7bf0e656b1
> > --- /dev/null
> > +++ b/sysdeps/x86/tst-cet-legacy-3.c
> > @@ -0,0 +1,88 @@
> > +/* Check compatibility of CET-enabled executable with dlopened legacy
> > +   shared object.  Copied from gcc.target/i386/pr81128.c in GCC testsuite.
> 
> You cannot copy from GCC and relicense from GPLv3 to GPLv2.1 unless you
> owned the original code.
> 

We only need to check if we can dlopen non-CET shared object from a CET
program.  I am checking in this patch with a simple test:

int
test (void)
{
  printf ("PASS\n");
  return 0;
}


H.J.
---
Check binary compatibility of CET-enabled executables:

1. When CET-enabled executable is used with legacy non-CET shared object
at run-time, ld.so should disable SHSTK and put legacy non-CET shared
objects in legacy bitmap.
2. When IBT-enabled executable dlopens legacy non-CET shared object,
ld.so should put legacy shared object in legacy bitmap.
3. Use GLIBC_TUNABLES=glibc.tune.x86_shstk=[on|off|permissive] to
control how SHSTK is enabled.

	* sysdeps/x86/Makefile (tests): Add tst-cet-legacy-1,
	tst-cet-legacy-2, tst-cet-legacy-2a, tst-cet-legacy-3,
	tst-cet-legacy-4, tst-cet-legacy-4a, tst-cet-legacy-4b
	and tst-cet-legacy-4c.
	(modules-names): Add tst-cet-legacy-mod-1, tst-cet-legacy-mod-2
	and tst-cet-legacy-mod-4.
	(CFLAGS-tst-cet-legacy-2.c): New.
	(CFLAGS-tst-cet-legacy-mod-1.c): Likewise.
	(CFLAGS-tst-cet-legacy-mod-2.c): Likewise.
	(CFLAGS-tst-cet-legacy-3.c): Likewise.
	(CFLAGS-tst-cet-legacy-4.c): Likewise.
	(CFLAGS-tst-cet-legacy-mod-4.c): Likewise.
	($(objpfx)tst-cet-legacy-1): Likewise.
	($(objpfx)tst-cet-legacy-2): Likewise.
	($(objpfx)tst-cet-legacy-2.out): Likewise.
	($(objpfx)tst-cet-legacy-2a): Likewise.
	($(objpfx)tst-cet-legacy-2a.out): Likewise.
	($(objpfx)tst-cet-legacy-4): Likewise.
	($(objpfx)tst-cet-legacy-4.out): Likewise.
	($(objpfx)tst-cet-legacy-4a): Likewise.
	($(objpfx)tst-cet-legacy-4a.out): Likewise.
	(tst-cet-legacy-4a-ENV): Likewise.
	($(objpfx)tst-cet-legacy-4b): Likewise.
	($(objpfx)tst-cet-legacy-4b.out): Likewise.
	(tst-cet-legacy-4b-ENV): Likewise.
	($(objpfx)tst-cet-legacy-4c): Likewise.
	($(objpfx)tst-cet-legacy-4c.out): Likewise.
	(tst-cet-legacy-4c-ENV): Likewise.
	* sysdeps/x86/tst-cet-legacy-1.c: New file.
	* sysdeps/x86/tst-cet-legacy-2.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-2a.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-3.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-4.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-4a.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-4b.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-4c.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-mod-1.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-mod-2.c: Likewise.
	* sysdeps/x86/tst-cet-legacy-mod-4.c: Likewise.
---
 sysdeps/x86/Makefile               | 38 ++++++++++++++++++
 sysdeps/x86/tst-cet-legacy-1.c     | 44 ++++++++++++++++++++
 sysdeps/x86/tst-cet-legacy-2.c     | 64 ++++++++++++++++++++++++++++++
 sysdeps/x86/tst-cet-legacy-2a.c    |  1 +
 sysdeps/x86/tst-cet-legacy-3.c     | 37 +++++++++++++++++
 sysdeps/x86/tst-cet-legacy-4.c     | 56 ++++++++++++++++++++++++++
 sysdeps/x86/tst-cet-legacy-4a.c    |  1 +
 sysdeps/x86/tst-cet-legacy-4b.c    |  1 +
 sysdeps/x86/tst-cet-legacy-4c.c    |  1 +
 sysdeps/x86/tst-cet-legacy-mod-1.c | 24 +++++++++++
 sysdeps/x86/tst-cet-legacy-mod-2.c | 24 +++++++++++
 sysdeps/x86/tst-cet-legacy-mod-4.c |  2 +
 12 files changed, 293 insertions(+)
 create mode 100644 sysdeps/x86/tst-cet-legacy-1.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-2.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-2a.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-3.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4a.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4b.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-4c.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-mod-1.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-mod-2.c
 create mode 100644 sysdeps/x86/tst-cet-legacy-mod-4.c

diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
index e9b2d0b35d..672bb19489 100644
--- a/sysdeps/x86/Makefile
+++ b/sysdeps/x86/Makefile
@@ -17,6 +17,44 @@ endif
 ifeq ($(enable-cet),yes)
 ifeq ($(subdir),elf)
 sysdep-dl-routines += dl-cet
+
+tests += tst-cet-legacy-1 tst-cet-legacy-2 tst-cet-legacy-2a \
+	 tst-cet-legacy-3 tst-cet-legacy-4
+ifneq (no,$(have-tunables))
+tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c
+endif
+modules-names += tst-cet-legacy-mod-1 tst-cet-legacy-mod-2 \
+		 tst-cet-legacy-mod-4
+
+CFLAGS-tst-cet-legacy-2.c += -fcf-protection=branch
+CFLAGS-tst-cet-legacy-2a.c += -fcf-protection
+CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none
+CFLAGS-tst-cet-legacy-4.c += -fcf-protection=branch
+CFLAGS-tst-cet-legacy-4a.c += -fcf-protection
+CFLAGS-tst-cet-legacy-4b.c += -fcf-protection
+CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none
+
+$(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \
+		       $(objpfx)tst-cet-legacy-mod-2.so
+$(objpfx)tst-cet-legacy-2: $(objpfx)tst-cet-legacy-mod-2.so $(libdl)
+$(objpfx)tst-cet-legacy-2.out: $(objpfx)tst-cet-legacy-mod-1.so
+$(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so $(libdl)
+$(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so
+$(objpfx)tst-cet-legacy-4: $(libdl)
+$(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so
+ifneq (no,$(have-tunables))
+$(objpfx)tst-cet-legacy-4a: $(libdl)
+$(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so
+tst-cet-legacy-4a-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=permissive
+$(objpfx)tst-cet-legacy-4b: $(libdl)
+$(objpfx)tst-cet-legacy-4b.out: $(objpfx)tst-cet-legacy-mod-4.so
+tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=on
+$(objpfx)tst-cet-legacy-4c: $(libdl)
+$(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so
+tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=off
+endif
 endif
 
 # Add -fcf-protection to CFLAGS when CET is enabled.
diff --git a/sysdeps/x86/tst-cet-legacy-1.c b/sysdeps/x86/tst-cet-legacy-1.c
new file mode 100644
index 0000000000..861c09a26e
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-1.c
@@ -0,0 +1,44 @@
+/* Check compatibility of CET-enabled executable linked with legacy
+   shared object.
+   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 <stdio.h>
+#include <stdlib.h>
+
+extern int in_dso_1 (void);
+extern int in_dso_2 (void);
+
+static int
+do_test (void)
+{
+  if (in_dso_1 () != 0x1234678)
+    {
+      puts ("in_dso_1 () != 0x1234678");
+      exit (1);
+    }
+
+  if (in_dso_2 () != 0xbadbeef)
+    {
+      puts ("in_dso_2 () != 0xbadbeef");
+      exit (1);
+    }
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86/tst-cet-legacy-2.c b/sysdeps/x86/tst-cet-legacy-2.c
new file mode 100644
index 0000000000..e039a16797
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-2.c
@@ -0,0 +1,64 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   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 <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int in_dso_2 (void);
+
+static int
+do_test (void)
+{
+  static const char modname[] = "tst-cet-legacy-mod-1.so";
+  int (*fp) (void);
+  void *h;
+
+  h = dlopen (modname, RTLD_LAZY);
+  if (h == NULL)
+    {
+      printf ("cannot open '%s': %s\n", modname, dlerror ());
+      exit (1);
+    }
+
+  fp = dlsym (h, "in_dso_1");
+  if (fp == NULL)
+    {
+      printf ("cannot get symbol 'in_dso': %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (fp () != 0x1234678)
+    {
+      puts ("in_dso_1 () != 0x1234678");
+      exit (1);
+    }
+
+  if (in_dso_2 () != 0xbadbeef)
+    {
+      puts ("in_dso_2 () != 0xbadbeef");
+      exit (1);
+    }
+
+  dlclose (h);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86/tst-cet-legacy-2a.c b/sysdeps/x86/tst-cet-legacy-2a.c
new file mode 100644
index 0000000000..d5aead4303
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-2a.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-2.c"
diff --git a/sysdeps/x86/tst-cet-legacy-3.c b/sysdeps/x86/tst-cet-legacy-3.c
new file mode 100644
index 0000000000..bab9faa8b0
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-3.c
@@ -0,0 +1,37 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   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 <stdio.h>
+
+int
+test (void)
+{
+  printf ("PASS\n");
+  return 0;
+}
+
+#ifndef TEST_MODULE
+static int
+do_test (void)
+{
+  return test ();
+}
+
+#include <support/test-driver.c>
+#endif
diff --git a/sysdeps/x86/tst-cet-legacy-4.c b/sysdeps/x86/tst-cet-legacy-4.c
new file mode 100644
index 0000000000..3ead63dd24
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-4.c
@@ -0,0 +1,56 @@
+/* Check compatibility of CET-enabled executable with dlopened legacy
+   shared object.
+   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 <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int
+do_test (void)
+{
+  static const char modname[] = "tst-cet-legacy-mod-4.so";
+  int (*fp) (void);
+  void *h;
+
+  h = dlopen (modname, RTLD_LAZY);
+  if (h == NULL)
+    {
+      printf ("cannot open '%s': %s\n", modname, dlerror ());
+      exit (1);
+    }
+
+  fp = dlsym (h, "test");
+  if (fp == NULL)
+    {
+      printf ("cannot get symbol 'test': %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (fp () != 0)
+    {
+      puts ("test () != 0");
+      exit (1);
+    }
+
+  dlclose (h);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86/tst-cet-legacy-4a.c b/sysdeps/x86/tst-cet-legacy-4a.c
new file mode 100644
index 0000000000..b9bb18c36b
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-4a.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-4.c"
diff --git a/sysdeps/x86/tst-cet-legacy-4b.c b/sysdeps/x86/tst-cet-legacy-4b.c
new file mode 100644
index 0000000000..b9bb18c36b
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-4b.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-4.c"
diff --git a/sysdeps/x86/tst-cet-legacy-4c.c b/sysdeps/x86/tst-cet-legacy-4c.c
new file mode 100644
index 0000000000..b9bb18c36b
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-4c.c
@@ -0,0 +1 @@
+#include "tst-cet-legacy-4.c"
diff --git a/sysdeps/x86/tst-cet-legacy-mod-1.c b/sysdeps/x86/tst-cet-legacy-mod-1.c
new file mode 100644
index 0000000000..09762bce13
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-mod-1.c
@@ -0,0 +1,24 @@
+/* Check compatibility of CET-enabled executable with legacy shared
+   object.
+   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/>.  */
+
+int
+in_dso_1 (void)
+{
+  return 0x1234678;
+}
diff --git a/sysdeps/x86/tst-cet-legacy-mod-2.c b/sysdeps/x86/tst-cet-legacy-mod-2.c
new file mode 100644
index 0000000000..1c8de443f6
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-mod-2.c
@@ -0,0 +1,24 @@
+/* Check compatibility of CET-enabled executable with legacy shared
+   object.
+   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/>.  */
+
+int
+in_dso_2 (void)
+{
+  return 0xbadbeef;
+}
diff --git a/sysdeps/x86/tst-cet-legacy-mod-4.c b/sysdeps/x86/tst-cet-legacy-mod-4.c
new file mode 100644
index 0000000000..a93c2fe4a7
--- /dev/null
+++ b/sysdeps/x86/tst-cet-legacy-mod-4.c
@@ -0,0 +1,2 @@
+#define TEST_MODULE
+#include "tst-cet-legacy-3.c"
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 08/12] Add a test for swapcontext with a wrapper
  2018-07-25  3:27   ` Carlos O'Donell
@ 2018-07-25 11:50     ` H.J. Lu
  0 siblings, 0 replies; 70+ messages in thread
From: H.J. Lu @ 2018-07-25 11:50 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: H.J. Lu, libc-alpha

On Tue, Jul 24, 2018 at 11:27:04PM -0400, Carlos O'Donell wrote:
> On 07/21/2018 10:20 AM, H.J. Lu wrote:
> > Check swapcontext works with a wrapper.
> > 
> > 	* stdlib/Makefile (tests): Add tst-swapcontext1.
> > 	* stdlib/tst-swapcontext1.c: New test.
> 
> OK for 2.28 if you can answer the licensing question.
> 

I am dropping this for now.

H.J.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/12] Add a test for multiple makecontext calls
  2018-07-25  3:31   ` Carlos O'Donell
@ 2018-07-25 11:55     ` H.J. Lu
  0 siblings, 0 replies; 70+ messages in thread
From: H.J. Lu @ 2018-07-25 11:55 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: H.J. Lu, libc-alpha

On Tue, Jul 24, 2018 at 11:31:12PM -0400, Carlos O'Donell wrote:
> On 07/21/2018 10:20 AM, H.J. Lu wrote:
> > Check multiple makecontext calls.
> > 
> > 	* stdlib/Makefile (tests): Add tst-swapcontext2.
> > 	* stdlib/tst-swapcontext2.c: New test.
> 
> OK for 2.28.
> 
> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
> 

This is what I checked in.


H.J.
---
From 8516ad2de3ae7c720370e06e7aa98d135b3c30eb Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 16 May 2018 12:28:19 -0700
Subject: [PATCH] Add a test for multiple makecontext calls

Check multiple makecontext calls.

	* stdlib/Makefile (tests): Add tst-swapcontext1.
	* stdlib/tst-swapcontext1.c: New test.
---
 ChangeLog                 |   5 ++
 stdlib/Makefile           |   3 +-
 stdlib/tst-swapcontext1.c | 108 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-swapcontext1.c

diff --git a/ChangeLog b/ChangeLog
index d387465f29..18329df423 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-07-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* stdlib/Makefile (tests): Add tst-swapcontext1.
+	* stdlib/tst-swapcontext1.c: New test.
+
 2018-07-25  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* sysdeps/x86/Makefile (tests): Add tst-cet-legacy-1,
diff --git a/stdlib/Makefile b/stdlib/Makefile
index b5e55b0a55..bc8929f2b9 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -84,7 +84,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   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 		    \
-		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign
+		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
+		   tst-swapcontext1
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-swapcontext1.c b/stdlib/tst-swapcontext1.c
new file mode 100644
index 0000000000..7802df4868
--- /dev/null
+++ b/stdlib/tst-swapcontext1.c
@@ -0,0 +1,108 @@
+/* Check multiple makecontext calls.
+   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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+
+static ucontext_t uctx_main, uctx_func1, uctx_func2;
+const char *str1 = "\e[31mswapcontext(&uctx_func1, &uctx_main)\e[0m";
+const char *str2 = "\e[34mswapcontext(&uctx_func2, &uctx_main)\e[0m";
+const char *fmt1 = "\e[31m";
+const char *fmt2 = "\e[34m";
+
+#define handle_error(msg) \
+  do { perror(msg); exit(EXIT_FAILURE); } while (0)
+
+__attribute__((noinline, noclone))
+static void
+func4(ucontext_t *uocp, ucontext_t *ucp, const char *str, const char *fmt)
+{
+  printf("      %sfunc4: %s\e[0m\n", fmt, str);
+  if (swapcontext(uocp, ucp) == -1)
+    handle_error("swapcontext");
+  printf("      %sfunc4: returning\e[0m\n", fmt);
+}
+
+__attribute__((noinline, noclone))
+static void
+func3(ucontext_t *uocp, ucontext_t *ucp, const char *str, const char *fmt)
+{
+  printf("    %sfunc3: func4(uocp, ucp, str)\e[0m\n", fmt);
+  func4(uocp, ucp, str, fmt);
+  printf("    %sfunc3: returning\e[0m\n", fmt);
+}
+
+__attribute__((noinline, noclone))
+static void
+func1(void)
+{
+  while ( 1 )
+    {
+      printf("  \e[31mfunc1: func3(&uctx_func1, &uctx_main, str1)\e[0m\n");
+      func3( &uctx_func1, &uctx_main, str1, fmt1);
+    }
+}
+
+__attribute__((noinline, noclone))
+static void
+func2(void)
+{
+  while ( 1 )
+    {
+      printf("  \e[34mfunc2: func3(&uctx_func2, &uctx_main, str2)\e[0m\n");
+      func3(&uctx_func2, &uctx_main, str2, fmt2);
+    }
+}
+
+static int
+do_test (void)
+{
+  char func1_stack[16384];
+  char func2_stack[16384];
+  int i;
+
+  if (getcontext(&uctx_func1) == -1)
+    handle_error("getcontext");
+  uctx_func1.uc_stack.ss_sp = func1_stack;
+  uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
+  uctx_func1.uc_link = &uctx_main;
+  makecontext(&uctx_func1, func1, 0);
+
+  if (getcontext(&uctx_func2) == -1)
+    handle_error("getcontext");
+  uctx_func2.uc_stack.ss_sp = func2_stack;
+  uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
+  uctx_func2.uc_link = &uctx_func1;
+  makecontext(&uctx_func2, func2, 0);
+
+  for ( i = 0; i < 4; i++ )
+    {
+      if (swapcontext(&uctx_main, &uctx_func1) == -1)
+	handle_error("swapcontext");
+      printf("        \e[35mmain: swapcontext(&uctx_main, &uctx_func2)\n\e[0m");
+      if (swapcontext(&uctx_main, &uctx_func2) == -1)
+	handle_error("swapcontext");
+      printf("        \e[35mmain: swapcontext(&uctx_main, &uctx_func1)\n\e[0m");
+    }
+
+  printf("main: exiting\n");
+  exit(EXIT_SUCCESS);
+}
+
+#include <support/test-driver.c>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 12/12] Add tests for setcontext on the context from makecontext
  2018-07-25  3:51   ` Carlos O'Donell
@ 2018-07-25 12:14     ` H.J. Lu
  0 siblings, 0 replies; 70+ messages in thread
From: H.J. Lu @ 2018-07-25 12:14 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: libc-alpha

On Tue, Jul 24, 2018 at 11:51:16PM -0400, Carlos O'Donell wrote:
> On 07/21/2018 10:20 AM, H.J. Lu wrote:
> > 	* stdlib/Makefile ((tests): Add tst-setcontext6, tst-setcontext7,
> > 	tst-setcontext8 and tst-setcontext9.
> > 	* stdlib/tst-setcontext6.c: New file.
> > 	* stdlib/tst-setcontext7.c: Likewise.
> > 	* stdlib/tst-setcontext8.c: Likewise.
> > 	* stdlib/tst-setcontext9.c: Likewise.
> 
> OK for 2.28 if you use atomics instead of volatile int.
> 
> Reviewed-by: Carlos O'Donell <carlos@redhat.com>

This is what I checked in.

H.J.
---
From 375a484459efcf2da1100e9ed228863be6665986 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 25 Jul 2018 05:12:59 -0700
Subject: [PATCH] Add tests for setcontext on the context from makecontext

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

	* stdlib/Makefile ((tests): Add tst-setcontext6, tst-setcontext7,
	tst-setcontext8 and tst-setcontext9.
	* stdlib/tst-setcontext6.c: New file.
	* stdlib/tst-setcontext7.c: Likewise.
	* stdlib/tst-setcontext8.c: Likewise.
	* stdlib/tst-setcontext9.c: Likewise.
---
 ChangeLog                |   9 ++++
 stdlib/Makefile          |   4 +-
 stdlib/tst-setcontext6.c |  77 +++++++++++++++++++++++++++++
 stdlib/tst-setcontext7.c |  97 +++++++++++++++++++++++++++++++++++++
 stdlib/tst-setcontext8.c |  82 +++++++++++++++++++++++++++++++
 stdlib/tst-setcontext9.c | 101 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 369 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-setcontext6.c
 create mode 100644 stdlib/tst-setcontext7.c
 create mode 100644 stdlib/tst-setcontext8.c
 create mode 100644 stdlib/tst-setcontext9.c

diff --git a/ChangeLog b/ChangeLog
index 6935bc3b09..24396a0573 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2018-07-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* stdlib/Makefile ((tests): Add tst-setcontext6, tst-setcontext7,
+	tst-setcontext8 and tst-setcontext9.
+	* stdlib/tst-setcontext6.c: New file.
+	* stdlib/tst-setcontext7.c: Likewise.
+	* stdlib/tst-setcontext8.c: Likewise.
+	* stdlib/tst-setcontext9.c: Likewise.
+
 2018-07-25  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* stdlib/Makefile ((tests): Add tst-setcontext5.
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 403ca22f49..01194bbf7c 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -85,7 +85,9 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   test-at_quick_exit-race test-cxa_atexit-race             \
 		   test-on_exit-race test-dlclose-exit-race 		    \
 		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
-		   tst-swapcontext1 tst-setcontext4 tst-setcontext5
+		   tst-swapcontext1 tst-setcontext4 tst-setcontext5 \
+		   tst-setcontext6 tst-setcontext7 tst-setcontext8 \
+		   tst-setcontext9
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-setcontext6.c b/stdlib/tst-setcontext6.c
new file mode 100644
index 0000000000..e530154554
--- /dev/null
+++ b/stdlib/tst-setcontext6.c
@@ -0,0 +1,77 @@
+/* Check getcontext and setcontext on the context from 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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+#include <stdatomic.h>
+
+static ucontext_t ctx[3];
+static atomic_int done;
+
+static void
+f1 (void)
+{
+  printf ("start f1\n");
+  if (!done)
+    {
+      if (getcontext (&ctx[2]) != 0)
+	{
+	  printf ("%s: getcontext: %m\n", __FUNCTION__);
+	  exit (EXIT_FAILURE);
+	}
+      if (done)
+	exit (EXIT_SUCCESS);
+    }
+  done++;
+  if (setcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  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);
+  if (setcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
diff --git a/stdlib/tst-setcontext7.c b/stdlib/tst-setcontext7.c
new file mode 100644
index 0000000000..053819f358
--- /dev/null
+++ b/stdlib/tst-setcontext7.c
@@ -0,0 +1,97 @@
+/* Check setcontext on the context from 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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+#include <stdatomic.h>
+
+static ucontext_t ctx[5];
+static atomic_int done;
+
+static void
+f1 (void)
+{
+  puts ("start f1");
+  if (!done)
+    {
+      if (getcontext (&ctx[2]) != 0)
+	{
+	  printf ("%s: getcontext: %m\n", __FUNCTION__);
+	  exit (EXIT_FAILURE);
+	}
+      if (done)
+	{
+	  puts ("set context in f1");
+	  if (setcontext (&ctx[3]) != 0)
+	    {
+	      printf ("%s: setcontext: %m\n", __FUNCTION__);
+	      exit (EXIT_FAILURE);
+	    }
+	}
+    }
+  done++;
+  puts ("swap contexts in f1");
+  if (swapcontext (&ctx[4], &ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  puts ("end f1");
+  exit (done == 2 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  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);
+  puts ("swap contexts");
+  if (swapcontext (&ctx[3], &ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (done != 1)
+    exit (EXIT_FAILURE);
+  done++;
+  puts ("set context");
+  if (setcontext (&ctx[4]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
diff --git a/stdlib/tst-setcontext8.c b/stdlib/tst-setcontext8.c
new file mode 100644
index 0000000000..53fb2bc1dd
--- /dev/null
+++ b/stdlib/tst-setcontext8.c
@@ -0,0 +1,82 @@
+/* Check getcontext and setcontext on the context from 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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+#include <stdatomic.h>
+
+static ucontext_t ctx[3];
+static atomic_int done;
+
+static void
+__attribute__((noinline, noclone))
+f2 (void)
+{
+  printf ("start f2\n");
+  done++;
+  if (setcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+}
+
+static void
+f1 (void)
+{
+  printf ("start f1\n");
+  if (getcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (done)
+    exit (EXIT_SUCCESS);
+  f2 ();
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  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);
+  if (setcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
new file mode 100644
index 0000000000..4636ce9030
--- /dev/null
+++ b/stdlib/tst-setcontext9.c
@@ -0,0 +1,101 @@
+/* Check setcontext on the context from 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 <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+#include <stdatomic.h>
+
+static ucontext_t ctx[5];
+static atomic_int done;
+
+static void
+__attribute__((noinline, noclone))
+f2 (void)
+{
+  done++;
+  puts ("swap contexts in f2");
+  if (swapcontext (&ctx[4], &ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  puts ("end f2");
+  exit (done == 2 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+static void
+f1 (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");
+      if (setcontext (&ctx[3]) != 0)
+	{
+	  printf ("%s: setcontext: %m\n", __FUNCTION__);
+	  exit (EXIT_FAILURE);
+	}
+    }
+  f2 ();
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  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);
+  puts ("swap contexts");
+  if (swapcontext (&ctx[3], &ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (done != 1)
+    exit (EXIT_FAILURE);
+  done++;
+  puts ("set context");
+  if (setcontext (&ctx[4]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
-- 
2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 07/12] x86/CET: Add tests with legacy non-CET shared objects
  2018-07-25 11:46     ` H.J. Lu
@ 2018-07-25 14:28       ` Carlos O'Donell
  0 siblings, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25 14:28 UTC (permalink / raw)
  To: H.J. Lu; +Cc: libc-alpha

On 07/25/2018 07:46 AM, H.J. Lu wrote:
> On Tue, Jul 24, 2018 at 11:21:22PM -0400, Carlos O'Donell wrote:
>> On 07/21/2018 10:20 AM, H.J. Lu wrote:
>>> Check binary compatibility of CET-enabled executables:
>>>
>>
>> OK for 2.28.
>>
>> Gold star for always enabling the tests and having them 
>>
>> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
>>
>>> 1. When CET-enabled executable is used with legacy non-CET shared object
>>> at run-time, ld.so should disable SHSTK and put legacy non-CET shared
>>> objects in legacy bitmap.
>>
>> OK.
>>
>>> 2. When IBT-enabled executable dlopens legacy non-CET shared object,
>>> ld.so should put legacy shared object in legacy bitmap.
>>
>> OK.
>>
>>> 3. Use GLIBC_TUNABLES=glibc.tune.x86_shstk=[on|off|permissive] to
>>> control how SHSTK is enabled.
>>
>> OK.
>>
>>>
>>> 	* sysdeps/x86/Makefile (tests): Add tst-cet-legacy-1,
>>> 	tst-cet-legacy-2, tst-cet-legacy-2a, tst-cet-legacy-3,
>>> 	tst-cet-legacy-4, tst-cet-legacy-4a, tst-cet-legacy-4b
>>> 	and tst-cet-legacy-4c.
>>> 	(modules-names): Add tst-cet-legacy-mod-1, tst-cet-legacy-mod-2
>>> 	and tst-cet-legacy-mod-4.
>>> 	(CFLAGS-tst-cet-legacy-2.c): New.
>>> 	(CFLAGS-tst-cet-legacy-mod-1.c): Likewise.
>>> 	(CFLAGS-tst-cet-legacy-mod-2.c): Likewise.
>>> 	(CFLAGS-tst-cet-legacy-3.c): Likewise.
>>> 	(CFLAGS-tst-cet-legacy-4.c): Likewise.
>>> 	(CFLAGS-tst-cet-legacy-mod-4.c): Likewise.
>>> 	($(objpfx)tst-cet-legacy-1): Likewise.
>>> 	($(objpfx)tst-cet-legacy-2): Likewise.
>>> 	($(objpfx)tst-cet-legacy-2.out): Likewise.
>>> 	($(objpfx)tst-cet-legacy-2a): Likewise.
>>> 	($(objpfx)tst-cet-legacy-2a.out): Likewise.
>>> 	($(objpfx)tst-cet-legacy-4): Likewise.
>>> 	($(objpfx)tst-cet-legacy-4.out): Likewise.
>>> 	($(objpfx)tst-cet-legacy-4a): Likewise.
>>> 	($(objpfx)tst-cet-legacy-4a.out): Likewise.
>>> 	(tst-cet-legacy-4a-ENV): Likewise.
>>> 	($(objpfx)tst-cet-legacy-4b): Likewise.
>>> 	($(objpfx)tst-cet-legacy-4b.out): Likewise.
>>> 	(tst-cet-legacy-4b-ENV): Likewise.
>>> 	($(objpfx)tst-cet-legacy-4c): Likewise.
>>> 	($(objpfx)tst-cet-legacy-4c.out): Likewise.
>>> 	(tst-cet-legacy-4c-ENV): Likewise.
>>> 	* sysdeps/x86/tst-cet-legacy-1.c: New file.
>>> 	* sysdeps/x86/tst-cet-legacy-2.c: Likewise.
>>> 	* sysdeps/x86/tst-cet-legacy-2a.c: Likewise.
>>> 	* sysdeps/x86/tst-cet-legacy-3.c: Likewise.
>>> 	* sysdeps/x86/tst-cet-legacy-4.c: Likewise.
>>> 	* sysdeps/x86/tst-cet-legacy-4a.c: Likewise.
>>> 	* sysdeps/x86/tst-cet-legacy-4b.c: Likewise.
>>> 	* sysdeps/x86/tst-cet-legacy-4c.c: Likewise.
>>> 	* sysdeps/x86/tst-cet-legacy-mod-1.c: Likewise.
>>> 	* sysdeps/x86/tst-cet-legacy-mod-2.c: Likewise.
>>> 	* sysdeps/x86/tst-cet-legacy-mod-4.c: Likewise.
>>> ---
>>>  sysdeps/x86/Makefile               | 38 +++++++++++++
>>>  sysdeps/x86/tst-cet-legacy-1.c     | 44 +++++++++++++++
>>>  sysdeps/x86/tst-cet-legacy-2.c     | 64 ++++++++++++++++++++++
>>>  sysdeps/x86/tst-cet-legacy-2a.c    |  1 +
>>>  sysdeps/x86/tst-cet-legacy-3.c     | 88 ++++++++++++++++++++++++++++++
>>>  sysdeps/x86/tst-cet-legacy-4.c     | 56 +++++++++++++++++++
>>>  sysdeps/x86/tst-cet-legacy-4a.c    |  1 +
>>>  sysdeps/x86/tst-cet-legacy-4b.c    |  1 +
>>>  sysdeps/x86/tst-cet-legacy-4c.c    |  1 +
>>>  sysdeps/x86/tst-cet-legacy-mod-1.c | 24 ++++++++
>>>  sysdeps/x86/tst-cet-legacy-mod-2.c | 24 ++++++++
>>>  sysdeps/x86/tst-cet-legacy-mod-4.c |  2 +
>>>  12 files changed, 344 insertions(+)
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-1.c
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-2.c
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-2a.c
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-3.c
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-4.c
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-4a.c
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-4b.c
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-4c.c
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-1.c
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-2.c
>>>  create mode 100644 sysdeps/x86/tst-cet-legacy-mod-4.c
>>>
>>> diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
>>> index e9b2d0b35d..672bb19489 100644
>>> --- a/sysdeps/x86/Makefile
>>> +++ b/sysdeps/x86/Makefile
>>> @@ -17,6 +17,44 @@ endif
>>>  ifeq ($(enable-cet),yes)
>>>  ifeq ($(subdir),elf)
>>>  sysdep-dl-routines += dl-cet
>>> +
>>> +tests += tst-cet-legacy-1 tst-cet-legacy-2 tst-cet-legacy-2a \
>>> +	 tst-cet-legacy-3 tst-cet-legacy-4
>>
>> OK.
>>
>>> +ifneq (no,$(have-tunables))
>>> +tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c
>>
>> OK.
>>
>>> +endif
>>> +modules-names += tst-cet-legacy-mod-1 tst-cet-legacy-mod-2 \
>>> +		 tst-cet-legacy-mod-4
>>> +
>>> +CFLAGS-tst-cet-legacy-2.c += -fcf-protection=branch
>>> +CFLAGS-tst-cet-legacy-2a.c += -fcf-protection
>>> +CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none
>>> +CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none
>>> +CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none
>>> +CFLAGS-tst-cet-legacy-4.c += -fcf-protection=branch
>>> +CFLAGS-tst-cet-legacy-4a.c += -fcf-protection
>>> +CFLAGS-tst-cet-legacy-4b.c += -fcf-protection
>>> +CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none
>>
>> OK, but I'm slightly disappointed that we can't have all tests
>> enabled and just have these return UNSUPPORTED. These tests are
>> effectively hidden behind the enable-cet check and could bitrot
>> because we aren't compiling them.
>>
>>> +
>>> +$(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \
>>> +		       $(objpfx)tst-cet-legacy-mod-2.so
>>> +$(objpfx)tst-cet-legacy-2: $(objpfx)tst-cet-legacy-mod-2.so $(libdl)
>>> +$(objpfx)tst-cet-legacy-2.out: $(objpfx)tst-cet-legacy-mod-1.so
>>> +$(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so $(libdl)
>>> +$(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so
>>> +$(objpfx)tst-cet-legacy-4: $(libdl)
>>> +$(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so
>>> +ifneq (no,$(have-tunables))
>>> +$(objpfx)tst-cet-legacy-4a: $(libdl)
>>> +$(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so
>>> +tst-cet-legacy-4a-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=permissive
>>
>> OK.
>>
>>> +$(objpfx)tst-cet-legacy-4b: $(libdl)
>>> +$(objpfx)tst-cet-legacy-4b.out: $(objpfx)tst-cet-legacy-mod-4.so
>>> +tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=on
>>
>> OK.
>>
>>> +$(objpfx)tst-cet-legacy-4c: $(libdl)
>>> +$(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so
>>> +tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=off
>>
>> OK.
>>
>>> +endif
>>>  endif
>>>  
> ...
>>> diff --git a/sysdeps/x86/tst-cet-legacy-3.c b/sysdeps/x86/tst-cet-legacy-3.c
>>> new file mode 100644
>>> index 0000000000..7bf0e656b1
>>> --- /dev/null
>>> +++ b/sysdeps/x86/tst-cet-legacy-3.c
>>> @@ -0,0 +1,88 @@
>>> +/* Check compatibility of CET-enabled executable with dlopened legacy
>>> +   shared object.  Copied from gcc.target/i386/pr81128.c in GCC testsuite.
>>
>> You cannot copy from GCC and relicense from GPLv3 to GPLv2.1 unless you
>> owned the original code.
>>
> 
> We only need to check if we can dlopen non-CET shared object from a CET
> program.  I am checking in this patch with a simple test:
>

That is perfect, and the test is simpler. I'm OK wit hthis.

> int
> test (void)
> {
>   printf ("PASS\n");
>   return 0;
> }
> 
> 
> H.J.
> ---
> Check binary compatibility of CET-enabled executables:
> 
> 1. When CET-enabled executable is used with legacy non-CET shared object
> at run-time, ld.so should disable SHSTK and put legacy non-CET shared
> objects in legacy bitmap.
> 2. When IBT-enabled executable dlopens legacy non-CET shared object,
> ld.so should put legacy shared object in legacy bitmap.
> 3. Use GLIBC_TUNABLES=glibc.tune.x86_shstk=[on|off|permissive] to
> control how SHSTK is enabled.
> 
> 	* sysdeps/x86/Makefile (tests): Add tst-cet-legacy-1,
> 	tst-cet-legacy-2, tst-cet-legacy-2a, tst-cet-legacy-3,
> 	tst-cet-legacy-4, tst-cet-legacy-4a, tst-cet-legacy-4b
> 	and tst-cet-legacy-4c.
> 	(modules-names): Add tst-cet-legacy-mod-1, tst-cet-legacy-mod-2
> 	and tst-cet-legacy-mod-4.
> 	(CFLAGS-tst-cet-legacy-2.c): New.
> 	(CFLAGS-tst-cet-legacy-mod-1.c): Likewise.
> 	(CFLAGS-tst-cet-legacy-mod-2.c): Likewise.
> 	(CFLAGS-tst-cet-legacy-3.c): Likewise.
> 	(CFLAGS-tst-cet-legacy-4.c): Likewise.
> 	(CFLAGS-tst-cet-legacy-mod-4.c): Likewise.
> 	($(objpfx)tst-cet-legacy-1): Likewise.
> 	($(objpfx)tst-cet-legacy-2): Likewise.
> 	($(objpfx)tst-cet-legacy-2.out): Likewise.
> 	($(objpfx)tst-cet-legacy-2a): Likewise.
> 	($(objpfx)tst-cet-legacy-2a.out): Likewise.
> 	($(objpfx)tst-cet-legacy-4): Likewise.
> 	($(objpfx)tst-cet-legacy-4.out): Likewise.
> 	($(objpfx)tst-cet-legacy-4a): Likewise.
> 	($(objpfx)tst-cet-legacy-4a.out): Likewise.
> 	(tst-cet-legacy-4a-ENV): Likewise.
> 	($(objpfx)tst-cet-legacy-4b): Likewise.
> 	($(objpfx)tst-cet-legacy-4b.out): Likewise.
> 	(tst-cet-legacy-4b-ENV): Likewise.
> 	($(objpfx)tst-cet-legacy-4c): Likewise.
> 	($(objpfx)tst-cet-legacy-4c.out): Likewise.
> 	(tst-cet-legacy-4c-ENV): Likewise.
> 	* sysdeps/x86/tst-cet-legacy-1.c: New file.
> 	* sysdeps/x86/tst-cet-legacy-2.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-2a.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-3.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-4.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-4a.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-4b.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-4c.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-mod-1.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-mod-2.c: Likewise.
> 	* sysdeps/x86/tst-cet-legacy-mod-4.c: Likewise.

OK for 2.28.

Reviewed that the gcc copied test is removed.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

Cheers,
Carlos.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-21 14:20 ` [PATCH 10/12] Add another test for setcontext H.J. Lu
  2018-07-25  3:36   ` Carlos O'Donell
@ 2018-07-25 16:21   ` Florian Weimer
  2018-07-25 16:31     ` H.J. Lu
  1 sibling, 1 reply; 70+ messages in thread
From: Florian Weimer @ 2018-07-25 16:21 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha; +Cc: Carlos O'Donell

On 07/21/2018 04:20 PM, H.J. Lu wrote:
> +  /* check sigmask in old context of swapcontext-call  */
> +  if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1)
> +    {
> +      puts ("FAIL: SIGUSR2 is not blocked in oldctx.uc_sigmask.");
> +      exit (1);
> +    }

This breaks on ia64 because uc_sigmask does not have the correct type there:

tst-setcontext4.c: In function ‘do_test’:
tst-setcontext4.c:202:20: error: passing argument 1 of ‘sigismember’ 
from incompatible pointer type [-Werror=incompatible-pointer-types]
    if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1)
In file included from ../include/signal.h:2,
                  from tst-setcontext4.c:23:
../signal/signal.h:208:41: note: expected ‘const sigset_t *’ {aka ‘const 
struct <anonymous> *’} but argument is of type ‘long unsigned int *’
  extern int sigismember (const sigset_t *__set, int __signo)
                          ~~~~~~~~~~~~~~~~^~~~~

I don't have a quick solution for this.  How important is this part of 
the test?

Thanks,
Florian

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 16:21   ` Florian Weimer
@ 2018-07-25 16:31     ` H.J. Lu
  2018-07-25 20:40       ` Carlos O'Donell
  0 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-25 16:31 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 1206 bytes --]

On Wed, Jul 25, 2018 at 9:21 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 07/21/2018 04:20 PM, H.J. Lu wrote:
>>
>> +  /* check sigmask in old context of swapcontext-call  */
>> +  if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1)
>> +    {
>> +      puts ("FAIL: SIGUSR2 is not blocked in oldctx.uc_sigmask.");
>> +      exit (1);
>> +    }
>
>
> This breaks on ia64 because uc_sigmask does not have the correct type there:
>
> tst-setcontext4.c: In function ‘do_test’:
> tst-setcontext4.c:202:20: error: passing argument 1 of ‘sigismember’ from
> incompatible pointer type [-Werror=incompatible-pointer-types]
>    if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1)
> In file included from ../include/signal.h:2,
>                  from tst-setcontext4.c:23:
> ../signal/signal.h:208:41: note: expected ‘const sigset_t *’ {aka ‘const
> struct <anonymous> *’} but argument is of type ‘long unsigned int *’
>  extern int sigismember (const sigset_t *__set, int __signo)
>                          ~~~~~~~~~~~~~~~~^~~~~
>
> I don't have a quick solution for this.  How important is this part of the
> test?
>

I am testing this patch.

-- 
H.J.

[-- Attachment #2: 0001-ia64-Work-around-incorrect-type-of-IA64-uc_sigmask.patch --]
[-- Type: text/x-patch, Size: 1726 bytes --]

From 70951c51d03623c10485380fcccd3a384dff20d6 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 25 Jul 2018 09:30:50 -0700
Subject: [PATCH] ia64: Work around incorrect type of IA64 uc_sigmask

	* sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c: New file.
---
 .../unix/sysv/linux/ia64/tst-setcontext4.c    | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c

diff --git a/sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c b/sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c
new file mode 100644
index 0000000000..58807e78cb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c
@@ -0,0 +1,24 @@
+/* Work around incorrect type of IA64 uc_sigmask.
+   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 <signal.h>
+
+#undef sigismember
+#define sigismember(set, signo) sigismember ((const sigset_t *) (set), (signo))
+
+#include <stdlib/tst-setcontext4.c>
-- 
2.17.1


^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 16:31     ` H.J. Lu
@ 2018-07-25 20:40       ` Carlos O'Donell
  2018-07-25 20:42         ` Florian Weimer
  2018-07-25 20:45         ` Joseph Myers
  0 siblings, 2 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25 20:40 UTC (permalink / raw)
  To: H.J. Lu, Florian Weimer; +Cc: GNU C Library

On 07/25/2018 12:31 PM, H.J. Lu wrote:
> From 70951c51d03623c10485380fcccd3a384dff20d6 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Wed, 25 Jul 2018 09:30:50 -0700
> Subject: [PATCH] ia64: Work around incorrect type of IA64 uc_sigmask
> 
> 	* sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c: New file.

Please file a bug for ia64 about this issue, then add the comment below.

Pre-accepted for 2.28 / master.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  .../unix/sysv/linux/ia64/tst-setcontext4.c    | 24 +++++++++++++++++++
>  1 file changed, 24 insertions(+)
>  create mode 100644 sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c
> 
> diff --git a/sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c b/sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c
> new file mode 100644
> index 0000000000..58807e78cb
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c
> @@ -0,0 +1,24 @@
> +/* Work around incorrect type of IA64 uc_sigmask.
> +   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 <signal.h>
> +

Add comment:

/* The uc_sigmask on IA64 has the wrong type and this needs fixing,
   but until that change is evaluated, we fix this here with a cast.
   See bug XXX.  */

> +#undef sigismember
> +#define sigismember(set, signo) sigismember ((const sigset_t *) (set), (signo))
> +
> +#include <stdlib/tst-setcontext4.c>
> -- 2.17.1

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 20:40       ` Carlos O'Donell
@ 2018-07-25 20:42         ` Florian Weimer
  2018-07-25 21:19           ` Carlos O'Donell
  2018-07-25 21:54           ` Andreas Schwab
  2018-07-25 20:45         ` Joseph Myers
  1 sibling, 2 replies; 70+ messages in thread
From: Florian Weimer @ 2018-07-25 20:42 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: H.J. Lu, GNU C Library

* Carlos O'Donell:

> /* The uc_sigmask on IA64 has the wrong type and this needs fixing,
>    but until that change is evaluated, we fix this here with a cast.
>    See bug XXX.  */

Is this really a bug?  After this long, I would consider it just a
quirk of the ia64 API/ABI and move on …

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 20:40       ` Carlos O'Donell
  2018-07-25 20:42         ` Florian Weimer
@ 2018-07-25 20:45         ` Joseph Myers
  2018-07-25 20:57           ` H.J. Lu
  2018-07-26 12:31           ` Adhemerval Zanella
  1 sibling, 2 replies; 70+ messages in thread
From: Joseph Myers @ 2018-07-25 20:45 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: H.J. Lu, Florian Weimer, GNU C Library

On Wed, 25 Jul 2018, Carlos O'Donell wrote:

> On 07/25/2018 12:31 PM, H.J. Lu wrote:
> > From 70951c51d03623c10485380fcccd3a384dff20d6 Mon Sep 17 00:00:00 2001
> > From: "H.J. Lu" <hjl.tools@gmail.com>
> > Date: Wed, 25 Jul 2018 09:30:50 -0700
> > Subject: [PATCH] ia64: Work around incorrect type of IA64 uc_sigmask
> > 
> > 	* sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c: New file.
> 
> Please file a bug for ia64 about this issue, then add the comment below.

It's bug 21634 (filed for XFAILing the relevant conform/ test assertions, 
not because of any expectation of being fixable while staying 
ABI-compatible).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 20:45         ` Joseph Myers
@ 2018-07-25 20:57           ` H.J. Lu
  2018-07-26 12:31           ` Adhemerval Zanella
  1 sibling, 0 replies; 70+ messages in thread
From: H.J. Lu @ 2018-07-25 20:57 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Carlos O'Donell, Florian Weimer, GNU C Library

[-- Attachment #1: Type: text/plain, Size: 758 bytes --]

On Wed, Jul 25, 2018 at 1:45 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Wed, 25 Jul 2018, Carlos O'Donell wrote:
>
>> On 07/25/2018 12:31 PM, H.J. Lu wrote:
>> > From 70951c51d03623c10485380fcccd3a384dff20d6 Mon Sep 17 00:00:00 2001
>> > From: "H.J. Lu" <hjl.tools@gmail.com>
>> > Date: Wed, 25 Jul 2018 09:30:50 -0700
>> > Subject: [PATCH] ia64: Work around incorrect type of IA64 uc_sigmask
>> >
>> >     * sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c: New file.
>>
>> Please file a bug for ia64 about this issue, then add the comment below.
>
> It's bug 21634 (filed for XFAILing the relevant conform/ test assertions,
> not because of any expectation of being fixable while staying
> ABI-compatible).

This is what I checked in.


-- 
H.J.

[-- Attachment #2: 0001-ia64-Work-around-incorrect-type-of-IA64-uc_sigmask.patch --]
[-- Type: text/x-patch, Size: 2331 bytes --]

From 3fb455b318c48f76280b4f8a0ff23b2cb1af9a3e Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 25 Jul 2018 13:54:08 -0700
Subject: [PATCH] ia64: Work around incorrect type of IA64 uc_sigmask

Work around:

https://sourceware.org/bugzilla/show_bug.cgi?id=21634

	* sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c: New file.
---
 ChangeLog                                     |  4 +++
 .../unix/sysv/linux/ia64/tst-setcontext4.c    | 26 +++++++++++++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c

diff --git a/ChangeLog b/ChangeLog
index 240d4a0c7d..e6c2adc95e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-07-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c: New file.
+
 2018-07-25  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
 
 	* nptl/threads.h: Move to ...
diff --git a/sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c b/sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c
new file mode 100644
index 0000000000..17916d451f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c
@@ -0,0 +1,26 @@
+/* The uc_sigmask on IA64 has the wrong type and this needs fixing,
+   but until that change is evaluated, we fix this here with a cast.
+   See https://sourceware.org/bugzilla/show_bug.cgi?id=21634
+   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 <signal.h>
+
+#undef sigismember
+#define sigismember(set, signo) sigismember ((const sigset_t *) (set), (signo))
+
+#include <stdlib/tst-setcontext4.c>
-- 
2.17.1


^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 20:42         ` Florian Weimer
@ 2018-07-25 21:19           ` Carlos O'Donell
  2018-07-25 21:21             ` Florian Weimer
  2018-07-25 21:54           ` Andreas Schwab
  1 sibling, 1 reply; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25 21:19 UTC (permalink / raw)
  To: Florian Weimer; +Cc: H.J. Lu, GNU C Library

On 07/25/2018 04:42 PM, Florian Weimer wrote:
> * Carlos O'Donell:
> 
>> /* The uc_sigmask on IA64 has the wrong type and this needs fixing,
>>    but until that change is evaluated, we fix this here with a cast.
>>    See bug XXX.  */
> 
> Is this really a bug?  After this long, I would consider it just a
> quirk of the ia64 API/ABI and move on …

You can't use sigismember(); I would consider that a bug?

c.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 21:19           ` Carlos O'Donell
@ 2018-07-25 21:21             ` Florian Weimer
  2018-07-25 21:27               ` Carlos O'Donell
  0 siblings, 1 reply; 70+ messages in thread
From: Florian Weimer @ 2018-07-25 21:21 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: H.J. Lu, GNU C Library

* Carlos O'Donell:

> On 07/25/2018 04:42 PM, Florian Weimer wrote:
>> * Carlos O'Donell:
>> 
>>> /* The uc_sigmask on IA64 has the wrong type and this needs fixing,
>>>    but until that change is evaluated, we fix this here with a cast.
>>>    See bug XXX.  */
>> 
>> Is this really a bug?  After this long, I would consider it just a
>> quirk of the ia64 API/ABI and move on …
>
> You can't use sigismember(); I would consider that a bug?

Well, if the ABI says the member has the type it has, and that's not
compatible with sigismember, then that's how things are.  Surely this
isn't the only such example.  What about the return type of the
tsearch function?

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 21:21             ` Florian Weimer
@ 2018-07-25 21:27               ` Carlos O'Donell
  2018-07-25 21:31                 ` Florian Weimer
  0 siblings, 1 reply; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-25 21:27 UTC (permalink / raw)
  To: Florian Weimer; +Cc: H.J. Lu, GNU C Library

On 07/25/2018 05:21 PM, Florian Weimer wrote:
> * Carlos O'Donell:
> 
>> On 07/25/2018 04:42 PM, Florian Weimer wrote:
>>> * Carlos O'Donell:
>>>
>>>> /* The uc_sigmask on IA64 has the wrong type and this needs fixing,
>>>>    but until that change is evaluated, we fix this here with a cast.
>>>>    See bug XXX.  */
>>>
>>> Is this really a bug?  After this long, I would consider it just a
>>> quirk of the ia64 API/ABI and move on …
>>
>> You can't use sigismember(); I would consider that a bug?
> 
> Well, if the ABI says the member has the type it has, and that's not
> compatible with sigismember, then that's how things are.  Surely this
> isn't the only such example.  What about the return type of the
> tsearch function?

What about tsearch? It returns a void* and so you do have to cast that
to something. Are you saying this is a similar issue? The void* creates
an expectation of a cast, which I think we don't have here.

c.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 21:27               ` Carlos O'Donell
@ 2018-07-25 21:31                 ` Florian Weimer
  0 siblings, 0 replies; 70+ messages in thread
From: Florian Weimer @ 2018-07-25 21:31 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: H.J. Lu, GNU C Library

* Carlos O'Donell:

> On 07/25/2018 05:21 PM, Florian Weimer wrote:
>> * Carlos O'Donell:
>> 
>>> On 07/25/2018 04:42 PM, Florian Weimer wrote:
>>>> * Carlos O'Donell:
>>>>
>>>>> /* The uc_sigmask on IA64 has the wrong type and this needs fixing,
>>>>>    but until that change is evaluated, we fix this here with a cast.
>>>>>    See bug XXX.  */
>>>>
>>>> Is this really a bug?  After this long, I would consider it just a
>>>> quirk of the ia64 API/ABI and move on …
>>>
>>> You can't use sigismember(); I would consider that a bug?
>> 
>> Well, if the ABI says the member has the type it has, and that's not
>> compatible with sigismember, then that's how things are.  Surely this
>> isn't the only such example.  What about the return type of the
>> tsearch function?
>
> What about tsearch? It returns a void* and so you do have to cast that
> to something. Are you saying this is a similar issue? The void* creates
> an expectation of a cast, which I think we don't have here.

The return type is a pointer to a const void *.  You are not supposed
to cast the returned pointer, but that const void * (after checking
that the return value is not NULL).

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 20:42         ` Florian Weimer
  2018-07-25 21:19           ` Carlos O'Donell
@ 2018-07-25 21:54           ` Andreas Schwab
  1 sibling, 0 replies; 70+ messages in thread
From: Andreas Schwab @ 2018-07-25 21:54 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Carlos O'Donell, H.J. Lu, GNU C Library

On Jul 25 2018, Florian Weimer <fw@deneb.enyo.de> wrote:

> * Carlos O'Donell:
>
>> /* The uc_sigmask on IA64 has the wrong type and this needs fixing,
>>    but until that change is evaluated, we fix this here with a cast.
>>    See bug XXX.  */
>
> Is this really a bug?  After this long, I would consider it just a
> quirk of the ia64 API/ABI and move on …

It isn't POSIX compatible (when POSIX still supported it).

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
                   ` (12 preceding siblings ...)
  2018-07-24  1:41 ` [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET Carlos O'Donell
@ 2018-07-26 11:17 ` Florian Weimer
  2018-07-27 14:53   ` Florian Weimer
  13 siblings, 1 reply; 70+ messages in thread
From: Florian Weimer @ 2018-07-26 11:17 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha; +Cc: Carlos O'Donell

On 07/21/2018 04:20 PM, H.J. Lu wrote:
> These are the last 12 patches to enable Intel CET.  Tested by
> 
> 1. build-many-glibcs.py.
> 2. With --enable-cet and without --enable-cet for i686, x86-64 and x32
> on non-CET x86-64 processors.
> 3. With --enable-cet for x86-64 and x32 on CET SDV using the CET kernel
> from cet branch at:
> 
> https://github.com/yyu168/linux_cet/tree/cet
> 
> When the shadow stack (SHSTK) is enabled, makecontext needs to allocate
> a new shadow stack to go with the new stack allocated by the caller.
> setcontext and swapcontext must properly handle the corresponding shadow
> stack when the stack is switched.  Add more tests for user context
> functions to provide more coverage for the shadow stack support.

Building glibc with --enable-cet currently breaks valgrind (even for 
current CPUs which do not support CET):

   https://bugzilla.redhat.com/show_bug.cgi?id=1608824

Mark is working on a valgrind fix.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-25 20:45         ` Joseph Myers
  2018-07-25 20:57           ` H.J. Lu
@ 2018-07-26 12:31           ` Adhemerval Zanella
  2018-07-26 12:54             ` Carlos O'Donell
  2018-07-26 15:04             ` Joseph Myers
  1 sibling, 2 replies; 70+ messages in thread
From: Adhemerval Zanella @ 2018-07-26 12:31 UTC (permalink / raw)
  To: libc-alpha



On 25/07/2018 17:45, Joseph Myers wrote:
> On Wed, 25 Jul 2018, Carlos O'Donell wrote:
> 
>> On 07/25/2018 12:31 PM, H.J. Lu wrote:
>>> From 70951c51d03623c10485380fcccd3a384dff20d6 Mon Sep 17 00:00:00 2001
>>> From: "H.J. Lu" <hjl.tools@gmail.com>
>>> Date: Wed, 25 Jul 2018 09:30:50 -0700
>>> Subject: [PATCH] ia64: Work around incorrect type of IA64 uc_sigmask
>>>
>>> 	* sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c: New file.
>>
>> Please file a bug for ia64 about this issue, then add the comment below.
> 
> It's bug 21634 (filed for XFAILing the relevant conform/ test assertions, 
> not because of any expectation of being fixable while staying 
> ABI-compatible).
> 

What would require to fix this issue for ia64? The kernel interface already
seems to use the expected sigset_t type for sc_mask and I think it would
be feasible to use the *context functions as is with only adjusting the
size of rt_sigprocmask to be dependent of _NSIG.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-26 12:31           ` Adhemerval Zanella
@ 2018-07-26 12:54             ` Carlos O'Donell
  2018-07-26 15:04             ` Joseph Myers
  1 sibling, 0 replies; 70+ messages in thread
From: Carlos O'Donell @ 2018-07-26 12:54 UTC (permalink / raw)
  To: Adhemerval Zanella, libc-alpha

On 07/26/2018 08:31 AM, Adhemerval Zanella wrote:
> 
> 
> On 25/07/2018 17:45, Joseph Myers wrote:
>> On Wed, 25 Jul 2018, Carlos O'Donell wrote:
>>
>>> On 07/25/2018 12:31 PM, H.J. Lu wrote:
>>>> From 70951c51d03623c10485380fcccd3a384dff20d6 Mon Sep 17 00:00:00 2001
>>>> From: "H.J. Lu" <hjl.tools@gmail.com>
>>>> Date: Wed, 25 Jul 2018 09:30:50 -0700
>>>> Subject: [PATCH] ia64: Work around incorrect type of IA64 uc_sigmask
>>>>
>>>> 	* sysdeps/unix/sysv/linux/ia64/tst-setcontext4.c: New file.
>>>
>>> Please file a bug for ia64 about this issue, then add the comment below.
>>
>> It's bug 21634 (filed for XFAILing the relevant conform/ test assertions, 
>> not because of any expectation of being fixable while staying 
>> ABI-compatible).
>>
> 
> What would require to fix this issue for ia64? The kernel interface already
> seems to use the expected sigset_t type for sc_mask and I think it would
> be feasible to use the *context functions as is with only adjusting the
> size of rt_sigprocmask to be dependent of _NSIG.

That all sounds reasonable :-)

c.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-26 12:31           ` Adhemerval Zanella
  2018-07-26 12:54             ` Carlos O'Donell
@ 2018-07-26 15:04             ` Joseph Myers
  2018-07-27 18:12               ` Adhemerval Zanella
  1 sibling, 1 reply; 70+ messages in thread
From: Joseph Myers @ 2018-07-26 15:04 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Thu, 26 Jul 2018, Adhemerval Zanella wrote:

> > It's bug 21634 (filed for XFAILing the relevant conform/ test assertions, 
> > not because of any expectation of being fixable while staying 
> > ABI-compatible).
> 
> What would require to fix this issue for ia64? The kernel interface already
> seems to use the expected sigset_t type for sc_mask and I think it would
> be feasible to use the *context functions as is with only adjusting the
> size of rt_sigprocmask to be dependent of _NSIG.

glibc sigset_t is much larger than kernel sigset_t.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-26 11:17 ` Florian Weimer
@ 2018-07-27 14:53   ` Florian Weimer
  2018-07-27 14:58     ` Florian Weimer
  2018-07-27 16:37     ` H.J. Lu
  0 siblings, 2 replies; 70+ messages in thread
From: Florian Weimer @ 2018-07-27 14:53 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha; +Cc: Carlos O'Donell

On 07/26/2018 01:16 PM, Florian Weimer wrote:
> On 07/21/2018 04:20 PM, H.J. Lu wrote:
>> These are the last 12 patches to enable Intel CET.  Tested by
>>
>> 1. build-many-glibcs.py.
>> 2. With --enable-cet and without --enable-cet for i686, x86-64 and x32
>> on non-CET x86-64 processors.
>> 3. With --enable-cet for x86-64 and x32 on CET SDV using the CET kernel
>> from cet branch at:
>>
>> https://github.com/yyu168/linux_cet/tree/cet
>>
>> When the shadow stack (SHSTK) is enabled, makecontext needs to allocate
>> a new shadow stack to go with the new stack allocated by the caller.
>> setcontext and swapcontext must properly handle the corresponding shadow
>> stack when the stack is switched.  Add more tests for user context
>> functions to provide more coverage for the shadow stack support.
> 
> Building glibc with --enable-cet currently breaks valgrind (even for 
> current CPUs which do not support CET):
> 
>    https://bugzilla.redhat.com/show_bug.cgi?id=1608824
> 
> Mark is working on a valgrind fix.

This has now been fixed (in valgrind-3.13.0-22.fc29.x86_64), but I get 
this instead:

==22== Conditional jump or move depends on uninitialised value(s)
==22==    at 0x10DF43: _dl_process_cet_property_note (dl-prop.h:82)
==22==    by 0x10DF43: _dl_process_pt_note (dl-prop.h:137)
==22==    by 0x10E713: _dl_map_object_from_fd (dl-load.c:1170)
==22==    by 0x11120B: _dl_map_object (dl-load.c:2241)
==22==    by 0x10D92B: dl_main (rtld.c:1050)
==22==    by 0x121A6E: _dl_sysdep_start (dl-sysdep.c:253)
==22==    by 0x10A1D7: _dl_start_final (rtld.c:413)
==22==    by 0x10A1D7: _dl_start (rtld.c:520)
==22==    by 0x109117: ??? (in …/build-x86_64-redhat-linux/elf/ld.so)
==22==    by 0x3: ???
==22==    by 0x1FFF000746: ???
==22==    by 0x1FFF000750: ???
==22==    by 0x1FFF00075F: ???
==22==    by 0x1FFF000770: ???
==22==  Uninitialised value was created by a stack allocation
==22==    at 0x10DE80: _dl_process_pt_note (dl-prop.h:111)

One potential cause could be that note traversal loop is buggy.

GDB says:

(gdb) bt
#0  0x000000000010df43 in _dl_process_cet_property_note 
(align=<optimized out>, size=48, note=0x1ffefff930, l=0x134160)
     at ../sysdeps/x86/dl-prop.h:82
#1  _dl_process_pt_note (l=l@entry=0x134160, ph=ph@entry=0x1fff000018, 
fd=fd@entry=3, fbp=fbp@entry=0x1ffefffe10)
     at ../sysdeps/x86/dl-prop.h:137
#2  0x000000000010e714 in _dl_map_object_from_fd 
(name=name@entry=0x1fff000721 "/usr/bin/true", origname=origname@entry=0x0,
     fd=<optimized out>, fbp=fbp@entry=0x1ffefffe10, realname=<optimized 
out>, loader=loader@entry=0x0, l_type=<optimized out>,
     mode=<optimized out>, stack_endp=<optimized out>, nsid=<optimized 
out>) at dl-load.c:1170
#3  0x000000000011120c in _dl_map_object (loader=loader@entry=0x0, 
name=0x1fff000721 "/usr/bin/true", type=type@entry=0,
     trace_mode=trace_mode@entry=0, mode=mode@entry=536870912, 
nsid=nsid@entry=0) at dl-load.c:2241
#4  0x000000000010d92c in dl_main (phdr=<optimized out>, phnum=10, 
user_entry=0x1fff0003d8, auxv=<optimized out>) at rtld.c:1050
#5  0x0000000000121a6f in _dl_sysdep_start 
(start_argptr=start_argptr@entry=0x1fff0004b0, 
dl_main=dl_main@entry=0x10a610 <dl_main>)
     at ../elf/dl-sysdep.c:253
#6  0x000000000010a1d8 in _dl_start_final (arg=0x1fff0004b0) at rtld.c:413
#7  _dl_start (arg=0x1fff0004b0) at rtld.c:520
#8  0x0000000000109118 in _start ()

The problem seems to be this:

	      unsigned int type = *(unsigned int *) ptr;
	      unsigned int datasz = *(unsigned int *) (ptr + 4);

	      ptr += 8;
	      if ((ptr + datasz) > ptr_end)
		break;

We load datasz and then check for having encountered the last note.  I'm 
checking a fix.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-27 14:53   ` Florian Weimer
@ 2018-07-27 14:58     ` Florian Weimer
  2018-07-27 16:37     ` H.J. Lu
  1 sibling, 0 replies; 70+ messages in thread
From: Florian Weimer @ 2018-07-27 14:58 UTC (permalink / raw)
  To: H.J. Lu, libc-alpha; +Cc: Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 4337 bytes --]

On 07/27/2018 04:53 PM, Florian Weimer wrote:
> On 07/26/2018 01:16 PM, Florian Weimer wrote:
>> On 07/21/2018 04:20 PM, H.J. Lu wrote:
>>> These are the last 12 patches to enable Intel CET.  Tested by
>>>
>>> 1. build-many-glibcs.py.
>>> 2. With --enable-cet and without --enable-cet for i686, x86-64 and x32
>>> on non-CET x86-64 processors.
>>> 3. With --enable-cet for x86-64 and x32 on CET SDV using the CET kernel
>>> from cet branch at:
>>>
>>> https://github.com/yyu168/linux_cet/tree/cet
>>>
>>> When the shadow stack (SHSTK) is enabled, makecontext needs to allocate
>>> a new shadow stack to go with the new stack allocated by the caller.
>>> setcontext and swapcontext must properly handle the corresponding shadow
>>> stack when the stack is switched.  Add more tests for user context
>>> functions to provide more coverage for the shadow stack support.
>>
>> Building glibc with --enable-cet currently breaks valgrind (even for 
>> current CPUs which do not support CET):
>>
>>    https://bugzilla.redhat.com/show_bug.cgi?id=1608824
>>
>> Mark is working on a valgrind fix.
> 
> This has now been fixed (in valgrind-3.13.0-22.fc29.x86_64), but I get 
> this instead:
> 
> ==22== Conditional jump or move depends on uninitialised value(s)
> ==22==    at 0x10DF43: _dl_process_cet_property_note (dl-prop.h:82)
> ==22==    by 0x10DF43: _dl_process_pt_note (dl-prop.h:137)
> ==22==    by 0x10E713: _dl_map_object_from_fd (dl-load.c:1170)
> ==22==    by 0x11120B: _dl_map_object (dl-load.c:2241)
> ==22==    by 0x10D92B: dl_main (rtld.c:1050)
> ==22==    by 0x121A6E: _dl_sysdep_start (dl-sysdep.c:253)
> ==22==    by 0x10A1D7: _dl_start_final (rtld.c:413)
> ==22==    by 0x10A1D7: _dl_start (rtld.c:520)
> ==22==    by 0x109117: ??? (in …/build-x86_64-redhat-linux/elf/ld.so)
> ==22==    by 0x3: ???
> ==22==    by 0x1FFF000746: ???
> ==22==    by 0x1FFF000750: ???
> ==22==    by 0x1FFF00075F: ???
> ==22==    by 0x1FFF000770: ???
> ==22==  Uninitialised value was created by a stack allocation
> ==22==    at 0x10DE80: _dl_process_pt_note (dl-prop.h:111)
> 
> One potential cause could be that note traversal loop is buggy.
> 
> GDB says:
> 
> (gdb) bt
> #0  0x000000000010df43 in _dl_process_cet_property_note 
> (align=<optimized out>, size=48, note=0x1ffefff930, l=0x134160)
>      at ../sysdeps/x86/dl-prop.h:82
> #1  _dl_process_pt_note (l=l@entry=0x134160, ph=ph@entry=0x1fff000018, 
> fd=fd@entry=3, fbp=fbp@entry=0x1ffefffe10)
>      at ../sysdeps/x86/dl-prop.h:137
> #2  0x000000000010e714 in _dl_map_object_from_fd 
> (name=name@entry=0x1fff000721 "/usr/bin/true", origname=origname@entry=0x0,
>      fd=<optimized out>, fbp=fbp@entry=0x1ffefffe10, realname=<optimized 
> out>, loader=loader@entry=0x0, l_type=<optimized out>,
>      mode=<optimized out>, stack_endp=<optimized out>, nsid=<optimized 
> out>) at dl-load.c:1170
> #3  0x000000000011120c in _dl_map_object (loader=loader@entry=0x0, 
> name=0x1fff000721 "/usr/bin/true", type=type@entry=0,
>      trace_mode=trace_mode@entry=0, mode=mode@entry=536870912, 
> nsid=nsid@entry=0) at dl-load.c:2241
> #4  0x000000000010d92c in dl_main (phdr=<optimized out>, phnum=10, 
> user_entry=0x1fff0003d8, auxv=<optimized out>) at rtld.c:1050
> #5  0x0000000000121a6f in _dl_sysdep_start 
> (start_argptr=start_argptr@entry=0x1fff0004b0, 
> dl_main=dl_main@entry=0x10a610 <dl_main>)
>      at ../elf/dl-sysdep.c:253
> #6  0x000000000010a1d8 in _dl_start_final (arg=0x1fff0004b0) at rtld.c:413
> #7  _dl_start (arg=0x1fff0004b0) at rtld.c:520
> #8  0x0000000000109118 in _start ()
> 
> The problem seems to be this:
> 
>            unsigned int type = *(unsigned int *) ptr;
>            unsigned int datasz = *(unsigned int *) (ptr + 4);
> 
>            ptr += 8;
>            if ((ptr + datasz) > ptr_end)
>          break;
> 
> We load datasz and then check for having encountered the last note.  I'm 
> checking a fix.

The attached patch should fix this.  Only lightly tested.

Thanks,
Florian

[-- Attachment #2: cet-note.patch --]
[-- Type: text/x-patch, Size: 745 bytes --]

Subject: [PATCH] x86: Fix out of bounds access in CET note parser
To: libc-alpha@sourceware.org

2018-07-27  Florian Weimer  <fweimer@redhat.com>

	* sysdeps/x86/dl-prop.h (_dl_process_cet_property_note): Fixed
	out-of-bounds access in note parser.

diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h
index d56e20a6dc..9ee70ebc01 100644
--- a/sysdeps/x86/dl-prop.h
+++ b/sysdeps/x86/dl-prop.h
@@ -73,7 +73,7 @@ _dl_process_cet_property_note (struct link_map *l,
 	  unsigned char *ptr = (unsigned char *) (note + 1) + 4;
 	  unsigned char *ptr_end = ptr + note->n_descsz;
 
-	  while (1)
+	  while (ptr_end - ptr >= 8)
 	    {
 	      unsigned int type = *(unsigned int *) ptr;
 	      unsigned int datasz = *(unsigned int *) (ptr + 4);

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-27 14:53   ` Florian Weimer
  2018-07-27 14:58     ` Florian Weimer
@ 2018-07-27 16:37     ` H.J. Lu
  2018-07-27 16:44       ` Florian Weimer
  1 sibling, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-27 16:37 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library, Carlos O'Donell

On Fri, Jul 27, 2018 at 7:53 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 07/26/2018 01:16 PM, Florian Weimer wrote:
>>
>> On 07/21/2018 04:20 PM, H.J. Lu wrote:
>>>
>>> These are the last 12 patches to enable Intel CET.  Tested by
>>>
>>> 1. build-many-glibcs.py.
>>> 2. With --enable-cet and without --enable-cet for i686, x86-64 and x32
>>> on non-CET x86-64 processors.
>>> 3. With --enable-cet for x86-64 and x32 on CET SDV using the CET kernel
>>> from cet branch at:
>>>
>>> https://github.com/yyu168/linux_cet/tree/cet
>>>
>>> When the shadow stack (SHSTK) is enabled, makecontext needs to allocate
>>> a new shadow stack to go with the new stack allocated by the caller.
>>> setcontext and swapcontext must properly handle the corresponding shadow
>>> stack when the stack is switched.  Add more tests for user context
>>> functions to provide more coverage for the shadow stack support.
>>
>>
>> Building glibc with --enable-cet currently breaks valgrind (even for
>> current CPUs which do not support CET):
>>
>>    https://bugzilla.redhat.com/show_bug.cgi?id=1608824
>>
>> Mark is working on a valgrind fix.
>
>
> This has now been fixed (in valgrind-3.13.0-22.fc29.x86_64), but I get this
> instead:
>
> ==22== Conditional jump or move depends on uninitialised value(s)
> ==22==    at 0x10DF43: _dl_process_cet_property_note (dl-prop.h:82)
> ==22==    by 0x10DF43: _dl_process_pt_note (dl-prop.h:137)
> ==22==    by 0x10E713: _dl_map_object_from_fd (dl-load.c:1170)
> ==22==    by 0x11120B: _dl_map_object (dl-load.c:2241)
> ==22==    by 0x10D92B: dl_main (rtld.c:1050)
> ==22==    by 0x121A6E: _dl_sysdep_start (dl-sysdep.c:253)
> ==22==    by 0x10A1D7: _dl_start_final (rtld.c:413)
> ==22==    by 0x10A1D7: _dl_start (rtld.c:520)
> ==22==    by 0x109117: ??? (in …/build-x86_64-redhat-linux/elf/ld.so)
> ==22==    by 0x3: ???
> ==22==    by 0x1FFF000746: ???
> ==22==    by 0x1FFF000750: ???
> ==22==    by 0x1FFF00075F: ???
> ==22==    by 0x1FFF000770: ???
> ==22==  Uninitialised value was created by a stack allocation
> ==22==    at 0x10DE80: _dl_process_pt_note (dl-prop.h:111)
>
> One potential cause could be that note traversal loop is buggy.
>
> GDB says:
>
> (gdb) bt
> #0  0x000000000010df43 in _dl_process_cet_property_note (align=<optimized
> out>, size=48, note=0x1ffefff930, l=0x134160)
>     at ../sysdeps/x86/dl-prop.h:82
> #1  _dl_process_pt_note (l=l@entry=0x134160, ph=ph@entry=0x1fff000018,
> fd=fd@entry=3, fbp=fbp@entry=0x1ffefffe10)
>     at ../sysdeps/x86/dl-prop.h:137
> #2  0x000000000010e714 in _dl_map_object_from_fd
> (name=name@entry=0x1fff000721 "/usr/bin/true", origname=origname@entry=0x0,
>     fd=<optimized out>, fbp=fbp@entry=0x1ffefffe10, realname=<optimized
> out>, loader=loader@entry=0x0, l_type=<optimized out>,
>     mode=<optimized out>, stack_endp=<optimized out>, nsid=<optimized out>)
> at dl-load.c:1170
> #3  0x000000000011120c in _dl_map_object (loader=loader@entry=0x0,
> name=0x1fff000721 "/usr/bin/true", type=type@entry=0,
>     trace_mode=trace_mode@entry=0, mode=mode@entry=536870912,
> nsid=nsid@entry=0) at dl-load.c:2241
> #4  0x000000000010d92c in dl_main (phdr=<optimized out>, phnum=10,
> user_entry=0x1fff0003d8, auxv=<optimized out>) at rtld.c:1050
> #5  0x0000000000121a6f in _dl_sysdep_start
> (start_argptr=start_argptr@entry=0x1fff0004b0,
> dl_main=dl_main@entry=0x10a610 <dl_main>)
>     at ../elf/dl-sysdep.c:253
> #6  0x000000000010a1d8 in _dl_start_final (arg=0x1fff0004b0) at rtld.c:413
> #7  _dl_start (arg=0x1fff0004b0) at rtld.c:520
> #8  0x0000000000109118 in _start ()
>
> The problem seems to be this:
>
>               unsigned int type = *(unsigned int *) ptr;
>               unsigned int datasz = *(unsigned int *) (ptr + 4);
>
>               ptr += 8;
>               if ((ptr + datasz) > ptr_end)
>                 break;
>
> We load datasz and then check for having encountered the last note.  I'm
> checking a fix.

How can I reproduce it?

[hjl@gnu-cfl-1 build-x86_64-linux]$ strace ./misc/tst-mntent --direct
execve("./misc/tst-mntent", ["./misc/tst-mntent", "--direct"],
0x7ffca647e038 /* 70 vars */) = 0
brk(NULL)                               = 0x205c000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd122d56f0) = -1 EINVAL (Invalid argument)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0x7fce93e8a000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
...
[hjl@gnu-cfl-1 build-x86_64-linux]$ valgrind ./misc/tst-mntent --direct
==21245== Memcheck, a memory error detector
==21245== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==21245== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==21245== Command: ./misc/tst-mntent --direct
==21245==
Found!
==21245==
==21245== HEAP SUMMARY:
==21245==     in use at exit: 552 bytes in 1 blocks
==21245==   total heap usage: 3 allocs, 2 frees, 8,744 bytes allocated
==21245==
==21245== LEAK SUMMARY:
==21245==    definitely lost: 0 bytes in 0 blocks
==21245==    indirectly lost: 0 bytes in 0 blocks
==21245==      possibly lost: 0 bytes in 0 blocks
==21245==    still reachable: 552 bytes in 1 blocks
==21245==         suppressed: 0 bytes in 0 blocks
==21245== Rerun with --leak-check=full to see details of leaked memory
==21245==
==21245== For counts of detected and suppressed errors, rerun with: -v
==21245== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[hjl@gnu-cfl-1 build-x86_64-linux]$


-- 
H.J.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-27 16:37     ` H.J. Lu
@ 2018-07-27 16:44       ` Florian Weimer
  2018-07-27 16:47         ` H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Florian Weimer @ 2018-07-27 16:44 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library, Carlos O'Donell

On 07/27/2018 06:37 PM, H.J. Lu wrote:

>> We load datasz and then check for having encountered the last note.  I'm
>> checking a fix.
> 
> How can I reproduce it?

Perhaps it is only visible with an explicit invocation of the dynamic 
linker?

I saw it while building GCC on Fedora rawhide.  I've pushed my latest 
changes (commit a4a5659439698554d18b9f1ef56cbd86591e217b) to the 
distribution Git, even though they do not build.  The valgrind check at 
the end of the build fails.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-27 16:44       ` Florian Weimer
@ 2018-07-27 16:47         ` H.J. Lu
  2018-07-27 16:49           ` Florian Weimer
  0 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-27 16:47 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library, Carlos O'Donell

On Fri, Jul 27, 2018 at 9:44 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 07/27/2018 06:37 PM, H.J. Lu wrote:
>
>>> We load datasz and then check for having encountered the last note.  I'm
>>> checking a fix.
>>
>>
>> How can I reproduce it?
>
>
> Perhaps it is only visible with an explicit invocation of the dynamic
> linker?
>
> I saw it while building GCC on Fedora rawhide.  I've pushed my latest
> changes (commit a4a5659439698554d18b9f1ef56cbd86591e217b) to the
> distribution Git, even though they do not build.  The valgrind check at the
> end of the build fails.

What is the command line to reproduce it with glibc build configured
with --enable-cet?


-- 
H.J.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-27 16:47         ` H.J. Lu
@ 2018-07-27 16:49           ` Florian Weimer
  2018-07-27 17:13             ` H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Florian Weimer @ 2018-07-27 16:49 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library, Carlos O'Donell

On 07/27/2018 06:47 PM, H.J. Lu wrote:
> On Fri, Jul 27, 2018 at 9:44 AM, Florian Weimer <fweimer@redhat.com> wrote:
>> On 07/27/2018 06:37 PM, H.J. Lu wrote:
>>
>>>> We load datasz and then check for having encountered the last note.  I'm
>>>> checking a fix.
>>>
>>>
>>> How can I reproduce it?
>>
>>
>> Perhaps it is only visible with an explicit invocation of the dynamic
>> linker?
>>
>> I saw it while building GCC on Fedora rawhide.  I've pushed my latest
>> changes (commit a4a5659439698554d18b9f1ef56cbd86591e217b) to the
>> distribution Git, even though they do not build.  The valgrind check at the
>> end of the build fails.
> 
> What is the command line to reproduce it with glibc build configured
> with --enable-cet?

This command is run inside the build directory:

elf/ld.so --library-path .:elf:nptl:dlfcn /usr/bin/valgrind 
--vgdb-error=1 --track-origins=yes --error-exitcode=1 elf/ld.so 
--library-path .:elf:nptl:dlfcn /usr/bin/true

Thanks,
Florian

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-27 16:49           ` Florian Weimer
@ 2018-07-27 17:13             ` H.J. Lu
  2018-07-27 17:50               ` H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-27 17:13 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library, Carlos O'Donell

On Fri, Jul 27, 2018 at 9:49 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 07/27/2018 06:47 PM, H.J. Lu wrote:
>>
>> On Fri, Jul 27, 2018 at 9:44 AM, Florian Weimer <fweimer@redhat.com>
>> wrote:
>>>
>>> On 07/27/2018 06:37 PM, H.J. Lu wrote:
>>>
>>>>> We load datasz and then check for having encountered the last note.
>>>>> I'm
>>>>> checking a fix.
>>>>
>>>>
>>>>
>>>> How can I reproduce it?
>>>
>>>
>>>
>>> Perhaps it is only visible with an explicit invocation of the dynamic
>>> linker?
>>>
>>> I saw it while building GCC on Fedora rawhide.  I've pushed my latest
>>> changes (commit a4a5659439698554d18b9f1ef56cbd86591e217b) to the
>>> distribution Git, even though they do not build.  The valgrind check at
>>> the
>>> end of the build fails.
>>
>>
>> What is the command line to reproduce it with glibc build configured
>> with --enable-cet?
>
>
> This command is run inside the build directory:
>
> elf/ld.so --library-path .:elf:nptl:dlfcn /usr/bin/valgrind --vgdb-error=1
> --track-origins=yes --error-exitcode=1 elf/ld.so --library-path
> .:elf:nptl:dlfcn /usr/bin/true
>

[hjl@gnu-cet-2 build-x86_64-linux]$ elf/ld.so --library-path
.:elf:nptl:dlfcn /usr/bin/valgrind --vgdb-error=1 --track-origins=yes
--error-exitcode=1 elf/ld.so --library-path .:elf:nptl:dlfcn
/usr/bin/true
==1086== Memcheck, a memory error detector
==1086== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1086== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1086== Command: elf/ld.so --library-path .:elf:nptl:dlfcn /usr/bin/true
==1086==
==1086==
==1086== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==1086==   /path/to/gdb elf/ld.so
==1086== and then give GDB the following command
==1086==   target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=1086
==1086== --pid is optional if only one valgrind process is running
==1086==
==1086==
==1086== HEAP SUMMARY:
==1086==     in use at exit: 0 bytes in 0 blocks
==1086==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==1086==
==1086== All heap blocks were freed -- no leaks are possible
==1086==
==1086== For counts of detected and suppressed errors, rerun with: -v
==1086== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[hjl@gnu-cet-2 build-x86_64-linux]$ strace  elf/ld.so
execve("elf/ld.so", ["elf/ld.so"], 0x7fff35c62fc0 /* 51 vars */) = 0
brk(NULL)                               = 0x7f0fb46ec000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffecf6aedf0) = 0
writev(2, [{iov_base="Usage: ld.so [OPTION]... EXECUTA"...,
iov_len=1373}], 1Usage: ld.so [OPTION]... EXECUTABLE-FILE
[ARGS-FOR-PROGRAM...]
You have invoked `ld.so', the helper program for shared library executables.
This program usually lives in the file `/lib/ld.so', and special directives
in executable files using ELF shared libraries tell the system's program
loader to load the helper program from this file.  This helper program loads
the shared libraries needed by the program executable, prepares the program
to run, and runs it.  You may invoke this helper program directly from the
command line to load and run an ELF executable file; this is like executing
that file itself, but always uses this helper program from the file you
specified, instead of the helper program file specified in the executable
file you run.  This is mostly of use for maintainers to test new versions
of this helper program; chances are you did not intend to run this program.

  --list                list all dependencies and how they are resolved
  --verify              verify that given object really is a dynamically linked
object we can handle
  --inhibit-cache       Do not use /etc/ld.so.cache
  --library-path PATH   use given PATH instead of content of the environment
variable LD_LIBRARY_PATH
  --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object names
in LIST
  --audit LIST          use objects named in LIST as auditors
) = 1373
exit_group(127)                         = ?
+++ exited with 127 +++
[hjl@gnu-cet-2 build-x86_64-linux]$



-- 
H.J.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-27 17:13             ` H.J. Lu
@ 2018-07-27 17:50               ` H.J. Lu
  2018-07-27 17:52                 ` Florian Weimer
  0 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-27 17:50 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library, Carlos O'Donell

On Fri, Jul 27, 2018 at 10:13 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Jul 27, 2018 at 9:49 AM, Florian Weimer <fweimer@redhat.com> wrote:
>> On 07/27/2018 06:47 PM, H.J. Lu wrote:
>>>
>>> On Fri, Jul 27, 2018 at 9:44 AM, Florian Weimer <fweimer@redhat.com>
>>> wrote:
>>>>
>>>> On 07/27/2018 06:37 PM, H.J. Lu wrote:
>>>>
>>>>>> We load datasz and then check for having encountered the last note.
>>>>>> I'm
>>>>>> checking a fix.
>>>>>
>>>>>
>>>>>
>>>>> How can I reproduce it?
>>>>
>>>>
>>>>
>>>> Perhaps it is only visible with an explicit invocation of the dynamic
>>>> linker?
>>>>
>>>> I saw it while building GCC on Fedora rawhide.  I've pushed my latest
>>>> changes (commit a4a5659439698554d18b9f1ef56cbd86591e217b) to the
>>>> distribution Git, even though they do not build.  The valgrind check at
>>>> the
>>>> end of the build fails.
>>>
>>>
>>> What is the command line to reproduce it with glibc build configured
>>> with --enable-cet?
>>
>>
>> This command is run inside the build directory:
>>
>> elf/ld.so --library-path .:elf:nptl:dlfcn /usr/bin/valgrind --vgdb-error=1
>> --track-origins=yes --error-exitcode=1 elf/ld.so --library-path
>> .:elf:nptl:dlfcn /usr/bin/true
>>
>
> [hjl@gnu-cet-2 build-x86_64-linux]$ elf/ld.so --library-path
> .:elf:nptl:dlfcn /usr/bin/valgrind --vgdb-error=1 --track-origins=yes
> --error-exitcode=1 elf/ld.so --library-path .:elf:nptl:dlfcn
> /usr/bin/true
>

Your note may be different.  Mine has

[hjl@gnu-cet-1 build-x86_64-linux]$ readelf -n elf/ld.so

Displaying notes found in: .note.gnu.build-id
  Owner                 Data size Description
  GNU                  0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: 47063ae06339e7226b68aa983cd3225f2dfa1ee2

Displaying notes found in: .note.gnu.property
  Owner                 Data size Description
  GNU                  0x00000010 NT_GNU_PROPERTY_TYPE_0
      Properties: x86 feature: IBT, SHSTK
[hjl@gnu-cet-1 build-x86_64-linux]$

Can you send me your elf/ld.so?

-- 
H.J.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-27 17:50               ` H.J. Lu
@ 2018-07-27 17:52                 ` Florian Weimer
  2018-07-27 17:56                   ` H.J. Lu
  0 siblings, 1 reply; 70+ messages in thread
From: Florian Weimer @ 2018-07-27 17:52 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library, Carlos O'Donell

[-- Attachment #1: Type: text/plain, Size: 2211 bytes --]

On 07/27/2018 07:50 PM, H.J. Lu wrote:
> On Fri, Jul 27, 2018 at 10:13 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Fri, Jul 27, 2018 at 9:49 AM, Florian Weimer <fweimer@redhat.com> wrote:
>>> On 07/27/2018 06:47 PM, H.J. Lu wrote:
>>>>
>>>> On Fri, Jul 27, 2018 at 9:44 AM, Florian Weimer <fweimer@redhat.com>
>>>> wrote:
>>>>>
>>>>> On 07/27/2018 06:37 PM, H.J. Lu wrote:
>>>>>
>>>>>>> We load datasz and then check for having encountered the last note.
>>>>>>> I'm
>>>>>>> checking a fix.
>>>>>>
>>>>>>
>>>>>>
>>>>>> How can I reproduce it?
>>>>>
>>>>>
>>>>>
>>>>> Perhaps it is only visible with an explicit invocation of the dynamic
>>>>> linker?
>>>>>
>>>>> I saw it while building GCC on Fedora rawhide.  I've pushed my latest
>>>>> changes (commit a4a5659439698554d18b9f1ef56cbd86591e217b) to the
>>>>> distribution Git, even though they do not build.  The valgrind check at
>>>>> the
>>>>> end of the build fails.
>>>>
>>>>
>>>> What is the command line to reproduce it with glibc build configured
>>>> with --enable-cet?
>>>
>>>
>>> This command is run inside the build directory:
>>>
>>> elf/ld.so --library-path .:elf:nptl:dlfcn /usr/bin/valgrind --vgdb-error=1
>>> --track-origins=yes --error-exitcode=1 elf/ld.so --library-path
>>> .:elf:nptl:dlfcn /usr/bin/true
>>>
>>
>> [hjl@gnu-cet-2 build-x86_64-linux]$ elf/ld.so --library-path
>> .:elf:nptl:dlfcn /usr/bin/valgrind --vgdb-error=1 --track-origins=yes
>> --error-exitcode=1 elf/ld.so --library-path .:elf:nptl:dlfcn
>> /usr/bin/true
>>
> 
> Your note may be different.  Mine has
> 
> [hjl@gnu-cet-1 build-x86_64-linux]$ readelf -n elf/ld.so
> 
> Displaying notes found in: .note.gnu.build-id
>    Owner                 Data size Description
>    GNU                  0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
>      Build ID: 47063ae06339e7226b68aa983cd3225f2dfa1ee2
> 
> Displaying notes found in: .note.gnu.property
>    Owner                 Data size Description
>    GNU                  0x00000010 NT_GNU_PROPERTY_TYPE_0
>        Properties: x86 feature: IBT, SHSTK
> [hjl@gnu-cet-1 build-x86_64-linux]$
> 
> Can you send me your elf/ld.so?

The note for /bin/true causes the problem.  I'm attaching it.

Thanks,
Florian

[-- Attachment #2: true --]
[-- Type: application/octet-stream, Size: 43832 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-27 17:52                 ` Florian Weimer
@ 2018-07-27 17:56                   ` H.J. Lu
  2018-07-27 18:20                     ` Florian Weimer
  0 siblings, 1 reply; 70+ messages in thread
From: H.J. Lu @ 2018-07-27 17:56 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library, Carlos O'Donell

On Fri, Jul 27, 2018 at 10:52 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 07/27/2018 07:50 PM, H.J. Lu wrote:
>>
>> On Fri, Jul 27, 2018 at 10:13 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>
>>> On Fri, Jul 27, 2018 at 9:49 AM, Florian Weimer <fweimer@redhat.com>
>>> wrote:
>>>>
>>>> On 07/27/2018 06:47 PM, H.J. Lu wrote:
>>>>>
>>>>>
>>>>> On Fri, Jul 27, 2018 at 9:44 AM, Florian Weimer <fweimer@redhat.com>
>>>>> wrote:
>>>>>>
>>>>>>
>>>>>> On 07/27/2018 06:37 PM, H.J. Lu wrote:
>>>>>>
>>>>>>>> We load datasz and then check for having encountered the last note.
>>>>>>>> I'm
>>>>>>>> checking a fix.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> How can I reproduce it?
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Perhaps it is only visible with an explicit invocation of the dynamic
>>>>>> linker?
>>>>>>
>>>>>> I saw it while building GCC on Fedora rawhide.  I've pushed my latest
>>>>>> changes (commit a4a5659439698554d18b9f1ef56cbd86591e217b) to the
>>>>>> distribution Git, even though they do not build.  The valgrind check
>>>>>> at
>>>>>> the
>>>>>> end of the build fails.
>>>>>
>>>>>
>>>>>
>>>>> What is the command line to reproduce it with glibc build configured
>>>>> with --enable-cet?
>>>>
>>>>
>>>>
>>>> This command is run inside the build directory:
>>>>
>>>> elf/ld.so --library-path .:elf:nptl:dlfcn /usr/bin/valgrind
>>>> --vgdb-error=1
>>>> --track-origins=yes --error-exitcode=1 elf/ld.so --library-path
>>>> .:elf:nptl:dlfcn /usr/bin/true
>>>>
>>>
>>> [hjl@gnu-cet-2 build-x86_64-linux]$ elf/ld.so --library-path
>>> .:elf:nptl:dlfcn /usr/bin/valgrind --vgdb-error=1 --track-origins=yes
>>> --error-exitcode=1 elf/ld.so --library-path .:elf:nptl:dlfcn
>>> /usr/bin/true
>>>
>>
>> Your note may be different.  Mine has
>>
>> [hjl@gnu-cet-1 build-x86_64-linux]$ readelf -n elf/ld.so
>>
>> Displaying notes found in: .note.gnu.build-id
>>    Owner                 Data size Description
>>    GNU                  0x00000014 NT_GNU_BUILD_ID (unique build ID
>> bitstring)
>>      Build ID: 47063ae06339e7226b68aa983cd3225f2dfa1ee2
>>
>> Displaying notes found in: .note.gnu.property
>>    Owner                 Data size Description
>>    GNU                  0x00000010 NT_GNU_PROPERTY_TYPE_0
>>        Properties: x86 feature: IBT, SHSTK
>> [hjl@gnu-cet-1 build-x86_64-linux]$
>>
>> Can you send me your elf/ld.so?
>
>
> The note for /bin/true causes the problem.  I'm attaching it.
>

Yes, I can reproduce it.  Let me take a look.

-- 
H.J.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-26 15:04             ` Joseph Myers
@ 2018-07-27 18:12               ` Adhemerval Zanella
  2018-07-27 19:18                 ` Joseph Myers
  0 siblings, 1 reply; 70+ messages in thread
From: Adhemerval Zanella @ 2018-07-27 18:12 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha



On 26/07/2018 12:04, Joseph Myers wrote:
> On Thu, 26 Jul 2018, Adhemerval Zanella wrote:
> 
>>> It's bug 21634 (filed for XFAILing the relevant conform/ test assertions, 
>>> not because of any expectation of being fixable while staying 
>>> ABI-compatible).
>>
>> What would require to fix this issue for ia64? The kernel interface already
>> seems to use the expected sigset_t type for sc_mask and I think it would
>> be feasible to use the *context functions as is with only adjusting the
>> size of rt_sigprocmask to be dependent of _NSIG.
> 
> glibc sigset_t is much larger than kernel sigset_t.
> 

Sigh, indeed 'new' kernel sigset_t has the same size as previous one,
it has changed only to use a struct. I still think it would be feasible
to change uc_sigmask to glibc sigset_t, the *context functions is
already using the expected sizes for __NR_sigprocmask. Do you see 
anything that need further adjustment?

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET
  2018-07-27 17:56                   ` H.J. Lu
@ 2018-07-27 18:20                     ` Florian Weimer
  0 siblings, 0 replies; 70+ messages in thread
From: Florian Weimer @ 2018-07-27 18:20 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library, Carlos O'Donell

On 07/27/2018 07:56 PM, H.J. Lu wrote:
> Yes, I can reproduce it.  Let me take a look.

Great.  Did you see the patch I posted?

Thanks,
Florian

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/12] Add another test for setcontext
  2018-07-27 18:12               ` Adhemerval Zanella
@ 2018-07-27 19:18                 ` Joseph Myers
  0 siblings, 0 replies; 70+ messages in thread
From: Joseph Myers @ 2018-07-27 19:18 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Fri, 27 Jul 2018, Adhemerval Zanella wrote:

> Sigh, indeed 'new' kernel sigset_t has the same size as previous one,
> it has changed only to use a struct. I still think it would be feasible
> to change uc_sigmask to glibc sigset_t, the *context functions is
> already using the expected sizes for __NR_sigprocmask. Do you see 
> anything that need further adjustment?

Well, there are all the usual risks of any structure size change.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 70+ messages in thread

end of thread, other threads:[~2018-07-27 19:18 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-21 14:20 [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET H.J. Lu
2018-07-21 14:20 ` [PATCH 09/12] Add a test for multiple makecontext calls H.J. Lu
2018-07-25  3:31   ` Carlos O'Donell
2018-07-25 11:55     ` H.J. Lu
2018-07-21 14:20 ` [PATCH 02/12] x86-64: Add endbr64 to tst-quadmod[12].S H.J. Lu
2018-07-24  2:53   ` Carlos O'Donell
2018-07-24 11:58     ` H.J. Lu
2018-07-24 12:27       ` Carlos O'Donell
2018-07-21 14:20 ` [PATCH 04/12] x86/CET: Extend arch_prctl syscall for CET control H.J. Lu
2018-07-24  3:05   ` Carlos O'Donell
2018-07-24 13:24     ` V2 " H.J. Lu
2018-07-24 13:49       ` Carlos O'Donell
2018-07-24 14:28       ` Joseph Myers
2018-07-24 15:29         ` Carlos O'Donell
2018-07-21 14:20 ` [PATCH 10/12] Add another test for setcontext H.J. Lu
2018-07-25  3:36   ` Carlos O'Donell
2018-07-25 16:21   ` Florian Weimer
2018-07-25 16:31     ` H.J. Lu
2018-07-25 20:40       ` Carlos O'Donell
2018-07-25 20:42         ` Florian Weimer
2018-07-25 21:19           ` Carlos O'Donell
2018-07-25 21:21             ` Florian Weimer
2018-07-25 21:27               ` Carlos O'Donell
2018-07-25 21:31                 ` Florian Weimer
2018-07-25 21:54           ` Andreas Schwab
2018-07-25 20:45         ` Joseph Myers
2018-07-25 20:57           ` H.J. Lu
2018-07-26 12:31           ` Adhemerval Zanella
2018-07-26 12:54             ` Carlos O'Donell
2018-07-26 15:04             ` Joseph Myers
2018-07-27 18:12               ` Adhemerval Zanella
2018-07-27 19:18                 ` Joseph Myers
2018-07-21 14:20 ` [PATCH 12/12] Add tests for setcontext on the context from makecontext H.J. Lu
2018-07-25  3:51   ` Carlos O'Donell
2018-07-25 12:14     ` H.J. Lu
2018-07-21 14:20 ` [PATCH 07/12] x86/CET: Add tests with legacy non-CET shared objects H.J. Lu
2018-07-25  3:21   ` Carlos O'Donell
2018-07-25  3:22     ` Carlos O'Donell
2018-07-25 11:46     ` H.J. Lu
2018-07-25 14:28       ` Carlos O'Donell
2018-07-21 14:20 ` [PATCH 08/12] Add a test for swapcontext with a wrapper H.J. Lu
2018-07-25  3:27   ` Carlos O'Donell
2018-07-25 11:50     ` H.J. Lu
2018-07-21 14:21 ` [PATCH 05/12] x86: Rename __glibc_reserved2 to ssp_base in tcbhead_t H.J. Lu
2018-07-24 20:49   ` Carlos O'Donell
2018-07-21 14:21 ` [PATCH 06/12] x86-64/CET: Extend ucontext_t to save shadow stack H.J. Lu
2018-07-24 20:49   ` Carlos O'Donell
2018-07-21 14:21 ` [PATCH 03/12] Add <bits/indirect-return.h> H.J. Lu
2018-07-24 12:57   ` Carlos O'Donell
2018-07-24 13:52     ` V2 " H.J. Lu
2018-07-21 14:21 ` [PATCH 11/12] Add a test for multiple setcontext calls H.J. Lu
2018-07-25  3:38   ` Carlos O'Donell
2018-07-21 14:21 ` [PATCH 01/12] x86: Update vfork to pop shadow stack H.J. Lu
2018-07-24  2:47   ` Carlos O'Donell
2018-07-24 12:25     ` H.J. Lu
2018-07-24 12:32       ` Carlos O'Donell
2018-07-24 13:17         ` H.J. Lu
2018-07-24  1:41 ` [PATCH 00/12] x86/CET: The last 12 patches to enable Intel CET Carlos O'Donell
2018-07-26 11:17 ` Florian Weimer
2018-07-27 14:53   ` Florian Weimer
2018-07-27 14:58     ` Florian Weimer
2018-07-27 16:37     ` H.J. Lu
2018-07-27 16:44       ` Florian Weimer
2018-07-27 16:47         ` H.J. Lu
2018-07-27 16:49           ` Florian Weimer
2018-07-27 17:13             ` H.J. Lu
2018-07-27 17:50               ` H.J. Lu
2018-07-27 17:52                 ` Florian Weimer
2018-07-27 17:56                   ` H.J. Lu
2018-07-27 18:20                     ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).