README revision 1.1.1.1
1libfido2 can be fuzzed using AFL or libFuzzer, with or without 2ASAN/MSAN/UBSAN. 3 4AFL is more convenient when fuzzing the path from the authenticator to 5libfido2 in an existing application. To do so, use preload-snoop.c with a real 6authenticator 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 8this approach can be found in the harnesses under fuzz/harnesses/ that fuzz 9the standalone examples and tools bundled with libfido2. 10 11libFuzzer is better suited for bespoke fuzzers; see fuzz_cred.c, fuzz_credman.c, 12fuzz_assert.c, and fuzz_mgmt.c for examples. To build these harnesses, 13use -DFUZZ=1 -DLIBFUZZER=1. 14 15To run under ASAN/MSAN/UBSAN, libfido2 needs to be linked against flavours of 16libcbor and OpenSSL built with the respective sanitiser. In order to keep 17memory utilisation at a manageable level, you can either enforce limits at 18the OS level (e.g. cgroups on Linux) or, alternatively, patch libcbor with 19the diff at the bottom of this file. 20 211. 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 271.1 Decide where your workspace will live 28 29$ export FAKEROOT=/home/pedro/fakeroot 30$ mkdir -p ${FAKEROOT}/src 31 321.2 Building libcbor with ASAN 33 34$ git clone https://github.com/pjk/libcbor ${FAKEROOT}/src/libcbor 35$ cd ${FAKEROOT}/src/libcbor 36 37Assuming 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 491.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 591.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 722. 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 782.1 Decide where your workspace will live 79 80$ export FAKEROOT=/home/pedro/fakeroot 81$ mkdir -p ${FAKEROOT}/src 82 832.2 Building libcbor with MSAN 84 85$ git clone https://github.com/pjk/libcbor ${FAKEROOT}/src/libcbor 86$ cd ${FAKEROOT}/src/libcbor 87 88Assuming 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 1002.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 1112.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 1243. Running the libFuzzer harnesses 125 126When running under ASAN, you may want to set ASAN_OPTIONS to 127'allocator_may_return_null=1:detect_stack_use_after_return=1'. 128 129The 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 134You may want to use -jobs or -workers depending on the number of logical 135cores available for fuzzing. 136 1374. Auxiliary scripts 138 139A set of harnesses and auxiliary scripts can be found under harnesses/. To 140compile coverage reports, adjust the harnesses to your setup and run 'report'. 141 142diff --git src/cbor/internal/memory_utils.c src/cbor/internal/memory_utils.c 143index 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