diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-02-03 00:02:47 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-02-03 00:02:47 +0000 |
commit | 71b2f2af5febaa11c07e32467fc3407a74ba7529 (patch) | |
tree | 0e7b680e5b0e8d124cc0924d38a348e5b2b9f371 | |
parent | 3988bf32fad2c5a98caee6900d82ea4d4b4cba9a (diff) | |
parent | c459e6947807cdb8e7d05b3f89ed44e9693a8bf4 (diff) | |
download | libfmq-simpleperf-release.tar.gz |
Snap for 11400057 from c459e6947807cdb8e7d05b3f89ed44e9693a8bf4 to simpleperf-releasesimpleperf-release
Change-Id: Ieefaa72e0324fc21723e98e38f8459d686348be0
-rw-r--r-- | EventFlag.cpp | 10 | ||||
-rw-r--r-- | fuzzer/Android.bp | 5 | ||||
-rw-r--r-- | fuzzer/fmq_fuzzer.cpp | 6 | ||||
-rw-r--r-- | include/fmq/MessageQueueBase.h | 20 | ||||
-rw-r--r-- | tests/fmq_unit_tests.cpp | 72 |
5 files changed, 102 insertions, 11 deletions
diff --git a/EventFlag.cpp b/EventFlag.cpp index d353873..8cf2760 100644 --- a/EventFlag.cpp +++ b/EventFlag.cpp @@ -171,6 +171,11 @@ status_t EventFlag::wait(uint32_t bitmask, int64_t prevTimeNs = shouldTimeOut ? android::elapsedRealtimeNano() : 0; status_t status; while (true) { + status = waitHelper(bitmask, efState, timeoutNanoSeconds); + if ((status != -EAGAIN) && (status != -EINTR)) { + break; + } + if (shouldTimeOut) { int64_t currentTimeNs = android::elapsedRealtimeNano(); /* @@ -185,11 +190,6 @@ status_t EventFlag::wait(uint32_t bitmask, break; } } - - status = waitHelper(bitmask, efState, timeoutNanoSeconds); - if ((status != -EAGAIN) && (status != -EINTR)) { - break; - } } return status; } diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp index ee7afb9..6d15b52 100644 --- a/fuzzer/Android.bp +++ b/fuzzer/Android.bp @@ -51,7 +51,10 @@ cc_fuzz { libfuzzer_options: [ "max_len=50000", ], - use_for_presubmit: true + use_for_presubmit: true, + }, + sanitize: { + integer_overflow: true, }, host_supported: true, diff --git a/fuzzer/fmq_fuzzer.cpp b/fuzzer/fmq_fuzzer.cpp index b5318a3..47dd7fa 100644 --- a/fuzzer/fmq_fuzzer.cpp +++ b/fuzzer/fmq_fuzzer.cpp @@ -203,7 +203,7 @@ void writer(const Desc& desc, Queue& writeMq, FuzzedDataProvider& fdp, bool user *readCounter = fdp.ConsumeIntegral<uint64_t>(); } } - *firstStart = fdp.ConsumeIntegral<payload_t>(); + *firstStart = fdp.ConsumeIntegral<uint8_t>(); writeMq.commitWrite(numElements); } @@ -218,7 +218,7 @@ void writerBlocking(Queue& writeMq, FuzzedDataProvider& fdp, size_t count = fdp.ConsumeIntegralInRange<size_t>(0, writeMq.getQuantumCount() + 1); std::vector<payload_t> data; for (int i = 0; i < count; i++) { - data.push_back(fdp.ConsumeIntegral<payload_t>()); + data.push_back(fdp.ConsumeIntegral<uint8_t>()); } writeMq.writeBlocking(data.data(), count, kBlockingTimeoutNs); } @@ -250,7 +250,7 @@ inline std::optional<Desc> getAidlDesc(std::unique_ptr<Queue>& queue, FuzzedData std::vector<aidl::android::hardware::common::fmq::GrantorDescriptor> grantors; size_t numGrantors = fdp.ConsumeIntegralInRange<size_t>(0, 4); for (int i = 0; i < numGrantors; i++) { - grantors.push_back({fdp.ConsumeIntegralInRange<int32_t>(-2, 2) /* fdIndex */, + grantors.push_back({fdp.ConsumeIntegralInRange<int32_t>(0, 2) /* fdIndex */, fdp.ConsumeIntegralInRange<int32_t>( 0, kMaxCustomGrantorMemoryBytes) /* offset */, fdp.ConsumeIntegralInRange<int64_t>( diff --git a/include/fmq/MessageQueueBase.h b/include/fmq/MessageQueueBase.h index 8144937..1b71abf 100644 --- a/include/fmq/MessageQueueBase.h +++ b/include/fmq/MessageQueueBase.h @@ -1047,7 +1047,15 @@ bool MessageQueueBase<MQDescriptorType, T, flavor>::readBlocking(T* data, size_t template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor> size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToWriteBytes() const { - return mDesc->getSize() - availableToReadBytes(); + size_t queueSizeBytes = mDesc->getSize(); + size_t availableBytes = availableToReadBytes(); + if (queueSizeBytes < availableBytes) { + hardware::details::logError( + "The write or read pointer has become corrupted. Reading from the queue is no " + "longer possible."); + return 0; + } + return queueSizeBytes - availableBytes; } template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor> @@ -1135,7 +1143,15 @@ size_t MessageQueueBase<MQDescriptorType, T, flavor>::availableToReadBytes() con * hence requires a memory_order_acquired load for both mReadPtr and * mWritePtr. */ - return mWritePtr->load(std::memory_order_acquire) - mReadPtr->load(std::memory_order_acquire); + uint64_t writePtr = mWritePtr->load(std::memory_order_acquire); + uint64_t readPtr = mReadPtr->load(std::memory_order_acquire); + if (writePtr < readPtr) { + hardware::details::logError( + "The write or read pointer has become corrupted. Reading from the queue is no " + "longer possible."); + return 0; + } + return writePtr - readPtr; } template <template <typename, MQFlavor> typename MQDescriptorType, typename T, MQFlavor flavor> diff --git a/tests/fmq_unit_tests.cpp b/tests/fmq_unit_tests.cpp index 08790c8..96a8261 100644 --- a/tests/fmq_unit_tests.cpp +++ b/tests/fmq_unit_tests.cpp @@ -695,6 +695,78 @@ TYPED_TEST(BlockingReadWrites, BlockingTimeOutTest) { } /* + * Test EventFlag wait on a waked flag with a short timeout. + */ +TYPED_TEST(BlockingReadWrites, ShortEventFlagWaitWithWakeTest) { + std::atomic<uint32_t> eventFlagWord; + std::atomic_init(&eventFlagWord, static_cast<uint32_t>(kFmqNotFull)); + android::hardware::EventFlag* efGroup = nullptr; + android::status_t status = + android::hardware::EventFlag::createEventFlag(&eventFlagWord, &efGroup); + ASSERT_EQ(android::NO_ERROR, status); + ASSERT_NE(nullptr, efGroup); + + status = efGroup->wake(kFmqNotEmpty); + ASSERT_EQ(android::NO_ERROR, status); + + uint32_t efState = 0; + android::status_t ret = efGroup->wait(kFmqNotEmpty, &efState, 1 /* ns */, true /* retry */); + ASSERT_EQ(android::NO_ERROR, ret); + + status = android::hardware::EventFlag::deleteEventFlag(&efGroup); + ASSERT_EQ(android::NO_ERROR, status); +} + +/* + * Test on an EventFlag with no wakeup, short timeout. + */ +TYPED_TEST(BlockingReadWrites, ShortEventFlagWaitWithoutWakeTest) { + std::atomic<uint32_t> eventFlagWord; + std::atomic_init(&eventFlagWord, static_cast<uint32_t>(kFmqNotFull)); + android::hardware::EventFlag* efGroup = nullptr; + android::status_t status = + android::hardware::EventFlag::createEventFlag(&eventFlagWord, &efGroup); + ASSERT_EQ(android::NO_ERROR, status); + ASSERT_NE(nullptr, efGroup); + + uint32_t efState = 0; + android::status_t ret = efGroup->wait(kFmqNotEmpty, &efState, 1 /* ns */, true /* retry */); + ASSERT_EQ(android::TIMED_OUT, ret); + + status = android::hardware::EventFlag::deleteEventFlag(&efGroup); + ASSERT_EQ(android::NO_ERROR, status); +} + +/* + * Test FMQ write and read with event flag wait. + */ +TYPED_TEST(BlockingReadWrites, FmqWriteAndReadWithShortEventFlagWaitTest) { + android::hardware::EventFlag* efGroup = nullptr; + android::status_t status = android::hardware::EventFlag::createEventFlag(&this->mFw, &efGroup); + ASSERT_EQ(android::NO_ERROR, status); + ASSERT_NE(nullptr, efGroup); + + /* + * After waiting for some time write into the FMQ + * and call Wake on kFmqNotEmpty. + */ + const size_t dataLen = 16; + uint8_t dataW[dataLen] = {0}; + uint8_t dataR[dataLen] = {0}; + ASSERT_TRUE(this->mQueue->write(dataW, dataLen)); + status = efGroup->wake(kFmqNotEmpty); + ASSERT_EQ(android::NO_ERROR, status); + + ASSERT_TRUE(this->mQueue->readBlocking(dataR, dataLen, static_cast<uint32_t>(kFmqNotEmpty), + static_cast<uint32_t>(kFmqNotFull), 1 /* timeOutNanos */, + efGroup)); + ASSERT_EQ(0, memcmp(dataW, dataR, dataLen)); + + status = android::hardware::EventFlag::deleteEventFlag(&efGroup); + ASSERT_EQ(android::NO_ERROR, status); +} + +/* * Test that odd queue sizes do not cause unaligned error * on access to EventFlag object. */ |