[compiler-rt] r337603 - Mark REAL(swapcontext) with indirect_return attribute on x86
H.J. Lu via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 20 12:24:11 PDT 2018
Author: hjl
Date: Fri Jul 20 12:24:11 2018
New Revision: 337603
URL: http://llvm.org/viewvc/llvm-project?rev=337603&view=rev
Log:
Mark REAL(swapcontext) with indirect_return attribute on x86
When shadow stack from Intel CET is enabled, the first instruction of all
indirect branch targets must be a special instruction, ENDBR.
lib/asan/asan_interceptors.cc has
...
int res = REAL(swapcontext)(oucp, ucp);
...
REAL(swapcontext) is a function pointer to swapcontext in libc. Since
swapcontext may return via indirect branch on x86 when shadow stack is
enabled, as in this case,
int res = REAL(swapcontext)(oucp, ucp);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This function may be
returned via an indirect branch.
Here compiler must insert ENDBR after call, like
call *bar(%rip)
endbr64
I opened an LLVM bug:
https://bugs.llvm.org/show_bug.cgi?id=38207
to add the indirect_return attribute so that it can be used to inform
compiler to insert ENDBR after REAL(swapcontext) call. We mark
REAL(swapcontext) with the indirect_return attribute if it is available.
This fixed:
https://bugs.llvm.org/show_bug.cgi?id=38249
Reviewed By: eugenis
Differential Revision: https://reviews.llvm.org/D49608
Modified:
compiler-rt/trunk/lib/asan/asan_interceptors.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=337603&r1=337602&r2=337603&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Fri Jul 20 12:24:11 2018
@@ -275,7 +275,15 @@ INTERCEPTOR(int, swapcontext, struct uco
uptr stack, ssize;
ReadContextStack(ucp, &stack, &ssize);
ClearShadowMemoryForContextStack(stack, ssize);
+#if __has_attribute(__indirect_return__) && \
+ (defined(__x86_64__) || defined(__i386__))
+ int (*real_swapcontext)(struct ucontext_t *, struct ucontext_t *)
+ __attribute__((__indirect_return__))
+ = REAL(swapcontext);
+ int res = real_swapcontext(oucp, ucp);
+#else
int res = REAL(swapcontext)(oucp, ucp);
+#endif
// swapcontext technically does not return, but program may swap context to
// "oucp" later, that would look as if swapcontext() returned 0.
// We need to clear shadow for ucp once again, as it may be in arbitrary
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h?rev=337603&r1=337602&r2=337603&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h Fri Jul 20 12:24:11 2018
@@ -122,6 +122,11 @@
# define __has_feature(x) 0
#endif
+// Older GCCs do not understand __has_attribute.
+#if !defined(__has_attribute)
+# define __has_attribute(x) 0
+#endif
+
// For portability reasons we do not include stddef.h, stdint.h or any other
// system header, but we do need some basic types that are not defined
// in a portable way by the language itself.
More information about the llvm-commits
mailing list