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.
  */