Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce15b9fc authored by Steven Moreland's avatar Steven Moreland
Browse files

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
parent ec6c073a
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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 {
+1 −2
Original line number Diff line number Diff line
@@ -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) {