/* * Copyright 2021 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace android::fuzzer { using namespace renderengine; constexpr uint16_t kRandomStringLength = 256; class LayerFuzzer { public: LayerFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){}; void init(); void invokeBufferStateLayer(); void invokeEffectLayer(); LayerCreationArgs createLayerCreationArgs(TestableSurfaceFlinger* flinger, sp client); Rect getFuzzedRect(); FrameTimelineInfo getFuzzedFrameTimelineInfo(); private: FuzzedDataProvider mFdp; }; Rect LayerFuzzer::getFuzzedRect() { return Rect(mFdp.ConsumeIntegral() /*left*/, mFdp.ConsumeIntegral() /*top*/, mFdp.ConsumeIntegral() /*right*/, mFdp.ConsumeIntegral() /*bottom*/); } FrameTimelineInfo LayerFuzzer::getFuzzedFrameTimelineInfo() { return FrameTimelineInfo{.vsyncId = mFdp.ConsumeIntegral(), .inputEventId = mFdp.ConsumeIntegral()}; } LayerCreationArgs LayerFuzzer::createLayerCreationArgs(TestableSurfaceFlinger* flinger, sp client) { flinger->setupScheduler(std::make_unique(), std::make_unique(), std::make_unique(), std::make_unique()); return LayerCreationArgs(flinger->flinger(), client, mFdp.ConsumeRandomLengthString(kRandomStringLength) /*name*/, mFdp.ConsumeIntegral() /*flags*/, {} /*metadata*/); } void LayerFuzzer::invokeEffectLayer() { TestableSurfaceFlinger flinger; sp client = sp::make(flinger.flinger()); const LayerCreationArgs layerCreationArgs = createLayerCreationArgs(&flinger, client); sp effectLayer = sp::make(layerCreationArgs); effectLayer->setColor({(mFdp.ConsumeFloatingPointInRange(0, 255) /*x*/, mFdp.ConsumeFloatingPointInRange(0, 255) /*y*/, mFdp.ConsumeFloatingPointInRange(0, 255) /*z*/)}); effectLayer->setDataspace(mFdp.PickValueInArray(kDataspaces)); sp parent = sp::make(layerCreationArgs); effectLayer->setChildrenDrawingParent(parent); const FrameTimelineInfo frameInfo = getFuzzedFrameTimelineInfo(); const int64_t postTime = mFdp.ConsumeIntegral(); effectLayer->setFrameTimelineVsyncForBufferTransaction(frameInfo, postTime); effectLayer->setFrameTimelineVsyncForBufferlessTransaction(frameInfo, postTime); auto surfaceFrame = effectLayer->createSurfaceFrameForTransaction(frameInfo, postTime); auto surfaceFrame1 = effectLayer->createSurfaceFrameForBuffer(frameInfo, postTime, mFdp.ConsumeRandomLengthString( kRandomStringLength) /*bufferName*/); effectLayer->addSurfaceFramePresentedForBuffer(surfaceFrame, mFdp.ConsumeIntegral() /*acquireTime*/, mFdp.ConsumeIntegral() /*currentTime*/); effectLayer->addSurfaceFrameDroppedForBuffer(surfaceFrame1); parent.clear(); client.clear(); effectLayer.clear(); } void LayerFuzzer::invokeBufferStateLayer() { TestableSurfaceFlinger flinger; sp client = sp::make(flinger.flinger()); sp layer = sp::make(createLayerCreationArgs(&flinger, client)); sp fence = sp::make(); const std::shared_ptr fenceTime = std::make_shared(fence); const CompositorTiming compositor = {mFdp.ConsumeIntegral(), mFdp.ConsumeIntegral(), mFdp.ConsumeIntegral()}; layer->onLayerDisplayed(ftl::yield(fence).share()); layer->onLayerDisplayed( ftl::yield(base::unexpected(mFdp.ConsumeIntegral())).share()); layer->releasePendingBuffer(mFdp.ConsumeIntegral()); layer->finalizeFrameEventHistory(fenceTime, compositor); layer->onPostComposition(nullptr, fenceTime, fenceTime, compositor); layer->isBufferDue(mFdp.ConsumeIntegral()); layer->setTransform(mFdp.ConsumeIntegral()); layer->setTransformToDisplayInverse(mFdp.ConsumeBool()); layer->setCrop(getFuzzedRect()); layer->setHdrMetadata(getFuzzedHdrMetadata(&mFdp)); layer->setDataspace(mFdp.PickValueInArray(kDataspaces)); if (mFdp.ConsumeBool()) { layer->setSurfaceDamageRegion(Region()); layer->setTransparentRegionHint(Region()); } else { layer->setSurfaceDamageRegion(Region(getFuzzedRect())); layer->setTransparentRegionHint(Region(getFuzzedRect())); } layer->setApi(mFdp.ConsumeIntegral()); native_handle_t* testHandle = native_handle_create(0, 1); const bool ownsHandle = mFdp.ConsumeBool(); sp nativeHandle = sp::make(testHandle, ownsHandle); layer->setSidebandStream(nativeHandle); layer->computeSourceBounds(getFuzzedFloatRect(&mFdp)); layer->fenceHasSignaled(); layer->framePresentTimeIsCurrent(mFdp.ConsumeIntegral()); layer->onPreComposition(mFdp.ConsumeIntegral()); const std::vector> callbacks; layer->setTransactionCompletedListeners(callbacks); std::shared_ptr texture = std::make_shared< renderengine::mock::FakeExternalTexture>(mFdp.ConsumeIntegral(), mFdp.ConsumeIntegral(), mFdp.ConsumeIntegral(), static_cast( mFdp.PickValueInArray(kPixelFormats)), mFdp.ConsumeIntegral()); layer->setBuffer(texture, {} /*bufferData*/, mFdp.ConsumeIntegral() /*postTime*/, mFdp.ConsumeIntegral() /*desiredTime*/, mFdp.ConsumeBool() /*isAutoTimestamp*/, {mFdp.ConsumeIntegral()} /*dequeue*/, {} /*info*/); LayerRenderArea layerArea(*(flinger.flinger()), layer, getFuzzedRect(), {mFdp.ConsumeIntegral(), mFdp.ConsumeIntegral()} /*reqSize*/, mFdp.PickValueInArray(kDataspaces), mFdp.ConsumeBool(), getFuzzedRect(), mFdp.ConsumeBool()); layerArea.render([]() {} /*drawLayers*/); if (!ownsHandle) { native_handle_close(testHandle); native_handle_delete(testHandle); } nativeHandle.clear(); fence.clear(); client.clear(); layer.clear(); } void LayerFuzzer::init() { invokeBufferStateLayer(); invokeEffectLayer(); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { LayerFuzzer layerFuzzer(data, size); layerFuzzer.init(); return 0; } } // namespace android::fuzzer