From 915382439c1db7768c48cbecb235bfc57a9b6437 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Thu, 10 Jun 2021 23:35:35 +0000 Subject: libbinder: RPC prevent binder address collision It's not clear that we're going to continue using such large addresses (they are expensive, and we don't actually need addresses themselves to be cryptographically unguessable - also since we are reading from urandom, we're using a lot of entropy - ...), but just in case, clearing out TODOs (and also in preparation of using RpcAddress for something else, which we probably will continue using). This prevents address collision by doing two things: - create a bitspace for server vs client addresses (one bit in the address, in a newly defined header, determines the originating side of the connection for the address). - instead of aborting when a duplicated address is created, try to create a new one. As a side-effect, this also adds a header to binder RPC addresses. Bug: 182939933 Test: binderRpcTest Change-Id: I8ff0d29ca6df25b3f1d9662978fccbb3eb76c8ad --- libs/binder/RpcAddress.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'libs/binder/RpcAddress.cpp') diff --git a/libs/binder/RpcAddress.cpp b/libs/binder/RpcAddress.cpp index 5c3232045e..98dee9a039 100644 --- a/libs/binder/RpcAddress.cpp +++ b/libs/binder/RpcAddress.cpp @@ -29,7 +29,7 @@ RpcAddress RpcAddress::zero() { } bool RpcAddress::isZero() const { - RpcWireAddress ZERO{0}; + RpcWireAddress ZERO{.options = 0}; return memcmp(mRawAddr.get(), &ZERO, sizeof(RpcWireAddress)) == 0; } @@ -51,13 +51,34 @@ static void ReadRandomBytes(uint8_t* buf, size_t len) { close(fd); } -RpcAddress RpcAddress::unique() { +RpcAddress RpcAddress::random(bool forServer) { + // The remainder of this header acts as reserved space for different kinds + // of binder objects. + uint64_t options = RPC_WIRE_ADDRESS_OPTION_CREATED; + + // servers and clients allocate addresses independently, so this bit can + // tell you where an address originates + if (forServer) options |= RPC_WIRE_ADDRESS_OPTION_FOR_SERVER; + RpcAddress ret; - ReadRandomBytes((uint8_t*)ret.mRawAddr.get(), sizeof(RpcWireAddress)); + RpcWireAddress* raw = ret.mRawAddr.get(); + + raw->options = options; + ReadRandomBytes(raw->address, sizeof(raw->address)); + LOG_RPC_DETAIL("Creating new address: %s", ret.toString().c_str()); return ret; } +bool RpcAddress::isForServer() const { + return mRawAddr.get()->options & RPC_WIRE_ADDRESS_OPTION_FOR_SERVER; +} + +bool RpcAddress::isRecognizedType() const { + uint64_t allKnownOptions = RPC_WIRE_ADDRESS_OPTION_CREATED | RPC_WIRE_ADDRESS_OPTION_FOR_SERVER; + return (mRawAddr.get()->options & ~allKnownOptions) == 0; +} + RpcAddress RpcAddress::fromRawEmbedded(const RpcWireAddress* raw) { RpcAddress addr; memcpy(addr.mRawAddr.get(), raw, sizeof(RpcWireAddress)); -- cgit v1.2.3-59-g8ed1b