Merge changes Id2c1d0dc,I654fcd2c

* changes:
  libbinder: Add binder already sent checks
  libbinder: +2 bytes in BBinder from stability rep
diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h
index fa77593..509ee0e 100644
--- a/include/android/multinetwork.h
+++ b/include/android/multinetwork.h
@@ -102,6 +102,28 @@
  */
 int android_getprocnetwork(net_handle_t *network) __INTRODUCED_IN(31);
 
+/**
+ * Binds domain name resolutions performed by this process to |network|.
+ * android_setprocnetwork takes precedence over this setting.
+ *
+ * To clear a previous process binding, invoke with NETWORK_UNSPECIFIED.
+ * On success 0 is returned. On error -1 is returned, and errno is set.
+ *
+ * Available since API level 31.
+ */
+int android_setprocdns(net_handle_t network) __INTRODUCED_IN(31);
+
+/**
+ * Gets the |network| to which domain name resolutions are bound on the
+ * current process.
+ *
+ * Returns 0 on success, or -1 setting errno to EINVAL if a null pointer is
+ * passed in.
+ *
+ * Available since API level 31.
+ */
+int android_getprocdns(net_handle_t *network) __INTRODUCED_IN(31);
+
 
 /**
  * Perform hostname resolution via the DNS servers associated with |network|.
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 47dd32e..d421060 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -129,8 +129,7 @@
     return checkCallingPermission(permission, nullptr, nullptr);
 }
 
-static String16 _permission("permission");
-
+static StaticString16 _permission(u"permission");
 
 bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
 {
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index 1f97293..93f1529 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -134,6 +134,15 @@
 
 void RpcState::dump() {
     std::lock_guard<std::mutex> _l(mNodeMutex);
+    dumpLocked();
+}
+
+void RpcState::terminate() {
+    std::unique_lock<std::mutex> _l(mNodeMutex);
+    terminate(_l);
+}
+
+void RpcState::dumpLocked() {
     ALOGE("DUMP OF RpcState %p", this);
     ALOGE("DUMP OF RpcState (%zu nodes)", mNodeForAddress.size());
     for (const auto& [address, node] : mNodeForAddress) {
@@ -161,10 +170,10 @@
     ALOGE("END DUMP OF RpcState");
 }
 
-void RpcState::terminate() {
+void RpcState::terminate(std::unique_lock<std::mutex>& lock) {
     if (SHOULD_LOG_RPC_DETAIL) {
         ALOGE("RpcState::terminate()");
-        dump();
+        dumpLocked();
     }
 
     // if the destructor of a binder object makes another RPC call, then calling
@@ -172,20 +181,20 @@
     // mNodeMutex is no longer taken.
     std::vector<sp<IBinder>> tempHoldBinder;
 
-    {
-        std::lock_guard<std::mutex> _l(mNodeMutex);
-        mTerminated = true;
-        for (auto& [address, node] : mNodeForAddress) {
-            sp<IBinder> binder = node.binder.promote();
-            LOG_ALWAYS_FATAL_IF(binder == nullptr, "Binder %p expected to be owned.", binder.get());
+    mTerminated = true;
+    for (auto& [address, node] : mNodeForAddress) {
+        sp<IBinder> binder = node.binder.promote();
+        LOG_ALWAYS_FATAL_IF(binder == nullptr, "Binder %p expected to be owned.", binder.get());
 
-            if (node.sentRef != nullptr) {
-                tempHoldBinder.push_back(node.sentRef);
-            }
+        if (node.sentRef != nullptr) {
+            tempHoldBinder.push_back(node.sentRef);
         }
-
-        mNodeForAddress.clear();
     }
+
+    mNodeForAddress.clear();
+
+    lock.unlock();
+    tempHoldBinder.clear(); // explicit
 }
 
 RpcState::CommandData::CommandData(size_t size) : mSize(size) {
@@ -341,14 +350,15 @@
     uint64_t asyncNumber = 0;
 
     if (!address.isZero()) {
-        std::lock_guard<std::mutex> _l(mNodeMutex);
+        std::unique_lock<std::mutex> _l(mNodeMutex);
         if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races
         auto it = mNodeForAddress.find(address);
         LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), "Sending transact on unknown address %s",
                             address.toString().c_str());
 
         if (flags & IBinder::FLAG_ONEWAY) {
-            asyncNumber = it->second.asyncNumber++;
+            asyncNumber = it->second.asyncNumber;
+            if (!nodeProgressAsyncNumber(&it->second, _l)) return DEAD_OBJECT;
         }
     }
 
@@ -458,9 +468,8 @@
                             addr.toString().c_str());
 
         it->second.timesRecd--;
-        if (it->second.timesRecd == 0 && it->second.timesSent == 0) {
-            mNodeForAddress.erase(it);
-        }
+        LOG_ALWAYS_FATAL_IF(nullptr != tryEraseNode(it),
+                            "Bad state. RpcState shouldn't own received binder");
     }
 
     RpcWireHeader cmd = {
@@ -698,13 +707,7 @@
             // last refcount dropped after this transaction happened
             if (it == mNodeForAddress.end()) return OK;
 
-            // note - only updated now, instead of later, so that other threads
-            // will queue any later transactions
-
-            // TODO(b/183140903): support > 2**64 async transactions
-            //     (we can do this by allowing asyncNumber to wrap, since we
-            //     don't expect more than 2**64 simultaneous transactions)
-            it->second.asyncNumber++;
+            if (!nodeProgressAsyncNumber(&it->second, _l)) return DEAD_OBJECT;
 
             if (it->second.asyncTodo.size() == 0) return OK;
             if (it->second.asyncTodo.top().asyncNumber == it->second.asyncNumber) {
@@ -799,22 +802,40 @@
     LOG_ALWAYS_FATAL_IF(it->second.sentRef == nullptr, "Inconsistent state, lost ref for %s",
                         addr.toString().c_str());
 
-    sp<IBinder> tempHold;
-
     it->second.timesSent--;
-    if (it->second.timesSent == 0) {
-        tempHold = it->second.sentRef;
-        it->second.sentRef = nullptr;
-
-        if (it->second.timesRecd == 0) {
-            mNodeForAddress.erase(it);
-        }
-    }
-
+    sp<IBinder> tempHold = tryEraseNode(it);
     _l.unlock();
     tempHold = nullptr; // destructor may make binder calls on this session
 
     return OK;
 }
 
+sp<IBinder> RpcState::tryEraseNode(std::map<RpcAddress, BinderNode>::iterator& it) {
+    sp<IBinder> ref;
+
+    if (it->second.timesSent == 0) {
+        ref = std::move(it->second.sentRef);
+
+        if (it->second.timesRecd == 0) {
+            LOG_ALWAYS_FATAL_IF(!it->second.asyncTodo.empty(),
+                                "Can't delete binder w/ pending async transactions");
+            mNodeForAddress.erase(it);
+        }
+    }
+
+    return ref;
+}
+
+bool RpcState::nodeProgressAsyncNumber(BinderNode* node, std::unique_lock<std::mutex>& lock) {
+    // 2**64 =~ 10**19 =~ 1000 transactions per second for 585 million years to
+    // a single binder
+    if (node->asyncNumber >= std::numeric_limits<decltype(node->asyncNumber)>::max()) {
+        ALOGE("Out of async transaction IDs. Terminating");
+        terminate(lock);
+        return false;
+    }
+    node->asyncNumber++;
+    return true;
+}
+
 } // namespace android
diff --git a/libs/binder/RpcState.h b/libs/binder/RpcState.h
index d448938..81ff458 100644
--- a/libs/binder/RpcState.h
+++ b/libs/binder/RpcState.h
@@ -113,6 +113,9 @@
     void terminate();
 
 private:
+    void dumpLocked();
+    void terminate(std::unique_lock<std::mutex>& lock);
+
     // Alternative to std::vector<uint8_t> that doesn't abort on allocation failure and caps
     // large allocations to avoid being requested from allocating too much data.
     struct CommandData {
@@ -195,6 +198,16 @@
         // (no additional data specific to remote binders)
     };
 
+    // checks if there is any reference left to a node and erases it. If erase
+    // happens, and there is a strong reference to the binder kept by
+    // binderNode, this returns that strong reference, so that it can be
+    // dropped after any locks are removed.
+    sp<IBinder> tryEraseNode(std::map<RpcAddress, BinderNode>::iterator& it);
+    // true - success
+    // false - state terminated, lock gone, halt
+    [[nodiscard]] bool nodeProgressAsyncNumber(BinderNode* node,
+                                               std::unique_lock<std::mutex>& lock);
+
     std::mutex mNodeMutex;
     bool mTerminated = false;
     // binders known by both sides of a session