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