1 /*
2 * Copyright (c) 2020 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 */
6
7 #include <assert.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdio.h>
12
13 #include "../openbsd-compat/openbsd-compat.h"
14 #include "mutator_aux.h"
15
16 struct param {
17 int seed;
18 int dev;
19 struct blob wiredata;
20 };
21
22 /*
23 * Sample netlink messages. These are unlikely to get the harness very far in
24 * terms of coverage, but serve to give libFuzzer a sense of the underlying
25 * structure.
26 */
27 static const uint8_t sample_netlink_wiredata[] = {
28 0xd8, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00,
30 0x01, 0x02, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
31 0x6e, 0x66, 0x63, 0x00, 0x06, 0x00, 0x01, 0x00,
32 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
33 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00,
35 0x1f, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0x00,
36 0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00,
37 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
38 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
39 0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
40 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
41 0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00,
42 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
43 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00,
44 0x08, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00,
45 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
46 0x14, 0x00, 0x05, 0x00, 0x08, 0x00, 0x01, 0x00,
47 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
48 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x06, 0x00,
49 0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
50 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
51 0x14, 0x00, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00,
52 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
53 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00,
54 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00,
55 0x08, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00,
56 0x14, 0x00, 0x09, 0x00, 0x08, 0x00, 0x01, 0x00,
57 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
58 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0a, 0x00,
59 0x08, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
60 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
61 0x14, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00,
62 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
63 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0c, 0x00,
64 0x08, 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00,
65 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
66 0x14, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x01, 0x00,
67 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
68 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0e, 0x00,
69 0x08, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00,
70 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
71 0x14, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x01, 0x00,
72 0x1a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
73 0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x10, 0x00,
74 0x08, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x00,
75 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
76 0x14, 0x00, 0x11, 0x00, 0x08, 0x00, 0x01, 0x00,
77 0x1c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
78 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,
79 0x08, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x00, 0x00,
80 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
81 0x14, 0x00, 0x13, 0x00, 0x08, 0x00, 0x01, 0x00,
82 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
83 0x0a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x07, 0x00,
84 0x18, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00,
85 0x05, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00,
86 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00,
87 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,
88 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
90 0x1e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
92 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
93 0x9d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x09, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
100 0x1e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x9d, 0x2e, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00,
102 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x08, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00,
104 0x06, 0x00, 0x05, 0x00, 0x44, 0x00, 0x00, 0x00,
105 0x05, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00,
106 0x0b, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00,
107 0x93, 0xb9, 0x25, 0x00
108 };
109
110 struct param *
unpack(const uint8_t * ptr,size_t len)111 unpack(const uint8_t *ptr, size_t len)
112 {
113 cbor_item_t *item = NULL, **v;
114 struct cbor_load_result cbor;
115 struct param *p;
116 int ok = -1;
117
118 if ((p = calloc(1, sizeof(*p))) == NULL ||
119 (item = cbor_load(ptr, len, &cbor)) == NULL ||
120 cbor.read != len ||
121 cbor_isa_array(item) == false ||
122 cbor_array_is_definite(item) == false ||
123 cbor_array_size(item) != 3 ||
124 (v = cbor_array_handle(item)) == NULL)
125 goto fail;
126
127 if (unpack_int(v[0], &p->seed) < 0 ||
128 unpack_int(v[1], &p->dev) < 0 ||
129 unpack_blob(v[2], &p->wiredata) < 0)
130 goto fail;
131
132 ok = 0;
133 fail:
134 if (ok < 0) {
135 free(p);
136 p = NULL;
137 }
138
139 if (item)
140 cbor_decref(&item);
141
142 return p;
143 }
144
145 size_t
pack(uint8_t * ptr,size_t len,const struct param * p)146 pack(uint8_t *ptr, size_t len, const struct param *p)
147 {
148 cbor_item_t *argv[3], *array = NULL;
149 size_t cbor_alloc_len, cbor_len = 0;
150 unsigned char *cbor = NULL;
151
152 memset(argv, 0, sizeof(argv));
153
154 if ((array = cbor_new_definite_array(3)) == NULL ||
155 (argv[0] = pack_int(p->seed)) == NULL ||
156 (argv[1] = pack_int(p->dev)) == NULL ||
157 (argv[2] = pack_blob(&p->wiredata)) == NULL)
158 goto fail;
159
160 for (size_t i = 0; i < 3; i++)
161 if (cbor_array_push(array, argv[i]) == false)
162 goto fail;
163
164 if ((cbor_len = cbor_serialize_alloc(array, &cbor,
165 &cbor_alloc_len)) > len) {
166 cbor_len = 0;
167 goto fail;
168 }
169
170 memcpy(ptr, cbor, cbor_len);
171 fail:
172 for (size_t i = 0; i < 3; i++)
173 if (argv[i])
174 cbor_decref(&argv[i]);
175
176 if (array)
177 cbor_decref(&array);
178
179 free(cbor);
180
181 return cbor_len;
182 }
183
184 size_t
pack_dummy(uint8_t * ptr,size_t len)185 pack_dummy(uint8_t *ptr, size_t len)
186 {
187 struct param dummy;
188 uint8_t blob[4096];
189 size_t blob_len;
190
191 memset(&dummy, 0, sizeof(dummy));
192
193 dummy.wiredata.len = sizeof(sample_netlink_wiredata);
194 memcpy(&dummy.wiredata.body, &sample_netlink_wiredata,
195 dummy.wiredata.len);
196
197 assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
198
199 if (blob_len > len) {
200 memcpy(ptr, blob, len);
201 return len;
202 }
203
204 memcpy(ptr, blob, blob_len);
205
206 return blob_len;
207 }
208
209 void
test(const struct param * p)210 test(const struct param *p)
211 {
212 fido_nl_t *nl;
213 uint32_t target;
214
215 prng_init((unsigned int)p->seed);
216 fido_init(FIDO_DEBUG);
217 fido_set_log_handler(consume_str);
218
219 set_netlink_io_functions(fd_read, fd_write);
220 set_wire_data(p->wiredata.body, p->wiredata.len);
221
222 if ((nl = fido_nl_new()) == NULL)
223 return;
224
225 consume(&nl->fd, sizeof(nl->fd));
226 consume(&nl->nfc_type, sizeof(nl->nfc_type));
227 consume(&nl->nfc_mcastgrp, sizeof(nl->nfc_mcastgrp));
228 consume(&nl->saddr, sizeof(nl->saddr));
229
230 fido_nl_power_nfc(nl, (uint32_t)p->dev);
231
232 if (fido_nl_get_nfc_target(nl, (uint32_t)p->dev, &target) == 0)
233 consume(&target, sizeof(target));
234
235 fido_nl_free(&nl);
236 }
237
238 void
mutate(struct param * p,unsigned int seed,unsigned int flags)239 mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
240 {
241 if (flags & MUTATE_SEED)
242 p->seed = (int)seed;
243
244 if (flags & MUTATE_PARAM)
245 mutate_int(&p->dev);
246
247 if (flags & MUTATE_WIREDATA)
248 mutate_blob(&p->wiredata);
249 }
250