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