diff options
Diffstat (limited to 'fuzz/README')
-rw-r--r-- | fuzz/README | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/fuzz/README b/fuzz/README new file mode 100644 index 0000000..ecb02bb --- /dev/null +++ b/fuzz/README | |||
@@ -0,0 +1,157 @@ | |||
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 -max_len=17408 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 | } | ||