This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] ucontext.h: Add __INDIRECT_RETURN
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Wed, 18 Jul 2018 10:35:58 -0700
- Subject: [PATCH] ucontext.h: Add __INDIRECT_RETURN
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
On x86, swapcontext returns via indirect branch when shadow stack is
enabled. Add __INDIRECT_RETURN to swapcontext to mark it return via
indirect branch. When shadow stack is enabled, __INDIRECT_RETURN is
defined with indirect_return attribute, which has been added to GCC 9.
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)
if indirect_return attribute isn't available.
OK for master branch?
H.J.
---
* stdlib/ucontext.h (__INDIRECT_RETURN): New. Define as empty
if not defined.
(swapcontext): Add __INDIRECT_RETURN.
* string/tst-xbzero-opt.c (ALWAYS_INLINE): New.
(prepare_test_buffer): Use it.
* sysdeps/unix/sysv/linux/x86/sys/ucontext.h
(__INDIRECT_RETURN): New. Defined with indirect_return attribute
or returns_twice attribute when shadow stack is enabled.
---
stdlib/ucontext.h | 7 ++++++-
string/tst-xbzero-opt.c | 10 +++++++++-
sysdeps/unix/sysv/linux/x86/sys/ucontext.h | 11 +++++++++++
3 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/stdlib/ucontext.h b/stdlib/ucontext.h
index eec7611631..0f29c38d71 100644
--- a/stdlib/ucontext.h
+++ b/stdlib/ucontext.h
@@ -25,6 +25,10 @@
/* Get machine dependent definition of data structures. */
#include <sys/ucontext.h>
+#ifndef __INDIRECT_RETURN
+# define __INDIRECT_RETURN
+#endif
+
__BEGIN_DECLS
/* Get user context and store it in variable pointed to by UCP. */
@@ -36,7 +40,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..d49ddef9ae 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__ && !__GNUC_PREREQ (9, 0)
+/* Note: swapcontext returns via indirect branch when SHSTK is enabled.
+ Without indirect_return attribute in GCC 9, 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/unix/sysv/linux/x86/sys/ucontext.h b/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
index afb7c181bf..0b2b1e4804 100644
--- a/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
+++ b/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
@@ -24,6 +24,17 @@
#include <bits/types/sigset_t.h>
#include <bits/types/stack_t.h>
+#ifndef __INDIRECT_RETURN
+# if defined __CET__ && (__CET__ & 2) != 0
+/* Note: Functions returned via indirect branch returns once. Without
+ indirect_return attribute in GCC 9, use returns_twice attribute. */
+# if __GNUC_PREREQ (9, 0)
+# define __INDIRECT_RETURN __attribute__ ((__indirect_return__))
+# else
+# define __INDIRECT_RETURN __attribute__ ((__returns_twice__))
+# endif
+# endif
+#endif
#ifdef __USE_MISC
# define __ctx(fld) fld
--
2.17.1