summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/sanitizer.h
diff options
context:
space:
mode:
authorBenoît Ganne <bganne@cisco.com>2019-04-15 15:28:21 +0200
committerDamjan Marion <dmarion@me.com>2019-11-27 10:50:28 +0000
commit9fb6d40eb3d4a2da8f45187de773498b784596e6 (patch)
treee785ebfbe73b847146debb2dae4a4304c51aa9cf /src/vppinfra/sanitizer.h
parent99fbf0574f099f09b7b46dcabe5bb50d78091dce (diff)
misc: add address sanitizer heap instrumentation
Introduce AddressSanitizer support: https://github.com/google/sanitizers/ This starts with heap instrumentation. vlib_buffer, bihash and stack instrumentation should follow. Type: feature Change-Id: I7f20e235b2f79db72efd0e756f22c75f717a9884 Signed-off-by: Benoît Ganne <bganne@cisco.com>
Diffstat (limited to 'src/vppinfra/sanitizer.h')
-rw-r--r--src/vppinfra/sanitizer.h62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/vppinfra/sanitizer.h b/src/vppinfra/sanitizer.h
new file mode 100644
index 00000000000..d099d3a941f
--- /dev/null
+++ b/src/vppinfra/sanitizer.h
@@ -0,0 +1,62 @@
+#ifndef _included_clib_sanitizer_h
+#define _included_clib_sanitizer_h
+
+#ifdef CLIB_SANITIZE_ADDR
+
+#include <sanitizer/asan_interface.h>
+#include <vppinfra/clib.h>
+
+#define CLIB_NOSANITIZE_ADDR __attribute__((no_sanitize_address))
+#define CLIB_MEM_POISON(a, s) ASAN_POISON_MEMORY_REGION((a), (s))
+#define CLIB_MEM_UNPOISON(a, s) ASAN_UNPOISON_MEMORY_REGION((a), (s))
+
+#define CLIB_MEM_OVERFLOW(f, src, n) \
+ ({ \
+ typeof (f) clib_mem_overflow_ret__; \
+ const void *clib_mem_overflow_src__ = (src); \
+ size_t clib_mem_overflow_n__ = (n); \
+ const void *clib_mem_overflow_start__ = __asan_region_is_poisoned((void *)clib_mem_overflow_src__, clib_mem_overflow_n__); \
+ clib_mem_overflow_n__ -= (size_t)(clib_mem_overflow_start__ - clib_mem_overflow_src__); \
+ if (clib_mem_overflow_start__) \
+ CLIB_MEM_UNPOISON(clib_mem_overflow_start__, clib_mem_overflow_n__); \
+ clib_mem_overflow_ret__ = f; \
+ if (clib_mem_overflow_start__) \
+ CLIB_MEM_POISON(clib_mem_overflow_start__, clib_mem_overflow_n__); \
+ clib_mem_overflow_ret__; \
+ })
+
+#define CLIB_MEM_OVERFLOW_LOAD(f, src) \
+ ({ \
+ typeof(src) clib_mem_overflow_load_src__ = (src); \
+ CLIB_MEM_OVERFLOW(f(clib_mem_overflow_load_src__), clib_mem_overflow_load_src__, sizeof(typeof(f(clib_mem_overflow_load_src__)))); \
+ })
+
+static_always_inline void
+CLIB_MEM_POISON_LEN (void *src, size_t oldlen, size_t newlen)
+{
+ if (oldlen > newlen)
+ CLIB_MEM_POISON (src + newlen, oldlen - newlen);
+ else if (newlen > oldlen)
+ CLIB_MEM_UNPOISON (src + oldlen, newlen - oldlen);
+}
+
+#else /* CLIB_SANITIZE_ADDR */
+
+#define CLIB_NOSANITIZE_ADDR
+#define CLIB_MEM_POISON(a, s) (void)(a)
+#define CLIB_MEM_UNPOISON(a, s) (void)(a)
+#define CLIB_MEM_OVERFLOW(a, b, c) a
+#define CLIB_MEM_OVERFLOW_LOAD(f, src) f(src)
+#define CLIB_MEM_POISON_LEN(a, b, c)
+
+#endif /* CLIB_SANITIZE_ADDR */
+
+#endif /* _included_clib_sanitizer_h */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */