summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Steven Moreland <smoreland@google.com> 2022-09-08 17:42:45 +0000
committer Steven Moreland <smoreland@google.com> 2022-09-08 19:42:38 +0000
commitce15b9fc8930edb034938afd972d1f2e3fd1974c (patch)
tree45939b6b10fd498f0c7abc34ebec9ae4204fc400
parentec6c073aed281ce50cdd0f38b0f9f4e247109700 (diff)
libbinder: fix buffer free race
Well, so the race is: - client sends a large transaction (buffer A) - server processes result - server sends reply (1) - client gets reply - client sends another large transaction (buffer B) - transaction fails, not enough space - server frees buffer A (2) This CL moves (2) to happen before (1). We set the Parcel size to 0, which has the effect of freeing data, before the destructor runs. Test: binderLibTest Test: binderLibTest --gtest_filter="*Garg*" --gtest_repeat=1000 --gtest_break_on_failure Fixes: 238777741 Change-Id: Ic223a98c55904bb3f77ca13729cdf24a992cef1e
-rw-r--r--libs/binder/IPCThreadState.cpp7
-rw-r--r--libs/binder/tests/binderLibTest.cpp3
2 files changed, 8 insertions, 2 deletions
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index b50cfb3d19..bfcf39ad30 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -1318,6 +1318,13 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
LOG_ONEWAY("Sending reply to %d!", mCallingPid);
if (error < NO_ERROR) reply.setError(error);
+ // b/238777741: clear buffer before we send the reply.
+ // Otherwise, there is a race where the client may
+ // receive the reply and send another transaction
+ // here and the space used by this transaction won't
+ // be freed for the client.
+ buffer.setDataSize(0);
+
constexpr uint32_t kForwardReplyFlags = TF_CLEAR_BUF;
sendReply(reply, (tr.flags & kForwardReplyFlags));
} else {
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 5de08bdc00..6e1c8ac16a 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -1161,8 +1161,7 @@ TEST_F(BinderLibTest, VectorSent) {
// see ProcessState.cpp BINDER_VM_SIZE = 1MB.
// This value is not exposed, but some code in the framework relies on being able to use
// buffers near the cap size.
-// TODO(b/238777741): why do larger values, like 300K fail sometimes
-constexpr size_t kSizeBytesAlmostFull = 100'000;
+constexpr size_t kSizeBytesAlmostFull = 950'000;
constexpr size_t kSizeBytesOverFull = 1'050'000;
TEST_F(BinderLibTest, GargantuanVectorSent) {