summaryrefslogtreecommitdiff
path: root/fuzz/README
blob: 42646e48b68297f7c1d6b2e78495642e2639ad98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
libfido2 can be fuzzed using AFL or libFuzzer, with or without
ASAN/MSAN/UBSAN.

AFL is more convenient when fuzzing the path from the authenticator to
libfido2 in an existing application. To do so, use preload-snoop.c with a real
authenticator to obtain an initial corpus, rebuild libfido2 with -DFUZZ=1
-DAFL=1, and use preload-fuzz.c to read device data from stdin. Examples of
this approach can be found in the harnesses under fuzz/harnesses/ that fuzz
the standalone examples and tools bundled with libfido2.

libFuzzer is better suited for bespoke fuzzers; see fuzz_cred.c, fuzz_credman.c,
fuzz_assert.c, and fuzz_mgmt.c for examples. To build these harnesses,
use -DFUZZ=1 -DLIBFUZZER=1.

To run under ASAN/MSAN/UBSAN, libfido2 needs to be linked against flavours of
libcbor and OpenSSL built with the respective sanitiser. In order to keep
memory utilisation at a manageable level, you can either enforce limits at
the OS level (e.g. cgroups on Linux) or, alternatively, patch libcbor with
the diff at the bottom of this file.

1. Using ASAN + UBSAN

- Make sure you have libcbor built with -fsanitize=address;
- Make sure you have OpenSSL built with -fsanitize=address;
- Rebuild libfido2 with -DASAN=1 -DUBSAN=1.

1.1 Decide where your workspace will live

$ export FAKEROOT=/home/pedro/fakeroot
$ mkdir -p ${FAKEROOT}/src

1.2 Building libcbor with ASAN

$ git clone https://github.com/pjk/libcbor ${FAKEROOT}/src/libcbor
$ cd ${FAKEROOT}/src/libcbor

Assuming libfido2 is under ${FAKEROOT}/src/libfido2:

$ patch -p0 < ${FAKEROOT}/src/libfido2/fuzz/README
$ mkdir build
$ cd build
$ cmake -DCMAKE_C_FLAGS_DEBUG="-g2 -fno-omit-frame-pointer" \
	-DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug \
	-DCMAKE_INSTALL_PREFIX=${FAKEROOT} -DSANITIZE=ON \
	-DCMAKE_INSTALL_LIBDIR=lib ..
$ make
$ make install

1.3 Building OpenSSL with ASAN

$ git clone https://github.com/openssl/openssl ${FAKEROOT}/src/openssl
$ cd ${FAKEROOT}/src/openssl
$ ./Configure linux-x86_64-clang enable-asan --prefix=${FAKEROOT} \
	--openssldir=${FAKEROOT}/openssl
$ make clean
$ make
$ make install_sw

1.4 Building libfido2 with libFuzzer and ASAN + UBSAN

$ cd ${FAKEROOT}/src/libfido2
$ mkdir build
$ cd build
$ cmake -DFUZZ=1 -DLIBFUZZER=1 -DASAN=1 -DUBSAN=1 -DCMAKE_C_COMPILER=clang \
	-DCRYPTO_INCLUDE_DIRS=${FAKEROOT}/include \
	-DCRYPTO_LIBRARY_DIRS=${FAKEROOT}/lib \
	-DCBOR_INCLUDE_DIRS=${FAKEROOT}/include \
	-DCBOR_LIBRARY_DIRS=${FAKEROOT}/lib \
	-DCMAKE_BUILD_TYPE=Debug ..
$ make

2. Using MSAN + UBSAN

- Make sure you have libcbor built with -fsanitize=memory;
- Make sure you have OpenSSL built with -fsanitize=memory;
- Rebuild libfido2 with -DMSAN=1 -DUBSAN=1.

2.1 Decide where your workspace will live

$ export FAKEROOT=/home/pedro/fakeroot
$ mkdir -p ${FAKEROOT}/src

2.2 Building libcbor with MSAN

$ git clone https://github.com/pjk/libcbor ${FAKEROOT}/src/libcbor
$ cd ${FAKEROOT}/src/libcbor

Assuming libfido2 is under ${FAKEROOT}/src/libfido2:

$ patch -p0 < ${FAKEROOT}/src/libfido2/fuzz/README
$ mkdir build
$ cd build
$ cmake -DCMAKE_C_FLAGS_DEBUG="-fsanitize=memory,undefined -g2 -fno-omit-frame-pointer" \  
	-DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug \
	-DCMAKE_INSTALL_PREFIX=${FAKEROOT} -DSANITIZE=OFF \
	-DCMAKE_INSTALL_LIBDIR=lib ..
$ make
$ make install

2.2 Building OpenSSL with MSAN

$ mkdir -p ${FAKEROOT}/src
$ git clone https://github.com/openssl/openssl ${FAKEROOT}/src/openssl
$ cd ${FAKEROOT}/src/openssl
$ ./Configure linux-x86_64-clang enable-msan --prefix=${FAKEROOT} \
	--openssldir=${FAKEROOT}/openssl
$ make clean
$ make
$ make install_sw

2.3 Building libfido2 with libFuzzer and MSAN + UBSAN

$ cd ${FAKEROOT}/src/libfido2
$ mkdir build
$ cd build
$ cmake -DFUZZ=1 -DLIBFUZZER=1 -DMSAN=1 -DUBSAN=1 -DCMAKE_C_COMPILER=clang \
	-DCRYPTO_INCLUDE_DIRS=${FAKEROOT}/include \
	-DCRYPTO_LIBRARY_DIRS=${FAKEROOT}/lib \
	-DCBOR_INCLUDE_DIRS=${FAKEROOT}/include \
	-DCBOR_LIBRARY_DIRS=${FAKEROOT}/lib \
	-DCMAKE_BUILD_TYPE=Debug ..
$ make

3. Running the libFuzzer harnesses

When running under ASAN, you may want to set ASAN_OPTIONS to
'allocator_may_return_null=1:detect_stack_use_after_return=1'.

The recommended way to run the harnesses is:

$ fuzz_{assert,cred,credman,mgmt} -use_value_profile=1 -reload=30 \
	-print_pcs=1 -print_funcs=30 -timeout=10 CORPUS_DIR

You may want to use -jobs or -workers depending on the number of logical
cores available for fuzzing.

4. Auxiliary scripts

A set of harnesses and auxiliary scripts can be found under harnesses/. To
compile coverage reports, adjust the harnesses to your setup and run 'report'.

diff --git src/cbor/internal/memory_utils.c src/cbor/internal/memory_utils.c
index aa049a2..e294b38 100644
--- src/cbor/internal/memory_utils.c
+++ src/cbor/internal/memory_utils.c
@@ -28,7 +28,10 @@ bool _cbor_safe_to_multiply(size_t a, size_t b) {
 
 void* _cbor_alloc_multiple(size_t item_size, size_t item_count) {
   if (_cbor_safe_to_multiply(item_size, item_count)) {
-    return _CBOR_MALLOC(item_size * item_count);
+    if (item_count > 1000) {
+      return NULL;
+    } else
+      return _CBOR_MALLOC(item_size * item_count);
   } else {
     return NULL;
   }