diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-01-25 23:34:38 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-01-25 23:34:38 +0000 |
commit | a4225860cbaea66a30477500507710875fb84516 (patch) | |
tree | 82ce4808e09c768f47b91999583b6104bc688c2c /lib/cfi/cfi.cc | |
parent | 9f33bba73dfa49d4f4e0eac68a1768d13ea51642 (diff) |
[cfi] Cross-DSO CFI diagnostic mode (compiler-rt part)
* add __cfi_slowpath_diag with a 3rd parameter which is a pointer to
the diagnostic info for the ubsan handlers.
*__cfi_check gets a 3rd parameter as well.
* unify vcall/cast/etc and icall diagnostic info format, and merge
the handlers to have a single entry point (actually two points due
to abort/noabort variants).
* tests
Note that this comes with a tiny overhead in the non-diag mode:
cfi_slowpath must pass 0 as the 3rd argument to cfi_check.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@258744 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/cfi/cfi.cc')
-rw-r--r-- | lib/cfi/cfi.cc | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/lib/cfi/cfi.cc b/lib/cfi/cfi.cc index 711866f3f..86035381f 100644 --- a/lib/cfi/cfi.cc +++ b/lib/cfi/cfi.cc @@ -42,7 +42,7 @@ static uint16_t *mem_to_shadow(uptr x) { return (uint16_t *)(__cfi_shadow + ((x >> kShadowGranularity) << 1)); } -typedef int (*CFICheckFn)(u64, void *); +typedef int (*CFICheckFn)(u64, void *, void *); class ShadowValue { uptr addr; @@ -188,14 +188,20 @@ static void init_shadow() { dl_iterate_phdr(dl_iterate_phdr_cb, nullptr); } -extern "C" SANITIZER_INTERFACE_ATTRIBUTE -void __cfi_slowpath(u64 CallSiteTypeId, void *Ptr) { +static ALWAYS_INLINE void CfiSlowPathCommon(u64 CallSiteTypeId, void *Ptr, + void *DiagData) { uptr Addr = (uptr)Ptr; VReport(3, "__cfi_slowpath: %llx, %p\n", CallSiteTypeId, Ptr); ShadowValue sv = ShadowValue::load(Addr); if (sv.is_invalid()) { - VReport(2, "CFI: invalid memory region for a function pointer (shadow==0): %p\n", Ptr); - Die(); + // FIXME: call the ubsan handler if DiagData != nullptr? + Report( + "CFI: invalid memory region for a function pointer (shadow==0): %p\n", + Ptr); + if (DiagData) + return; + else + Die(); } if (sv.is_unchecked()) { VReport(2, "CFI: unchecked call (shadow=FFFF): %p\n", Ptr); @@ -203,7 +209,17 @@ void __cfi_slowpath(u64 CallSiteTypeId, void *Ptr) { } CFICheckFn cfi_check = sv.get_cfi_check(); VReport(2, "__cfi_check at %p\n", cfi_check); - cfi_check(CallSiteTypeId, Ptr); + cfi_check(CallSiteTypeId, Ptr, DiagData); +} + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void +__cfi_slowpath(u64 CallSiteTypeId, void *Ptr) { + CfiSlowPathCommon(CallSiteTypeId, Ptr, nullptr); +} + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void +__cfi_slowpath_diag(u64 CallSiteTypeId, void *Ptr, void *DiagData) { + CfiSlowPathCommon(CallSiteTypeId, Ptr, DiagData); } static void InitializeFlags() { |