From 19615278de286a0b22fdf668601df48d768c71df Mon Sep 17 00:00:00 2001 From: Steven Wirsz Date: Tue, 25 Oct 2022 12:05:29 -0700 Subject: [PATCH] filename and file descriptor fuzz drivers to hit I/O in bzlib.c (#8858) With the addition of these 2 fuzz drivers, all valid functions in BZIP2 should be covered --- projects/bzip2/bzip2_fd.c | 101 ++++++++++++++++++++++++++++++++ projects/bzip2/bzip2_filename.c | 38 ++++-------- 2 files changed, 113 insertions(+), 26 deletions(-) create mode 100644 projects/bzip2/bzip2_fd.c diff --git a/projects/bzip2/bzip2_fd.c b/projects/bzip2/bzip2_fd.c new file mode 100644 index 000000000..663d700f6 --- /dev/null +++ b/projects/bzip2/bzip2_fd.c @@ -0,0 +1,101 @@ +/* +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +############################################################################### +*/ + +#include "bzlib.h" +#include +#include +#include +#include +#include +#include +#include +#include + +static void fuzzer_write_data(FILE *file, const uint8_t *data, size_t size) { + int bzerr = 0; + int blockSize100k = 9; + int verbosity = 0; + int workFactor = 30; + uint nbytes_in_lo32, nbytes_in_hi32; + uint nbytes_out_lo32, nbytes_out_hi32; + + BZFILE* bzf = BZ2_bzWriteOpen ( &bzerr, file, + blockSize100k, verbosity, workFactor ); + + BZ2_bzwrite(bzf, (void*)data, size); + + BZ2_bzWriteClose64 ( &bzerr, bzf, 0, + &nbytes_in_lo32, &nbytes_in_hi32, + &nbytes_out_lo32, &nbytes_out_hi32 ); +} + +static void fuzzer_read_data(const int file_descriptor) { + int bzerr = 0; + int nUnused = 0; + char obuf[BZ_MAX_UNUSED]; + void* unusedTmpV; + + BZFILE* bzf2 = BZ2_bzdopen(file_descriptor, "rb"); + + while (bzerr == BZ_OK) { + BZ2_bzread(bzf2, obuf, BZ_MAX_UNUSED); + BZ2_bzReadGetUnused( &bzerr, bzf2, &unusedTmpV, &nUnused); + } + + BZ2_bzclose(bzf2); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + int* bzerror; + char* filename = strdup("/tmp/generate_temporary_file.XXXXXX"); + + if (!filename) { + perror("Failed to allocate file name buffer.\n"); + abort(); + } + const int file_descriptor = mkstemp(filename); + if (file_descriptor < 0) { + perror("Failed to make temporary file.\n"); + abort(); + } + FILE* file = fdopen(file_descriptor, "wb"); + + if (!file) { + perror("Failed to open file descriptor."); + close(file_descriptor); + BZ2_bzerror(file,bzerror); + abort(); + } + + fuzzer_write_data(file, data, size); + + fuzzer_read_data(file_descriptor); + + BZ2_bzlibVersion(); + + BZ2_bzflush(file); + fclose(file); + + if (unlink(filename) != 0) { + perror("WARNING: Failed to delete temporary file."); + } + free(filename); + return 0; +} \ No newline at end of file diff --git a/projects/bzip2/bzip2_filename.c b/projects/bzip2/bzip2_filename.c index 77dc8a3e2..09def647b 100644 --- a/projects/bzip2/bzip2_filename.c +++ b/projects/bzip2/bzip2_filename.c @@ -26,23 +26,8 @@ #include #include -extern BZFILE* BZ2_bzWriteOpen( - int* bzerror, - FILE* f, - int blockSize100k, - int verbosity, - int workFactor ); - -extern BZFILE* BZ2_bzReadOpen( - int* bzerror, - FILE* f, - int verbosity, - int small, - void* unused, - int nUnused ); - static void fuzzer_write_data(FILE *file, const uint8_t *data, size_t size) { - int bzerr; + int bzerr = 0; int blockSize100k = 9; int verbosity = 0; int workFactor = 30; @@ -57,23 +42,21 @@ static void fuzzer_write_data(FILE *file, const uint8_t *data, size_t size) { BZ2_bzWriteClose64 ( &bzerr, bzf, 0, &nbytes_in_lo32, &nbytes_in_hi32, &nbytes_out_lo32, &nbytes_out_hi32 ); + return; } -static void fuzzer_read_data(FILE *file) { - int bzerr; - int verbosity = 0; +static void fuzzer_read_data(char *filename) { + int bzerr = 0; char obuf[BZ_MAX_UNUSED]; - char unused[BZ_MAX_UNUSED]; - int nUnused = 0; - bool smallMode = 0; - - BZFILE* bzf2 = BZ2_bzReadOpen (&bzerr, file, verbosity, (int)smallMode, unused, nUnused); + + BZFILE* bzf2 = BZ2_bzopen(filename,"rb"); while (bzerr == BZ_OK) { BZ2_bzRead ( &bzerr, bzf2, obuf, BZ_MAX_UNUSED); } BZ2_bzReadClose ( &bzerr, bzf2); + return; } int @@ -95,11 +78,14 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) close(file_descriptor); abort(); } - + fuzzer_write_data(file, data, size); - fuzzer_read_data(file); + fuzzer_read_data(filename); + BZ2_bzlibVersion(); + + BZ2_bzflush(file); fclose(file); if (unlink(filename) != 0) {