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