FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
sanitizer.h
Go to the documentation of this file.
1 #ifndef _included_clib_sanitizer_h
2 #define _included_clib_sanitizer_h
3 
4 #ifdef CLIB_SANITIZE_ADDR
5 
6 #include <sanitizer/asan_interface.h>
7 #include <vppinfra/clib.h>
9 
10 typedef struct
11 {
12  size_t shadow_scale;
13  size_t shadow_offset;
14 } clib_sanitizer_main_t;
15 
16 extern clib_sanitizer_main_t sanitizer_main;
17 
18 #define CLIB_NOSANITIZE_ADDR __attribute__((no_sanitize_address))
19 #define CLIB_MEM_POISON(a, s) ASAN_POISON_MEMORY_REGION((a), (s))
20 #define CLIB_MEM_UNPOISON(a, s) ASAN_UNPOISON_MEMORY_REGION((a), (s))
21 
22 #define CLIB_MEM_OVERFLOW_MAX 64
23 
25 sanitizer_unpoison__ (u64 *restrict *shadow_ptr, size_t *shadow_len,
26  const void *ptr, size_t len)
27 {
28  size_t scale, off;
29 
30  if (PREDICT_FALSE (~0 == sanitizer_main.shadow_scale))
31  __asan_get_shadow_mapping (&sanitizer_main.shadow_scale,
32  &sanitizer_main.shadow_offset);
33 
34  scale = sanitizer_main.shadow_scale;
35  off = sanitizer_main.shadow_offset;
36 
37  /* compute the shadow address and length */
38  *shadow_len = len >> scale;
39  ASSERT (*shadow_len <= CLIB_MEM_OVERFLOW_MAX);
40  *shadow_ptr = (void *) (((clib_address_t) ptr >> scale) + off);
41 }
42 
44 sanitizer_unpoison_push__ (u64 *restrict shadow, const void *ptr, size_t len)
45 {
46  u64 *restrict shadow_ptr;
47  size_t shadow_len;
48  int i;
49 
50  sanitizer_unpoison__ (&shadow_ptr, &shadow_len, ptr, len);
51 
52  /* save the shadow area */
53  for (i = 0; i < shadow_len; i++)
54  shadow[i] = shadow_ptr[i];
55 
56  /* unpoison */
57  for (i = 0; i < shadow_len; i++)
58  shadow_ptr[i] = 0;
59 }
60 
62 sanitizer_unpoison_pop__ (const u64 *restrict shadow, const void *ptr,
63  size_t len)
64 {
65  u64 *restrict shadow_ptr;
66  size_t shadow_len;
67  int i;
68 
69  sanitizer_unpoison__ (&shadow_ptr, &shadow_len, ptr, len);
70 
71  /* restore the shadow area */
72  for (i = 0; i < shadow_len; i++)
73  {
74  ASSERT (0 == shadow_ptr[i]);
75  shadow_ptr[i] = shadow[i];
76  }
77 }
78 
79 #define CLIB_MEM_OVERFLOW(f, src, n) \
80  ({ \
81  typeof (f) clib_mem_overflow_ret__; \
82  const void *clib_mem_overflow_src__ = (src); \
83  size_t clib_mem_overflow_n__ = (n); \
84  u64 clib_mem_overflow_shadow__[CLIB_MEM_OVERFLOW_MAX]; \
85  sanitizer_unpoison_push__ (clib_mem_overflow_shadow__, \
86  clib_mem_overflow_src__, \
87  clib_mem_overflow_n__); \
88  clib_mem_overflow_ret__ = f; \
89  sanitizer_unpoison_pop__ (clib_mem_overflow_shadow__, \
90  clib_mem_overflow_src__, \
91  clib_mem_overflow_n__); \
92  clib_mem_overflow_ret__; \
93  })
94 
95 #define CLIB_MEM_OVERFLOW_LOAD(f, src) \
96  ({ \
97  typeof(src) clib_mem_overflow_load_src__ = (src); \
98  CLIB_MEM_OVERFLOW(f(clib_mem_overflow_load_src__), clib_mem_overflow_load_src__, sizeof(typeof(f(clib_mem_overflow_load_src__)))); \
99  })
100 
102 CLIB_MEM_POISON_LEN (void *src, size_t oldlen, size_t newlen)
103 {
104  if (oldlen > newlen)
105  CLIB_MEM_POISON (src + newlen, oldlen - newlen);
106  else if (newlen > oldlen)
107  CLIB_MEM_UNPOISON (src + oldlen, newlen - oldlen);
108 }
109 
110 #else /* CLIB_SANITIZE_ADDR */
111 
112 #define CLIB_NOSANITIZE_ADDR
113 #define CLIB_MEM_POISON(a, s) (void)(a)
114 #define CLIB_MEM_UNPOISON(a, s) (void)(a)
115 #define CLIB_MEM_OVERFLOW(a, b, c) a
116 #define CLIB_MEM_OVERFLOW_LOAD(f, src) f(src)
117 #define CLIB_MEM_POISON_LEN(a, b, c)
118 
119 #endif /* CLIB_SANITIZE_ADDR */
120 
121 /*
122  * clang tends to force alignment of all sections when compiling for address
123  * sanitizer. This confuse VPP plugin infra, prevent clang to do that
124  * On the contrary, GCC does not support this kind of attribute on sections
125  * sigh.
126  */
127 #ifdef __clang__
128 #define CLIB_NOSANITIZE_PLUGIN_REG_SECTION CLIB_NOSANITIZE_ADDR
129 #else
130 #define CLIB_NOSANITIZE_PLUGIN_REG_SECTION
131 #endif
132 
133 #endif /* _included_clib_sanitizer_h */
134 
135 /*
136  * fd.io coding-style-patch-verification: ON
137  *
138  * Local Variables:
139  * eval: (c-set-style "gnu")
140  * End:
141  */
CLIB_MEM_POISON
#define CLIB_MEM_POISON(a, s)
Definition: sanitizer.h:113
clib.h
error_bootstrap.h
clib_address_t
u64 clib_address_t
Definition: types.h:121
len
u8 len
Definition: ip_types.api:103
CLIB_NOSANITIZE_ADDR
#define CLIB_NOSANITIZE_ADDR
Definition: sanitizer.h:112
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
static_always_inline
#define static_always_inline
Definition: clib.h:112
src
vl_api_address_t src
Definition: gre.api:54
u64
unsigned long u64
Definition: types.h:89
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
off
u32 off
Definition: interface_output.c:1096
CLIB_MEM_UNPOISON
#define CLIB_MEM_UNPOISON(a, s)
Definition: sanitizer.h:114
i
int i
Definition: flowhash_template.h:376
CLIB_MEM_POISON_LEN
#define CLIB_MEM_POISON_LEN(a, b, c)
Definition: sanitizer.h:117