diff options
Diffstat (limited to 'fuzz/mutator_aux.c')
-rw-r--r-- | fuzz/mutator_aux.c | 253 |
1 files changed, 65 insertions, 188 deletions
diff --git a/fuzz/mutator_aux.c b/fuzz/mutator_aux.c index fe09438..98815e8 100644 --- a/fuzz/mutator_aux.c +++ b/fuzz/mutator_aux.c | |||
@@ -5,26 +5,28 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <assert.h> | 7 | #include <assert.h> |
8 | #include <cbor.h> | ||
8 | #include <stddef.h> | 9 | #include <stddef.h> |
9 | #include <stdint.h> | 10 | #include <stdint.h> |
10 | #include <stdio.h> | 11 | #include <stdio.h> |
11 | #include <stdlib.h> | 12 | #include <stdlib.h> |
12 | #include <string.h> | 13 | #include <string.h> |
13 | 14 | ||
15 | #include "fido.h" | ||
14 | #include "mutator_aux.h" | 16 | #include "mutator_aux.h" |
15 | 17 | ||
16 | size_t LLVMFuzzerMutate(uint8_t *, size_t, size_t); | 18 | size_t LLVMFuzzerMutate(uint8_t *, size_t, size_t); |
17 | 19 | ||
18 | static uint8_t *wire_data_ptr = NULL; | 20 | static const uint8_t *wire_data_ptr = NULL; |
19 | static size_t wire_data_len = 0; | 21 | static size_t wire_data_len = 0; |
20 | 22 | ||
21 | size_t | 23 | size_t |
22 | xstrlen(const char *s) | 24 | xstrlen(const char *s) |
23 | { | 25 | { |
24 | if (s == NULL) | 26 | if (s == NULL) |
25 | return (0); | 27 | return 0; |
26 | 28 | ||
27 | return (strlen(s)); | 29 | return strlen(s); |
28 | } | 30 | } |
29 | 31 | ||
30 | void | 32 | void |
@@ -33,6 +35,10 @@ consume(const void *body, size_t len) | |||
33 | const volatile uint8_t *ptr = body; | 35 | const volatile uint8_t *ptr = body; |
34 | volatile uint8_t x = 0; | 36 | volatile uint8_t x = 0; |
35 | 37 | ||
38 | #ifdef WITH_MSAN | ||
39 | __msan_check_mem_is_initialized(body, len); | ||
40 | #endif | ||
41 | |||
36 | while (len--) | 42 | while (len--) |
37 | x ^= *ptr++; | 43 | x ^= *ptr++; |
38 | } | 44 | } |
@@ -44,217 +50,87 @@ consume_str(const char *str) | |||
44 | } | 50 | } |
45 | 51 | ||
46 | int | 52 | int |
47 | unpack_int(uint8_t t, uint8_t **ptr, size_t *len, int *v) NO_MSAN | 53 | unpack_int(cbor_item_t *item, int *v) |
48 | { | ||
49 | size_t l; | ||
50 | |||
51 | if (*len < sizeof(t) || **ptr != t) | ||
52 | return (-1); | ||
53 | |||
54 | *ptr += sizeof(t); | ||
55 | *len -= sizeof(t); | ||
56 | |||
57 | if (*len < sizeof(l)) | ||
58 | return (-1); | ||
59 | |||
60 | memcpy(&l, *ptr, sizeof(l)); | ||
61 | *ptr += sizeof(l); | ||
62 | *len -= sizeof(l); | ||
63 | |||
64 | if (l != sizeof(*v) || *len < l) | ||
65 | return (-1); | ||
66 | |||
67 | memcpy(v, *ptr, sizeof(*v)); | ||
68 | *ptr += sizeof(*v); | ||
69 | *len -= sizeof(*v); | ||
70 | |||
71 | return (0); | ||
72 | } | ||
73 | |||
74 | int | ||
75 | unpack_string(uint8_t t, uint8_t **ptr, size_t *len, char *v) NO_MSAN | ||
76 | { | 54 | { |
77 | size_t l; | 55 | if (cbor_is_int(item) == false || |
78 | 56 | cbor_int_get_width(item) != CBOR_INT_64) | |
79 | if (*len < sizeof(t) || **ptr != t) | 57 | return -1; |
80 | return (-1); | ||
81 | |||
82 | *ptr += sizeof(t); | ||
83 | *len -= sizeof(t); | ||
84 | |||
85 | if (*len < sizeof(l)) | ||
86 | return (-1); | ||
87 | |||
88 | memcpy(&l, *ptr, sizeof(l)); | ||
89 | *ptr += sizeof(l); | ||
90 | *len -= sizeof(l); | ||
91 | 58 | ||
92 | if (*len < l || l >= MAXSTR) | 59 | if (cbor_isa_uint(item)) |
93 | return (-1); | 60 | *v = (int)cbor_get_uint64(item); |
94 | 61 | else | |
95 | memcpy(v, *ptr, l); | 62 | *v = (int)(-cbor_get_uint64(item) - 1); |
96 | v[l] = '\0'; | ||
97 | |||
98 | *ptr += l; | ||
99 | *len -= l; | ||
100 | |||
101 | return (0); | ||
102 | } | ||
103 | |||
104 | int | ||
105 | unpack_byte(uint8_t t, uint8_t **ptr, size_t *len, uint8_t *v) NO_MSAN | ||
106 | { | ||
107 | size_t l; | ||
108 | |||
109 | if (*len < sizeof(t) || **ptr != t) | ||
110 | return (-1); | ||
111 | |||
112 | *ptr += sizeof(t); | ||
113 | *len -= sizeof(t); | ||
114 | |||
115 | if (*len < sizeof(l)) | ||
116 | return (-1); | ||
117 | |||
118 | memcpy(&l, *ptr, sizeof(l)); | ||
119 | *ptr += sizeof(l); | ||
120 | *len -= sizeof(l); | ||
121 | |||
122 | if (l != sizeof(*v) || *len < l) | ||
123 | return (-1); | ||
124 | |||
125 | memcpy(v, *ptr, sizeof(*v)); | ||
126 | *ptr += sizeof(*v); | ||
127 | *len -= sizeof(*v); | ||
128 | |||
129 | return (0); | ||
130 | } | ||
131 | |||
132 | int | ||
133 | unpack_blob(uint8_t t, uint8_t **ptr, size_t *len, struct blob *v) NO_MSAN | ||
134 | { | ||
135 | size_t l; | ||
136 | |||
137 | v->len = 0; | ||
138 | |||
139 | if (*len < sizeof(t) || **ptr != t) | ||
140 | return (-1); | ||
141 | |||
142 | *ptr += sizeof(t); | ||
143 | *len -= sizeof(t); | ||
144 | |||
145 | if (*len < sizeof(l)) | ||
146 | return (-1); | ||
147 | |||
148 | memcpy(&l, *ptr, sizeof(l)); | ||
149 | *ptr += sizeof(l); | ||
150 | *len -= sizeof(l); | ||
151 | |||
152 | if (*len < l || l > sizeof(v->body)) | ||
153 | return (-1); | ||
154 | |||
155 | memcpy(v->body, *ptr, l); | ||
156 | *ptr += l; | ||
157 | *len -= l; | ||
158 | |||
159 | v->len = l; | ||
160 | 63 | ||
161 | return (0); | 64 | return 0; |
162 | } | 65 | } |
163 | 66 | ||
164 | int | 67 | int |
165 | pack_int(uint8_t t, uint8_t **ptr, size_t *len, int v) NO_MSAN | 68 | unpack_string(cbor_item_t *item, char *v) |
166 | { | 69 | { |
167 | const size_t l = sizeof(v); | 70 | size_t len; |
168 | 71 | ||
169 | if (*len < sizeof(t) + sizeof(l) + l) | 72 | if (cbor_isa_bytestring(item) == false || |
170 | return (-1); | 73 | (len = cbor_bytestring_length(item)) >= MAXSTR) |
74 | return -1; | ||
171 | 75 | ||
172 | (*ptr)[0] = t; | 76 | memcpy(v, cbor_bytestring_handle(item), len); |
173 | memcpy(&(*ptr)[sizeof(t)], &l, sizeof(l)); | 77 | v[len] = '\0'; |
174 | memcpy(&(*ptr)[sizeof(t) + sizeof(l)], &v, l); | ||
175 | 78 | ||
176 | *ptr += sizeof(t) + sizeof(l) + l; | 79 | return 0; |
177 | *len -= sizeof(t) + sizeof(l) + l; | ||
178 | |||
179 | return (0); | ||
180 | } | 80 | } |
181 | 81 | ||
182 | int | 82 | int |
183 | pack_string(uint8_t t, uint8_t **ptr, size_t *len, const char *v) NO_MSAN | 83 | unpack_byte(cbor_item_t *item, uint8_t *v) |
184 | { | 84 | { |
185 | const size_t l = strlen(v); | 85 | if (cbor_isa_uint(item) == false || |
186 | 86 | cbor_int_get_width(item) != CBOR_INT_8) | |
187 | if (*len < sizeof(t) + sizeof(l) + l) | 87 | return -1; |
188 | return (-1); | ||
189 | |||
190 | (*ptr)[0] = t; | ||
191 | memcpy(&(*ptr)[sizeof(t)], &l, sizeof(l)); | ||
192 | memcpy(&(*ptr)[sizeof(t) + sizeof(l)], v, l); | ||
193 | 88 | ||
194 | *ptr += sizeof(t) + sizeof(l) + l; | 89 | *v = cbor_get_uint8(item); |
195 | *len -= sizeof(t) + sizeof(l) + l; | ||
196 | 90 | ||
197 | return (0); | 91 | return 0; |
198 | } | 92 | } |
199 | 93 | ||
200 | int | 94 | int |
201 | pack_byte(uint8_t t, uint8_t **ptr, size_t *len, uint8_t v) NO_MSAN | 95 | unpack_blob(cbor_item_t *item, struct blob *v) |
202 | { | 96 | { |
203 | const size_t l = sizeof(v); | 97 | if (cbor_isa_bytestring(item) == false || |
98 | (v->len = cbor_bytestring_length(item)) > sizeof(v->body)) | ||
99 | return -1; | ||
204 | 100 | ||
205 | if (*len < sizeof(t) + sizeof(l) + l) | 101 | memcpy(v->body, cbor_bytestring_handle(item), v->len); |
206 | return (-1); | ||
207 | 102 | ||
208 | (*ptr)[0] = t; | 103 | return 0; |
209 | memcpy(&(*ptr)[sizeof(t)], &l, sizeof(l)); | ||
210 | memcpy(&(*ptr)[sizeof(t) + sizeof(l)], &v, l); | ||
211 | |||
212 | *ptr += sizeof(t) + sizeof(l) + l; | ||
213 | *len -= sizeof(t) + sizeof(l) + l; | ||
214 | |||
215 | return (0); | ||
216 | } | 104 | } |
217 | 105 | ||
218 | int | 106 | cbor_item_t * |
219 | pack_blob(uint8_t t, uint8_t **ptr, size_t *len, const struct blob *v) NO_MSAN | 107 | pack_int(int v) NO_MSAN |
220 | { | 108 | { |
221 | const size_t l = v->len; | 109 | if (v < 0) |
222 | 110 | return cbor_build_negint64((uint64_t)(-(int64_t)v - 1)); | |
223 | if (*len < sizeof(t) + sizeof(l) + l) | 111 | else |
224 | return (-1); | 112 | return cbor_build_uint64((uint64_t)v); |
225 | |||
226 | (*ptr)[0] = t; | ||
227 | memcpy(&(*ptr)[sizeof(t)], &l, sizeof(l)); | ||
228 | memcpy(&(*ptr)[sizeof(t) + sizeof(l)], v->body, l); | ||
229 | |||
230 | *ptr += sizeof(t) + sizeof(l) + l; | ||
231 | *len -= sizeof(t) + sizeof(l) + l; | ||
232 | |||
233 | return (0); | ||
234 | } | 113 | } |
235 | 114 | ||
236 | size_t | 115 | cbor_item_t * |
237 | len_int(void) | 116 | pack_string(const char *v) NO_MSAN |
238 | { | 117 | { |
239 | return (sizeof(uint8_t) + sizeof(size_t) + sizeof(int)); | 118 | if (strlen(v) >= MAXSTR) |
240 | } | 119 | return NULL; |
241 | 120 | ||
242 | size_t | 121 | return cbor_build_bytestring((const unsigned char *)v, strlen(v)); |
243 | len_string(int max) | ||
244 | { | ||
245 | return ((sizeof(uint8_t) + sizeof(size_t)) + (max ? MAXSTR - 1 : 0)); | ||
246 | } | 122 | } |
247 | 123 | ||
248 | size_t | 124 | cbor_item_t * |
249 | len_byte(void) | 125 | pack_byte(uint8_t v) NO_MSAN |
250 | { | 126 | { |
251 | return (sizeof(uint8_t) + sizeof(size_t) + sizeof(uint8_t)); | 127 | return cbor_build_uint8(v); |
252 | } | 128 | } |
253 | 129 | ||
254 | size_t | 130 | cbor_item_t * |
255 | len_blob(int max) | 131 | pack_blob(const struct blob *v) NO_MSAN |
256 | { | 132 | { |
257 | return (sizeof(uint8_t) + sizeof(size_t) + (max ? MAXBLOB : 0)); | 133 | return cbor_build_bytestring(v->body, v->len); |
258 | } | 134 | } |
259 | 135 | ||
260 | void | 136 | void |
@@ -284,13 +160,13 @@ mutate_string(char *s) | |||
284 | n = LLVMFuzzerMutate((uint8_t *)s, strlen(s), MAXSTR - 1); | 160 | n = LLVMFuzzerMutate((uint8_t *)s, strlen(s), MAXSTR - 1); |
285 | s[n] = '\0'; | 161 | s[n] = '\0'; |
286 | } | 162 | } |
287 | 163 | ||
288 | void * | 164 | void * |
289 | dev_open(const char *path) | 165 | dev_open(const char *path) |
290 | { | 166 | { |
291 | (void)path; | 167 | (void)path; |
292 | 168 | ||
293 | return ((void *)0xdeadbeef); | 169 | return (void *)0xdeadbeef; |
294 | } | 170 | } |
295 | 171 | ||
296 | void | 172 | void |
@@ -307,7 +183,7 @@ dev_read(void *handle, unsigned char *ptr, size_t len, int ms) | |||
307 | (void)ms; | 183 | (void)ms; |
308 | 184 | ||
309 | assert(handle == (void *)0xdeadbeef); | 185 | assert(handle == (void *)0xdeadbeef); |
310 | assert(len == 64); | 186 | assert(len >= CTAP_MIN_REPORT_LEN && len <= CTAP_MAX_REPORT_LEN); |
311 | 187 | ||
312 | if (wire_data_len < len) | 188 | if (wire_data_len < len) |
313 | n = wire_data_len; | 189 | n = wire_data_len; |
@@ -319,25 +195,26 @@ dev_read(void *handle, unsigned char *ptr, size_t len, int ms) | |||
319 | wire_data_ptr += n; | 195 | wire_data_ptr += n; |
320 | wire_data_len -= n; | 196 | wire_data_len -= n; |
321 | 197 | ||
322 | return ((int)n); | 198 | return (int)n; |
323 | } | 199 | } |
324 | 200 | ||
325 | int | 201 | int |
326 | dev_write(void *handle, const unsigned char *ptr, size_t len) | 202 | dev_write(void *handle, const unsigned char *ptr, size_t len) |
327 | { | 203 | { |
328 | assert(handle == (void *)0xdeadbeef); | 204 | assert(handle == (void *)0xdeadbeef); |
329 | assert(len == 64 + 1); | 205 | assert(len >= CTAP_MIN_REPORT_LEN + 1 && |
206 | len <= CTAP_MAX_REPORT_LEN + 1); | ||
330 | 207 | ||
331 | consume(ptr, len); | 208 | consume(ptr, len); |
332 | 209 | ||
333 | if (uniform_random(400) < 1) | 210 | if (uniform_random(400) < 1) |
334 | return (-1); | 211 | return -1; |
335 | 212 | ||
336 | return ((int)len); | 213 | return (int)len; |
337 | } | 214 | } |
338 | 215 | ||
339 | void | 216 | void |
340 | set_wire_data(uint8_t *ptr, size_t len) | 217 | set_wire_data(const uint8_t *ptr, size_t len) |
341 | { | 218 | { |
342 | wire_data_ptr = ptr; | 219 | wire_data_ptr = ptr; |
343 | wire_data_len = len; | 220 | wire_data_len = len; |