From 730780faf41fc828fca711267a6de785184ffe3f Mon Sep 17 00:00:00 2001 From: Mina Farid Date: Fri, 13 Jul 2018 15:02:48 -0400 Subject: Fuzz testing Serializer with a dictionary and corpus (#1513) Added functionality to read dictionary file and seed input corpus from bundle --- .../Example/FuzzTests/FSTFuzzTestsPrincipal.mm | 40 ++++++++++++++++------ 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'Firestore/Example/FuzzTests/FSTFuzzTestsPrincipal.mm') diff --git a/Firestore/Example/FuzzTests/FSTFuzzTestsPrincipal.mm b/Firestore/Example/FuzzTests/FSTFuzzTestsPrincipal.mm index 0d832c0..7acb8b5 100644 --- a/Firestore/Example/FuzzTests/FSTFuzzTestsPrincipal.mm +++ b/Firestore/Example/FuzzTests/FSTFuzzTestsPrincipal.mm @@ -29,15 +29,16 @@ namespace { // Fuzz-test the deserialization process in Firestore. The Serializer reads raw // bytes and converts them to a model object. void FuzzTestDeserialization(const uint8_t *data, size_t size) { - DatabaseId database_id{"project", DatabaseId::kDefault}; - Serializer serializer{database_id}; - - @try { - serializer.DecodeFieldValue(data, size); - } @catch (...) { - // Caught exceptions are ignored because the input might be malformed and - // the deserialization might throw an error as intended. Fuzzing focuses on - // runtime errors that are detected by the sanitizers. + Serializer serializer{DatabaseId{"project", DatabaseId::kDefault}}; + + @autoreleasepool { + @try { + serializer.DecodeFieldValue(data, size); + } @catch (...) { + // Caught exceptions are ignored because the input might be malformed and + // the deserialization might throw an error as intended. Fuzzing focuses on + // runtime errors that are detected by the sanitizers. + } } } @@ -50,10 +51,27 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { // Simulates calling the main() function of libFuzzer (FuzzerMain.cpp). int RunFuzzTestingMain() { + // Get dictionary file path from resources and convert to a program argument. + NSString *plugins_path = [[NSBundle mainBundle] builtInPlugInsPath]; + + NSString *dict_location = + @"Firestore_FuzzTests_iOS.xctest/FuzzingResources/Serializer/serializer.dictionary"; + NSString *dict_path = [plugins_path stringByAppendingPathComponent:dict_location]; + const char *dict_arg = [[NSString stringWithFormat:@"-dict=%@", dict_path] UTF8String]; + + // Get corpus and convert to a program argument. + NSString *corpus_location = @"FuzzTestsCorpus"; + NSString *corpus_path = [plugins_path stringByAppendingPathComponent:corpus_location]; + const char *corpus_arg = [corpus_path UTF8String]; + // Arguments to libFuzzer main() function should be added to this array, - // e.g., dictionaries, corpus, number of runs, jobs, etc. + // e.g., dictionaries, corpus, number of runs, jobs, etc. The FuzzerDriver of + // libFuzzer expects the non-const argument 'char ***argv' and it does not + // modify it throughout the method. char *program_args[] = { - const_cast("RunFuzzTestingMain") // First arg is program name. + const_cast("RunFuzzTestingMain"), // First arg is program name. + const_cast(dict_arg), // Dictionary arg. + const_cast(corpus_arg) // Corpus must be the last arg. }; char **argv = program_args; int argc = sizeof(program_args) / sizeof(program_args[0]); -- cgit v1.2.3