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

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

Merge changes I2b7e9fd5,I2626dc65

* changes:
  Added libgui_consumer_fuzzer
  Added libgui_bufferQueue_fuzzer
parents 42456e6a e387a12d
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -105,3 +105,23 @@ cc_fuzz {
        "libgui_fuzzer_defaults",
    ],
}

cc_fuzz {
    name: "libgui_bufferQueue_fuzzer",
    srcs: [
        "libgui_bufferQueue_fuzzer.cpp",
    ],
    defaults: [
        "libgui_fuzzer_defaults",
    ],
}

cc_fuzz {
    name: "libgui_consumer_fuzzer",
    srcs: [
        "libgui_consumer_fuzzer.cpp",
    ],
    defaults: [
        "libgui_fuzzer_defaults",
    ],
}
+68 −0
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@
+ [libgui_surfaceComposer_fuzzer](#SurfaceComposer)
+ [libgui_surfaceComposerClient_fuzzer](#SurfaceComposerClient)
+ [libgui_parcelable_fuzzer](#Libgui_Parcelable)
+ [libgui_bufferQueue_fuzzer](#BufferQueue)
+ [libgui_consumer_fuzzer](#Libgui_Consumer)

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

@@ -122,3 +124,69 @@ Libgui_Parcelable supports the following parameters:
  $ adb sync data
  $ adb shell /data/fuzz/arm64/libgui_fuzzer/libgui_fuzzer
```

# <a name="libgui_bufferQueue_fuzzer"></a> Fuzzer for BufferQueue

BufferQueue supports the following parameters:
1. SurfaceWidth (parameter name:`width`)
2. SurfaceHeight (parameter name:`height`)
3. TransactionStateFlags (parameter name:`flags`)
4. TransformHint (parameter name:`outTransformHint`)
5. SurfacePixelFormat (parameter name:`format`)
6. LayerId (parameter name:`layerId`)
7. BufferId (parameter name:`bufferId`)
8. FrameNumber (parameter name:`frameNumber`)
9. FrameRate (parameter name:`frameRate`)
10. Compatability (parameter name:`compatability`)
11. LatchTime (parameter name:`latchTime`)
12. AcquireTime (parameter name:`acquireTime`)
13. RefreshTime (parameter name:`refreshTime`)
14. DequeueTime (parameter name:`dequeueTime`)
15. Slot (parameter name:`slot`)
16. MaxBuffers (parameter name:`maxBuffers`)
17. GenerationNumber (parameter name:`generationNumber`)
18. Api (parameter name:`api`)
19. Usage (parameter name:`usage`)
20. MaxFrameNumber (parameter name:`maxFrameNumber`)
21. BufferCount (parameter name:`bufferCount`)
22. MaxAcquredBufferCount (parameter name:`maxAcquredBufferCount`)
23. Status (parameter name:`status`)
24. ApiConnection (parameter name:`apiConnection`)
25. Dataspace (parameter name:`dataspace`)

| Parameter| Valid Values| Configured Value|
|------------- |-------------| ----- |
|`status`| 0.`OK`, 1.`NO_MEMORY`, 2.`NO_INIT`, 3.`BAD_VALUE`, 4.`DEAD_OBJECT`, 5.`INVALID_OPERATION`, 6.`TIMED_OUT`, 7.`WOULD_BLOCK`, 8.`UNKNOWN_ERROR`, 9.`ALREADY_EXISTS`, |Value obtained from FuzzedDataProvider|
|`apiConnection`| 0.`BufferQueueCore::CURRENTLY_CONNECTED_API`, 1.`BufferQueueCore::NO_CONNECTED_API`, 2.`NATIVE_WINDOW_API_EGL`, 3.`NATIVE_WINDOW_API_CPU`, 4.`NATIVE_WINDOW_API_MEDIA`, 5.`NATIVE_WINDOW_API_CAMERA`, |Value obtained from FuzzedDataProvider|
|`dataspace`| 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_bufferQueue_fuzzer
```
2. To run on device
```
  $ adb sync data
  $ adb shell /data/fuzz/arm64/libgui_bufferQueue_fuzzer/libgui_bufferQueue_fuzzer
```

# <a name="libgui_consumer_fuzzer"></a> Fuzzer for Libgui_Consumer

Libgui_Consumer supports the following parameters:
1. GraphicWidth (parameter name:`graphicWidth`)
2. GraphicHeight (parameter name:`graphicHeight`)
4. TransformHint (parameter name:`outTransformHint`)
5. GraphicPixelFormat (parameter name:`format`)
6. Usage (parameter name:`usage`)

#### Steps to run
1. Build the fuzzer
```
  $ mm -j$(nproc) libgui_consumer_fuzzer
```
2. Run on device
```
  $ adb sync data
  $ adb shell /data/fuzz/arm64/libgui_consumer_fuzzer/libgui_consumer_fuzzer
```
+388 −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/bufferqueue/2.0/types.h>
#include <system/window.h>

#include <libgui_fuzzer_utils.h>

using namespace android;
using namespace hardware::graphics::bufferqueue;
using namespace V1_0::utils;
using namespace V2_0::utils;

constexpr int32_t kMaxBytes = 256;

constexpr int32_t kError[] = {
        OK,        NO_MEMORY,   NO_INIT,       BAD_VALUE,      DEAD_OBJECT, INVALID_OPERATION,
        TIMED_OUT, WOULD_BLOCK, UNKNOWN_ERROR, ALREADY_EXISTS,
};

constexpr int32_t kAPIConnection[] = {
        BufferQueueCore::CURRENTLY_CONNECTED_API,
        BufferQueueCore::NO_CONNECTED_API,
        NATIVE_WINDOW_API_EGL,
        NATIVE_WINDOW_API_CPU,
        NATIVE_WINDOW_API_MEDIA,
        NATIVE_WINDOW_API_CAMERA,
};

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

private:
    void invokeTypes();
    void invokeH2BGraphicBufferV1();
    void invokeH2BGraphicBufferV2();
    void invokeBufferQueueConsumer();
    void invokeBufferQueueProducer();
    void invokeBlastBufferQueue();
    void invokeQuery(sp<BufferQueueProducer>);
    void invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer>);
    void invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer>);
    void invokeAcquireBuffer(sp<BufferQueueConsumer>);
    void invokeOccupancyTracker(sp<BufferQueueConsumer>);
    sp<SurfaceControl> makeSurfaceControl();
    sp<BLASTBufferQueue> makeBLASTBufferQueue(sp<SurfaceControl>);

    FuzzedDataProvider mFdp;
};

class ManageResourceHandle {
public:
    ManageResourceHandle(FuzzedDataProvider* fdp) {
        mNativeHandle = native_handle_create(0 /*numFds*/, 1 /*numInts*/);
        mShouldOwn = fdp->ConsumeBool();
        mStream = NativeHandle::create(mNativeHandle, mShouldOwn);
    }
    ~ManageResourceHandle() {
        if (!mShouldOwn) {
            native_handle_close(mNativeHandle);
            native_handle_delete(mNativeHandle);
        }
    }
    sp<NativeHandle> getStream() { return mStream; }

private:
    bool mShouldOwn;
    sp<NativeHandle> mStream;
    native_handle_t* mNativeHandle;
};

sp<SurfaceControl> BufferQueueFuzzer::makeSurfaceControl() {
    sp<IBinder> handle;
    const sp<FakeBnSurfaceComposerClient> testClient(new FakeBnSurfaceComposerClient());
    sp<SurfaceComposerClient> client = new SurfaceComposerClient(testClient);
    sp<BnGraphicBufferProducer> producer;
    return sp<SurfaceControl>::make(client, handle, mFdp.ConsumeIntegral<int32_t>(),
                                    mFdp.ConsumeIntegral<uint32_t>(),
                                    mFdp.ConsumeIntegral<uint32_t>(),
                                    mFdp.ConsumeIntegral<int32_t>(),
                                    mFdp.ConsumeIntegral<uint32_t>(),
                                    mFdp.ConsumeIntegral<uint32_t>());
}

sp<BLASTBufferQueue> BufferQueueFuzzer::makeBLASTBufferQueue(sp<SurfaceControl> surface) {
    return sp<BLASTBufferQueue>::make(mFdp.ConsumeRandomLengthString(kMaxBytes), surface,
                                      mFdp.ConsumeIntegral<uint32_t>(),
                                      mFdp.ConsumeIntegral<uint32_t>(),
                                      mFdp.ConsumeIntegral<int32_t>());
}

void BufferQueueFuzzer::invokeBlastBufferQueue() {
    sp<SurfaceControl> surface = makeSurfaceControl();
    sp<BLASTBufferQueue> queue = makeBLASTBufferQueue(surface);

    BufferItem item;
    queue->onFrameAvailable(item);
    queue->onFrameReplaced(item);
    uint64_t bufferId = mFdp.ConsumeIntegral<uint64_t>();
    queue->onFrameDequeued(bufferId);
    queue->onFrameCancelled(bufferId);

    SurfaceComposerClient::Transaction next;
    uint64_t frameNumber = mFdp.ConsumeIntegral<uint64_t>();
    queue->mergeWithNextTransaction(&next, frameNumber);
    queue->applyPendingTransactions(frameNumber);

    queue->update(surface, mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
                  mFdp.ConsumeIntegral<int32_t>());
    queue->setFrameRate(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeIntegral<int8_t>(),
                        mFdp.ConsumeBool() /*shouldBeSeamless*/);
    FrameTimelineInfo info;
    queue->setFrameTimelineInfo(info);

    ManageResourceHandle handle(&mFdp);
    queue->setSidebandStream(handle.getStream());

    queue->getLastTransformHint();
    queue->getLastAcquiredFrameNum();

    CompositorTiming compTiming;
    sp<Fence> previousFence = new Fence(memfd_create("pfd", MFD_ALLOW_SEALING));
    sp<Fence> gpuFence = new Fence(memfd_create("gfd", MFD_ALLOW_SEALING));
    FrameEventHistoryStats frameStats(frameNumber, gpuFence, compTiming,
                                      mFdp.ConsumeIntegral<int64_t>(),
                                      mFdp.ConsumeIntegral<int64_t>());
    std::vector<SurfaceControlStats> stats;
    sp<Fence> presentFence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING));
    SurfaceControlStats controlStats(surface, mFdp.ConsumeIntegral<int64_t>(),
                                     mFdp.ConsumeIntegral<int64_t>(), presentFence, previousFence,
                                     mFdp.ConsumeIntegral<uint32_t>(), frameStats);
    stats.push_back(controlStats);
}

void BufferQueueFuzzer::invokeQuery(sp<BufferQueueProducer> producer) {
    int32_t value;
    producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
}

void BufferQueueFuzzer::invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer> producer) {
    int32_t value;
    producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
}

void BufferQueueFuzzer::invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer> producer) {
    int32_t value;
    producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
}

void BufferQueueFuzzer::invokeBufferQueueProducer() {
    sp<BufferQueueCore> core(new BufferQueueCore());
    sp<BufferQueueProducer> producer(new BufferQueueProducer(core));
    const sp<android::IProducerListener> listener;
    android::IGraphicBufferProducer::QueueBufferOutput output;
    uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
    producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);

    sp<GraphicBuffer> buffer;
    int32_t slot = mFdp.ConsumeIntegral<int32_t>();
    uint32_t maxBuffers = mFdp.ConsumeIntegral<uint32_t>();
    producer->requestBuffer(slot, &buffer);
    producer->setMaxDequeuedBufferCount(maxBuffers);
    producer->setAsyncMode(mFdp.ConsumeBool() /*async*/);

    android::IGraphicBufferProducer::QueueBufferInput input;
    producer->attachBuffer(&slot, buffer);
    producer->queueBuffer(slot, input, &output);

    int32_t format = mFdp.ConsumeIntegral<int32_t>();
    uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
    uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
    uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
    uint64_t outBufferAge;
    FrameEventHistoryDelta outTimestamps;
    sp<android::Fence> fence;
    producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
                            &outTimestamps);
    producer->detachBuffer(slot);
    producer->detachNextBuffer(&buffer, &fence);
    producer->cancelBuffer(slot, fence);

    invokeQuery(producer);

    ManageResourceHandle handle(&mFdp);
    producer->setSidebandStream(handle.getStream());

    producer->allocateBuffers(width, height, format, usage);
    producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
    producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
    producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);
    producer->setLegacyBufferDrop(mFdp.ConsumeBool() /*drop*/);
    producer->setAutoPrerotation(mFdp.ConsumeBool() /*autoPrerotation*/);

    producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
    producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
    producer->disconnect(api);
}

void BufferQueueFuzzer::invokeAcquireBuffer(sp<BufferQueueConsumer> consumer) {
    BufferItem item;
    consumer->acquireBuffer(&item, mFdp.ConsumeIntegral<uint32_t>(),
                            mFdp.ConsumeIntegral<uint64_t>());
}

void BufferQueueFuzzer::invokeOccupancyTracker(sp<BufferQueueConsumer> consumer) {
    String8 outResult;
    String8 prefix((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
    consumer->dumpState(prefix, &outResult);

    std::vector<OccupancyTracker::Segment> outHistory;
    consumer->getOccupancyHistory(mFdp.ConsumeBool() /*forceFlush*/, &outHistory);
}

void BufferQueueFuzzer::invokeBufferQueueConsumer() {
    sp<BufferQueueCore> core(new BufferQueueCore());
    sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
    sp<android::IConsumerListener> listener;
    consumer->consumerConnect(listener, mFdp.ConsumeBool() /*controlledByApp*/);
    invokeAcquireBuffer(consumer);

    int32_t slot = mFdp.ConsumeIntegral<int32_t>();
    sp<GraphicBuffer> buffer =
            new GraphicBuffer(mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
                              mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
                              mFdp.ConsumeIntegral<uint64_t>());
    consumer->attachBuffer(&slot, buffer);
    consumer->detachBuffer(slot);

    consumer->setDefaultBufferSize(mFdp.ConsumeIntegral<uint32_t>(),
                                   mFdp.ConsumeIntegral<uint32_t>());
    consumer->setMaxBufferCount(mFdp.ConsumeIntegral<int32_t>());
    consumer->setMaxAcquiredBufferCount(mFdp.ConsumeIntegral<int32_t>());

    String8 name((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
    consumer->setConsumerName(name);
    consumer->setDefaultBufferFormat(mFdp.ConsumeIntegral<int32_t>());
    android_dataspace dataspace =
            static_cast<android_dataspace>(mFdp.PickValueInArray(kDataspaces));
    consumer->setDefaultBufferDataSpace(dataspace);

    consumer->setTransformHint(mFdp.ConsumeIntegral<uint32_t>());
    consumer->setConsumerUsageBits(mFdp.ConsumeIntegral<uint64_t>());
    consumer->setConsumerIsProtected(mFdp.ConsumeBool() /*isProtected*/);
    invokeOccupancyTracker(consumer);

    sp<Fence> releaseFence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING));
    consumer->releaseBuffer(mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint64_t>(),
                            EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
    consumer->consumerDisconnect();
}

void BufferQueueFuzzer::invokeTypes() {
    HStatus hStatus;
    int32_t status = mFdp.PickValueInArray(kError);
    bool bufferNeedsReallocation = mFdp.ConsumeBool();
    bool releaseAllBuffers = mFdp.ConsumeBool();
    b2h(status, &hStatus, &bufferNeedsReallocation, &releaseAllBuffers);
    h2b(hStatus, &status);

    HConnectionType type;
    int32_t apiConnection = mFdp.PickValueInArray(kAPIConnection);
    b2h(apiConnection, &type);
    h2b(type, &apiConnection);
}

void BufferQueueFuzzer::invokeH2BGraphicBufferV1() {
    sp<V1_0::utils::H2BGraphicBufferProducer> producer(
            new V1_0::utils::H2BGraphicBufferProducer(new FakeGraphicBufferProducerV1()));
    const sp<android::IProducerListener> listener;
    android::IGraphicBufferProducer::QueueBufferOutput output;
    uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
    producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);

    sp<GraphicBuffer> buffer;
    int32_t slot = mFdp.ConsumeIntegral<int32_t>();
    producer->requestBuffer(slot, &buffer);
    producer->setMaxDequeuedBufferCount(mFdp.ConsumeIntegral<int32_t>());
    producer->setAsyncMode(mFdp.ConsumeBool());

    android::IGraphicBufferProducer::QueueBufferInput input;
    input.fence = new Fence(memfd_create("ffd", MFD_ALLOW_SEALING));
    producer->attachBuffer(&slot, buffer);
    producer->queueBuffer(slot, input, &output);

    int32_t format = mFdp.ConsumeIntegral<int32_t>();
    uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
    uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
    uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
    uint64_t outBufferAge;
    FrameEventHistoryDelta outTimestamps;
    sp<android::Fence> fence;
    producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
                            &outTimestamps);
    producer->detachBuffer(slot);
    producer->cancelBuffer(slot, fence);

    invokeQuery(producer);

    ManageResourceHandle handle(&mFdp);
    producer->setSidebandStream(handle.getStream());

    producer->allocateBuffers(width, height, format, usage);
    producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
    producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
    producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);

    producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
    producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
    producer->disconnect(api);
}

void BufferQueueFuzzer::invokeH2BGraphicBufferV2() {
    sp<V2_0::utils::H2BGraphicBufferProducer> producer(
            new V2_0::utils::H2BGraphicBufferProducer(new FakeGraphicBufferProducerV2()));
    const sp<android::IProducerListener> listener;
    android::IGraphicBufferProducer::QueueBufferOutput output;
    uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
    producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);

    sp<GraphicBuffer> buffer;
    int32_t slot = mFdp.ConsumeIntegral<int32_t>();
    producer->requestBuffer(slot, &buffer);
    producer->setMaxDequeuedBufferCount(mFdp.ConsumeIntegral<uint32_t>());
    producer->setAsyncMode(mFdp.ConsumeBool());

    android::IGraphicBufferProducer::QueueBufferInput input;
    input.fence = new Fence(memfd_create("ffd", MFD_ALLOW_SEALING));
    producer->attachBuffer(&slot, buffer);
    producer->queueBuffer(slot, input, &output);

    int32_t format = mFdp.ConsumeIntegral<int32_t>();
    uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
    uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
    uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
    uint64_t outBufferAge;
    FrameEventHistoryDelta outTimestamps;
    sp<android::Fence> fence;
    producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
                            &outTimestamps);
    producer->detachBuffer(slot);
    producer->cancelBuffer(slot, fence);

    invokeQuery(producer);

    ManageResourceHandle handle(&mFdp);
    producer->setSidebandStream(handle.getStream());

    producer->allocateBuffers(width, height, format, usage);
    producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
    producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
    producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);

    producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
    producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
    producer->disconnect(api);
}

void BufferQueueFuzzer::process() {
    invokeBlastBufferQueue();
    invokeH2BGraphicBufferV1();
    invokeH2BGraphicBufferV2();
    invokeTypes();
    invokeBufferQueueConsumer();
    invokeBufferQueueProducer();
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    BufferQueueFuzzer bufferQueueFuzzer(data, size);
    bufferQueueFuzzer.process();
    return 0;
}
+82 −0

File added.

Preview size limit exceeded, changes collapsed.