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

Commit 300a944e authored by Alec Mouri's avatar Alec Mouri
Browse files

Delete (most) sf fuzzers

The remaining fuzzer works at the AIDL service level, which is under development + evaluation.

The rest of the fuzzers don't operate at the right interface to meaningfully catch security issues, and are a maintenance cost.

Bug: 325656219
Change-Id: I7ec9b41ff561ab3f0e7d48a93a9b6bb57caffe50
Test: builds
parent 74962b78
Loading
Loading
Loading
Loading
+0 −88
Original line number Diff line number Diff line
@@ -26,46 +26,18 @@ package {

cc_defaults {
    name: "surfaceflinger_fuzz_defaults",
    include_dirs: [
        "frameworks/native/services/surfaceflinger/tests/unittests",
    ],
    static_libs: [
        "android.hardware.graphics.composer@2.1-resources",
        "libc++fs",
        "libgmock",
        "libgui_mocks",
        "libgmock_ndk",
        "libgmock_main",
        "libgtest_ndk_c++",
        "libgmock_main_ndk",
        "librenderengine_mocks",
        "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: [
        ":libsurfaceflinger_sources",
        ":libsurfaceflinger_mock_sources",
    ],
    defaults: [
        "libsurfaceflinger_defaults",
    ],
    header_libs: [
        "libui_fuzzableDataspaces_headers",
        "libsurfaceflinger_headers",
        "libui_headers",
    ],
    cflags: [
        "-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 {
    name: "surfaceflinger_service_fuzzer",
    defaults: [
+0 −108
Original line number 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 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 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