1 /* 2 * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 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 * https://www.openssl.org/source/license.html 8 * or in the file LICENSE in the source distribution. 9 */ 10 11 /* 12 * Given a list of files, run each of them through the fuzzer. Note that 13 * failure will be indicated by some kind of crash. Switching on things like 14 * asan improves the test. 15 */ 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <sys/stat.h> 21 #include <openssl/crypto.h> 22 #include "fuzzer.h" 23 #include "internal/o_dir.h" 24 25 #if defined(_WIN32) && defined(_MAX_PATH) && !defined(PATH_MAX) 26 # define PATH_MAX _MAX_PATH 27 #endif 28 29 #ifndef PATH_MAX 30 # define PATH_MAX 4096 31 #endif 32 33 # if !defined(S_ISREG) 34 # define S_ISREG(m) ((m) & S_IFREG) 35 # endif 36 37 static void testfile(const char *pathname) 38 { 39 struct stat st; 40 FILE *f; 41 unsigned char *buf; 42 size_t s; 43 44 if (stat(pathname, &st) < 0 || !S_ISREG(st.st_mode)) 45 return; 46 printf("# %s\n", pathname); 47 fflush(stdout); 48 f = fopen(pathname, "rb"); 49 if (f == NULL) 50 return; 51 buf = malloc(st.st_size); 52 if (buf != NULL) { 53 s = fread(buf, 1, st.st_size, f); 54 OPENSSL_assert(s == (size_t)st.st_size); 55 FuzzerTestOneInput(buf, s); 56 free(buf); 57 } 58 fclose(f); 59 } 60 61 int main(int argc, char **argv) { 62 int n; 63 64 FuzzerInitialize(&argc, &argv); 65 66 for (n = 1; n < argc; ++n) { 67 size_t dirname_len = strlen(argv[n]); 68 const char *filename = NULL; 69 char *pathname = NULL; 70 OPENSSL_DIR_CTX *ctx = NULL; 71 int wasdir = 0; 72 73 /* 74 * We start with trying to read the given path as a directory. 75 */ 76 while ((filename = OPENSSL_DIR_read(&ctx, argv[n])) != NULL) { 77 wasdir = 1; 78 if (pathname == NULL) { 79 pathname = malloc(PATH_MAX); 80 if (pathname == NULL) 81 break; 82 strcpy(pathname, argv[n]); 83 #ifdef __VMS 84 if (strchr(":<]", pathname[dirname_len - 1]) == NULL) 85 #endif 86 pathname[dirname_len++] = '/'; 87 pathname[dirname_len] = '\0'; 88 } 89 strcpy(pathname + dirname_len, filename); 90 testfile(pathname); 91 } 92 OPENSSL_DIR_end(&ctx); 93 94 /* If it wasn't a directory, treat it as a file instead */ 95 if (!wasdir) 96 testfile(argv[n]); 97 98 free(pathname); 99 } 100 101 FuzzerCleanup(); 102 103 return 0; 104 } 105