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