Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Need indirect_return function attribute for CET #37180

Open Quuxplusone opened 6 years ago

Quuxplusone commented 6 years ago
Bugzilla Link PR38207
Status NEW
Importance P normal
Reported by H.J. Lu (hjl.tools@gmail.com)
Reported on 2018-07-17 20:56:39 -0700
Last modified on 2018-07-20 09:45:01 -0700
Version trunk
Hardware PC Linux
CC aivchenk@gmail.com, craig.topper@gmail.com, efriedma@quicinc.com, hfinkel@anl.gov, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also PR38249
On x86, swapcontext may return via indirect branch when shadow stack
is enabled.  To support code instrumentation of control-flow transfers
with -fcf-protection, add indirect_return function attribute to inform
compiler that a function may return via indirect branch.

Note: Unlike setjmp, swapcontext only returns once.  Mark it return
twice will unnecessarily disable compiler optimization as shown in
the testcase here.

This has been implemented in GCC 9:

https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=d4d9fba553cd199f422fbd10cf3de72a9b0eafa8

We need a way to generate ENDBR in compiler-rt:

INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
            struct ucontext_t *ucp) {
  static bool reported_warning = false;
  if (!reported_warning) {
    Report("WARNING: ASan doesn't fully support makecontext/swapcontext "
           "functions and may produce false positives in some cases!\n");
    reported_warning = true;
  }
  // Clear shadow memory for new context (it may share stack
  // with current context).
  uptr stack, ssize;
  ReadContextStack(ucp, &stack, &ssize);
  ClearShadowMemoryForContextStack(stack, ssize);
  int res = REAL(swapcontext)(oucp, ucp);
<<<< Need ENDBR here.
  // 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
  // state.
  ClearShadowMemoryForContextStack(stack, ssize);
  return res;
}
Quuxplusone commented 6 years ago
indirect_return attribute needs to be allowed on variable or type of
function pointer.  A GCC patch has been submitted:

https://gcc.gnu.org/ml/gcc-patches/2018-07/msg01007.html

and asan/asan_interceptors.cc can be fixed with

https://gcc.gnu.org/ml/gcc-patches/2018-07/msg01008.html

with indirect_return attribute.