From c7d40135ed5fb30434c95f3058324b0af6916711 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Thu, 10 Jun 2021 03:42:11 +0000 Subject: libbinder: RPC disallow nested oneway transactions Previously, nested transactions were accidentally allowed while processing oneway transactions. This changes things so that nested transactions are only explicitly allowed when a synchronous transaction is being processed (like how kernel binder is). Future considerations: this CL makes it more explicit that we allow refcount transactions as part of nested transactions. This is okay because 'drainCommands' will process these, but there might be some delay. We could make refcount behavior nicer if we always preferred using an active threadpool (if one is available) to process them. Bug: 167966510 Test: binderRpcTest Change-Id: Iaeb472896654ff4bcd75b20394f8f3230febaabf --- libs/binder/RpcState.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'libs/binder/RpcState.cpp') diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp index 5a2015691f..050f4fbeb3 100644 --- a/libs/binder/RpcState.cpp +++ b/libs/binder/RpcState.cpp @@ -633,6 +633,7 @@ processTransactInternalTailCall: // TODO(b/182939933): heap allocation just for lookup in mNodeForAddress, // maybe add an RpcAddress 'view' if the type remains 'heavy' auto addr = RpcAddress::fromRawEmbedded(&transaction->address); + bool oneway = transaction->flags & IBinder::FLAG_ONEWAY; status_t replyStatus = OK; sp target; @@ -661,7 +662,7 @@ processTransactInternalTailCall: addr.toString().c_str()); (void)session->shutdownAndWait(false); replyStatus = BAD_VALUE; - } else if (transaction->flags & IBinder::FLAG_ONEWAY) { + } else if (oneway) { std::unique_lock _l(mNodeMutex); auto it = mNodeForAddress.find(addr); if (it->second.binder.promote() != target) { @@ -718,7 +719,12 @@ processTransactInternalTailCall: data.markForRpc(session); if (target) { + bool origAllowNested = connection->allowNested; + connection->allowNested = !oneway; + replyStatus = target->transact(transaction->code, data, &reply, transaction->flags); + + connection->allowNested = origAllowNested; } else { LOG_RPC_DETAIL("Got special transaction %u", transaction->code); @@ -754,7 +760,7 @@ processTransactInternalTailCall: } } - if (transaction->flags & IBinder::FLAG_ONEWAY) { + if (oneway) { if (replyStatus != OK) { ALOGW("Oneway call failed with error: %d", replyStatus); } -- cgit v1.2.3-59-g8ed1b