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

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

Merge "Added libgui_parcelable_fuzzer"

parents 65cd2df1 447a9e60
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -95,3 +95,13 @@ cc_fuzz {
        "libgui_fuzzer_defaults",
    ],
}

cc_fuzz {
    name: "libgui_parcelable_fuzzer",
    srcs: [
        "libgui_parcelable_fuzzer.cpp",
    ],
    defaults: [
        "libgui_fuzzer_defaults",
    ],
}
+23 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
## Table of contents
+ [libgui_surfaceComposer_fuzzer](#SurfaceComposer)
+ [libgui_surfaceComposerClient_fuzzer](#SurfaceComposerClient)
+ [libgui_parcelable_fuzzer](#Libgui_Parcelable)

# <a name="libgui_surfaceComposer_fuzzer"></a> Fuzzer for SurfaceComposer

@@ -99,3 +100,25 @@ SurfaceComposerClient supports the following data sources:
  $ adb sync data
  $ adb shell /data/fuzz/arm64/libgui_surfaceComposerClient_fuzzer/libgui_surfaceComposerClient_fuzzer
```

# <a name="libgui_parcelable_fuzzer"></a> Fuzzer for Libgui_Parcelable

Libgui_Parcelable supports the following parameters:
1. LayerMetadataKey (parameter name:`key`)
2. Dataspace (parameter name:`mDataspace`)

| Parameter| Valid Values| Configured Value|
|------------- |-------------| ----- |
|`key`| 0.`view::LayerMetadataKey::METADATA_OWNER_UID`, 1.`view::LayerMetadataKey::METADATA_WINDOW_TYPE`, 2.`view::LayerMetadataKey::METADATA_TASK_ID`, 3.`view::LayerMetadataKey::METADATA_MOUSE_CURSOR`, 4.`view::LayerMetadataKey::METADATA_ACCESSIBILITY_ID`, 5.`view::LayerMetadataKey::METADATA_OWNER_PID`, 6.`view::LayerMetadataKey::METADATA_DEQUEUE_TIME`, 7.`view::LayerMetadataKey::METADATA_GAME_MODE`, |Value obtained from FuzzedDataProvider|
|`mDataSpace`| 0.`ui::Dataspace::UNKNOWN`, 1.`ui::Dataspace::ARBITRARY`, 2.`ui::Dataspace::STANDARD_SHIFT`, 3.`ui::Dataspace::STANDARD_MASK`, 4.`ui::Dataspace::STANDARD_UNSPECIFIED`, 5.`ui::Dataspace::STANDARD_BT709`, 6.`ui::Dataspace::STANDARD_BT601_625`, 7.`ui::Dataspace::STANDARD_BT601_625_UNADJUSTED`, 8.`ui::Dataspace::STANDARD_BT601_525`, 9.`ui::Dataspace::STANDARD_BT601_525_UNADJUSTED`, 10.`ui::Dataspace::STANDARD_BT2020`, 11.`ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE`, 12.`ui::Dataspace::STANDARD_BT470M`, 13.`ui::Dataspace::STANDARD_FILM`, 14.`ui::Dataspace::STANDARD_DCI_P3`, 15.`ui::Dataspace::STANDARD_ADOBE_RGB`, 16.`ui::Dataspace::TRANSFER_SHIFT`, 17.`ui::Dataspace::TRANSFER_MASK`, 18.`ui::Dataspace::TRANSFER_UNSPECIFIED`, 19.`ui::Dataspace::TRANSFER_LINEAR`, 20.`ui::Dataspace::TRANSFER_SRGB`, 21.`ui::Dataspace::TRANSFER_SMPTE_170M`, 22.`ui::Dataspace::TRANSFER_GAMMA2_2`, 23.`ui::Dataspace::TRANSFER_GAMMA2_6`, 24.`ui::Dataspace::TRANSFER_GAMMA2_8`, 25.`ui::Dataspace::TRANSFER_ST2084`, 26.`ui::Dataspace::TRANSFER_HLG`, 27.`ui::Dataspace::RANGE_SHIFT`, 28.`ui::Dataspace::RANGE_MASK`, 29.`ui::Dataspace::RANGE_UNSPECIFIED`, 30.`ui::Dataspace::RANGE_FULL`, 31.`ui::Dataspace::RANGE_LIMITED`, 32.`ui::Dataspace::RANGE_EXTENDED`, 33.`ui::Dataspace::SRGB_LINEAR`, 34.`ui::Dataspace::V0_SRGB_LINEAR`, 35.`ui::Dataspace::V0_SCRGB_LINEAR`, 36.`ui::Dataspace::SRGB`, 37.`ui::Dataspace::V0_SRGB`, 38.`ui::Dataspace::V0_SCRGB`, 39.`ui::Dataspace::JFIF`, 40.`ui::Dataspace::V0_JFIF`, 41.`ui::Dataspace::BT601_625`, 42.`ui::Dataspace::V0_BT601_625`, 43.`ui::Dataspace::BT601_525`, 44.`ui::Dataspace::V0_BT601_525`, 45.`ui::Dataspace::BT709`, 46.`ui::Dataspace::V0_BT709`, 47.`ui::Dataspace::DCI_P3_LINEAR`, 48.`ui::Dataspace::DCI_P3`, 49.`ui::Dataspace::DISPLAY_P3_LINEAR`, 50.`ui::Dataspace::DISPLAY_P3`, 51.`ui::Dataspace::ADOBE_RGB`, 52.`ui::Dataspace::BT2020_LINEAR`, 53.`ui::Dataspace::BT2020`, 54.`ui::Dataspace::BT2020_PQ`, 55.`ui::Dataspace::DEPTH`, 56.`ui::Dataspace::SENSOR`, 57.`ui::Dataspace::BT2020_ITU`, 58.`ui::Dataspace::BT2020_ITU_PQ`, 59.`ui::Dataspace::BT2020_ITU_HLG`, 60.`ui::Dataspace::BT2020_HLG`, 61.`ui::Dataspace::DISPLAY_BT2020`, 62.`ui::Dataspace::DYNAMIC_DEPTH`, 63.`ui::Dataspace::JPEG_APP_SEGMENTS`, 64.`ui::Dataspace::HEIF`, |Value obtained from FuzzedDataProvider|

#### Steps to run
1. Build the fuzzer
```
  $ mm -j$(nproc) libgui_fuzzer
```
2. Run on device
```
  $ adb sync data
  $ adb shell /data/fuzz/arm64/libgui_fuzzer/libgui_fuzzer
```
+175 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 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 <gui/BufferQueueConsumer.h>
#include <gui/BufferQueueCore.h>
#include <gui/BufferQueueProducer.h>
#include <gui/LayerMetadata.h>
#include <gui/OccupancyTracker.h>
#include <gui/StreamSplitter.h>
#include <gui/Surface.h>
#include <gui/SurfaceControl.h>
#include <gui/view/Surface.h>
#include <libgui_fuzzer_utils.h>
#include "android/view/LayerMetadataKey.h"

using namespace android;

constexpr int32_t kMaxBytes = 256;
constexpr int32_t kMatrixSize = 4;
constexpr int32_t kLayerMetadataKeyCount = 8;

constexpr uint32_t kMetadataKey[] = {
        (uint32_t)view::LayerMetadataKey::METADATA_OWNER_UID,
        (uint32_t)view::LayerMetadataKey::METADATA_WINDOW_TYPE,
        (uint32_t)view::LayerMetadataKey::METADATA_TASK_ID,
        (uint32_t)view::LayerMetadataKey::METADATA_MOUSE_CURSOR,
        (uint32_t)view::LayerMetadataKey::METADATA_ACCESSIBILITY_ID,
        (uint32_t)view::LayerMetadataKey::METADATA_OWNER_PID,
        (uint32_t)view::LayerMetadataKey::METADATA_DEQUEUE_TIME,
        (uint32_t)view::LayerMetadataKey::METADATA_GAME_MODE,
};

class ParcelableFuzzer {
public:
    ParcelableFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
    void process();

private:
    void invokeStreamSplitter();
    void invokeOccupancyTracker();
    void invokeLayerDebugInfo();
    void invokeLayerMetadata();
    void invokeViewSurface();

    FuzzedDataProvider mFdp;
};

void ParcelableFuzzer::invokeViewSurface() {
    view::Surface surface;
    surface.name = String16((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
    Parcel parcel;
    surface.writeToParcel(&parcel);
    parcel.setDataPosition(0);
    surface.readFromParcel(&parcel);
    bool nameAlreadyWritten = mFdp.ConsumeBool();
    surface.writeToParcel(&parcel, nameAlreadyWritten);
    parcel.setDataPosition(0);
    surface.readFromParcel(&parcel, mFdp.ConsumeBool());
}

void ParcelableFuzzer::invokeLayerMetadata() {
    std::unordered_map<uint32_t, std::vector<uint8_t>> map;
    for (size_t idx = 0; idx < kLayerMetadataKeyCount; ++idx) {
        std::vector<uint8_t> data;
        for (size_t idx1 = 0; idx1 < mFdp.ConsumeIntegral<uint32_t>(); ++idx1) {
            data.push_back(mFdp.ConsumeIntegral<uint8_t>());
        }
        map[kMetadataKey[idx]] = data;
    }
    LayerMetadata metadata(map);
    uint32_t key = mFdp.PickValueInArray(kMetadataKey);
    metadata.setInt32(key, mFdp.ConsumeIntegral<int32_t>());
    metadata.itemToString(key, (mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());

    Parcel parcel;
    metadata.writeToParcel(&parcel);
    parcel.setDataPosition(0);
    metadata.readFromParcel(&parcel);
}

void ParcelableFuzzer::invokeLayerDebugInfo() {
    gui::LayerDebugInfo info;
    info.mName = mFdp.ConsumeRandomLengthString(kMaxBytes);
    info.mParentName = mFdp.ConsumeRandomLengthString(kMaxBytes);
    info.mType = mFdp.ConsumeRandomLengthString(kMaxBytes);
    info.mLayerStack = mFdp.ConsumeIntegral<uint32_t>();
    info.mX = mFdp.ConsumeFloatingPoint<float>();
    info.mY = mFdp.ConsumeFloatingPoint<float>();
    info.mZ = mFdp.ConsumeIntegral<uint32_t>();
    info.mWidth = mFdp.ConsumeIntegral<int32_t>();
    info.mHeight = mFdp.ConsumeIntegral<int32_t>();
    info.mActiveBufferWidth = mFdp.ConsumeIntegral<int32_t>();
    info.mActiveBufferHeight = mFdp.ConsumeIntegral<int32_t>();
    info.mActiveBufferStride = mFdp.ConsumeIntegral<int32_t>();
    info.mActiveBufferFormat = mFdp.ConsumeIntegral<int32_t>();
    info.mNumQueuedFrames = mFdp.ConsumeIntegral<int32_t>();

    info.mFlags = mFdp.ConsumeIntegral<uint32_t>();
    info.mPixelFormat = mFdp.ConsumeIntegral<int32_t>();
    info.mTransparentRegion = Region(getRect(&mFdp));
    info.mVisibleRegion = Region(getRect(&mFdp));
    info.mSurfaceDamageRegion = Region(getRect(&mFdp));
    info.mCrop = getRect(&mFdp);
    info.mDataSpace = static_cast<android_dataspace>(mFdp.PickValueInArray(kDataspaces));
    info.mColor = half4(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
                        mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>());
    for (size_t idx = 0; idx < kMatrixSize; ++idx) {
        info.mMatrix[idx / 2][idx % 2] = mFdp.ConsumeFloatingPoint<float>();
    }
    info.mIsOpaque = mFdp.ConsumeBool();
    info.mContentDirty = mFdp.ConsumeBool();
    info.mStretchEffect.width = mFdp.ConsumeFloatingPoint<float>();
    info.mStretchEffect.height = mFdp.ConsumeFloatingPoint<float>();
    info.mStretchEffect.vectorX = mFdp.ConsumeFloatingPoint<float>();
    info.mStretchEffect.vectorY = mFdp.ConsumeFloatingPoint<float>();
    info.mStretchEffect.maxAmountX = mFdp.ConsumeFloatingPoint<float>();
    info.mStretchEffect.maxAmountY = mFdp.ConsumeFloatingPoint<float>();
    info.mStretchEffect.mappedChildBounds =
            FloatRect(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
                      mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>());

    Parcel parcel;
    info.writeToParcel(&parcel);
    parcel.setDataPosition(0);
    info.readFromParcel(&parcel);
}

void ParcelableFuzzer::invokeOccupancyTracker() {
    nsecs_t totalTime = mFdp.ConsumeIntegral<uint32_t>();
    size_t numFrames = mFdp.ConsumeIntegral<size_t>();
    float occupancyAverage = mFdp.ConsumeFloatingPoint<float>();
    OccupancyTracker::Segment segment(totalTime, numFrames, occupancyAverage,
                                      mFdp.ConsumeBool() /*usedThirdBuffer*/);
    Parcel parcel;
    segment.writeToParcel(&parcel);
    parcel.setDataPosition(0);
    segment.readFromParcel(&parcel);
}

void ParcelableFuzzer::invokeStreamSplitter() {
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer);
    sp<StreamSplitter> splitter;
    StreamSplitter::createSplitter(consumer, &splitter);
    splitter->addOutput(producer);
    std::string name = mFdp.ConsumeRandomLengthString(kMaxBytes);
    splitter->setName(String8(name.c_str()));
}

void ParcelableFuzzer::process() {
    invokeStreamSplitter();
    invokeOccupancyTracker();
    invokeLayerDebugInfo();
    invokeLayerMetadata();
    invokeViewSurface();
}

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