README revision 1.1 1 libfido2 can be fuzzed using AFL or libFuzzer, with or without
2 ASAN/MSAN/UBSAN.
3
4 AFL is more convenient when fuzzing the path from the authenticator to
5 libfido2 in an existing application. To do so, use preload-snoop.c with a real
6 authenticator to obtain an initial corpus, rebuild libfido2 with -DFUZZ=1
7 -DAFL=1, and use preload-fuzz.c to read device data from stdin. Examples of
8 this approach can be found in the harnesses under fuzz/harnesses/ that fuzz
9 the standalone examples and tools bundled with libfido2.
10
11 libFuzzer is better suited for bespoke fuzzers; see fuzz_cred.c, fuzz_credman.c,
12 fuzz_assert.c, and fuzz_mgmt.c for examples. To build these harnesses,
13 use -DFUZZ=1 -DLIBFUZZER=1.
14
15 To run under ASAN/MSAN/UBSAN, libfido2 needs to be linked against flavours of
16 libcbor and OpenSSL built with the respective sanitiser. In order to keep
17 memory utilisation at a manageable level, you can either enforce limits at
18 the OS level (e.g. cgroups on Linux) or, alternatively, patch libcbor with
19 the diff at the bottom of this file.
20
21 1. Using ASAN + UBSAN
22
23 - Make sure you have libcbor built with -fsanitize=address;
24 - Make sure you have OpenSSL built with -fsanitize=address;
25 - Rebuild libfido2 with -DASAN=1 -DUBSAN=1.
26
27 1.1 Decide where your workspace will live
28
29 $ export FAKEROOT=/home/pedro/fakeroot
30 $ mkdir -p ${FAKEROOT}/src
31
32 1.2 Building libcbor with ASAN
33
34 $ git clone https://github.com/pjk/libcbor ${FAKEROOT}/src/libcbor
35 $ cd ${FAKEROOT}/src/libcbor
36
37 Assuming libfido2 is under ${FAKEROOT}/src/libfido2:
38
39 $ patch -p0 < ${FAKEROOT}/src/libfido2/fuzz/README
40 $ mkdir build
41 $ cd build
42 $ cmake -DCMAKE_C_FLAGS_DEBUG="-g2 -fno-omit-frame-pointer" \
43 -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug \
44 -DCMAKE_INSTALL_PREFIX=${FAKEROOT} -DSANITIZE=ON \
45 -DCMAKE_INSTALL_LIBDIR=lib ..
46 $ make
47 $ make install
48
49 1.3 Building OpenSSL with ASAN
50
51 $ git clone https://github.com/openssl/openssl ${FAKEROOT}/src/openssl
52 $ cd ${FAKEROOT}/src/openssl
53 $ ./Configure linux-x86_64-clang enable-asan --prefix=${FAKEROOT} \
54 --openssldir=${FAKEROOT}/openssl
55 $ make clean
56 $ make
57 $ make install_sw
58
59 1.4 Building libfido2 with libFuzzer and ASAN + UBSAN
60
61 $ cd ${FAKEROOT}/src/libfido2
62 $ mkdir build
63 $ cd build
64 $ cmake -DFUZZ=1 -DLIBFUZZER=1 -DASAN=1 -DUBSAN=1 -DCMAKE_C_COMPILER=clang \
65 -DCRYPTO_INCLUDE_DIRS=${FAKEROOT}/include \
66 -DCRYPTO_LIBRARY_DIRS=${FAKEROOT}/lib \
67 -DCBOR_INCLUDE_DIRS=${FAKEROOT}/include \
68 -DCBOR_LIBRARY_DIRS=${FAKEROOT}/lib \
69 -DCMAKE_BUILD_TYPE=Debug ..
70 $ make
71
72 2. Using MSAN + UBSAN
73
74 - Make sure you have libcbor built with -fsanitize=memory;
75 - Make sure you have OpenSSL built with -fsanitize=memory;
76 - Rebuild libfido2 with -DMSAN=1 -DUBSAN=1.
77
78 2.1 Decide where your workspace will live
79
80 $ export FAKEROOT=/home/pedro/fakeroot
81 $ mkdir -p ${FAKEROOT}/src
82
83 2.2 Building libcbor with MSAN
84
85 $ git clone https://github.com/pjk/libcbor ${FAKEROOT}/src/libcbor
86 $ cd ${FAKEROOT}/src/libcbor
87
88 Assuming libfido2 is under ${FAKEROOT}/src/libfido2:
89
90 $ patch -p0 < ${FAKEROOT}/src/libfido2/fuzz/README
91 $ mkdir build
92 $ cd build
93 $ cmake -DCMAKE_C_FLAGS_DEBUG="-fsanitize=memory,undefined -g2 -fno-omit-frame-pointer" \
94 -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug \
95 -DCMAKE_INSTALL_PREFIX=${FAKEROOT} -DSANITIZE=OFF \
96 -DCMAKE_INSTALL_LIBDIR=lib ..
97 $ make
98 $ make install
99
100 2.2 Building OpenSSL with MSAN
101
102 $ mkdir -p ${FAKEROOT}/src
103 $ git clone https://github.com/openssl/openssl ${FAKEROOT}/src/openssl
104 $ cd ${FAKEROOT}/src/openssl
105 $ ./Configure linux-x86_64-clang enable-msan --prefix=${FAKEROOT} \
106 --openssldir=${FAKEROOT}/openssl
107 $ make clean
108 $ make
109 $ make install_sw
110
111 2.3 Building libfido2 with libFuzzer and MSAN + UBSAN
112
113 $ cd ${FAKEROOT}/src/libfido2
114 $ mkdir build
115 $ cd build
116 $ cmake -DFUZZ=1 -DLIBFUZZER=1 -DMSAN=1 -DUBSAN=1 -DCMAKE_C_COMPILER=clang \
117 -DCRYPTO_INCLUDE_DIRS=${FAKEROOT}/include \
118 -DCRYPTO_LIBRARY_DIRS=${FAKEROOT}/lib \
119 -DCBOR_INCLUDE_DIRS=${FAKEROOT}/include \
120 -DCBOR_LIBRARY_DIRS=${FAKEROOT}/lib \
121 -DCMAKE_BUILD_TYPE=Debug ..
122 $ make
123
124 3. Running the libFuzzer harnesses
125
126 When running under ASAN, you may want to set ASAN_OPTIONS to
127 'allocator_may_return_null=1:detect_stack_use_after_return=1'.
128
129 The recommended way to run the harnesses is:
130
131 $ fuzz_{assert,cred,credman,mgmt} -use_value_profile=1 -reload=30 \
132 -print_pcs=1 -print_funcs=30 -timeout=10 CORPUS_DIR
133
134 You may want to use -jobs or -workers depending on the number of logical
135 cores available for fuzzing.
136
137 4. Auxiliary scripts
138
139 A set of harnesses and auxiliary scripts can be found under harnesses/. To
140 compile coverage reports, adjust the harnesses to your setup and run 'report'.
141
142 diff --git src/cbor/internal/memory_utils.c src/cbor/internal/memory_utils.c
143 index aa049a2..e294b38 100644
144 --- src/cbor/internal/memory_utils.c
145 +++ src/cbor/internal/memory_utils.c
146 @@ -28,7 +28,10 @@ bool _cbor_safe_to_multiply(size_t a, size_t b) {
147
148 void* _cbor_alloc_multiple(size_t item_size, size_t item_count) {
149 if (_cbor_safe_to_multiply(item_size, item_count)) {
150 - return _CBOR_MALLOC(item_size * item_count);
151 + if (item_count > 1000) {
152 + return NULL;
153 + } else
154 + return _CBOR_MALLOC(item_size * item_count);
155 } else {
156 return NULL;
157 }
158