Merge Android 24Q1 Release (ab/11220357)
Bug: 319669529
Merged-In: I7969096a2a7e17aaf821cc93272a1c78d1876c75
Change-Id: I697a6f7bfcb6373914c07e8473f9b4cfb2dfb423
diff --git a/EventFlag.cpp b/EventFlag.cpp
index d353873..8cf2760 100644
--- a/EventFlag.cpp
+++ b/EventFlag.cpp
@@ -171,6 +171,11 @@
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 @@
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 @@
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 @@
*readCounter = fdp.ConsumeIntegral<uint64_t>();
}
}
- *firstStart = fdp.ConsumeIntegral<payload_t>();
+ *firstStart = fdp.ConsumeIntegral<uint8_t>();
writeMq.commitWrite(numElements);
}
@@ -218,7 +218,7 @@
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 @@
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 017e7fc..abb28d7 100644
--- a/include/fmq/MessageQueueBase.h
+++ b/include/fmq/MessageQueueBase.h
@@ -1047,7 +1047,15 @@
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 @@
* 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 @@
}
/*
+ * 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.
*/