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: 30 explicit ProxyBQP(const sp<IGraphicBufferProducer>& producer) : mProducer(producer) {} 31 32 // Pass through calls to mProducer 33 status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override { 34 return mProducer->requestBuffer(slot, buf); 35 } 36 status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override { 37 return mProducer->setMaxDequeuedBufferCount(maxDequeuedBuffers); 38 } 39 status_t setAsyncMode(bool async) override { return mProducer->setAsyncMode(async); } 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 } 46 status_t detachBuffer(int slot) override { return mProducer->detachBuffer(slot); } 47 status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) override { 48 return mProducer->detachNextBuffer(outBuffer, outFence); 49 } 50 status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer) override { 51 return mProducer->attachBuffer(outSlot, buffer); 52 } 53 status_t queueBuffer(int slot, const QueueBufferInput& input, 54 QueueBufferOutput* output) override { 55 return mProducer->queueBuffer(slot, input, output); 56 } 57 status_t cancelBuffer(int slot, const sp<Fence>& fence) override { 58 return mProducer->cancelBuffer(slot, fence); 59 } 60 int query(int what, int* value) override { return mProducer->query(what, value); } 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 } 65 status_t disconnect(int api, DisconnectMode mode) override { 66 return mProducer->disconnect(api, mode); 67 } 68 status_t setSidebandStream(const sp<NativeHandle>& stream) override { 69 return mProducer->setSidebandStream(stream); 70 } 71 void allocateBuffers(uint32_t width, uint32_t height, PixelFormat format, 72 uint64_t usage) override { 73 mProducer->allocateBuffers(width, height, format, usage); 74 } 75 status_t allowAllocation(bool allow) override { return mProducer->allowAllocation(allow); } 76 status_t setGenerationNumber(uint32_t generationNumber) override { 77 return mProducer->setGenerationNumber(generationNumber); 78 } 79 String8 getConsumerName() const override { return mProducer->getConsumerName(); } 80 status_t setSharedBufferMode(bool sharedBufferMode) override { 81 return mProducer->setSharedBufferMode(sharedBufferMode); 82 } 83 status_t setAutoRefresh(bool autoRefresh) override { 84 return mProducer->setAutoRefresh(autoRefresh); 85 } 86 status_t setDequeueTimeout(nsecs_t timeout) override { 87 return mProducer->setDequeueTimeout(timeout); 88 } 89 status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence, 90 float outTransformMatrix[16]) override { 91 return mProducer->getLastQueuedBuffer(outBuffer, outFence, outTransformMatrix); 92 } 93 void getFrameTimestamps(FrameEventHistoryDelta*) override {} 94 status_t getUniqueId(uint64_t* outId) const override { return mProducer->getUniqueId(outId); } 95 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: 105 explicit MaliciousBQP(const sp<IGraphicBufferProducer>& producer) : ProxyBQP(producer) {} 106 107 void beMalicious(int32_t value) { mMaliciousValue = value; } 108 109 void setExpectedSlot(int32_t slot) { mExpectedSlot = slot; } 110 111 // Override dequeueBuffer, optionally corrupting the returned slot number 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 DummyListener : public BnConsumerListener { 133 public: 134 void onFrameAvailable(const BufferItem&) override {} 135 void onBuffersReleased() override {} 136 void onSidebandStreamChanged() override {} 137 }; 138 139 sp<MaliciousBQP> getMaliciousBQP() { 140 sp<IGraphicBufferProducer> producer; 141 sp<IGraphicBufferConsumer> consumer; 142 BufferQueue::createBufferQueue(&producer, &consumer); 143 sp<IConsumerListener> listener = new DummyListener; 144 consumer->consumerConnect(listener, false); 145 146 sp<MaliciousBQP> malicious = new MaliciousBQP(producer); 147 return malicious; 148 } 149 150 TEST(Malicious, Bug36991414Max) { 151 sp<MaliciousBQP> malicious = getMaliciousBQP(); 152 sp<Surface> surface = new Surface(malicious); 153 154 ASSERT_EQ(NO_ERROR, surface->connect(NATIVE_WINDOW_API_CPU, nullptr, false)); 155 ANativeWindow_Buffer buffer; 156 ASSERT_EQ(NO_ERROR, surface->lock(&buffer, nullptr)); 157 ASSERT_EQ(NO_ERROR, surface->unlockAndPost()); 158 159 malicious->setExpectedSlot(1); 160 malicious->beMalicious(std::numeric_limits<int32_t>::max()); 161 ASSERT_EQ(FAILED_TRANSACTION, surface->lock(&buffer, nullptr)); 162 } 163 164 TEST(Malicious, Bug36991414Min) { 165 sp<MaliciousBQP> malicious = getMaliciousBQP(); 166 sp<Surface> surface = new Surface(malicious); 167 168 ASSERT_EQ(NO_ERROR, surface->connect(NATIVE_WINDOW_API_CPU, nullptr, false)); 169 ANativeWindow_Buffer buffer; 170 ASSERT_EQ(NO_ERROR, surface->lock(&buffer, nullptr)); 171 ASSERT_EQ(NO_ERROR, surface->unlockAndPost()); 172 173 malicious->setExpectedSlot(1); 174 malicious->beMalicious(std::numeric_limits<int32_t>::min()); 175 ASSERT_EQ(FAILED_TRANSACTION, surface->lock(&buffer, nullptr)); 176 } 177 178 TEST(Malicious, Bug36991414NegativeOne) { 179 sp<MaliciousBQP> malicious = getMaliciousBQP(); 180 sp<Surface> surface = new Surface(malicious); 181 182 ASSERT_EQ(NO_ERROR, surface->connect(NATIVE_WINDOW_API_CPU, nullptr, false)); 183 ANativeWindow_Buffer buffer; 184 ASSERT_EQ(NO_ERROR, surface->lock(&buffer, nullptr)); 185 ASSERT_EQ(NO_ERROR, surface->unlockAndPost()); 186 187 malicious->setExpectedSlot(1); 188 malicious->beMalicious(-1); 189 ASSERT_EQ(FAILED_TRANSACTION, surface->lock(&buffer, nullptr)); 190 } 191 192 TEST(Malicious, Bug36991414NumSlots) { 193 sp<MaliciousBQP> malicious = getMaliciousBQP(); 194 sp<Surface> surface = new Surface(malicious); 195 196 ASSERT_EQ(NO_ERROR, surface->connect(NATIVE_WINDOW_API_CPU, nullptr, false)); 197 ANativeWindow_Buffer buffer; 198 ASSERT_EQ(NO_ERROR, surface->lock(&buffer, nullptr)); 199 ASSERT_EQ(NO_ERROR, surface->unlockAndPost()); 200 201 malicious->setExpectedSlot(1); 202 malicious->beMalicious(BufferQueueDefs::NUM_BUFFER_SLOTS); 203 ASSERT_EQ(FAILED_TRANSACTION, surface->lock(&buffer, nullptr)); 204 } 205 206 } // namespace test 207 } // namespace android 208