summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-03 00:02:47 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-03 00:02:47 +0000
commit71b2f2af5febaa11c07e32467fc3407a74ba7529 (patch)
tree0e7b680e5b0e8d124cc0924d38a348e5b2b9f371
parent3988bf32fad2c5a98caee6900d82ea4d4b4cba9a (diff)
parentc459e6947807cdb8e7d05b3f89ed44e9693a8bf4 (diff)
downloadlibfmq-simpleperf-release.tar.gz
Snap for 11400057 from c459e6947807cdb8e7d05b3f89ed44e9693a8bf4 to simpleperf-releasesimpleperf-release
Change-Id: Ieefaa72e0324fc21723e98e38f8459d686348be0
-rw-r--r--EventFlag.cpp10
-rw-r--r--fuzzer/Android.bp5
-rw-r--r--fuzzer/fmq_fuzzer.cpp6
-rw-r--r--include/fmq/MessageQueueBase.h20
-rw-r--r--tests/fmq_unit_tests.cpp72
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.
*/