libpng-proto: Add new proto fuzzer with custom mutator that changes unknown chunk to known chunk. (#3168)

This commit is contained in:
Bhargava Shastry 2020-04-03 16:33:15 +02:00 committed by GitHub
parent 96b94f6741
commit c06fadbbbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 4 deletions

View File

@ -23,4 +23,4 @@ RUN git clone --depth 1 https://github.com/glennrp/libpng.git
RUN git clone --depth 1 https://github.com/google/libprotobuf-mutator.git
RUN git clone --depth 1 https://github.com/google/fuzzer-test-suite
RUN (mkdir LPM && cd LPM && cmake ../libprotobuf-mutator -GNinja -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON -DLIB_PROTO_MUTATOR_TESTING=OFF -DCMAKE_BUILD_TYPE=Release && ninja)
COPY build.sh png_fuzz_proto.proto png_proto_fuzzer_example.cc libpng_transforms_fuzzer.cc $SRC/
COPY build.sh png_fuzz_proto.proto png_proto_fuzzer_example.cc libpng_transforms_fuzzer.cc png_proto_mutator.cc $SRC/

View File

@ -1,9 +1,25 @@
# Copyright 2020 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.
#
################################################################################
#!/bin/bash
# build libpng using the upstream-provided build.sh.
# it will also build the vanilla (non-proto) fuzz target,
# but we discard it.
(cd libpng/ && contrib/oss-fuzz/build.sh && rm $OUT/*)
(cd libpng/ && contrib/oss-fuzz/build.sh && rm -rf $OUT/*)
# Compile png_fuzz_proto.proto; should produce two files in genfiles/:
# png_fuzz_proto.pb.cc png_fuzz_proto.pb.h
@ -26,6 +42,16 @@ $CXX $CXXFLAGS png_proto_fuzzer_example.cc libpng_read_fuzzer.o genfiles/png_fuz
$LIB_FUZZING_ENGINE \
-o $OUT/png_proto_fuzzer_example
# custom png proto mutator
$CXX $CXXFLAGS png_proto_fuzzer_example.cc png_proto_mutator.cc libpng_read_fuzzer.o genfiles/png_fuzz_proto.pb.cc \
-I genfiles -I. -I libprotobuf-mutator/ -I LPM/external.protobuf/include \
-lz \
LPM/src/libfuzzer/libprotobuf-mutator-libfuzzer.a \
LPM/src/libprotobuf-mutator.a \
LPM/external.protobuf/lib/libprotobuf.a \
libpng/.libs/libpng16.a \
$LIB_FUZZING_ENGINE \
-o $OUT/png_proto_fuzzer_example_custom_mutator
echo > dummy.cc
@ -49,5 +75,3 @@ $CXX $CXXFLAGS libpng_transforms_fuzzer.cc \
libpng/.libs/libpng16.a \
$LIB_FUZZING_ENGINE \
-o $OUT/png_transforms_fuzzer

View File

@ -0,0 +1,53 @@
/*
* Copyright 2020 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.
*/
#include "libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h"
#include "png_fuzz_proto.pb.h"
template <typename Proto>
using FuzzMutatorCallback = std::function<void(Proto*, unsigned int)>;
template <typename Proto>
struct PngProtoCBRegistration
{
PngProtoCBRegistration(FuzzMutatorCallback<Proto> const& _callback)
{
static protobuf_mutator::libfuzzer::PostProcessorRegistration<Proto> reg = {_callback};
}
};
/// Custom mutation: Otherchunk unknown_type -> known_type
static PngProtoCBRegistration<OtherChunk> addCustomChunk = {
[](OtherChunk* message, unsigned int seed)
{
// Mutate with a probability of roughly 1/47
// 47 has been chosen ad-hoc
if (seed % 47 == 0)
{
// If otherChunk is unknown type, mutate
// it to known type
if (message->has_unknown_type())
{
// This is our custom mutation
// We assume (k * 47 mod N) distribute
// uniformly, where
// - N is total number of known
// chunks defined by png proto converter
// - k is a factor of seed
message->set_known_type(seed);
}
}
}
};