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

Commit 87173832 authored by Alec Mouri's avatar Alec Mouri Committed by Android (Google) Code Review
Browse files

Merge "Delete (most) sf fuzzers" into main

parents f9b7ec9f 300a944e
Loading
Loading
Loading
Loading
+0 −88
Original line number Original line Diff line number Diff line
@@ -26,46 +26,18 @@ package {


cc_defaults {
cc_defaults {
    name: "surfaceflinger_fuzz_defaults",
    name: "surfaceflinger_fuzz_defaults",
    include_dirs: [
        "frameworks/native/services/surfaceflinger/tests/unittests",
    ],
    static_libs: [
    static_libs: [
        "android.hardware.graphics.composer@2.1-resources",
        "libc++fs",
        "libc++fs",
        "libgmock",
        "libgui_mocks",
        "libgmock_ndk",
        "libgmock_main",
        "libgtest_ndk_c++",
        "libgmock_main_ndk",
        "librenderengine_mocks",
        "libsurfaceflinger_common",
        "libsurfaceflinger_common",
        "perfetto_trace_protos",
        "libcompositionengine_mocks",
        "perfetto_trace_protos",
    ],
    shared_libs: [
        "libprotoutil",
        "libstatssocket",
        "libstatspull",
        "libtimestats",
        "libtimestats_proto",
        "libprotobuf-cpp-full",
        "android.hardware.graphics.mapper@2.0",
        "android.hardware.graphics.mapper@3.0",
        "android.hardware.graphics.mapper@4.0",
    ],
    ],
    srcs: [
    srcs: [
        ":libsurfaceflinger_sources",
        ":libsurfaceflinger_sources",
        ":libsurfaceflinger_mock_sources",
    ],
    ],
    defaults: [
    defaults: [
        "libsurfaceflinger_defaults",
        "libsurfaceflinger_defaults",
    ],
    ],
    header_libs: [
    header_libs: [
        "libui_fuzzableDataspaces_headers",
        "libsurfaceflinger_headers",
        "libsurfaceflinger_headers",
        "libui_headers",
    ],
    ],
    cflags: [
    cflags: [
        "-Wno-unused-result",
        "-Wno-unused-result",
@@ -89,66 +61,6 @@ cc_defaults {
    },
    },
}
}


cc_fuzz {
    name: "surfaceflinger_fuzzer",
    defaults: [
        "surfaceflinger_fuzz_defaults",
    ],
    srcs: [
        "surfaceflinger_fuzzer.cpp",
    ],
}

cc_fuzz {
    name: "surfaceflinger_displayhardware_fuzzer",
    defaults: [
        "surfaceflinger_fuzz_defaults",
    ],
    srcs: [
        "surfaceflinger_displayhardware_fuzzer.cpp",
    ],
    header_libs: [
        "android.hardware.graphics.composer@2.4-command-buffer",
        "android.hardware.graphics.composer@2.4-hal",
    ],
}

cc_fuzz {
    name: "surfaceflinger_scheduler_fuzzer",
    defaults: [
        "surfaceflinger_fuzz_defaults",
    ],
    srcs: [
        "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",
    ],
}

cc_fuzz {
    name: "surfaceflinger_frametracer_fuzzer",
    defaults: [
        "surfaceflinger_fuzz_defaults",
    ],
    srcs: [
        "surfaceflinger_frametracer_fuzzer.cpp",
    ],
}

cc_fuzz {
cc_fuzz {
    name: "surfaceflinger_service_fuzzer",
    name: "surfaceflinger_service_fuzzer",
    defaults: [
    defaults: [
+0 −108
Original line number Original line Diff line number Diff line
# Fuzzers for SurfaceFlinger
## Table of contents
+ [SurfaceFlinger](#SurfaceFlinger)
+ [DisplayHardware](#DisplayHardware)
+ [Scheduler](#Scheduler)
+ [Layer](#Layer)
+ [FrameTracer](#FrameTracer)

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

SurfaceFlinger supports the following data sources:
1. Pixel Formats (parameter name: `defaultCompositionPixelFormat`)
2. Data Spaces (parameter name: `defaultCompositionDataspace`)
3. Rotations (parameter name: `internalDisplayOrientation`)
3. Surface composer tags (parameter name: `onTransact`)

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

#### Steps to run
1. Build the fuzzer
```
  $ mm -j$(nproc) surfaceflinger_fuzzer
```
2. To run on device
```
  $ adb sync data
  $ adb shell /data/fuzz/arm64/surfaceflinger_fuzzer/surfaceflinger_fuzzer
```

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

DisplayHardware supports the following parameters:
1. Hal Capability (parameter name: `hasCapability`)
2. Hal BlendMode (parameter name: `setBlendMode`)
3. Hal Composition (parameter name: `setCompositionType`)
4. Hal Display Capability (parameter name: `hasDisplayCapability`)
5. Composition Types (parameter name: `prepareFrame`)
6. Color Modes (parameter name: `setActiveColorMode`)
7. Render Intents (parameter name: `setActiveColorMode`)
8. Power Modes (parameter name: `setPowerMode`)
9. Content Types (parameter name: `setContentType`)
10. Data Space (parameter name: `setDataspace`)
11. Transforms (parameter name: `setLayerTransform`)

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

#### Steps to run
1. Build the fuzzer
```
  $ mm -j$(nproc) surfaceflinger_displayhardware_fuzzer
```
2. Run on device
```
  $ adb sync data
  $ adb shell /data/fuzz/arm64/surfaceflinger_displayhardware_fuzzer/surfaceflinger_displayhardware_fuzzer
```

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

Scheduler supports the following parameters:
1. VSync Periods (parameter name: `lowFpsPeriod`)

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

#### Steps to run
1. Build the fuzzer
```
  $ mm -j$(nproc) surfaceflinger_scheduler_fuzzer
```
2. To run on device
```
  $ 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. Disconnect modes (parameter name: `disconnect`)
4. 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
```

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

#### Steps to run
1. Build the fuzzer
```
  $ mm -j$(nproc) surfaceflinger_frametracer_fuzzer
```
2. To run on device
```
  $ adb sync data
  $ adb shell /data/fuzz/arm64/surfaceflinger_frametracer_fuzzer/surfaceflinger_frametracer_fuzzer
```
+0 −663

File deleted.

Preview size limit exceeded, changes collapsed.

+0 −109
Original line number Original line 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.
 */

#pragma once

#include <utils/Condition.h>
#include <chrono>
#include <vector>

#include <android/hardware/graphics/composer/2.4/IComposer.h>
#include <composer-hal/2.1/ComposerClient.h>
#include <composer-hal/2.2/ComposerClient.h>
#include <composer-hal/2.3/ComposerClient.h>
#include <composer-hal/2.4/ComposerClient.h>

#include "DisplayHardware/HWC2.h"
#include "surfaceflinger_fuzzers_utils.h"

namespace {
class LayerImpl;
class Frame;
class DelayedEventGenerator;
} // namespace

namespace android {
class SurfaceComposerClient;
} // namespace android

namespace android::hardware::graphics::composer::hal {

using aidl::android::hardware::graphics::common::DisplayHotplugEvent;
using aidl::android::hardware::graphics::composer3::RefreshRateChangedDebugData;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::HWC2::ComposerCallback;

class ComposerCallbackBridge : public IComposerCallback {
public:
    ComposerCallbackBridge(ComposerCallback* callback, bool vsyncSwitchingSupported)
          : mCallback(callback), mVsyncSwitchingSupported(vsyncSwitchingSupported) {}

    Return<void> onHotplug(HWDisplayId display, Connection connection) override {
        const auto event = connection == Connection::CONNECTED ? DisplayHotplugEvent::CONNECTED
                                                               : DisplayHotplugEvent::DISCONNECTED;
        mCallback->onComposerHalHotplugEvent(display, event);
        return Void();
    }

    Return<void> onRefresh(HWDisplayId display) override {
        mCallback->onComposerHalRefresh(display);
        return Void();
    }

    Return<void> onVsync(HWDisplayId display, int64_t timestamp) override {
        if (!mVsyncSwitchingSupported) {
            mCallback->onComposerHalVsync(display, timestamp, std::nullopt);
        }
        return Void();
    }

    Return<void> onVsync_2_4(HWDisplayId display, int64_t timestamp,
                             VsyncPeriodNanos vsyncPeriodNanos) override {
        if (mVsyncSwitchingSupported) {
            mCallback->onComposerHalVsync(display, timestamp, vsyncPeriodNanos);
        }
        return Void();
    }

    Return<void> onVsyncPeriodTimingChanged(HWDisplayId display,
                                            const VsyncPeriodChangeTimeline& timeline) override {
        mCallback->onComposerHalVsyncPeriodTimingChanged(display, timeline);
        return Void();
    }

    Return<void> onSeamlessPossible(HWDisplayId display) override {
        mCallback->onComposerHalSeamlessPossible(display);
        return Void();
    }

private:
    ComposerCallback* const mCallback;
    const bool mVsyncSwitchingSupported;
};

struct TestHWC2ComposerCallback : public HWC2::ComposerCallback {
    virtual ~TestHWC2ComposerCallback() = default;
    void onComposerHalHotplugEvent(HWDisplayId, DisplayHotplugEvent) {}
    void onComposerHalRefresh(HWDisplayId) {}
    void onComposerHalVsync(HWDisplayId, int64_t, std::optional<VsyncPeriodNanos>) {}
    void onComposerHalVsyncPeriodTimingChanged(HWDisplayId, const VsyncPeriodChangeTimeline&) {}
    void onComposerHalSeamlessPossible(HWDisplayId) {}
    void onComposerHalVsyncIdle(HWDisplayId) {}
    void onRefreshRateChangedDebug(const RefreshRateChangedDebugData&) {}
};

} // namespace android::hardware::graphics::composer::hal
+0 −147
Original line number Original line 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 <FrameTracer/FrameTracer.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <perfetto/trace/trace.pb.h>

namespace android::fuzz {

using namespace google::protobuf;

constexpr size_t kMaxStringSize = 256;
constexpr size_t kMinLayerIds = 1;
constexpr size_t kMaxLayerIds = 10;
constexpr int32_t kMinRange = 0;
constexpr int32_t kConfigDuration = 500;
constexpr int32_t kBufferSize = 1024;
constexpr int32_t kTimeOffset = 100000;

class FrameTracerFuzzer {
public:
    FrameTracerFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
        // Fuzzer is single-threaded, so no need to be thread-safe.
        static bool wasInitialized = false;
        if (!wasInitialized) {
            perfetto::TracingInitArgs args;
            args.backends = perfetto::kInProcessBackend;
            perfetto::Tracing::Initialize(args);
            wasInitialized = true;
        }
        mFrameTracer = std::make_unique<android::FrameTracer>();
    }
    ~FrameTracerFuzzer() { mFrameTracer.reset(); }
    void process();

private:
    void traceTimestamp();
    void traceTimestamp(std::vector<int32_t> layerIds, size_t numLayerIds);
    void traceFence(std::vector<int32_t> layerIds, size_t numLayerIds);
    std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest();
    std::unique_ptr<android::FrameTracer> mFrameTracer = nullptr;
    std::vector<int32_t> generateLayerIds(size_t numLayerIds);
    android::FenceToFenceTimeMap mFenceFactory;
    FuzzedDataProvider mFdp;
};

std::unique_ptr<perfetto::TracingSession> FrameTracerFuzzer::getTracingSessionForTest() {
    perfetto::TraceConfig cfg;
    cfg.set_duration_ms(mFdp.ConsumeIntegralInRange<int32_t>(kMinRange, kConfigDuration));
    cfg.add_buffers()->set_size_kb(mFdp.ConsumeIntegralInRange<int32_t>(kMinRange, kBufferSize));
    auto* dsCfg = cfg.add_data_sources()->mutable_config();
    dsCfg->set_name(android::FrameTracer::kFrameTracerDataSource);

    auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
    tracingSession->Setup(cfg);
    return tracingSession;
}

std::vector<int32_t> FrameTracerFuzzer::generateLayerIds(size_t numLayerIds) {
    std::vector<int32_t> layerIds;
    for (size_t i = 0; i < numLayerIds; ++i) {
        layerIds.push_back(mFdp.ConsumeIntegral<int32_t>());
    }
    return layerIds;
}

void FrameTracerFuzzer::traceTimestamp(std::vector<int32_t> layerIds, size_t numLayerIds) {
    uint32_t layerId = layerIds.at(mFdp.ConsumeIntegralInRange<size_t>(0, numLayerIds - 1));
    android::FrameTracer::FrameEvent::BufferEventType type = static_cast<
            android::FrameTracer::FrameEvent::BufferEventType>(
            mFdp.ConsumeIntegralInRange<uint32_t>(android::FrameTracer::FrameEvent::UNSPECIFIED,
                                                  android::FrameTracer::FrameEvent::CANCEL));
    mFrameTracer->traceTimestamp(layerId, mFdp.ConsumeIntegral<uint64_t>() /*bufferID*/,
                                 mFdp.ConsumeIntegral<uint64_t>() /*frameNumber*/,
                                 mFdp.ConsumeIntegral<nsecs_t>() /*timestamp*/, type,
                                 mFdp.ConsumeIntegral<nsecs_t>() /*duration*/);
}

void FrameTracerFuzzer::traceFence(std::vector<int32_t> layerIds, size_t numLayerIds) {
    const nsecs_t signalTime =
            mFdp.ConsumeBool() ? android::Fence::SIGNAL_TIME_PENDING : systemTime();
    const nsecs_t startTime = (signalTime == android::Fence::SIGNAL_TIME_PENDING)
            ? signalTime - kTimeOffset
            : signalTime + kTimeOffset;
    auto fence = mFenceFactory.createFenceTimeForTest(android::Fence::NO_FENCE);
    mFenceFactory.signalAllForTest(android::Fence::NO_FENCE, signalTime);
    int32_t layerId = layerIds.at(mFdp.ConsumeIntegralInRange<size_t>(0, numLayerIds - 1));
    mFrameTracer->traceFence(layerId, mFdp.ConsumeIntegral<uint64_t>() /*bufferID*/,
                             mFdp.ConsumeIntegral<uint64_t>() /*frameNumber*/, fence,
                             android::FrameTracer::FrameEvent::ACQUIRE_FENCE, startTime);
}

void FrameTracerFuzzer::process() {
    std::vector<int32_t> layerIds =
            generateLayerIds(mFdp.ConsumeIntegralInRange<size_t>(kMinLayerIds, kMaxLayerIds));

    std::unique_ptr<perfetto::TracingSession> tracingSession;
    while (mFdp.remaining_bytes()) {
        auto invokeFrametracerAPI = mFdp.PickValueInArray<const std::function<void()>>({
                [&]() { mFrameTracer->registerDataSource(); },
                [&]() {
                    if (tracingSession) {
                        tracingSession->StopBlocking();
                    }
                    tracingSession = getTracingSessionForTest();
                    tracingSession->StartBlocking();
                },
                [&]() { traceTimestamp(layerIds, layerIds.size()); },
                [&]() { traceFence(layerIds, layerIds.size()); },
                [&]() {
                    for (auto it = layerIds.begin(); it != layerIds.end(); ++it) {
                        mFrameTracer->traceNewLayer(*it /*layerId*/,
                                                    mFdp.ConsumeRandomLengthString(
                                                            kMaxStringSize) /*layerName*/);
                    }
                },
                [&]() { mFenceFactory.signalAllForTest(android::Fence::NO_FENCE, systemTime()); },
        });
        invokeFrametracerAPI();
    }

    for (auto it = layerIds.begin(); it != layerIds.end(); ++it) {
        mFrameTracer->onDestroy(*it);
    }
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    FrameTracerFuzzer frameTracerFuzzer(data, size);
    frameTracerFuzzer.process();
    return 0;
}

} // namespace android::fuzz
Loading