diff --git a/projects/mpg123/Dockerfile b/projects/mpg123/Dockerfile new file mode 100644 index 000000000..6653b6072 --- /dev/null +++ b/projects/mpg123/Dockerfile @@ -0,0 +1,25 @@ +# Copyright 2018 Google Inc. +# +# 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. +# +################################################################################ + +FROM gcr.io/oss-fuzz-base/base-builder +RUN apt-get update && apt-get install -y make autoconf automake libtool wget \ + bzip2 +RUN wget https://www.mpg123.de/snapshot +RUN tar -xvf snapshot +RUN mv mpg123* mpg123 +WORKDIR $SRC +COPY read_fuzzer.c $SRC/ +COPY build.sh $SRC/ diff --git a/projects/mpg123/build.sh b/projects/mpg123/build.sh new file mode 100755 index 000000000..abf18cb05 --- /dev/null +++ b/projects/mpg123/build.sh @@ -0,0 +1,25 @@ +#!/bin/bash -eu +# Copyright 2018 Google Inc. +# +# 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. +# +################################################################################ + +pushd mpg123 +./configure --prefix=$WORK --enable-static +make -j$(nproc) +make install +popd + +$CC $CXXFLAGS read_fuzzer.c -I$WORK/include $WORK/lib/libmpg123.a \ + -lFuzzingEngine -lc++ -o $OUT/read_fuzzer diff --git a/projects/mpg123/project.yaml b/projects/mpg123/project.yaml new file mode 100644 index 000000000..4d0fc33b3 --- /dev/null +++ b/projects/mpg123/project.yaml @@ -0,0 +1,11 @@ +homepage: "https://www.mpg123.de" +primary_contact: "kusano@google.com" + +sanitizers: + - address + - undefined + - memory + +labels: + read_fuzzer: + - sundew diff --git a/projects/mpg123/read_fuzzer.c b/projects/mpg123/read_fuzzer.c new file mode 100644 index 000000000..f65871608 --- /dev/null +++ b/projects/mpg123/read_fuzzer.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "mpg123.h" + +static char* fuzzer_get_tmpfile(const uint8_t* data, size_t size) { + char* filename_buffer = strdup("/tmp/generate_temporary_file.XXXXXX"); + if (!filename_buffer) { + perror("Failed to allocate file name buffer."); + abort(); + } + const int file_descriptor = mkstemp(filename_buffer); + if (file_descriptor < 0) { + perror("Failed to make temporary file."); + abort(); + } + FILE* file = fdopen(file_descriptor, "wb"); + if (!file) { + perror("Failed to open file descriptor."); + close(file_descriptor); + abort(); + } + const size_t bytes_written = fwrite(data, sizeof(uint8_t), size, file); + if (bytes_written < size) { + close(file_descriptor); + fprintf(stderr, "Failed to write all bytes to file (%zu out of %zu)", + bytes_written, size); + abort(); + } + fclose(file); + return filename_buffer; +} + +static void fuzzer_release_tmpfile(char* filename) { + if (unlink(filename) != 0) { + perror("WARNING: Failed to delete temporary file."); + } + free(filename); +} + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + static bool initialized = false; + if (!initialized) { + mpg123_init(); + initialized = true; + } + char* filename = fuzzer_get_tmpfile(data, size); + if (filename == NULL) { + return 0; + } + + size_t outmemorysize = size * 2; // Guess based on the size of data. + unsigned char* outmemory = (unsigned char*)malloc(outmemorysize); + if (outmemory == NULL) { + fuzzer_release_tmpfile(filename); + return 0; + } + + int error; + mpg123_handle* handle = mpg123_new(NULL, &error); + if (handle == NULL) { + free(outmemory); + fuzzer_release_tmpfile(filename); + return 0; + } + + if (mpg123_open(handle, filename) == MPG123_OK) { + int read_error; + do { + size_t decoded_size; + read_error = mpg123_read(handle, outmemory, outmemorysize, &decoded_size); + } while (read_error == MPG123_OK); + } + + mpg123_close(handle); + mpg123_delete(handle); + free(outmemory); + fuzzer_release_tmpfile(filename); + return 0; +}