Home | History | Annotate | Line # | Download | only in fuzz
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