mirror of
https://github.com/openssl/openssl.git
synced 2024-11-21 01:15:20 +08:00
Faster fuzz test: teach the fuzz test programs to handle directories
Instead of invoking the fuzz test programs once for every corpora file, we invoke them once for each directory of corpora files. This dramatically reduces the number of program invikations, as well as the time 99-test_fuzz.t takes to complete. fuzz/test-corpus.c was enhanced to handle directories as well as regular files. Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/5776)
This commit is contained in:
parent
00701e5ea8
commit
9d74090959
@ -16,9 +16,47 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "fuzzer.h"
|
||||
#include "internal/o_dir.h"
|
||||
|
||||
#if defined(_WIN32) && defined(_MAX_PATH)
|
||||
# define PATH_MAX _MAX_PATH
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
# if !defined(S_ISREG)
|
||||
# define S_ISREG(m) ((m) & S_IFREG)
|
||||
# endif
|
||||
|
||||
static void testfile(const char *pathname)
|
||||
{
|
||||
struct stat st;
|
||||
FILE *f;
|
||||
unsigned char *buf;
|
||||
size_t s;
|
||||
|
||||
if (stat(pathname, &st) < 0 || !S_ISREG(st.st_mode))
|
||||
return;
|
||||
printf("# %s\n", pathname);
|
||||
fflush(stdout);
|
||||
f = fopen(pathname, "rb");
|
||||
if (f == NULL)
|
||||
return;
|
||||
buf = malloc(st.st_size);
|
||||
if (buf != NULL) {
|
||||
s = fread(buf, 1, st.st_size, f);
|
||||
OPENSSL_assert(s == (size_t)st.st_size);
|
||||
FuzzerTestOneInput(buf, s);
|
||||
free(buf);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int n;
|
||||
@ -26,21 +64,38 @@ int main(int argc, char **argv) {
|
||||
FuzzerInitialize(&argc, &argv);
|
||||
|
||||
for (n = 1; n < argc; ++n) {
|
||||
struct stat st;
|
||||
FILE *f;
|
||||
unsigned char *buf;
|
||||
size_t s;
|
||||
size_t dirname_len = strlen(argv[n]);
|
||||
const char *filename = NULL;
|
||||
char *pathname = NULL;
|
||||
OPENSSL_DIR_CTX *ctx = NULL;
|
||||
int wasdir = 0;
|
||||
|
||||
stat(argv[n], &st);
|
||||
f = fopen(argv[n], "rb");
|
||||
if (f == NULL)
|
||||
continue;
|
||||
buf = malloc(st.st_size);
|
||||
s = fread(buf, 1, st.st_size, f);
|
||||
OPENSSL_assert(s == (size_t)st.st_size);
|
||||
FuzzerTestOneInput(buf, s);
|
||||
free(buf);
|
||||
fclose(f);
|
||||
/*
|
||||
* We start with trying to read the given path as a directory.
|
||||
*/
|
||||
while ((filename = OPENSSL_DIR_read(&ctx, argv[n])) != NULL) {
|
||||
wasdir = 1;
|
||||
if (pathname == NULL) {
|
||||
pathname = malloc(PATH_MAX);
|
||||
if (pathname == NULL)
|
||||
break;
|
||||
strcpy(pathname, argv[n]);
|
||||
#ifdef __VMS
|
||||
if (strchr(":<]", pathname[dirname_len - 1]) == NULL)
|
||||
#endif
|
||||
pathname[dirname_len++] = '/';
|
||||
pathname[dirname_len] = '\0';
|
||||
}
|
||||
strcpy(pathname + dirname_len, filename);
|
||||
testfile(pathname);
|
||||
}
|
||||
OPENSSL_DIR_end(&ctx);
|
||||
|
||||
/* If it wasn't a directory, treat it as a file instead */
|
||||
if (!wasdir)
|
||||
testfile(argv[n]);
|
||||
|
||||
free(pathname);
|
||||
}
|
||||
|
||||
FuzzerCleanup();
|
||||
|
@ -26,14 +26,14 @@ plan tests => scalar @fuzzers;
|
||||
|
||||
foreach my $f (@fuzzers) {
|
||||
subtest "Fuzzing $f" => sub {
|
||||
my @files = glob(srctop_file('fuzz', 'corpora', $f, '*'));
|
||||
push @files, glob(srctop_file('fuzz', 'corpora', "$f-*", '*'));
|
||||
my @dirs = glob(srctop_file('fuzz', 'corpora', $f));
|
||||
push @dirs, glob(srctop_file('fuzz', 'corpora', "$f-*"));
|
||||
|
||||
plan skip_all => "No corpora for $f-test" unless @files;
|
||||
plan skip_all => "No corpora for $f-test" unless @dirs;
|
||||
|
||||
plan tests => scalar @files;
|
||||
plan tests => scalar @dirs;
|
||||
|
||||
foreach (@files) {
|
||||
foreach (@dirs) {
|
||||
ok(run(fuzz(["$f-test", $_])));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user