[dfsan] Introduce memory mapping for origin tracking
authorJianzhou Zhao <jianzhouzh@google.com>
Thu, 11 Feb 2021 21:50:17 +0000 (21:50 +0000)
committerJianzhou Zhao <jianzhouzh@google.com>
Thu, 11 Feb 2021 22:33:16 +0000 (22:33 +0000)
Reviewed-by: morehouse
Differential Revision: https://reviews.llvm.org/D96545

compiler-rt/include/sanitizer/dfsan_interface.h
compiler-rt/lib/dfsan/dfsan.cpp
compiler-rt/lib/dfsan/dfsan.h
compiler-rt/lib/dfsan/dfsan_platform.h

index 18b2c81..eb4d48f 100644 (file)
@@ -22,6 +22,7 @@ extern "C" {
 #endif
 
 typedef uint16_t dfsan_label;
+typedef uint32_t dfsan_origin;
 
 /// Stores information associated with a specific label identifier.  A label
 /// may be a base label created using dfsan_create_label, with associated
index 4f02c49..43a5fe9 100644 (file)
@@ -65,9 +65,11 @@ SANITIZER_INTERFACE_ATTRIBUTE uptr __dfsan_shadow_ptr_mask;
 // |                    |
 // |       unused       |
 // |                    |
-// +--------------------+ 0x200200000000 (kUnusedAddr)
+// +--------------------+ 0x300200000000 (kUnusedAddr)
 // |    union table     |
-// +--------------------+ 0x200000000000 (kUnionTableAddr)
+// +--------------------+ 0x300000000000 (kUnionTableAddr)
+// |       origin       |
+// +--------------------+ 0x200000000000 (kOriginAddr)
 // |   shadow memory    |
 // +--------------------+ 0x000000010000 (kShadowAddr)
 // | reserved by kernel |
index 62eda73..73385f7 100644 (file)
 #include "dfsan_flags.h"
 #include "dfsan_platform.h"
 
-using __sanitizer::uptr;
 using __sanitizer::u16;
+using __sanitizer::u32;
+using __sanitizer::uptr;
 
 // Copy declarations from public sanitizer/dfsan_interface.h header here.
 typedef u16 dfsan_label;
+typedef u32 dfsan_origin;
 
 struct dfsan_label_info {
   dfsan_label l1;
@@ -60,6 +62,29 @@ inline const dfsan_label *shadow_for(const void *ptr) {
   return shadow_for(const_cast<void *>(ptr));
 }
 
+inline uptr unaligned_origin_for(uptr ptr) {
+  return OriginAddr() + (ptr & ShadowMask());
+}
+
+inline dfsan_origin *origin_for(void *ptr) {
+  auto aligned_addr = unaligned_origin_for(reinterpret_cast<uptr>(ptr)) &
+                      ~(sizeof(dfsan_origin) - 1);
+  return reinterpret_cast<dfsan_origin *>(aligned_addr);
+}
+
+inline const dfsan_origin *origin_for(const void *ptr) {
+  return origin_for(const_cast<void *>(ptr));
+}
+
+inline bool is_shadow_addr_valid(uptr shadow_addr) {
+  return (uptr)shadow_addr >= ShadowAddr() && (uptr)shadow_addr < OriginAddr();
+}
+
+inline bool has_valid_shadow_addr(const void *ptr) {
+  const dfsan_label *ptr_s = shadow_for(ptr);
+  return is_shadow_addr_valid((uptr)ptr_s);
+}
+
 }  // namespace __dfsan
 
 #endif  // DFSAN_H
index 4ff68b9..bf85214 100644 (file)
@@ -19,7 +19,8 @@ namespace __dfsan {
 #if defined(__x86_64__)
 struct Mapping {
   static const uptr kShadowAddr = 0x10000;
-  static const uptr kUnionTableAddr = 0x200000000000;
+  static const uptr kOriginAddr = 0x200000000000;
+  static const uptr kUnionTableAddr = 0x300000000000;
   static const uptr kAppAddr = 0x700000008000;
   static const uptr kShadowMask = ~0x700000000000;
 };
@@ -60,6 +61,9 @@ extern int vmaSize;
 
 enum MappingType {
   MAPPING_SHADOW_ADDR,
+#if defined(__x86_64__)
+  MAPPING_ORIGIN_ADDR,
+#endif
   MAPPING_UNION_TABLE_ADDR,
   MAPPING_APP_ADDR,
   MAPPING_SHADOW_MASK
@@ -69,6 +73,10 @@ template<typename Mapping, int Type>
 uptr MappingImpl(void) {
   switch (Type) {
     case MAPPING_SHADOW_ADDR: return Mapping::kShadowAddr;
+#if defined(__x86_64__)
+    case MAPPING_ORIGIN_ADDR:
+      return Mapping::kOriginAddr;
+#endif
     case MAPPING_UNION_TABLE_ADDR: return Mapping::kUnionTableAddr;
     case MAPPING_APP_ADDR: return Mapping::kAppAddr;
     case MAPPING_SHADOW_MASK: return Mapping::kShadowMask;
@@ -95,6 +103,11 @@ uptr ShadowAddr() {
   return MappingArchImpl<MAPPING_SHADOW_ADDR>();
 }
 
+#if defined(__x86_64__)
+ALWAYS_INLINE
+uptr OriginAddr() { return MappingArchImpl<MAPPING_ORIGIN_ADDR>(); }
+#endif
+
 ALWAYS_INLINE
 uptr UnionTableAddr() {
   return MappingArchImpl<MAPPING_UNION_TABLE_ADDR>();