summaryrefslogtreecommitdiff
path: root/lib/cfi/cfi.cc
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-01-25 23:34:38 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-01-25 23:34:38 +0000
commita4225860cbaea66a30477500507710875fb84516 (patch)
tree82ce4808e09c768f47b91999583b6104bc688c2c /lib/cfi/cfi.cc
parent9f33bba73dfa49d4f4e0eac68a1768d13ea51642 (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.cc28
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() {