1 /* 2 * Copyright 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef FUZZING_ORPHANS_LIBFFI_FUZZ_FFI_H_ 18 #define FUZZING_ORPHANS_LIBFFI_FUZZ_FFI_H_ 19 20 #include <fuzzer/FuzzedDataProvider.h> 21 #include <ffi.h> 22 #include <cstdarg> 23 #include <vector> 24 25 #if defined(__GNUC__) 26 #define __UNUSED__ __attribute__((__unused__)) 27 #endif 28 29 #define MAX_NUM_ARGS 128 30 #define MAX_NUM_ELEMENTS 16 31 #define MAX_RESP_SIZE 4096 32 #define WORDSIZE_BYTES (__WORDSIZE / 8) 33 34 // TODO(michael.ensing@leviathansecurity.com): 35 // Ideally, we should add/remove supported types based on 36 // arch-specific #defines (listed in ffi_gen.h) 37 #define NUM_TYPES 21 38 ffi_type* ffi_types[] = { 39 &ffi_type_uchar, 40 &ffi_type_schar, 41 &ffi_type_ushort, 42 &ffi_type_sshort, 43 &ffi_type_uint, 44 &ffi_type_sint, 45 &ffi_type_ulong, 46 &ffi_type_slong, 47 &ffi_type_void, 48 &ffi_type_uint8, 49 &ffi_type_sint8, 50 &ffi_type_uint16, 51 &ffi_type_sint16, 52 &ffi_type_uint32, 53 &ffi_type_sint32, 54 &ffi_type_uint64, 55 &ffi_type_sint64, 56 &ffi_type_float, 57 &ffi_type_double, 58 &ffi_type_pointer, 59 &ffi_type_longdouble, 60 // The following types are not available on some architectures 61 // &ffi_type_complex_float, 62 // &ffi_type_complex_double, 63 // &ffi_type_complex_longdouble, 64 // // nullptrs are used to terminate the array. Handle them manually. 65 // nullptr 66 }; 67 68 // Store vectors of allocated objects 69 std::vector<ffi_type*> ffi_alloc_vector; 70 std::vector<void*> raw_alloc_vector; 71 72 73 // Keep a boolean to track if the args have a struct, 74 // which will trigger an abort on java calls 75 bool args_contain_struct = false; 76 77 // Store the current ABI as a global 78 ffi_abi abi = FFI_DEFAULT_ABI; 79 80 // Define the number of possible ffi_abi values 81 // NOTE: Only supported architectures are arm/arm64, x86_64 82 // arm 83 #if defined(ARM) 84 #define MAX_ABI 4 85 // x86_64 86 #elif defined(X86_64) || (defined(__x86_64__) && defined(X86_DARWIN)) 87 #define MAX_ABI 7 88 #else 89 #define MAX_ABI 0 // If we hit this case, do NOT fuzz the abi value. 90 #endif 91 92 // Retrieve the total size (in bytes) of a ffi_type. 93 // Useful for custom structs 94 size_t getTotalSize(ffi_type*); 95 96 // Retrieve a random type from the ffi_types array 97 ffi_type* getRandomType(FuzzedDataProvider*, bool); 98 99 // Generates a custom struct, in ffi_type format 100 ffi_type* generateCustomType(FuzzedDataProvider*); 101 102 // Copies buffer data into a buffer described by the provided ffi_type 103 // (may be a struct or have subobjects) 104 size_t copyArg(ffi_type*, void*, FuzzedDataProvider*); 105 106 // Builds out the arrays of ffi_types and arguments to define a function's 107 // parameters. Returns true on success, false on failure. 108 bool buildArgArrays(ffi_type*[], void*[], size_t, FuzzedDataProvider*); 109 110 // Allocates the necessary space for a new argument buffer for given ffi_type 111 // After allocation, calls copyArg() to fill buffer with data 112 void* genArg(ffi_type*, FuzzedDataProvider*); 113 114 // Functions to perform our library calls 115 void runMainFunctions(ffi_cif&, void*, void**, FuzzedDataProvider*); 116 void runRawFunctions(ffi_cif&, void*, void**, FuzzedDataProvider*); 117 void runJavaFunctions(ffi_cif&, void*, void**, FuzzedDataProvider*); 118 119 // Free any custom struct ffi_type objects 120 // Safe to call on default types. 121 void freeFFI(ffi_type*); 122 123 // Frees all elements that the fuzzer has allocated 124 void freeAll(); 125 126 #endif // FUZZING_ORPHANS_LIBFFI_FUZZ_FFI_H_ 127