diff options
author | Dichen Zhang <dichenzhang@google.com> | 2023-06-06 01:07:57 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2023-06-06 01:07:57 +0000 |
commit | 05ff67be11fb137d986299ce8f8ed3abc5655e4d (patch) | |
tree | 97cd782862570f60ecc62e214d6a786bcf4fb3c8 | |
parent | cd3f63736194d676c30e2903f87c5d10b30e4b3a (diff) | |
parent | d136b8a2621f064f496cc114957b24588937befa (diff) | |
download | native-05ff67be11fb137d986299ce8f8ed3abc5655e4d.tar.gz |
Merge "ultrahdr: Add fuzz application for decode api" into udc-dev
-rw-r--r-- | libs/ultrahdr/fuzzer/Android.bp | 36 | ||||
-rw-r--r-- | libs/ultrahdr/fuzzer/ultrahdr_dec_fuzzer.cpp | 73 | ||||
-rw-r--r-- | libs/ultrahdr/fuzzer/ultrahdr_enc_fuzzer.cpp | 21 | ||||
-rw-r--r-- | libs/ultrahdr/include/ultrahdr/jpegdecoderhelper.h | 4 | ||||
-rw-r--r-- | libs/ultrahdr/jpegdecoderhelper.cpp | 6 | ||||
-rw-r--r-- | libs/ultrahdr/jpegr.cpp | 7 |
6 files changed, 120 insertions, 27 deletions
diff --git a/libs/ultrahdr/fuzzer/Android.bp b/libs/ultrahdr/fuzzer/Android.bp index 27b38c3590..6c0a2f577c 100644 --- a/libs/ultrahdr/fuzzer/Android.bp +++ b/libs/ultrahdr/fuzzer/Android.bp @@ -24,7 +24,17 @@ package { cc_defaults { name: "ultrahdr_fuzzer_defaults", host_supported: true, - static_libs: ["liblog"], + shared_libs: [ + "libimage_io", + "libjpeg", + ], + static_libs: [ + "libjpegdecoder", + "libjpegencoder", + "libultrahdr", + "libutils", + "liblog", + ], target: { darwin: { enabled: false, @@ -37,6 +47,8 @@ cc_defaults { description: "The fuzzers target the APIs of jpeg hdr", service_privilege: "constrained", users: "multi_user", + fuzzed_code_usage: "future_version", + vector: "local_no_privileges_required", }, } @@ -46,20 +58,12 @@ cc_fuzz { srcs: [ "ultrahdr_enc_fuzzer.cpp", ], - shared_libs: [ - "libimage_io", - "libjpeg", - "liblog", - ], - static_libs: [ - "libjpegdecoder", - "libjpegencoder", - "libultrahdr", - "libutils", - ], - fuzz_config: { - fuzzed_code_usage: "future_version", - vector: "local_no_privileges_required", - }, } +cc_fuzz { + name: "ultrahdr_dec_fuzzer", + defaults: ["ultrahdr_fuzzer_defaults"], + srcs: [ + "ultrahdr_dec_fuzzer.cpp", + ], +} diff --git a/libs/ultrahdr/fuzzer/ultrahdr_dec_fuzzer.cpp b/libs/ultrahdr/fuzzer/ultrahdr_dec_fuzzer.cpp new file mode 100644 index 0000000000..ad1d57aaee --- /dev/null +++ b/libs/ultrahdr/fuzzer/ultrahdr_dec_fuzzer.cpp @@ -0,0 +1,73 @@ +/* + * Copyright 2023 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. + */ + +// System include files +#include <fuzzer/FuzzedDataProvider.h> +#include <iostream> +#include <vector> + +// User include files +#include "ultrahdr/jpegr.h" + +using namespace android::ultrahdr; + +// Transfer functions for image data, sync with ultrahdr.h +const int kOfMin = ULTRAHDR_OUTPUT_UNSPECIFIED + 1; +const int kOfMax = ULTRAHDR_OUTPUT_MAX; + +class UltraHdrDecFuzzer { +public: + UltraHdrDecFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; + void process(); + +private: + FuzzedDataProvider mFdp; +}; + +void UltraHdrDecFuzzer::process() { + // hdr_of + auto of = static_cast<ultrahdr_output_format>(mFdp.ConsumeIntegralInRange<int>(kOfMin, kOfMax)); + auto buffer = mFdp.ConsumeRemainingBytes<uint8_t>(); + jpegr_compressed_struct jpegImgR{buffer.data(), (int)buffer.size(), (int)buffer.size(), + ULTRAHDR_COLORGAMUT_UNSPECIFIED}; + + std::vector<uint8_t> iccData(0); + std::vector<uint8_t> exifData(0); + jpegr_info_struct info{0, 0, &iccData, &exifData}; + JpegR jpegHdr; + (void)jpegHdr.getJPEGRInfo(&jpegImgR, &info); +//#define DUMP_PARAM +#ifdef DUMP_PARAM + std::cout << "input buffer size " << jpegImgR.length << std::endl; + std::cout << "image dimensions " << info.width << " x " << info.width << std::endl; +#endif + size_t outSize = info.width * info.height * ((of == ULTRAHDR_OUTPUT_SDR) ? 4 : 8); + jpegr_uncompressed_struct decodedJpegR; + auto decodedRaw = std::make_unique<uint8_t[]>(outSize); + decodedJpegR.data = decodedRaw.get(); + ultrahdr_metadata_struct metadata; + jpegr_uncompressed_struct decodedGainMap{}; + (void)jpegHdr.decodeJPEGR(&jpegImgR, &decodedJpegR, + mFdp.ConsumeFloatingPointInRange<float>(1.0, FLT_MAX), nullptr, of, + &decodedGainMap, &metadata); + if (decodedGainMap.data) free(decodedGainMap.data); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + UltraHdrDecFuzzer fuzzHandle(data, size); + fuzzHandle.process(); + return 0; +} diff --git a/libs/ultrahdr/fuzzer/ultrahdr_enc_fuzzer.cpp b/libs/ultrahdr/fuzzer/ultrahdr_enc_fuzzer.cpp index 290576d56f..acb9b795c0 100644 --- a/libs/ultrahdr/fuzzer/ultrahdr_enc_fuzzer.cpp +++ b/libs/ultrahdr/fuzzer/ultrahdr_enc_fuzzer.cpp @@ -55,12 +55,9 @@ const int kOfMax = ULTRAHDR_OUTPUT_MAX; const int kQfMin = 0; const int kQfMax = 100; -// seed -const unsigned kSeed = 0x7ab7; - -class JpegHDRFuzzer { +class UltraHdrEncFuzzer { public: - JpegHDRFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; + UltraHdrEncFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; void process(); void fillP010Buffer(uint16_t* data, int width, int height, int stride); void fill420Buffer(uint8_t* data, int size); @@ -69,7 +66,7 @@ private: FuzzedDataProvider mFdp; }; -void JpegHDRFuzzer::fillP010Buffer(uint16_t* data, int width, int height, int stride) { +void UltraHdrEncFuzzer::fillP010Buffer(uint16_t* data, int width, int height, int stride) { uint16_t* tmp = data; std::vector<uint16_t> buffer(16); for (int i = 0; i < buffer.size(); i++) { @@ -78,22 +75,24 @@ void JpegHDRFuzzer::fillP010Buffer(uint16_t* data, int width, int height, int st for (int j = 0; j < height; j++) { for (int i = 0; i < width; i += buffer.size()) { memcpy(data + i, buffer.data(), std::min((int)buffer.size(), (width - i))); - std::shuffle(buffer.begin(), buffer.end(), std::default_random_engine(kSeed)); + std::shuffle(buffer.begin(), buffer.end(), + std::default_random_engine(std::random_device{}())); } tmp += stride; } } -void JpegHDRFuzzer::fill420Buffer(uint8_t* data, int size) { +void UltraHdrEncFuzzer::fill420Buffer(uint8_t* data, int size) { std::vector<uint8_t> buffer(16); mFdp.ConsumeData(buffer.data(), buffer.size()); for (int i = 0; i < size; i += buffer.size()) { memcpy(data + i, buffer.data(), std::min((int)buffer.size(), (size - i))); - std::shuffle(buffer.begin(), buffer.end(), std::default_random_engine(kSeed)); + std::shuffle(buffer.begin(), buffer.end(), + std::default_random_engine(std::random_device{}())); } } -void JpegHDRFuzzer::process() { +void UltraHdrEncFuzzer::process() { while (mFdp.remaining_bytes()) { struct jpegr_uncompressed_struct p010Img {}; struct jpegr_uncompressed_struct yuv420Img {}; @@ -293,7 +292,7 @@ void JpegHDRFuzzer::process() { } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - JpegHDRFuzzer fuzzHandle(data, size); + UltraHdrEncFuzzer fuzzHandle(data, size); fuzzHandle.process(); return 0; } diff --git a/libs/ultrahdr/include/ultrahdr/jpegdecoderhelper.h b/libs/ultrahdr/include/ultrahdr/jpegdecoderhelper.h index f642bad89c..4f2b7423c8 100644 --- a/libs/ultrahdr/include/ultrahdr/jpegdecoderhelper.h +++ b/libs/ultrahdr/include/ultrahdr/jpegdecoderhelper.h @@ -25,6 +25,10 @@ extern "C" { } #include <utils/Errors.h> #include <vector> + +static const int kMaxWidth = 8192; +static const int kMaxHeight = 8192; + namespace android::ultrahdr { /* * Encapsulates a converter from JPEG to raw image (YUV420planer or grey-scale) format. diff --git a/libs/ultrahdr/jpegdecoderhelper.cpp b/libs/ultrahdr/jpegdecoderhelper.cpp index fac90c503d..2a9bc9ac1e 100644 --- a/libs/ultrahdr/jpegdecoderhelper.cpp +++ b/libs/ultrahdr/jpegdecoderhelper.cpp @@ -213,6 +213,12 @@ bool JpegDecoderHelper::decode(const void* image, int length, bool decodeToRGBA) } } + if (cinfo.image_width > kMaxWidth || cinfo.image_height > kMaxHeight) { + // constraint on max width and max height is only due to alloc constraints + // tune these values basing on the target device + return false; + } + mWidth = cinfo.image_width; mHeight = cinfo.image_height; diff --git a/libs/ultrahdr/jpegr.cpp b/libs/ultrahdr/jpegr.cpp index ed151f3ad2..415255d4ea 100644 --- a/libs/ultrahdr/jpegr.cpp +++ b/libs/ultrahdr/jpegr.cpp @@ -119,6 +119,13 @@ status_t JpegR::areInputArgumentsValid(jr_uncompressed_ptr uncompressed_p010_ima return ERROR_JPEGR_INVALID_INPUT_TYPE; } + if (uncompressed_p010_image->width > kMaxWidth + || uncompressed_p010_image->height > kMaxHeight) { + ALOGE("Image dimensions cannot be larger than %dx%d, image dimensions %dx%d", + kMaxWidth, kMaxHeight, uncompressed_p010_image->width, uncompressed_p010_image->height); + return ERROR_JPEGR_INVALID_INPUT_TYPE; + } + if (uncompressed_p010_image->colorGamut <= ULTRAHDR_COLORGAMUT_UNSPECIFIED || uncompressed_p010_image->colorGamut > ULTRAHDR_COLORGAMUT_MAX) { ALOGE("Unrecognized p010 color gamut %d", uncompressed_p010_image->colorGamut); |