/* * Copyright 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FUZZING_ORPHANS_LIBFFI_FUZZ_FFI_H_ #define FUZZING_ORPHANS_LIBFFI_FUZZ_FFI_H_ #include #include #include #include #if defined(__GNUC__) #define __UNUSED__ __attribute__((__unused__)) #endif #define MAX_NUM_ARGS 128 #define MAX_NUM_ELEMENTS 16 #define MAX_RESP_SIZE 4096 #define WORDSIZE_BYTES (__WORDSIZE / 8) // TODO(michael.ensing@leviathansecurity.com): // Ideally, we should add/remove supported types based on // arch-specific #defines (listed in ffi_gen.h) #define NUM_TYPES 21 ffi_type* ffi_types[] = { &ffi_type_uchar, &ffi_type_schar, &ffi_type_ushort, &ffi_type_sshort, &ffi_type_uint, &ffi_type_sint, &ffi_type_ulong, &ffi_type_slong, &ffi_type_void, &ffi_type_uint8, &ffi_type_sint8, &ffi_type_uint16, &ffi_type_sint16, &ffi_type_uint32, &ffi_type_sint32, &ffi_type_uint64, &ffi_type_sint64, &ffi_type_float, &ffi_type_double, &ffi_type_pointer, &ffi_type_longdouble, // The following types are not available on some architectures // &ffi_type_complex_float, // &ffi_type_complex_double, // &ffi_type_complex_longdouble, // // nullptrs are used to terminate the array. Handle them manually. // nullptr }; // Store vectors of allocated objects std::vector ffi_alloc_vector; std::vector raw_alloc_vector; // Keep a boolean to track if the args have a struct, // which will trigger an abort on java calls bool args_contain_struct = false; // Store the current ABI as a global ffi_abi abi = FFI_DEFAULT_ABI; // Define the number of possible ffi_abi values // NOTE: Only supported architectures are arm/arm64, x86_64 // arm #if defined(ARM) #define MAX_ABI 4 // x86_64 #elif defined(X86_64) || (defined(__x86_64__) && defined(X86_DARWIN)) #define MAX_ABI 7 #else #define MAX_ABI 0 // If we hit this case, do NOT fuzz the abi value. #endif // Retrieve the total size (in bytes) of a ffi_type. // Useful for custom structs size_t getTotalSize(ffi_type*); // Retrieve a random type from the ffi_types array ffi_type* getRandomType(FuzzedDataProvider*, bool); // Generates a custom struct, in ffi_type format ffi_type* generateCustomType(FuzzedDataProvider*); // Copies buffer data into a buffer described by the provided ffi_type // (may be a struct or have subobjects) size_t copyArg(ffi_type*, void*, FuzzedDataProvider*); // Builds out the arrays of ffi_types and arguments to define a function's // parameters. Returns true on success, false on failure. bool buildArgArrays(ffi_type*[], void*[], size_t, FuzzedDataProvider*); // Allocates the necessary space for a new argument buffer for given ffi_type // After allocation, calls copyArg() to fill buffer with data void* genArg(ffi_type*, FuzzedDataProvider*); // Functions to perform our library calls void runMainFunctions(ffi_cif&, void*, void**, FuzzedDataProvider*); void runRawFunctions(ffi_cif&, void*, void**, FuzzedDataProvider*); void runJavaFunctions(ffi_cif&, void*, void**, FuzzedDataProvider*); // Free any custom struct ffi_type objects // Safe to call on default types. void freeFFI(ffi_type*); // Frees all elements that the fuzzer has allocated void freeAll(); #endif // FUZZING_ORPHANS_LIBFFI_FUZZ_FFI_H_