On Wed, Jul 18, 2018 at 11:45 AM, Kostya Serebryany <k...@google.com> wrote:
> On Wed, Jul 18, 2018 at 11:40 AM H.J. Lu <hjl.to...@gmail.com> wrote:
>>
>> On Wed, Jul 18, 2018 at 11:18 AM, Kostya Serebryany <k...@google.com> wrote:
>> > What's ENDBR and do we really need to have it in compiler-rt?
>>
>> When shadow stack from Intel CET is enabled,  the first instruction of all
>> indirect branch targets must be a special instruction, ENDBR.  In this case,
>
> I am confused.
> CET is a security mitigation feature (and ENDBR is a pretty weak form of 
> such),
> while ASAN is a testing tool, rarely used in production is almost
> never as a mitigation (which it is not!).
> Why would anyone need to combine CET and ASAN in one process?
>

CET is transparent to ASAN.  It is perfectly OK to use -fcf-protection to
enable CET together with ASAN.

> Also, CET doesn't exist in the hardware yet, at least not publicly available.
> Which means there should be no rush (am I wrong?) and we can do things
> in the correct order:
> implement the Clang/LLVM support, make the compiler-rt change in LLVM,
> merge back to GCC.

I am working with our LLVM people to address this.

H.J.
> --kcc
>
>>
>> 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
>>
>> > As usual, I am opposed to any gcc compiler-rt that bypass upstream.
>>
>> We want it to be fixed in upstream.  That is why I opened an LLVM bug.
>>
>>
>> > --kcc
>> >
>> > On Wed, Jul 18, 2018 at 8:37 AM H.J. Lu <hongjiu...@intel.com> wrote:
>> >>
>> >> 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, we need to call REAL(swapcontext) with indirect_return attribute
>> >> on x86 so that compiler can insert ENDBR after REAL(swapcontext) call.
>> >>
>> >> I opened an LLVM bug:
>> >>
>> >> https://bugs.llvm.org/show_bug.cgi?id=38207
>> >>
>> >> But it won't get fixed before indirect_return attribute is added to
>> >> LLVM.  I'd like to get it fixed in GCC first.
>> >>
>> >> Tested on i386 and x86-64.  OK for trunk after
>> >>
>> >> https://gcc.gnu.org/ml/gcc-patches/2018-07/msg01007.html
>> >>
>> >> is approved?
>> >>
>> >> Thanks.
>> >>
>> >>
>> >> H.J.
>> >> ---
>> >>         PR target/86560
>> >>         * asan/asan_interceptors.cc (swapcontext): Call REAL(swapcontext)
>> >>         with indirect_return attribute on x86.
>> >> ---
>> >>  libsanitizer/asan/asan_interceptors.cc | 6 ++++++
>> >>  1 file changed, 6 insertions(+)
>> >>
>> >> diff --git a/libsanitizer/asan/asan_interceptors.cc 
>> >> b/libsanitizer/asan/asan_interceptors.cc
>> >> index a8f4b72723f..b8dde4f19c5 100644
>> >> --- a/libsanitizer/asan/asan_interceptors.cc
>> >> +++ b/libsanitizer/asan/asan_interceptors.cc
>> >> @@ -267,7 +267,13 @@ INTERCEPTOR(int, swapcontext, struct ucontext_t 
>> >> *oucp,
>> >>    uptr stack, ssize;
>> >>    ReadContextStack(ucp, &stack, &ssize);
>> >>    ClearShadowMemoryForContextStack(stack, ssize);
>> >> +#if 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
>> >> --
>> >> 2.17.1
>> >>
>>
>>
>>
>> --
>> H.J.



-- 
H.J.

Reply via email to