• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <android-base/stringprintf.h>
17 #include <gui/BufferQueueConsumer.h>
18 #include <gui/BufferQueueCore.h>
19 #include <gui/BufferQueueProducer.h>
20 #include <gui/bufferqueue/2.0/types.h>
21 #include <system/window.h>
22 
23 #include <libgui_fuzzer_utils.h>
24 
25 using namespace android;
26 using namespace hardware::graphics::bufferqueue;
27 using namespace V1_0::utils;
28 using namespace V2_0::utils;
29 
30 constexpr int32_t kMaxBytes = 256;
31 
32 constexpr int32_t kError[] = {
33         OK,        NO_MEMORY,   NO_INIT,       BAD_VALUE,      DEAD_OBJECT, INVALID_OPERATION,
34         TIMED_OUT, WOULD_BLOCK, UNKNOWN_ERROR, ALREADY_EXISTS,
35 };
36 
37 constexpr int32_t kAPIConnection[] = {
38         BufferQueueCore::CURRENTLY_CONNECTED_API,
39         BufferQueueCore::NO_CONNECTED_API,
40         NATIVE_WINDOW_API_EGL,
41         NATIVE_WINDOW_API_CPU,
42         NATIVE_WINDOW_API_MEDIA,
43         NATIVE_WINDOW_API_CAMERA,
44 };
45 
46 class BufferQueueFuzzer {
47 public:
BufferQueueFuzzer(const uint8_t * data,size_t size)48     BufferQueueFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
49     void process();
50 
51 private:
52     void invokeTypes();
53     void invokeH2BGraphicBufferV1();
54     void invokeH2BGraphicBufferV2();
55     void invokeBufferQueueConsumer();
56     void invokeBufferQueueProducer();
57     void invokeBlastBufferQueue();
58     void invokeQuery(sp<BufferQueueProducer>);
59     void invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer>);
60     void invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer>);
61     void invokeAcquireBuffer(sp<BufferQueueConsumer>);
62     void invokeOccupancyTracker(sp<BufferQueueConsumer>);
63     sp<SurfaceControl> makeSurfaceControl();
64     sp<BLASTBufferQueue> makeBLASTBufferQueue(sp<SurfaceControl>);
65 
66     FuzzedDataProvider mFdp;
67 };
68 
69 class ManageResourceHandle {
70 public:
ManageResourceHandle(FuzzedDataProvider * fdp)71     ManageResourceHandle(FuzzedDataProvider* fdp) {
72         mNativeHandle = native_handle_create(0 /*numFds*/, 1 /*numInts*/);
73         mShouldOwn = fdp->ConsumeBool();
74         mStream = NativeHandle::create(mNativeHandle, mShouldOwn);
75     }
~ManageResourceHandle()76     ~ManageResourceHandle() {
77         if (!mShouldOwn) {
78             native_handle_close(mNativeHandle);
79             native_handle_delete(mNativeHandle);
80         }
81     }
getStream()82     sp<NativeHandle> getStream() { return mStream; }
83 
84 private:
85     bool mShouldOwn;
86     sp<NativeHandle> mStream;
87     native_handle_t* mNativeHandle;
88 };
89 
makeSurfaceControl()90 sp<SurfaceControl> BufferQueueFuzzer::makeSurfaceControl() {
91     sp<IBinder> handle;
92     const sp<FakeBnSurfaceComposerClient> testClient(new FakeBnSurfaceComposerClient());
93     sp<SurfaceComposerClient> client = new SurfaceComposerClient(testClient);
94     sp<BnGraphicBufferProducer> producer;
95     uint32_t layerId = mFdp.ConsumeIntegral<uint32_t>();
96     std::string layerName = base::StringPrintf("#%d", layerId);
97     return sp<SurfaceControl>::make(client, handle, layerId, layerName,
98                                     mFdp.ConsumeIntegral<int32_t>(),
99                                     mFdp.ConsumeIntegral<uint32_t>(),
100                                     mFdp.ConsumeIntegral<int32_t>(),
101                                     mFdp.ConsumeIntegral<uint32_t>(),
102                                     mFdp.ConsumeIntegral<uint32_t>());
103 }
104 
makeBLASTBufferQueue(sp<SurfaceControl> surface)105 sp<BLASTBufferQueue> BufferQueueFuzzer::makeBLASTBufferQueue(sp<SurfaceControl> surface) {
106     return sp<BLASTBufferQueue>::make(mFdp.ConsumeRandomLengthString(kMaxBytes), surface,
107                                       mFdp.ConsumeIntegral<uint32_t>(),
108                                       mFdp.ConsumeIntegral<uint32_t>(),
109                                       mFdp.ConsumeIntegral<int32_t>());
110 }
111 
invokeBlastBufferQueue()112 void BufferQueueFuzzer::invokeBlastBufferQueue() {
113     sp<SurfaceControl> surface = makeSurfaceControl();
114     sp<BLASTBufferQueue> queue = makeBLASTBufferQueue(surface);
115 
116     BufferItem item;
117     queue->onFrameAvailable(item);
118     queue->onFrameReplaced(item);
119     uint64_t bufferId = mFdp.ConsumeIntegral<uint64_t>();
120     queue->onFrameDequeued(bufferId);
121     queue->onFrameCancelled(bufferId);
122 
123     SurfaceComposerClient::Transaction next;
124     uint64_t frameNumber = mFdp.ConsumeIntegral<uint64_t>();
125     queue->mergeWithNextTransaction(&next, frameNumber);
126     queue->applyPendingTransactions(frameNumber);
127 
128     queue->update(surface, mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
129                   mFdp.ConsumeIntegral<int32_t>());
130     queue->setFrameRate(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeIntegral<int8_t>(),
131                         mFdp.ConsumeBool() /*shouldBeSeamless*/);
132     FrameTimelineInfo info;
133     queue->setFrameTimelineInfo(mFdp.ConsumeIntegral<uint64_t>(), info);
134 
135     ManageResourceHandle handle(&mFdp);
136     queue->setSidebandStream(handle.getStream());
137 
138     queue->getLastTransformHint();
139     queue->getLastAcquiredFrameNum();
140 
141     CompositorTiming compTiming;
142     sp<Fence> previousFence = new Fence(memfd_create("pfd", MFD_ALLOW_SEALING));
143     sp<Fence> gpuFence = new Fence(memfd_create("gfd", MFD_ALLOW_SEALING));
144     FrameEventHistoryStats frameStats(frameNumber, gpuFence, compTiming,
145                                       mFdp.ConsumeIntegral<int64_t>(),
146                                       mFdp.ConsumeIntegral<int64_t>());
147     std::vector<SurfaceControlStats> stats;
148     sp<Fence> presentFence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING));
149     SurfaceControlStats controlStats(surface, mFdp.ConsumeIntegral<int64_t>(),
150                                      mFdp.ConsumeIntegral<int64_t>(), presentFence, previousFence,
151                                      mFdp.ConsumeIntegral<uint32_t>(), frameStats,
152                                      mFdp.ConsumeIntegral<uint32_t>());
153     stats.push_back(controlStats);
154 }
155 
invokeQuery(sp<BufferQueueProducer> producer)156 void BufferQueueFuzzer::invokeQuery(sp<BufferQueueProducer> producer) {
157     int32_t value;
158     producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
159 }
160 
invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer> producer)161 void BufferQueueFuzzer::invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer> producer) {
162     int32_t value;
163     producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
164 }
165 
invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer> producer)166 void BufferQueueFuzzer::invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer> producer) {
167     int32_t value;
168     producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
169 }
170 
invokeBufferQueueProducer()171 void BufferQueueFuzzer::invokeBufferQueueProducer() {
172     sp<BufferQueueCore> core(new BufferQueueCore());
173     sp<BufferQueueProducer> producer(new BufferQueueProducer(core));
174     const sp<android::IProducerListener> listener;
175     android::IGraphicBufferProducer::QueueBufferOutput output;
176     uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
177     producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);
178 
179     sp<GraphicBuffer> buffer;
180     int32_t slot = mFdp.ConsumeIntegral<int32_t>();
181     uint32_t maxBuffers = mFdp.ConsumeIntegral<uint32_t>();
182     producer->requestBuffer(slot, &buffer);
183     producer->setMaxDequeuedBufferCount(maxBuffers);
184     producer->setAsyncMode(mFdp.ConsumeBool() /*async*/);
185 
186     android::IGraphicBufferProducer::QueueBufferInput input;
187     producer->attachBuffer(&slot, buffer);
188     producer->queueBuffer(slot, input, &output);
189 
190     int32_t format = mFdp.ConsumeIntegral<int32_t>();
191     uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
192     uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
193     uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
194     uint64_t outBufferAge;
195     FrameEventHistoryDelta outTimestamps;
196     sp<android::Fence> fence;
197     producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
198                             &outTimestamps);
199     producer->detachBuffer(slot);
200     producer->detachNextBuffer(&buffer, &fence);
201     producer->cancelBuffer(slot, fence);
202 
203     invokeQuery(producer);
204 
205     ManageResourceHandle handle(&mFdp);
206     producer->setSidebandStream(handle.getStream());
207 
208     producer->allocateBuffers(width, height, format, usage);
209     producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
210     producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
211     producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);
212     producer->setLegacyBufferDrop(mFdp.ConsumeBool() /*drop*/);
213     producer->setAutoPrerotation(mFdp.ConsumeBool() /*autoPrerotation*/);
214 
215     producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
216     producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
217     producer->disconnect(api);
218 }
219 
invokeAcquireBuffer(sp<BufferQueueConsumer> consumer)220 void BufferQueueFuzzer::invokeAcquireBuffer(sp<BufferQueueConsumer> consumer) {
221     BufferItem item;
222     consumer->acquireBuffer(&item, mFdp.ConsumeIntegral<uint32_t>(),
223                             mFdp.ConsumeIntegral<uint64_t>());
224 }
225 
invokeOccupancyTracker(sp<BufferQueueConsumer> consumer)226 void BufferQueueFuzzer::invokeOccupancyTracker(sp<BufferQueueConsumer> consumer) {
227     String8 outResult;
228     String8 prefix((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
229     consumer->dumpState(prefix, &outResult);
230 
231     std::vector<OccupancyTracker::Segment> outHistory;
232     consumer->getOccupancyHistory(mFdp.ConsumeBool() /*forceFlush*/, &outHistory);
233 }
234 
invokeBufferQueueConsumer()235 void BufferQueueFuzzer::invokeBufferQueueConsumer() {
236     sp<BufferQueueCore> core(new BufferQueueCore());
237     sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
238     sp<android::IConsumerListener> listener;
239     consumer->consumerConnect(listener, mFdp.ConsumeBool() /*controlledByApp*/);
240     invokeAcquireBuffer(consumer);
241 
242     int32_t slot = mFdp.ConsumeIntegral<int32_t>();
243     sp<GraphicBuffer> buffer =
244             new GraphicBuffer(mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
245                               mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
246                               mFdp.ConsumeIntegral<uint64_t>());
247     consumer->attachBuffer(&slot, buffer);
248     consumer->detachBuffer(slot);
249 
250     consumer->setDefaultBufferSize(mFdp.ConsumeIntegral<uint32_t>(),
251                                    mFdp.ConsumeIntegral<uint32_t>());
252     consumer->setMaxBufferCount(mFdp.ConsumeIntegral<int32_t>());
253     consumer->setMaxAcquiredBufferCount(mFdp.ConsumeIntegral<int32_t>());
254 
255     String8 name((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
256     consumer->setConsumerName(name);
257     consumer->setDefaultBufferFormat(mFdp.ConsumeIntegral<int32_t>());
258     android_dataspace dataspace =
259             static_cast<android_dataspace>(mFdp.PickValueInArray(kDataspaces));
260     consumer->setDefaultBufferDataSpace(dataspace);
261 
262     consumer->setTransformHint(mFdp.ConsumeIntegral<uint32_t>());
263     consumer->setConsumerUsageBits(mFdp.ConsumeIntegral<uint64_t>());
264     consumer->setConsumerIsProtected(mFdp.ConsumeBool() /*isProtected*/);
265     invokeOccupancyTracker(consumer);
266 
267     sp<Fence> releaseFence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING));
268     consumer->releaseBuffer(mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint64_t>(),
269                             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
270     consumer->consumerDisconnect();
271 }
272 
invokeTypes()273 void BufferQueueFuzzer::invokeTypes() {
274     HStatus hStatus;
275     int32_t status = mFdp.PickValueInArray(kError);
276     bool bufferNeedsReallocation = mFdp.ConsumeBool();
277     bool releaseAllBuffers = mFdp.ConsumeBool();
278     b2h(status, &hStatus, &bufferNeedsReallocation, &releaseAllBuffers);
279     h2b(hStatus, &status);
280 
281     HConnectionType type;
282     int32_t apiConnection = mFdp.PickValueInArray(kAPIConnection);
283     b2h(apiConnection, &type);
284     h2b(type, &apiConnection);
285 }
286 
invokeH2BGraphicBufferV1()287 void BufferQueueFuzzer::invokeH2BGraphicBufferV1() {
288     sp<V1_0::utils::H2BGraphicBufferProducer> producer(
289             new V1_0::utils::H2BGraphicBufferProducer(new FakeGraphicBufferProducerV1()));
290     const sp<android::IProducerListener> listener;
291     android::IGraphicBufferProducer::QueueBufferOutput output;
292     uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
293     producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);
294 
295     sp<GraphicBuffer> buffer;
296     int32_t slot = mFdp.ConsumeIntegral<int32_t>();
297     producer->requestBuffer(slot, &buffer);
298     producer->setMaxDequeuedBufferCount(mFdp.ConsumeIntegral<int32_t>());
299     producer->setAsyncMode(mFdp.ConsumeBool());
300 
301     android::IGraphicBufferProducer::QueueBufferInput input;
302     input.fence = new Fence(memfd_create("ffd", MFD_ALLOW_SEALING));
303     producer->attachBuffer(&slot, buffer);
304     producer->queueBuffer(slot, input, &output);
305 
306     int32_t format = mFdp.ConsumeIntegral<int32_t>();
307     uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
308     uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
309     uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
310     uint64_t outBufferAge;
311     FrameEventHistoryDelta outTimestamps;
312     sp<android::Fence> fence;
313     producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
314                             &outTimestamps);
315     producer->detachBuffer(slot);
316     producer->cancelBuffer(slot, fence);
317 
318     invokeQuery(producer);
319 
320     ManageResourceHandle handle(&mFdp);
321     producer->setSidebandStream(handle.getStream());
322 
323     producer->allocateBuffers(width, height, format, usage);
324     producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
325     producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
326     producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);
327 
328     producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
329     producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
330     producer->disconnect(api);
331 }
332 
invokeH2BGraphicBufferV2()333 void BufferQueueFuzzer::invokeH2BGraphicBufferV2() {
334     sp<V2_0::utils::H2BGraphicBufferProducer> producer(
335             new V2_0::utils::H2BGraphicBufferProducer(new FakeGraphicBufferProducerV2()));
336     const sp<android::IProducerListener> listener;
337     android::IGraphicBufferProducer::QueueBufferOutput output;
338     uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
339     producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);
340 
341     sp<GraphicBuffer> buffer;
342     int32_t slot = mFdp.ConsumeIntegral<int32_t>();
343     producer->requestBuffer(slot, &buffer);
344     producer->setMaxDequeuedBufferCount(mFdp.ConsumeIntegral<uint32_t>());
345     producer->setAsyncMode(mFdp.ConsumeBool());
346 
347     android::IGraphicBufferProducer::QueueBufferInput input;
348     input.fence = new Fence(memfd_create("ffd", MFD_ALLOW_SEALING));
349     producer->attachBuffer(&slot, buffer);
350     producer->queueBuffer(slot, input, &output);
351 
352     int32_t format = mFdp.ConsumeIntegral<int32_t>();
353     uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
354     uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
355     uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
356     uint64_t outBufferAge;
357     FrameEventHistoryDelta outTimestamps;
358     sp<android::Fence> fence;
359     producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
360                             &outTimestamps);
361     producer->detachBuffer(slot);
362     producer->cancelBuffer(slot, fence);
363 
364     invokeQuery(producer);
365 
366     ManageResourceHandle handle(&mFdp);
367     producer->setSidebandStream(handle.getStream());
368 
369     producer->allocateBuffers(width, height, format, usage);
370     producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
371     producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
372     producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);
373 
374     producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
375     producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
376     producer->disconnect(api);
377 }
378 
process()379 void BufferQueueFuzzer::process() {
380     invokeBlastBufferQueue();
381     invokeH2BGraphicBufferV1();
382     invokeH2BGraphicBufferV2();
383     invokeTypes();
384     invokeBufferQueueConsumer();
385     invokeBufferQueueProducer();
386 }
387 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)388 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
389     BufferQueueFuzzer bufferQueueFuzzer(data, size);
390     bufferQueueFuzzer.process();
391     return 0;
392 }
393