Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libfido2/fuzz/mutator_aux.c
39586 views
1
/*
2
* Copyright (c) 2019-2022 Yubico AB. All rights reserved.
3
* Use of this source code is governed by a BSD-style
4
* license that can be found in the LICENSE file.
5
* SPDX-License-Identifier: BSD-2-Clause
6
*/
7
8
#include <assert.h>
9
#include <cbor.h>
10
#include <errno.h>
11
#include <stddef.h>
12
#include <stdint.h>
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include <string.h>
16
17
#include "mutator_aux.h"
18
19
int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int);
20
int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t);
21
size_t LLVMFuzzerMutate(uint8_t *, size_t, size_t);
22
23
extern int prng_up;
24
static const uint8_t *wire_data_ptr = NULL;
25
static size_t wire_data_len = 0;
26
27
void
28
consume(const void *body, size_t len)
29
{
30
const volatile uint8_t *ptr = body;
31
volatile uint8_t x = 0;
32
33
#ifdef WITH_MSAN
34
__msan_check_mem_is_initialized(body, len);
35
#endif
36
37
while (len--)
38
x ^= *ptr++;
39
40
(void)x;
41
}
42
43
void
44
consume_str(const char *str)
45
{
46
if (str != NULL)
47
consume(str, strlen(str) + 1);
48
}
49
50
int
51
unpack_int(cbor_item_t *item, int *v)
52
{
53
if (cbor_is_int(item) == false ||
54
cbor_int_get_width(item) != CBOR_INT_64)
55
return -1;
56
57
if (cbor_isa_uint(item))
58
*v = (int)cbor_get_uint64(item);
59
else
60
*v = (int)(-cbor_get_uint64(item) - 1);
61
62
return 0;
63
}
64
65
int
66
unpack_string(cbor_item_t *item, char *v)
67
{
68
size_t len;
69
70
if (cbor_isa_bytestring(item) == false ||
71
(len = cbor_bytestring_length(item)) >= MAXSTR)
72
return -1;
73
74
memcpy(v, cbor_bytestring_handle(item), len);
75
v[len] = '\0';
76
77
return 0;
78
}
79
80
int
81
unpack_byte(cbor_item_t *item, uint8_t *v)
82
{
83
if (cbor_isa_uint(item) == false ||
84
cbor_int_get_width(item) != CBOR_INT_8)
85
return -1;
86
87
*v = cbor_get_uint8(item);
88
89
return 0;
90
}
91
92
int
93
unpack_blob(cbor_item_t *item, struct blob *v)
94
{
95
if (cbor_isa_bytestring(item) == false ||
96
(v->len = cbor_bytestring_length(item)) > sizeof(v->body))
97
return -1;
98
99
memcpy(v->body, cbor_bytestring_handle(item), v->len);
100
101
return 0;
102
}
103
104
cbor_item_t *
105
pack_int(int v) NO_MSAN
106
{
107
if (v < 0)
108
return cbor_build_negint64((uint64_t)(-(int64_t)v - 1));
109
else
110
return cbor_build_uint64((uint64_t)v);
111
}
112
113
cbor_item_t *
114
pack_string(const char *v) NO_MSAN
115
{
116
if (strlen(v) >= MAXSTR)
117
return NULL;
118
119
return cbor_build_bytestring((const unsigned char *)v, strlen(v));
120
}
121
122
cbor_item_t *
123
pack_byte(uint8_t v) NO_MSAN
124
{
125
return cbor_build_uint8(v);
126
}
127
128
cbor_item_t *
129
pack_blob(const struct blob *v) NO_MSAN
130
{
131
return cbor_build_bytestring(v->body, v->len);
132
}
133
134
void
135
mutate_byte(uint8_t *b)
136
{
137
LLVMFuzzerMutate(b, sizeof(*b), sizeof(*b));
138
}
139
140
void
141
mutate_int(int *i)
142
{
143
LLVMFuzzerMutate((uint8_t *)i, sizeof(*i), sizeof(*i));
144
}
145
146
void
147
mutate_blob(struct blob *blob)
148
{
149
blob->len = LLVMFuzzerMutate((uint8_t *)blob->body, blob->len,
150
sizeof(blob->body));
151
}
152
153
void
154
mutate_string(char *s)
155
{
156
size_t n;
157
158
n = LLVMFuzzerMutate((uint8_t *)s, strlen(s), MAXSTR - 1);
159
s[n] = '\0';
160
}
161
162
static int
163
buf_read(unsigned char *ptr, size_t len, int ms)
164
{
165
size_t n;
166
167
(void)ms;
168
169
if (prng_up && uniform_random(400) < 1) {
170
errno = EIO;
171
return -1;
172
}
173
174
if (wire_data_len < len)
175
n = wire_data_len;
176
else
177
n = len;
178
179
memcpy(ptr, wire_data_ptr, n);
180
181
wire_data_ptr += n;
182
wire_data_len -= n;
183
184
return (int)n;
185
}
186
187
static int
188
buf_write(const unsigned char *ptr, size_t len)
189
{
190
consume(ptr, len);
191
192
if (prng_up && uniform_random(400) < 1) {
193
errno = EIO;
194
return -1;
195
}
196
197
return (int)len;
198
}
199
200
static void *
201
hid_open(const char *path)
202
{
203
(void)path;
204
205
return (void *)HID_DEV_HANDLE;
206
}
207
208
static void
209
hid_close(void *handle)
210
{
211
assert(handle == (void *)HID_DEV_HANDLE);
212
}
213
214
static int
215
hid_read(void *handle, unsigned char *ptr, size_t len, int ms)
216
{
217
assert(handle == (void *)HID_DEV_HANDLE);
218
assert(len >= CTAP_MIN_REPORT_LEN && len <= CTAP_MAX_REPORT_LEN);
219
220
return buf_read(ptr, len, ms);
221
}
222
223
static int
224
hid_write(void *handle, const unsigned char *ptr, size_t len)
225
{
226
assert(handle == (void *)HID_DEV_HANDLE);
227
assert(len >= CTAP_MIN_REPORT_LEN + 1 &&
228
len <= CTAP_MAX_REPORT_LEN + 1);
229
230
return buf_write(ptr, len);
231
}
232
233
static void *
234
nfc_open(const char *path)
235
{
236
(void)path;
237
238
return (void *)NFC_DEV_HANDLE;
239
}
240
241
static void
242
nfc_close(void *handle)
243
{
244
assert(handle == (void *)NFC_DEV_HANDLE);
245
}
246
247
int
248
nfc_read(void *handle, unsigned char *ptr, size_t len, int ms)
249
{
250
assert(handle == (void *)NFC_DEV_HANDLE);
251
assert(len > 0 && len <= 264);
252
253
return buf_read(ptr, len, ms);
254
}
255
256
int
257
nfc_write(void *handle, const unsigned char *ptr, size_t len)
258
{
259
assert(handle == (void *)NFC_DEV_HANDLE);
260
assert(len > 0 && len <= 256 + 2);
261
262
return buf_write(ptr, len);
263
}
264
265
ssize_t
266
fd_read(int fd, void *ptr, size_t len)
267
{
268
assert(fd != -1);
269
270
return buf_read(ptr, len, -1);
271
}
272
273
ssize_t
274
fd_write(int fd, const void *ptr, size_t len)
275
{
276
assert(fd != -1);
277
278
return buf_write(ptr, len);
279
}
280
281
fido_dev_t *
282
open_dev(int nfc)
283
{
284
fido_dev_t *dev;
285
fido_dev_io_t io;
286
fido_dev_transport_t t;
287
288
memset(&io, 0, sizeof(io));
289
memset(&t, 0, sizeof(t));
290
291
if ((dev = fido_dev_new()) == NULL)
292
return NULL;
293
294
if (nfc) {
295
io.open = nfc_open;
296
io.close = nfc_close;
297
io.read = nfc_read;
298
io.write = nfc_write;
299
} else {
300
io.open = hid_open;
301
io.close = hid_close;
302
io.read = hid_read;
303
io.write = hid_write;
304
}
305
306
if (fido_dev_set_io_functions(dev, &io) != FIDO_OK)
307
goto fail;
308
309
if (nfc) {
310
t.rx = fido_nfc_rx;
311
t.tx = fido_nfc_tx;
312
if (fido_dev_set_transport_functions(dev, &t) != FIDO_OK)
313
goto fail;
314
}
315
316
if (fido_dev_set_timeout(dev, 300) != FIDO_OK ||
317
fido_dev_open(dev, "nodev") != FIDO_OK)
318
goto fail;
319
320
return dev;
321
fail:
322
fido_dev_free(&dev);
323
324
return NULL;
325
}
326
327
void
328
set_wire_data(const uint8_t *ptr, size_t len)
329
{
330
wire_data_ptr = ptr;
331
wire_data_len = len;
332
}
333
334