diff options
author | Leon Scroggins <scroggo@google.com> | 2021-01-14 15:14:13 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-01-14 15:14:13 +0000 |
commit | cdbe8352daec1b76ebd8bd7871aae9f7faeb9b27 (patch) | |
tree | c95024a81b1b9589746a289d5781777f3c264c9e /native/graphics | |
parent | 8e713dbd5897bc95539d5c5e24aec316efc31bdb (diff) | |
parent | 140f5086ee607f023125c3df3ceb4d37f2b4aedb (diff) |
Merge "AImageDecoder: Add a fuzz target"
Diffstat (limited to 'native/graphics')
-rw-r--r-- | native/graphics/jni/Android.bp | 15 | ||||
-rw-r--r-- | native/graphics/jni/fuzz_imagedecoder.cpp | 78 |
2 files changed, 93 insertions, 0 deletions
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp index 15b473c2a6ab..aaaaa01de943 100644 --- a/native/graphics/jni/Android.bp +++ b/native/graphics/jni/Android.bp @@ -58,3 +58,18 @@ ndk_library { first_version: "9", unversioned_until: "current", } + +cc_fuzz { + name: "imagedecoder_fuzzer", + srcs: ["fuzz_imagedecoder.cpp"], + header_libs: ["jni_headers"], + shared_libs: [ + "libbinder", + "libjnigraphics", + "libutils", + ], + static_libs: ["libarect"], + fuzz_config: { + cc: ["scroggo@google.com"], + }, +} diff --git a/native/graphics/jni/fuzz_imagedecoder.cpp b/native/graphics/jni/fuzz_imagedecoder.cpp new file mode 100644 index 000000000000..f2cd1a8f4eb9 --- /dev/null +++ b/native/graphics/jni/fuzz_imagedecoder.cpp @@ -0,0 +1,78 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * 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 <android/imagedecoder.h> + +#include <binder/IPCThreadState.h> +#include <stddef.h> +#include <stdint.h> +#include <cstdlib> +#include <memory> + +struct DecoderDeleter { + void operator()(AImageDecoder* decoder) const { AImageDecoder_delete(decoder); } +}; + +using DecoderPointer = std::unique_ptr<AImageDecoder, DecoderDeleter>; + +static DecoderPointer makeDecoder(const uint8_t* data, size_t size) { + AImageDecoder* decoder = nullptr; + int result = AImageDecoder_createFromBuffer(data, size, &decoder); + if (result != ANDROID_IMAGE_DECODER_SUCCESS) { + // This was not a valid image. + return nullptr; + } + return DecoderPointer(decoder); +} + +struct PixelFreer { + void operator()(void* pixels) const { std::free(pixels); } +}; + +using PixelPointer = std::unique_ptr<void, PixelFreer>; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + // Without this call, decoding HEIF may time out on binder IPC calls. + android::ProcessState::self()->startThreadPool(); + + DecoderPointer decoder = makeDecoder(data, size); + if (!decoder) { + return 0; + } + + const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder.get()); + int32_t width = AImageDecoderHeaderInfo_getWidth(info); + int32_t height = AImageDecoderHeaderInfo_getHeight(info); + + // Set an arbitrary limit on the size of an image. The fuzzer runs with a + // limited amount of memory, and keeping this allocation small allows the + // fuzzer to continue running to try to find more serious problems. This + // size is large enough to hold a photo taken by a current gen phone. + constexpr int32_t kMaxDimension = 5000; + if (width > kMaxDimension || height > kMaxDimension) { + return 0; + } + + size_t stride = AImageDecoder_getMinimumStride(decoder.get()); + size_t pixelSize = height * stride; + auto pixels = PixelPointer(std::malloc(pixelSize)); + if (!pixels.get()) { + return 0; + } + + AImageDecoder_decodeImage(decoder.get(), pixels.get(), stride, pixelSize); + return 0; +} |