1*3117ece4Schristos /* 2*3117ece4Schristos * Copyright (c) Meta Platforms, Inc. and affiliates. 3*3117ece4Schristos * All rights reserved. 4*3117ece4Schristos * 5*3117ece4Schristos * This source code is licensed under both the BSD-style license (found in the 6*3117ece4Schristos * LICENSE file in the root directory of this source tree) and the GPLv2 (found 7*3117ece4Schristos * in the COPYING file in the root directory of this source tree). 8*3117ece4Schristos * You may select, at your option, one of the above-listed licenses. 9*3117ece4Schristos */ 10*3117ece4Schristos 11*3117ece4Schristos #include "fuzz.h" 12*3117ece4Schristos #include "fuzz_helpers.h" 13*3117ece4Schristos #include "util.h" 14*3117ece4Schristos #include <stddef.h> 15*3117ece4Schristos #include <stdint.h> 16*3117ece4Schristos #include <stdio.h> 17*3117ece4Schristos #include <stdlib.h> 18*3117ece4Schristos 19*3117ece4Schristos int main(int argc, char const **argv) { 20*3117ece4Schristos size_t const kMaxFileSize = (size_t)1 << 27; 21*3117ece4Schristos int const kFollowLinks = 1; 22*3117ece4Schristos FileNamesTable* files; 23*3117ece4Schristos const char** const fnTable = argv + 1; 24*3117ece4Schristos uint8_t *buffer = NULL; 25*3117ece4Schristos size_t bufferSize = 0; 26*3117ece4Schristos unsigned i; 27*3117ece4Schristos unsigned numFilesTested = 0; 28*3117ece4Schristos int ret = 0; 29*3117ece4Schristos 30*3117ece4Schristos { 31*3117ece4Schristos unsigned const numFiles = (unsigned)(argc - 1); 32*3117ece4Schristos #ifdef UTIL_HAS_CREATEFILELIST 33*3117ece4Schristos files = UTIL_createExpandedFNT(fnTable, numFiles, kFollowLinks); 34*3117ece4Schristos #else 35*3117ece4Schristos files = UTIL_createFNT_fromROTable(fnTable, numFiles); 36*3117ece4Schristos assert(numFiles == files->tableSize); 37*3117ece4Schristos #endif 38*3117ece4Schristos } 39*3117ece4Schristos if (!files) { 40*3117ece4Schristos fprintf(stderr, "ERROR: Failed to create file names table\n"); 41*3117ece4Schristos return 1; 42*3117ece4Schristos } 43*3117ece4Schristos if (files->tableSize == 0) 44*3117ece4Schristos fprintf(stderr, "WARNING: No files passed to %s\n", argv[0]); 45*3117ece4Schristos for (i = 0; i < files->tableSize; ++i) { 46*3117ece4Schristos char const *fileName = files->fileNames[i]; 47*3117ece4Schristos size_t const fileSize = UTIL_getFileSize(fileName); 48*3117ece4Schristos size_t readSize; 49*3117ece4Schristos FILE *file; 50*3117ece4Schristos 51*3117ece4Schristos DEBUGLOG(3, "Running %s", fileName); 52*3117ece4Schristos 53*3117ece4Schristos /* Check that it is a regular file, and that the fileSize is valid. 54*3117ece4Schristos * If it is not a regular file, then it may have been deleted since we 55*3117ece4Schristos * constructed the list, so just skip it, but return an error exit code. 56*3117ece4Schristos */ 57*3117ece4Schristos if (!UTIL_isRegularFile(fileName)) { 58*3117ece4Schristos ret = 1; 59*3117ece4Schristos continue; 60*3117ece4Schristos } 61*3117ece4Schristos FUZZ_ASSERT_MSG(fileSize <= kMaxFileSize, fileName); 62*3117ece4Schristos /* Ensure we have a large enough buffer allocated */ 63*3117ece4Schristos if (fileSize > bufferSize) { 64*3117ece4Schristos free(buffer); 65*3117ece4Schristos buffer = (uint8_t *)malloc(fileSize); 66*3117ece4Schristos FUZZ_ASSERT_MSG(buffer, fileName); 67*3117ece4Schristos bufferSize = fileSize; 68*3117ece4Schristos } 69*3117ece4Schristos /* Open the file */ 70*3117ece4Schristos file = fopen(fileName, "rb"); 71*3117ece4Schristos FUZZ_ASSERT_MSG(file, fileName); 72*3117ece4Schristos /* Read the file */ 73*3117ece4Schristos readSize = fread(buffer, 1, fileSize, file); 74*3117ece4Schristos FUZZ_ASSERT_MSG(readSize == fileSize, fileName); 75*3117ece4Schristos /* Close the file */ 76*3117ece4Schristos fclose(file); 77*3117ece4Schristos /* Run the fuzz target */ 78*3117ece4Schristos LLVMFuzzerTestOneInput(buffer, fileSize); 79*3117ece4Schristos ++numFilesTested; 80*3117ece4Schristos } 81*3117ece4Schristos fprintf(stderr, "Tested %u files: ", numFilesTested); 82*3117ece4Schristos if (ret == 0) { 83*3117ece4Schristos fprintf(stderr, "Success!\n"); 84*3117ece4Schristos } else { 85*3117ece4Schristos fprintf(stderr, "Failure!\n"); 86*3117ece4Schristos } 87*3117ece4Schristos free(buffer); 88*3117ece4Schristos UTIL_freeFileNamesTable(files); 89*3117ece4Schristos return ret; 90*3117ece4Schristos } 91