Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libfido2/fuzz/fuzz_netlink.c
39586 views
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
* SPDX-License-Identifier: BSD-2-Clause
6
*/
7
8
#include <assert.h>
9
#include <stdint.h>
10
#include <stdlib.h>
11
#include <string.h>
12
#include <stdio.h>
13
14
#include "../openbsd-compat/openbsd-compat.h"
15
#include "mutator_aux.h"
16
#include "dummy.h"
17
18
struct param {
19
int seed;
20
int dev;
21
struct blob wiredata;
22
};
23
24
struct param *
25
unpack(const uint8_t *ptr, size_t len)
26
{
27
cbor_item_t *item = NULL, **v;
28
struct cbor_load_result cbor;
29
struct param *p;
30
int ok = -1;
31
32
if ((p = calloc(1, sizeof(*p))) == NULL ||
33
(item = cbor_load(ptr, len, &cbor)) == NULL ||
34
cbor.read != len ||
35
cbor_isa_array(item) == false ||
36
cbor_array_is_definite(item) == false ||
37
cbor_array_size(item) != 3 ||
38
(v = cbor_array_handle(item)) == NULL)
39
goto fail;
40
41
if (unpack_int(v[0], &p->seed) < 0 ||
42
unpack_int(v[1], &p->dev) < 0 ||
43
unpack_blob(v[2], &p->wiredata) < 0)
44
goto fail;
45
46
ok = 0;
47
fail:
48
if (ok < 0) {
49
free(p);
50
p = NULL;
51
}
52
53
if (item)
54
cbor_decref(&item);
55
56
return p;
57
}
58
59
size_t
60
pack(uint8_t *ptr, size_t len, const struct param *p)
61
{
62
cbor_item_t *argv[3], *array = NULL;
63
size_t cbor_alloc_len, cbor_len = 0;
64
unsigned char *cbor = NULL;
65
66
memset(argv, 0, sizeof(argv));
67
68
if ((array = cbor_new_definite_array(3)) == NULL ||
69
(argv[0] = pack_int(p->seed)) == NULL ||
70
(argv[1] = pack_int(p->dev)) == NULL ||
71
(argv[2] = pack_blob(&p->wiredata)) == NULL)
72
goto fail;
73
74
for (size_t i = 0; i < 3; i++)
75
if (cbor_array_push(array, argv[i]) == false)
76
goto fail;
77
78
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
79
&cbor_alloc_len)) == 0 || cbor_len > len) {
80
cbor_len = 0;
81
goto fail;
82
}
83
84
memcpy(ptr, cbor, cbor_len);
85
fail:
86
for (size_t i = 0; i < 3; i++)
87
if (argv[i])
88
cbor_decref(&argv[i]);
89
90
if (array)
91
cbor_decref(&array);
92
93
free(cbor);
94
95
return cbor_len;
96
}
97
98
size_t
99
pack_dummy(uint8_t *ptr, size_t len)
100
{
101
struct param dummy;
102
uint8_t blob[MAXCORPUS];
103
size_t blob_len;
104
105
memset(&dummy, 0, sizeof(dummy));
106
107
dummy.wiredata.len = sizeof(dummy_netlink_wiredata);
108
memcpy(&dummy.wiredata.body, &dummy_netlink_wiredata,
109
dummy.wiredata.len);
110
111
assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
112
113
if (blob_len > len) {
114
memcpy(ptr, blob, len);
115
return len;
116
}
117
118
memcpy(ptr, blob, blob_len);
119
120
return blob_len;
121
}
122
123
void
124
test(const struct param *p)
125
{
126
fido_nl_t *nl;
127
uint32_t target;
128
129
prng_init((unsigned int)p->seed);
130
fuzz_clock_reset();
131
fido_init(FIDO_DEBUG);
132
fido_set_log_handler(consume_str);
133
134
set_netlink_io_functions(fd_read, fd_write);
135
set_wire_data(p->wiredata.body, p->wiredata.len);
136
137
if ((nl = fido_nl_new()) == NULL)
138
return;
139
140
consume(&nl->fd, sizeof(nl->fd));
141
consume(&nl->nfc_type, sizeof(nl->nfc_type));
142
consume(&nl->nfc_mcastgrp, sizeof(nl->nfc_mcastgrp));
143
consume(&nl->saddr, sizeof(nl->saddr));
144
145
fido_nl_power_nfc(nl, (uint32_t)p->dev);
146
147
if (fido_nl_get_nfc_target(nl, (uint32_t)p->dev, &target) == 0)
148
consume(&target, sizeof(target));
149
150
fido_nl_free(&nl);
151
}
152
153
void
154
mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
155
{
156
if (flags & MUTATE_SEED)
157
p->seed = (int)seed;
158
159
if (flags & MUTATE_PARAM)
160
mutate_int(&p->dev);
161
162
if (flags & MUTATE_WIREDATA)
163
mutate_blob(&p->wiredata);
164
}
165
166