[dfsan] Introduce memory mapping for origin tracking
Reviewed-by: morehouse
Differential Revision: https://reviews.llvm.org/D96545
GitOrigin-RevId: 5ebbc5802ff3248622506b90e93a93d0eb3bfcee
diff --git a/include/sanitizer/dfsan_interface.h b/include/sanitizer/dfsan_interface.h
index 18b2c81..eb4d48f 100644
--- a/include/sanitizer/dfsan_interface.h
+++ b/include/sanitizer/dfsan_interface.h
@@ -22,6 +22,7 @@
#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
diff --git a/lib/dfsan/dfsan.cpp b/lib/dfsan/dfsan.cpp
index 4f02c49..43a5fe9 100644
--- a/lib/dfsan/dfsan.cpp
+++ b/lib/dfsan/dfsan.cpp
@@ -65,9 +65,11 @@
// | |
// | unused |
// | |
-// +--------------------+ 0x200200000000 (kUnusedAddr)
+// +--------------------+ 0x300200000000 (kUnusedAddr)
// | union table |
-// +--------------------+ 0x200000000000 (kUnionTableAddr)
+// +--------------------+ 0x300000000000 (kUnionTableAddr)
+// | origin |
+// +--------------------+ 0x200000000000 (kOriginAddr)
// | shadow memory |
// +--------------------+ 0x000000010000 (kShadowAddr)
// | reserved by kernel |
diff --git a/lib/dfsan/dfsan.h b/lib/dfsan/dfsan.h
index 62eda73..73385f7 100644
--- a/lib/dfsan/dfsan.h
+++ b/lib/dfsan/dfsan.h
@@ -19,11 +19,13 @@
#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 @@
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
diff --git a/lib/dfsan/dfsan_platform.h b/lib/dfsan/dfsan_platform.h
index 4ff68b9..bf85214 100644
--- a/lib/dfsan/dfsan_platform.h
+++ b/lib/dfsan/dfsan_platform.h
@@ -19,7 +19,8 @@
#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 @@
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 @@
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 @@
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>();