diff options
author | 2020-09-11 09:22:44 -0700 | |
---|---|---|
committer | 2020-09-11 09:22:44 -0700 | |
commit | f796236bf632e782032dce4b4417f1d5b18b8c00 (patch) | |
tree | c0a92054727d9571bb726830bc05af4ba3b52c41 | |
parent | 008f2177e428aa7644117c551eeaff376b28bb15 (diff) |
[astc-encoder] Initial integration (#4188)
* initial commit, build failing
* added fuzzer, build failing
* build working, deadly signal at runtime
* fuzzer working until input ~25
* getting global-buffer-overflow, most likely due to insufficient size of output buffer
* encode_ise_fuzzer build working
* added decode_ise_fuzzer, load_decompress_image_fuzzer (build failing for the latter)
* removed test_fuzzer, build working
* fixed formatting issues with clang-format
* combined astc_encode_ise fuzzer and astc_decode_ise_fuzzer, found correct output buffer size, added relevant comments to astc_load_decompress_image_fuzzer, fixed if statement style, made input size checks more accurate, and removed unused variable declaration in build script
* style fixes
* Fix ASTC build issues.
Fixes the ASTC encoder build under AFL by putting Clang arguments in the
correct (?) order.
* removed implementation-specific checks, limited encode/decode_ise inputs to 64 bytes
* Update ASTC build to work with the updated Makefile.
* Try fixing AFL, Honggfuzz builds
Co-authored-by: Michael Jezierny <mtjz@google.com>
Co-authored-by: Abhishek Arya <inferno@chromium.org>
-rw-r--r-- | projects/astc-encoder/Dockerfile | 22 | ||||
-rw-r--r-- | projects/astc-encoder/Makefile.patch | 27 | ||||
-rw-r--r-- | projects/astc-encoder/astc_encode_decode_ise_fuzzer.cc | 35 | ||||
-rw-r--r-- | projects/astc-encoder/astc_load_decompress_image_fuzzer.cc | 103 | ||||
-rwxr-xr-x | projects/astc-encoder/build.sh | 29 | ||||
-rw-r--r-- | projects/astc-encoder/project.yaml | 3 |
6 files changed, 219 insertions, 0 deletions
diff --git a/projects/astc-encoder/Dockerfile b/projects/astc-encoder/Dockerfile new file mode 100644 index 00000000..9e3b58e2 --- /dev/null +++ b/projects/astc-encoder/Dockerfile @@ -0,0 +1,22 @@ +# 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. +# +################################################################################ + +FROM gcr.io/oss-fuzz-base/base-builder +RUN apt-get update && apt-get install -y make autoconf automake libtool +RUN git clone --depth 1 https://github.com/ARM-software/astc-encoder +WORKDIR astc-encoder/Source +COPY build.sh *_fuzzer.cc $SRC/ +COPY Makefile.patch $SRC/astc-encoder/Source diff --git a/projects/astc-encoder/Makefile.patch b/projects/astc-encoder/Makefile.patch new file mode 100644 index 00000000..a210aba9 --- /dev/null +++ b/projects/astc-encoder/Makefile.patch @@ -0,0 +1,27 @@ +diff --git a/Source/Makefile b/Source/Makefile +index 459ec42..52fc8c9 100644 +--- a/Source/Makefile ++++ b/Source/Makefile +@@ -92,21 +92,21 @@ HEADERS = \ + + BINARY = $(APP)-$(VEC) + + OBJECTS = $(SOURCES:.cpp=-$(BINARY).o) + + EXTERNAL_OBJECTS = $(EXTERNAL_SOURCES:.h=-$(BINARY).o) + + # ================================================== + # CXXFLAGS setup (and input validation) + +-CXXFLAGS = -std=c++14 -fvisibility=hidden \ ++CXXFLAGS += -std=c++14 -fvisibility=hidden \ + -Wall -Wextra -Wpedantic -Werror -Werror=shadow -Wdouble-promotion + + # Validate that the APP parameter is a supported value, and patch CXXFLAGS + ifeq ($(APP),astcenc) + # Nothing to set up + else + ifeq ($(APP),astcdec) + CXXFLAGS += -DASTCENC_DECOMPRESS_ONLY + else + $(error Unsupported app, use APP=astcenc/astcdec) diff --git a/projects/astc-encoder/astc_encode_decode_ise_fuzzer.cc b/projects/astc-encoder/astc_encode_decode_ise_fuzzer.cc new file mode 100644 index 00000000..37deeb45 --- /dev/null +++ b/projects/astc-encoder/astc_encode_decode_ise_fuzzer.cc @@ -0,0 +1,35 @@ +// 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 "astcenc_internal.h" + +#include <fuzzer/FuzzedDataProvider.h> +#include <vector> + +static constexpr size_t kMaxOutBufSize = 64; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + + FuzzedDataProvider stream(data, size); + int quantization_level = stream.ConsumeIntegral<int>(); + + // encode_ise and decode_ise will each write a max of 64 bytes to the buffer + std::vector<uint8_t> buffer = stream.ConsumeBytes<uint8_t>(kMaxOutBufSize); + uint8_t out[kMaxOutBufSize]; + + encode_ise(quantization_level, buffer.size(), buffer.data(), out, 0); + decode_ise(quantization_level, buffer.size(), buffer.data(), out, 0); + + return 0; +} diff --git a/projects/astc-encoder/astc_load_decompress_image_fuzzer.cc b/projects/astc-encoder/astc_load_decompress_image_fuzzer.cc new file mode 100644 index 00000000..433afeb2 --- /dev/null +++ b/projects/astc-encoder/astc_load_decompress_image_fuzzer.cc @@ -0,0 +1,103 @@ +// 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 "astcenc_internal.h" +#include "astcenccli_internal.h" + +#include <fuzzer/FuzzedDataProvider.h> +#include <limits> +#include <vector> + +static constexpr uint8_t kUint8Max = std::numeric_limits<uint8_t>::max(); + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + + astc_compressed_image image_comp; + astcenc_profile profile; + int out_bitness; + FuzzedDataProvider stream(data, size); + + const astcenc_profile profiles[] = {ASTCENC_PRF_LDR, ASTCENC_PRF_LDR_SRGB, + ASTCENC_PRF_HDR, + ASTCENC_PRF_HDR_RGB_LDR_A}; + + int profile_type = stream.ConsumeIntegralInRange<int>(0, 3); + profile = profiles[profile_type]; + out_bitness = 8 << (profile_type / 2); + + // Avoid dividing by zero + uint8_t block_x = stream.ConsumeIntegralInRange<uint8_t>(1, kUint8Max); + uint8_t block_y = stream.ConsumeIntegralInRange<uint8_t>(1, kUint8Max); + uint8_t block_z = stream.ConsumeIntegralInRange<uint8_t>(1, kUint8Max); + + // Reference file consumes 3 bytes for each, so we define a maximum value + unsigned int dim_x = + stream.ConsumeIntegralInRange<uint32_t>(1, ~(0xff << 24)); + unsigned int dim_y = + stream.ConsumeIntegralInRange<uint32_t>(1, ~(0xff << 24)); + unsigned int dim_z = + stream.ConsumeIntegralInRange<uint32_t>(1, ~(0xff << 24)); + + unsigned int xblocks = (dim_x + block_x - 1) / block_x; + unsigned int yblocks = (dim_y + block_y - 1) / block_y; + unsigned int zblocks = (dim_z + block_z - 1) / block_z; + + // Following the structure of + // ARM-software/astc-encoder/Source/astcenccli_toplevel.cpp:main(), located at + // https://github.com/ARM-software/astc-encoder/blob/master/Source/astcenccli_toplevel.cpp + size_t buffer_size = xblocks * yblocks * zblocks * 16; + std::vector<uint8_t> buffer = stream.ConsumeBytes<uint8_t>(buffer_size); + + image_comp.data = buffer.data(); + image_comp.data_len = buffer.size(); + image_comp.block_x = block_x; + image_comp.block_y = block_y; + image_comp.block_z = block_z; + image_comp.dim_x = dim_x; + image_comp.dim_y = dim_y; + image_comp.dim_z = dim_z; + + astcenc_config config{}; + astcenc_preset preset = ASTCENC_PRE_FAST; + if (astcenc_config_init(profile, image_comp.block_x, image_comp.block_y, + image_comp.block_z, preset, 0, + config) != ASTCENC_SUCCESS) + return 0; + + astcenc_swizzle default_swizzle{ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, + ASTCENC_SWZ_A}; + + // Initialize cli_config_options with default values + cli_config_options cli_config{/*thread_count=*/0, + /*array_size=*/1, + /*silent_mode=*/false, + /*y_flip=*/false, + /*low_fstop=*/-10, + /*high_fstop=*/10, + /*swz_encode=*/default_swizzle, + /*swz_decode=*/default_swizzle}; + + astcenc_context *codec_context; + if (astcenc_context_alloc(config, cli_config.thread_count, &codec_context) != + ASTCENC_SUCCESS) + return 0; + + astcenc_image *image_decomp_out = alloc_image( + out_bitness, image_comp.dim_x, image_comp.dim_y, image_comp.dim_z, 0); + + astcenc_decompress_image(codec_context, image_comp.data, image_comp.data_len, + *image_decomp_out, cli_config.swz_decode); + + return 0; +} diff --git a/projects/astc-encoder/build.sh b/projects/astc-encoder/build.sh new file mode 100755 index 00000000..357812b4 --- /dev/null +++ b/projects/astc-encoder/build.sh @@ -0,0 +1,29 @@ +# !/bin/bash -eu +# 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. +# +################################################################################ + +# build project +patch Makefile Makefile.patch +make -j$(nproc) BUILD=debug +ar -qc libastc.a *.o + +# build fuzzers +for fuzzer in $SRC/*_fuzzer.cc; do + $CXX $CXXFLAGS \ + -DASTCENC_SSE=0 -DASTCENC_AVX=0 -DASTCENC_POPCNT=0 -DASTCENC_VECALIGN=16 \ + -I. -std=c++14 $fuzzer $LIB_FUZZING_ENGINE $SRC/astc-encoder/Source/libastc.a \ + -o $OUT/$(basename -s .cc $fuzzer) +done diff --git a/projects/astc-encoder/project.yaml b/projects/astc-encoder/project.yaml new file mode 100644 index 00000000..b6bdf08f --- /dev/null +++ b/projects/astc-encoder/project.yaml @@ -0,0 +1,3 @@ +homepage: "https://github.com/ARM-software/astc-encoder" +language: c++ +primary_contact: "peter.harris@arm.com" |