Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 041415af authored by Chethan Kumar R E's avatar Chethan Kumar R E Committed by Alec Mouri
Browse files

Added surfaceflinger_layer_fuzzer

Test: ./surfaceflinger_layer_fuzzer
Bug: 189053744

Change-Id: I783b18389dd260b86eec2786c307d71d53785077
parent df4b0674
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -102,3 +102,19 @@ cc_fuzz {
        "surfaceflinger_scheduler_fuzzer.cpp",
    ],
}

cc_fuzz {
    name: "surfaceflinger_layer_fuzzer",
    defaults: [
        "surfaceflinger_fuzz_defaults",
    ],
    header_libs: [
        "libgui_headers",
    ],
    static_libs: [
        "librenderengine",
    ],
    srcs: [
        "surfaceflinger_layer_fuzzer.cpp",
    ],
}
+23 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
+ [SurfaceFlinger](#SurfaceFlinger)
+ [DisplayHardware](#DisplayHardware)
+ [Scheduler](#Scheduler)
+ [Layer](#Layer)

# <a name="SurfaceFlinger"></a> Fuzzer for SurfaceFlinger

@@ -70,3 +71,25 @@ You can find the possible values in the fuzzer's source code.
  $ adb sync data
  $ adb shell /data/fuzz/arm64/surfaceflinger_scheduler_fuzzer/surfaceflinger_scheduler_fuzzer
```

# <a name="Layer"></a> Fuzzer for Layer

Layer supports the following parameters:
1. Display Connection Types (parameter name: `fakeDisplay`)
2. State Sets (parameter name: `traverseInZOrder`)
3. State Subsets (parameter name: `prepareCompositionState`)
4. Disconnect modes (parameter name: `disconnect`)
5. Data Spaces (parameter name: `setDataspace`)

You can find the possible values in the fuzzer's source code.

#### Steps to run
1. Build the fuzzer
```
  $ mm -j$(nproc) surfaceflinger_layer_fuzzer
```
2. Run on device
```
  $ adb sync data
  $ adb shell /data/fuzz/arm64/surfaceflinger_layer_fuzzer/surfaceflinger_layer_fuzzer
```
+0 −29
Original line number Diff line number Diff line
@@ -29,35 +29,6 @@ static constexpr LatchUnsignaledConfig kLatchUnsignaledConfig[] = {
        LatchUnsignaledConfig::Disabled,
};

static constexpr ui::PixelFormat kPixelFormats[] = {ui::PixelFormat::RGBA_8888,
                                                    ui::PixelFormat::RGBX_8888,
                                                    ui::PixelFormat::RGB_888,
                                                    ui::PixelFormat::RGB_565,
                                                    ui::PixelFormat::BGRA_8888,
                                                    ui::PixelFormat::YCBCR_422_SP,
                                                    ui::PixelFormat::YCRCB_420_SP,
                                                    ui::PixelFormat::YCBCR_422_I,
                                                    ui::PixelFormat::RGBA_FP16,
                                                    ui::PixelFormat::RAW16,
                                                    ui::PixelFormat::BLOB,
                                                    ui::PixelFormat::IMPLEMENTATION_DEFINED,
                                                    ui::PixelFormat::YCBCR_420_888,
                                                    ui::PixelFormat::RAW_OPAQUE,
                                                    ui::PixelFormat::RAW10,
                                                    ui::PixelFormat::RAW12,
                                                    ui::PixelFormat::RGBA_1010102,
                                                    ui::PixelFormat::Y8,
                                                    ui::PixelFormat::Y16,
                                                    ui::PixelFormat::YV12,
                                                    ui::PixelFormat::DEPTH_16,
                                                    ui::PixelFormat::DEPTH_24,
                                                    ui::PixelFormat::DEPTH_24_STENCIL_8,
                                                    ui::PixelFormat::DEPTH_32F,
                                                    ui::PixelFormat::DEPTH_32F_STENCIL_8,
                                                    ui::PixelFormat::STENCIL_8,
                                                    ui::PixelFormat::YCBCR_P010,
                                                    ui::PixelFormat::HSV_888};

static constexpr ui::Rotation kRotations[] = {ui::Rotation::Rotation0, ui::Rotation::Rotation90,
                                              ui::Rotation::Rotation180, ui::Rotation::Rotation270};

+29 −0
Original line number Diff line number Diff line
@@ -123,6 +123,35 @@ static constexpr ui::ColorMode kColormodes[] = {ui::ColorMode::NATIVE,
                                                ui::ColorMode::BT2100_HLG,
                                                ui::ColorMode::DISPLAY_BT2020};

static constexpr ui::PixelFormat kPixelFormats[] = {ui::PixelFormat::RGBA_8888,
                                                    ui::PixelFormat::RGBX_8888,
                                                    ui::PixelFormat::RGB_888,
                                                    ui::PixelFormat::RGB_565,
                                                    ui::PixelFormat::BGRA_8888,
                                                    ui::PixelFormat::YCBCR_422_SP,
                                                    ui::PixelFormat::YCRCB_420_SP,
                                                    ui::PixelFormat::YCBCR_422_I,
                                                    ui::PixelFormat::RGBA_FP16,
                                                    ui::PixelFormat::RAW16,
                                                    ui::PixelFormat::BLOB,
                                                    ui::PixelFormat::IMPLEMENTATION_DEFINED,
                                                    ui::PixelFormat::YCBCR_420_888,
                                                    ui::PixelFormat::RAW_OPAQUE,
                                                    ui::PixelFormat::RAW10,
                                                    ui::PixelFormat::RAW12,
                                                    ui::PixelFormat::RGBA_1010102,
                                                    ui::PixelFormat::Y8,
                                                    ui::PixelFormat::Y16,
                                                    ui::PixelFormat::YV12,
                                                    ui::PixelFormat::DEPTH_16,
                                                    ui::PixelFormat::DEPTH_24,
                                                    ui::PixelFormat::DEPTH_24_STENCIL_8,
                                                    ui::PixelFormat::DEPTH_32F,
                                                    ui::PixelFormat::DEPTH_32F_STENCIL_8,
                                                    ui::PixelFormat::STENCIL_8,
                                                    ui::PixelFormat::YCBCR_P010,
                                                    ui::PixelFormat::HSV_888};

FloatRect getFuzzedFloatRect(FuzzedDataProvider *fdp) {
    return FloatRect(fdp->ConsumeFloatingPoint<float>() /*left*/,
                     fdp->ConsumeFloatingPoint<float>() /*right*/,
+199 −0
Original line number Diff line number Diff line
/*
 * 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 <BufferStateLayer.h>
#include <Client.h>
#include <DisplayDevice.h>
#include <EffectLayer.h>
#include <LayerRejecter.h>
#include <LayerRenderArea.h>
#include <MonitoredProducer.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <gui/IProducerListener.h>
#include <gui/LayerDebugInfo.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/WindowInfo.h>
#include <renderengine/mock/FakeExternalTexture.h>
#include <ui/DisplayStatInfo.h>

#include <FuzzableDataspaces.h>
#include <surfaceflinger_fuzzers_utils.h>

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> client);
    Rect getFuzzedRect();
    FrameTimelineInfo getFuzzedFrameTimelineInfo();

private:
    FuzzedDataProvider mFdp;
};

Rect LayerFuzzer::getFuzzedRect() {
    return Rect(mFdp.ConsumeIntegral<int32_t>() /*left*/, mFdp.ConsumeIntegral<int32_t>() /*top*/,
                mFdp.ConsumeIntegral<int32_t>() /*right*/,
                mFdp.ConsumeIntegral<int32_t>() /*bottom*/);
}

FrameTimelineInfo LayerFuzzer::getFuzzedFrameTimelineInfo() {
    return FrameTimelineInfo{.vsyncId = mFdp.ConsumeIntegral<int64_t>(),
                             .inputEventId = mFdp.ConsumeIntegral<int32_t>()};
}

LayerCreationArgs LayerFuzzer::createLayerCreationArgs(TestableSurfaceFlinger* flinger,
                                                       sp<Client> client) {
    flinger->setupScheduler(std::make_unique<android::mock::VsyncController>(),
                            std::make_unique<android::mock::VSyncTracker>(),
                            std::make_unique<android::mock::EventThread>(),
                            std::make_unique<android::mock::EventThread>());

    return LayerCreationArgs(flinger->flinger(), client,
                             mFdp.ConsumeRandomLengthString(kRandomStringLength) /*name*/,
                             mFdp.ConsumeIntegral<uint32_t>() /*flags*/, {} /*metadata*/);
}

void LayerFuzzer::invokeEffectLayer() {
    TestableSurfaceFlinger flinger;
    sp<Client> client = sp<Client>::make(flinger.flinger());
    const LayerCreationArgs layerCreationArgs = createLayerCreationArgs(&flinger, client);
    sp<EffectLayer> effectLayer = sp<EffectLayer>::make(layerCreationArgs);

    effectLayer->setColor({(mFdp.ConsumeFloatingPointInRange<float>(0, 255) /*x*/,
                            mFdp.ConsumeFloatingPointInRange<float>(0, 255) /*y*/,
                            mFdp.ConsumeFloatingPointInRange<float>(0, 255) /*z*/)});
    effectLayer->setDataspace(mFdp.PickValueInArray(kDataspaces));
    sp<EffectLayer> parent = sp<EffectLayer>::make(layerCreationArgs);
    effectLayer->setChildrenDrawingParent(parent);

    const FrameTimelineInfo frameInfo = getFuzzedFrameTimelineInfo();
    const int64_t postTime = mFdp.ConsumeIntegral<int64_t>();
    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<int64_t>() /*acquireTime*/,
                                                   mFdp.ConsumeIntegral<int64_t>() /*currentTime*/);
    effectLayer->addSurfaceFrameDroppedForBuffer(surfaceFrame1);

    parent.clear();
    client.clear();
    effectLayer.clear();
}

void LayerFuzzer::invokeBufferStateLayer() {
    TestableSurfaceFlinger flinger;
    sp<Client> client = sp<Client>::make(flinger.flinger());
    sp<BufferStateLayer> layer =
            sp<BufferStateLayer>::make(createLayerCreationArgs(&flinger, client));
    sp<Fence> fence = sp<Fence>::make();
    const std::shared_ptr<FenceTime> fenceTime = std::make_shared<FenceTime>(fence);

    const CompositorTiming compositor = {mFdp.ConsumeIntegral<int64_t>(),
                                         mFdp.ConsumeIntegral<int64_t>(),
                                         mFdp.ConsumeIntegral<int64_t>()};
    std::packaged_task<renderengine::RenderEngineResult()> renderResult([&] {
        return renderengine::RenderEngineResult{mFdp.ConsumeIntegral<int32_t>(),
                                                base::unique_fd(fence->get())};
    });
    layer->onLayerDisplayed(renderResult.get_future());
    layer->releasePendingBuffer(mFdp.ConsumeIntegral<int64_t>());
    layer->finalizeFrameEventHistory(fenceTime, compositor);
    layer->onPostComposition(nullptr, fenceTime, fenceTime, compositor);
    layer->isBufferDue(mFdp.ConsumeIntegral<int64_t>());

    layer->setTransform(mFdp.ConsumeIntegral<uint32_t>());
    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<int32_t>());

    native_handle_t* testHandle = native_handle_create(0, 1);
    const bool ownsHandle = mFdp.ConsumeBool();
    sp<NativeHandle> nativeHandle = sp<NativeHandle>::make(testHandle, ownsHandle);
    layer->setSidebandStream(nativeHandle);
    layer->addFrameEvent(fence, mFdp.ConsumeIntegral<int64_t>() /*postedTime*/,
                         mFdp.ConsumeIntegral<int64_t>() /*requestedTime*/);
    layer->computeSourceBounds(getFuzzedFloatRect(&mFdp));

    layer->fenceHasSignaled();
    layer->framePresentTimeIsCurrent(mFdp.ConsumeIntegral<int64_t>());
    layer->onPreComposition(mFdp.ConsumeIntegral<int64_t>());
    const std::vector<sp<CallbackHandle>> callbacks;
    layer->setTransactionCompletedListeners(callbacks);

    std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared<
            renderengine::mock::FakeExternalTexture>(mFdp.ConsumeIntegral<uint32_t>(),
                                                     mFdp.ConsumeIntegral<uint32_t>(),
                                                     mFdp.ConsumeIntegral<uint64_t>(),
                                                     static_cast<android::PixelFormat>(
                                                             mFdp.PickValueInArray(kPixelFormats)),
                                                     mFdp.ConsumeIntegral<uint64_t>());
    layer->setBuffer(texture, {} /*bufferData*/, mFdp.ConsumeIntegral<nsecs_t>() /*postTime*/,
                     mFdp.ConsumeIntegral<nsecs_t>() /*desiredTime*/,
                     mFdp.ConsumeBool() /*isAutoTimestamp*/,
                     {mFdp.ConsumeIntegral<nsecs_t>()} /*dequeue*/, {} /*info*/);

    LayerRenderArea layerArea(*(flinger.flinger()), layer, getFuzzedRect(),
                              {mFdp.ConsumeIntegral<int32_t>(),
                               mFdp.ConsumeIntegral<int32_t>()} /*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