1 /* 2 * Copyright 2017 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 17 #include <gui/BufferQueue.h> 18 #include <gui/IProducerListener.h> 19 #include <gui/Surface.h> 20 21 #include <android/native_window.h> 22 23 #include <gtest/gtest.h> 24 25 namespace android { 26 namespace test { 27 28 class ProxyBQP : public BnGraphicBufferProducer { 29 public: ProxyBQP(const sp<IGraphicBufferProducer> & producer)30 explicit ProxyBQP(const sp<IGraphicBufferProducer>& producer) : mProducer(producer) {} 31 32 // Pass through calls to mProducer requestBuffer(int slot,sp<GraphicBuffer> * buf)33 status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override { 34 return mProducer->requestBuffer(slot, buf); 35 } setMaxDequeuedBufferCount(int maxDequeuedBuffers)36 status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override { 37 return mProducer->setMaxDequeuedBufferCount(maxDequeuedBuffers); 38 } setAsyncMode(bool async)39 status_t setAsyncMode(bool async) override { return mProducer->setAsyncMode(async); } dequeueBuffer(int * slot,sp<Fence> * fence,uint32_t w,uint32_t h,PixelFormat format,uint64_t usage,uint64_t * outBufferAge,FrameEventHistoryDelta * outTimestamps)40 status_t dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w, uint32_t h, PixelFormat format, 41 uint64_t usage, uint64_t* outBufferAge, 42 FrameEventHistoryDelta* outTimestamps) override { 43 return mProducer->dequeueBuffer(slot, fence, w, h, format, usage, outBufferAge, 44 outTimestamps); 45 } detachBuffer(int slot)46 status_t detachBuffer(int slot) override { return mProducer->detachBuffer(slot); } detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)47 status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) override { 48 return mProducer->detachNextBuffer(outBuffer, outFence); 49 } attachBuffer(int * outSlot,const sp<GraphicBuffer> & buffer)50 status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer) override { 51 return mProducer->attachBuffer(outSlot, buffer); 52 } queueBuffer(int slot,const QueueBufferInput & input,QueueBufferOutput * output)53 status_t queueBuffer(int slot, const QueueBufferInput& input, 54 QueueBufferOutput* output) override { 55 return mProducer->queueBuffer(slot, input, output); 56 } cancelBuffer(int slot,const sp<Fence> & fence)57 status_t cancelBuffer(int slot, const sp<Fence>& fence) override { 58 return mProducer->cancelBuffer(slot, fence); 59 } query(int what,int * value)60 int query(int what, int* value) override { return mProducer->query(what, value); } connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)61 status_t connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp, 62 QueueBufferOutput* output) override { 63 return mProducer->connect(listener, api, producerControlledByApp, output); 64 } disconnect(int api,DisconnectMode mode)65 status_t disconnect(int api, DisconnectMode mode) override { 66 return mProducer->disconnect(api, mode); 67 } setSidebandStream(const sp<NativeHandle> & stream)68 status_t setSidebandStream(const sp<NativeHandle>& stream) override { 69 return mProducer->setSidebandStream(stream); 70 } allocateBuffers(uint32_t width,uint32_t height,PixelFormat format,uint64_t usage)71 void allocateBuffers(uint32_t width, uint32_t height, PixelFormat format, 72 uint64_t usage) override { 73 mProducer->allocateBuffers(width, height, format, usage); 74 } allowAllocation(bool allow)75 status_t allowAllocation(bool allow) override { return mProducer->allowAllocation(allow); } setGenerationNumber(uint32_t generationNumber)76 status_t setGenerationNumber(uint32_t generationNumber) override { 77 return mProducer->setGenerationNumber(generationNumber); 78 } getConsumerName() const79 String8 getConsumerName() const override { return mProducer->getConsumerName(); } setSharedBufferMode(bool sharedBufferMode)80 status_t setSharedBufferMode(bool sharedBufferMode) override { 81 return mProducer->setSharedBufferMode(sharedBufferMode); 82 } setAutoRefresh(bool autoRefresh)83 status_t setAutoRefresh(bool autoRefresh) override { 84 return mProducer->setAutoRefresh(autoRefresh); 85 } setDequeueTimeout(nsecs_t timeout)86 status_t setDequeueTimeout(nsecs_t timeout) override { 87 return mProducer->setDequeueTimeout(timeout); 88 } getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])89 status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence, 90 float outTransformMatrix[16]) override { 91 return mProducer->getLastQueuedBuffer(outBuffer, outFence, outTransformMatrix); 92 } getFrameTimestamps(FrameEventHistoryDelta *)93 void getFrameTimestamps(FrameEventHistoryDelta*) override {} getUniqueId(uint64_t * outId) const94 status_t getUniqueId(uint64_t* outId) const override { return mProducer->getUniqueId(outId); } getConsumerUsage(uint64_t * outUsage) const95 status_t getConsumerUsage(uint64_t* outUsage) const override { 96 return mProducer->getConsumerUsage(outUsage); 97 } 98 99 protected: 100 sp<IGraphicBufferProducer> mProducer; 101 }; 102 103 class MaliciousBQP : public ProxyBQP { 104 public: MaliciousBQP(const sp<IGraphicBufferProducer> & producer)105 explicit MaliciousBQP(const sp<IGraphicBufferProducer>& producer) : ProxyBQP(producer) {} 106 beMalicious(int32_t value)107 void beMalicious(int32_t value) { mMaliciousValue = value; } 108 setExpectedSlot(int32_t slot)109 void setExpectedSlot(int32_t slot) { mExpectedSlot = slot; } 110 111 // Override dequeueBuffer, optionally corrupting the returned slot number dequeueBuffer(int * buf,sp<Fence> * fence,uint32_t width,uint32_t height,PixelFormat format,uint64_t usage,uint64_t * outBufferAge,FrameEventHistoryDelta * outTimestamps)112 status_t dequeueBuffer(int* buf, sp<Fence>* fence, uint32_t width, uint32_t height, 113 PixelFormat format, uint64_t usage, uint64_t* outBufferAge, 114 FrameEventHistoryDelta* outTimestamps) override { 115 EXPECT_EQ(BUFFER_NEEDS_REALLOCATION, 116 mProducer->dequeueBuffer(buf, fence, width, height, format, usage, outBufferAge, 117 outTimestamps)); 118 EXPECT_EQ(mExpectedSlot, *buf); 119 if (mMaliciousValue != 0) { 120 *buf = mMaliciousValue; 121 return NO_ERROR; 122 } else { 123 return BUFFER_NEEDS_REALLOCATION; 124 } 125 } 126 127 private: 128 int32_t mMaliciousValue = 0; 129 int32_t mExpectedSlot = 0; 130 }; 131 132 class FakeListener : public BnConsumerListener { 133 public: onFrameAvailable(const BufferItem &)134 void onFrameAvailable(const BufferItem&) override {} onBuffersReleased()135 void onBuffersReleased() override {} onSidebandStreamChanged()136 void onSidebandStreamChanged() override {} 137 }; 138 getMaliciousBQP()139 sp<MaliciousBQP> getMaliciousBQP() { 140 sp<IGraphicBufferProducer> producer; 141 sp<IGraphicBufferConsumer> consumer; 142 BufferQueue::createBufferQueue(&producer, &consumer); 143 sp<IConsumerListener> listener = new FakeListener; 144 consumer->consumerConnect(listener, false); 145 146 sp<MaliciousBQP> malicious = new MaliciousBQP(producer); 147 return malicious; 148 } 149 TEST(Malicious,Bug36991414Max)150 TEST(Malicious, Bug36991414Max) { 151 sp<MaliciousBQP> malicious = getMaliciousBQP(); 152 sp<Surface> surface = new Surface(malicious); 153 154 ANativeWindow_Buffer buffer; 155 ASSERT_EQ(NO_ERROR, surface->lock(&buffer, nullptr)); 156 ASSERT_EQ(NO_ERROR, surface->unlockAndPost()); 157 158 malicious->setExpectedSlot(1); 159 malicious->beMalicious(std::numeric_limits<int32_t>::max()); 160 ASSERT_EQ(FAILED_TRANSACTION, surface->lock(&buffer, nullptr)); 161 } 162 TEST(Malicious,Bug36991414Min)163 TEST(Malicious, Bug36991414Min) { 164 sp<MaliciousBQP> malicious = getMaliciousBQP(); 165 sp<Surface> surface = new Surface(malicious); 166 167 ANativeWindow_Buffer buffer; 168 ASSERT_EQ(NO_ERROR, surface->lock(&buffer, nullptr)); 169 ASSERT_EQ(NO_ERROR, surface->unlockAndPost()); 170 171 malicious->setExpectedSlot(1); 172 malicious->beMalicious(std::numeric_limits<int32_t>::min()); 173 ASSERT_EQ(FAILED_TRANSACTION, surface->lock(&buffer, nullptr)); 174 } 175 TEST(Malicious,Bug36991414NegativeOne)176 TEST(Malicious, Bug36991414NegativeOne) { 177 sp<MaliciousBQP> malicious = getMaliciousBQP(); 178 sp<Surface> surface = new Surface(malicious); 179 180 ANativeWindow_Buffer buffer; 181 ASSERT_EQ(NO_ERROR, surface->lock(&buffer, nullptr)); 182 ASSERT_EQ(NO_ERROR, surface->unlockAndPost()); 183 184 malicious->setExpectedSlot(1); 185 malicious->beMalicious(-1); 186 ASSERT_EQ(FAILED_TRANSACTION, surface->lock(&buffer, nullptr)); 187 } 188 TEST(Malicious,Bug36991414NumSlots)189 TEST(Malicious, Bug36991414NumSlots) { 190 sp<MaliciousBQP> malicious = getMaliciousBQP(); 191 sp<Surface> surface = new Surface(malicious); 192 193 ANativeWindow_Buffer buffer; 194 ASSERT_EQ(NO_ERROR, surface->lock(&buffer, nullptr)); 195 ASSERT_EQ(NO_ERROR, surface->unlockAndPost()); 196 197 malicious->setExpectedSlot(1); 198 malicious->beMalicious(BufferQueueDefs::NUM_BUFFER_SLOTS); 199 ASSERT_EQ(FAILED_TRANSACTION, surface->lock(&buffer, nullptr)); 200 } 201 202 } // namespace test 203 } // namespace android 204