Loading services/camera/libcameraservice/fuzzer/Android.bp +15 −4 Original line number Diff line number Diff line Loading @@ -26,7 +26,18 @@ package { cc_defaults { name: "libcameraservice_fuzz_defaults", fuzz_config: { componentid: 41727 cc: [ "android-camera-fwk-eng@google.com", ], componentid: 41727, hotlists: [ "4593311", ], description: "The fuzzer targets the APIs of libcameraservice", vector: "local_no_privileges_required", service_privilege: "privileged", users: "multi_user", fuzzed_code_usage: "shipped", }, } Loading @@ -37,9 +48,9 @@ cc_fuzz { "DistortionMapperFuzzer.cpp", ], shared_libs: [ "libcameraservice", "camera_platform_flags_c_lib", "libcamera_client", "camera_platform_flags_c_lib" "libcameraservice", ], } Loading @@ -50,8 +61,8 @@ cc_fuzz { "DepthProcessorFuzzer.cpp", ], shared_libs: [ "camera_platform_flags_c_lib", "libcameraservice", "camera_platform_flags_c_lib" ], corpus: ["corpus/*.jpg"], } services/camera/libcameraservice/fuzzer/DepthProcessorFuzzer.cpp +70 −27 Original line number Diff line number Diff line Loading @@ -14,48 +14,91 @@ * limitations under the License. */ #include <array> #include <vector> #include "common/DepthPhotoProcessor.h" #include <fuzzer/FuzzedDataProvider.h> #include <random> #include "common/DepthPhotoProcessor.h" #include <fuzzer/FuzzedDataProvider.h> using namespace android; using namespace android::camera3; static const size_t kTestBufferWidth = 640; static const size_t kTestBufferHeight = 480; static const size_t kTestBufferDepthSize (kTestBufferWidth * kTestBufferHeight); static const float kMinRatio = 0.1f; static const float kMaxRatio = 0.9f; static const uint8_t kTotalDepthJpegBufferCount = 3; static const uint8_t kIntrinsicCalibrationSize = 5; static const uint8_t kLensDistortionSize = 5; static const DepthPhotoOrientation kDepthPhotoOrientations[] = { DepthPhotoOrientation::DEPTH_ORIENTATION_0_DEGREES, DepthPhotoOrientation::DEPTH_ORIENTATION_90_DEGREES, DepthPhotoOrientation::DEPTH_ORIENTATION_180_DEGREES, DepthPhotoOrientation::DEPTH_ORIENTATION_270_DEGREES}; void generateDepth16Buffer(const uint8_t* data, size_t size, std::array<uint16_t, kTestBufferDepthSize> *depth16Buffer /*out*/) { FuzzedDataProvider dataProvider(data, size); for (size_t i = 0; i < depth16Buffer->size(); i++) { (*depth16Buffer)[i] = dataProvider.ConsumeIntegral<uint16_t>(); void generateDepth16Buffer(std::vector<uint16_t>* depth16Buffer /*out*/, size_t length, FuzzedDataProvider& fdp) { std::default_random_engine gen(fdp.ConsumeIntegral<uint8_t>()); std::uniform_int_distribution uniDist(0, UINT16_MAX - 1); for (size_t i = 0; i < length; ++i) { (*depth16Buffer)[i] = uniDist(gen); } } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { FuzzedDataProvider fdp(data, size); DepthPhotoInputFrame inputFrame; /** * Consuming 80% of the data to set mMainJpegBuffer. This ensures that we * don't completely exhaust data and use the rest 20% for fuzzing of APIs. */ std::vector<uint8_t> buffer = fdp.ConsumeBytes<uint8_t>((size * 80) / 100); inputFrame.mMainJpegBuffer = reinterpret_cast<const char*>(buffer.data()); /** * Calculate height and width based on buffer size and a ratio within [0.1, 0.9]. * The ratio adjusts the dimensions while maintaining a relationship to the total buffer size. */ const float ratio = fdp.ConsumeFloatingPointInRange<float>(kMinRatio, kMaxRatio); const size_t height = std::sqrt(buffer.size()) * ratio; const size_t width = std::sqrt(buffer.size()) / ratio; inputFrame.mMainJpegHeight = height; inputFrame.mMainJpegWidth = width; inputFrame.mMainJpegSize = buffer.size(); // Worst case both depth and confidence maps have the same size as the main color image. inputFrame.mMaxJpegSize = inputFrame.mMainJpegSize * 3; inputFrame.mMaxJpegSize = inputFrame.mMainJpegSize * kTotalDepthJpegBufferCount; std::vector<uint16_t> depth16Buffer(height * width); generateDepth16Buffer(&depth16Buffer, height * width, fdp); inputFrame.mDepthMapBuffer = depth16Buffer.data(); inputFrame.mDepthMapHeight = height; inputFrame.mDepthMapWidth = inputFrame.mDepthMapStride = width; inputFrame.mIsLogical = fdp.ConsumeBool(); inputFrame.mOrientation = fdp.PickValueInArray<DepthPhotoOrientation>(kDepthPhotoOrientations); if (fdp.ConsumeBool()) { for (uint8_t i = 0; i < kIntrinsicCalibrationSize; ++i) { inputFrame.mIntrinsicCalibration[i] = fdp.ConsumeFloatingPoint<float>(); } inputFrame.mIsIntrinsicCalibrationValid = 1; } if (fdp.ConsumeBool()) { for (uint8_t i = 0; i < kLensDistortionSize; ++i) { inputFrame.mLensDistortion[i] = fdp.ConsumeFloatingPoint<float>(); } inputFrame.mIsLensDistortionValid = 1; } std::vector<uint8_t> depthPhotoBuffer(inputFrame.mMaxJpegSize); size_t actualDepthPhotoSize = 0; std::array<uint16_t, kTestBufferDepthSize> depth16Buffer; generateDepth16Buffer(data, size, &depth16Buffer); inputFrame.mMainJpegBuffer = reinterpret_cast<const char*> (data); inputFrame.mMainJpegSize = size; inputFrame.mDepthMapBuffer = depth16Buffer.data(); inputFrame.mDepthMapStride = kTestBufferWidth; inputFrame.mDepthMapWidth = kTestBufferWidth; inputFrame.mDepthMapHeight = kTestBufferHeight; processDepthPhotoFrame( inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(), processDepthPhotoFrame(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(), &actualDepthPhotoSize); return 0; Loading Loading
services/camera/libcameraservice/fuzzer/Android.bp +15 −4 Original line number Diff line number Diff line Loading @@ -26,7 +26,18 @@ package { cc_defaults { name: "libcameraservice_fuzz_defaults", fuzz_config: { componentid: 41727 cc: [ "android-camera-fwk-eng@google.com", ], componentid: 41727, hotlists: [ "4593311", ], description: "The fuzzer targets the APIs of libcameraservice", vector: "local_no_privileges_required", service_privilege: "privileged", users: "multi_user", fuzzed_code_usage: "shipped", }, } Loading @@ -37,9 +48,9 @@ cc_fuzz { "DistortionMapperFuzzer.cpp", ], shared_libs: [ "libcameraservice", "camera_platform_flags_c_lib", "libcamera_client", "camera_platform_flags_c_lib" "libcameraservice", ], } Loading @@ -50,8 +61,8 @@ cc_fuzz { "DepthProcessorFuzzer.cpp", ], shared_libs: [ "camera_platform_flags_c_lib", "libcameraservice", "camera_platform_flags_c_lib" ], corpus: ["corpus/*.jpg"], }
services/camera/libcameraservice/fuzzer/DepthProcessorFuzzer.cpp +70 −27 Original line number Diff line number Diff line Loading @@ -14,48 +14,91 @@ * limitations under the License. */ #include <array> #include <vector> #include "common/DepthPhotoProcessor.h" #include <fuzzer/FuzzedDataProvider.h> #include <random> #include "common/DepthPhotoProcessor.h" #include <fuzzer/FuzzedDataProvider.h> using namespace android; using namespace android::camera3; static const size_t kTestBufferWidth = 640; static const size_t kTestBufferHeight = 480; static const size_t kTestBufferDepthSize (kTestBufferWidth * kTestBufferHeight); static const float kMinRatio = 0.1f; static const float kMaxRatio = 0.9f; static const uint8_t kTotalDepthJpegBufferCount = 3; static const uint8_t kIntrinsicCalibrationSize = 5; static const uint8_t kLensDistortionSize = 5; static const DepthPhotoOrientation kDepthPhotoOrientations[] = { DepthPhotoOrientation::DEPTH_ORIENTATION_0_DEGREES, DepthPhotoOrientation::DEPTH_ORIENTATION_90_DEGREES, DepthPhotoOrientation::DEPTH_ORIENTATION_180_DEGREES, DepthPhotoOrientation::DEPTH_ORIENTATION_270_DEGREES}; void generateDepth16Buffer(const uint8_t* data, size_t size, std::array<uint16_t, kTestBufferDepthSize> *depth16Buffer /*out*/) { FuzzedDataProvider dataProvider(data, size); for (size_t i = 0; i < depth16Buffer->size(); i++) { (*depth16Buffer)[i] = dataProvider.ConsumeIntegral<uint16_t>(); void generateDepth16Buffer(std::vector<uint16_t>* depth16Buffer /*out*/, size_t length, FuzzedDataProvider& fdp) { std::default_random_engine gen(fdp.ConsumeIntegral<uint8_t>()); std::uniform_int_distribution uniDist(0, UINT16_MAX - 1); for (size_t i = 0; i < length; ++i) { (*depth16Buffer)[i] = uniDist(gen); } } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { FuzzedDataProvider fdp(data, size); DepthPhotoInputFrame inputFrame; /** * Consuming 80% of the data to set mMainJpegBuffer. This ensures that we * don't completely exhaust data and use the rest 20% for fuzzing of APIs. */ std::vector<uint8_t> buffer = fdp.ConsumeBytes<uint8_t>((size * 80) / 100); inputFrame.mMainJpegBuffer = reinterpret_cast<const char*>(buffer.data()); /** * Calculate height and width based on buffer size and a ratio within [0.1, 0.9]. * The ratio adjusts the dimensions while maintaining a relationship to the total buffer size. */ const float ratio = fdp.ConsumeFloatingPointInRange<float>(kMinRatio, kMaxRatio); const size_t height = std::sqrt(buffer.size()) * ratio; const size_t width = std::sqrt(buffer.size()) / ratio; inputFrame.mMainJpegHeight = height; inputFrame.mMainJpegWidth = width; inputFrame.mMainJpegSize = buffer.size(); // Worst case both depth and confidence maps have the same size as the main color image. inputFrame.mMaxJpegSize = inputFrame.mMainJpegSize * 3; inputFrame.mMaxJpegSize = inputFrame.mMainJpegSize * kTotalDepthJpegBufferCount; std::vector<uint16_t> depth16Buffer(height * width); generateDepth16Buffer(&depth16Buffer, height * width, fdp); inputFrame.mDepthMapBuffer = depth16Buffer.data(); inputFrame.mDepthMapHeight = height; inputFrame.mDepthMapWidth = inputFrame.mDepthMapStride = width; inputFrame.mIsLogical = fdp.ConsumeBool(); inputFrame.mOrientation = fdp.PickValueInArray<DepthPhotoOrientation>(kDepthPhotoOrientations); if (fdp.ConsumeBool()) { for (uint8_t i = 0; i < kIntrinsicCalibrationSize; ++i) { inputFrame.mIntrinsicCalibration[i] = fdp.ConsumeFloatingPoint<float>(); } inputFrame.mIsIntrinsicCalibrationValid = 1; } if (fdp.ConsumeBool()) { for (uint8_t i = 0; i < kLensDistortionSize; ++i) { inputFrame.mLensDistortion[i] = fdp.ConsumeFloatingPoint<float>(); } inputFrame.mIsLensDistortionValid = 1; } std::vector<uint8_t> depthPhotoBuffer(inputFrame.mMaxJpegSize); size_t actualDepthPhotoSize = 0; std::array<uint16_t, kTestBufferDepthSize> depth16Buffer; generateDepth16Buffer(data, size, &depth16Buffer); inputFrame.mMainJpegBuffer = reinterpret_cast<const char*> (data); inputFrame.mMainJpegSize = size; inputFrame.mDepthMapBuffer = depth16Buffer.data(); inputFrame.mDepthMapStride = kTestBufferWidth; inputFrame.mDepthMapWidth = kTestBufferWidth; inputFrame.mDepthMapHeight = kTestBufferHeight; processDepthPhotoFrame( inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(), processDepthPhotoFrame(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(), &actualDepthPhotoSize); return 0; Loading