Loading libs/binder/Parcel.cpp +39 −0 Original line number Diff line number Diff line Loading @@ -599,17 +599,53 @@ bool Parcel::hasFileDescriptors() const return mHasFds; } void Parcel::updateWorkSourceRequestHeaderPosition() const { // Only update the request headers once. We only want to point // to the first headers read/written. if (!mRequestHeaderPresent) { mWorkSourceRequestHeaderPosition = dataPosition(); mRequestHeaderPresent = true; } } // Write RPC headers. (previously just the interface token) status_t Parcel::writeInterfaceToken(const String16& interface) { const IPCThreadState* threadState = IPCThreadState::self(); writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER); updateWorkSourceRequestHeaderPosition(); writeInt32(threadState->shouldPropagateWorkSource() ? threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource); // currently the interface identification token is just its name as a string return writeString16(interface); } bool Parcel::replaceCallingWorkSourceUid(uid_t uid) { if (!mRequestHeaderPresent) { return false; } const size_t initialPosition = dataPosition(); setDataPosition(mWorkSourceRequestHeaderPosition); status_t err = writeInt32(uid); setDataPosition(initialPosition); return err == NO_ERROR; } uid_t Parcel::readCallingWorkSourceUid() { if (!mRequestHeaderPresent) { return IPCThreadState::kUnsetWorkSource; } const size_t initialPosition = dataPosition(); setDataPosition(mWorkSourceRequestHeaderPosition); uid_t uid = readInt32(); setDataPosition(initialPosition); return uid; } bool Parcel::checkInterface(IBinder* binder) const { return enforceInterface(binder->getInterfaceDescriptor()); Loading @@ -634,6 +670,7 @@ bool Parcel::enforceInterface(const String16& interface, threadState->setStrictModePolicy(strictPolicy); } // WorkSource. updateWorkSourceRequestHeaderPosition(); int32_t workSource = readInt32(); threadState->setCallingWorkSourceUidWithoutPropagation(workSource); // Interface descriptor. Loading Loading @@ -2889,6 +2926,8 @@ void Parcel::initState() mAllowFds = true; mOwner = nullptr; mOpenAshmemSize = 0; mWorkSourceRequestHeaderPosition = 0; mRequestHeaderPresent = false; // racing multiple init leads only to multiple identical write if (gMaxFds == 0) { Loading libs/binder/include/binder/Parcel.h +10 −0 Original line number Diff line number Diff line Loading @@ -395,6 +395,12 @@ public: static size_t getGlobalAllocSize(); static size_t getGlobalAllocCount(); bool replaceCallingWorkSourceUid(uid_t uid); // Returns the work source provided by the caller. This can only be trusted for trusted calling // uid. uid_t readCallingWorkSourceUid(); void readRequestHeaders() const; private: typedef void (*release_func)(Parcel* parcel, const uint8_t* data, size_t dataSize, Loading Loading @@ -429,6 +435,7 @@ private: void initState(); void scanForFds() const; status_t validateReadData(size_t len) const; void updateWorkSourceRequestHeaderPosition() const; template<class T> status_t readAligned(T *pArg) const; Loading Loading @@ -477,6 +484,9 @@ private: mutable size_t mNextObjectHint; mutable bool mObjectsSorted; mutable bool mRequestHeaderPresent; mutable size_t mWorkSourceRequestHeaderPosition; mutable bool mFdsKnown; mutable bool mHasFds; bool mAllowFds; Loading Loading
libs/binder/Parcel.cpp +39 −0 Original line number Diff line number Diff line Loading @@ -599,17 +599,53 @@ bool Parcel::hasFileDescriptors() const return mHasFds; } void Parcel::updateWorkSourceRequestHeaderPosition() const { // Only update the request headers once. We only want to point // to the first headers read/written. if (!mRequestHeaderPresent) { mWorkSourceRequestHeaderPosition = dataPosition(); mRequestHeaderPresent = true; } } // Write RPC headers. (previously just the interface token) status_t Parcel::writeInterfaceToken(const String16& interface) { const IPCThreadState* threadState = IPCThreadState::self(); writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER); updateWorkSourceRequestHeaderPosition(); writeInt32(threadState->shouldPropagateWorkSource() ? threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource); // currently the interface identification token is just its name as a string return writeString16(interface); } bool Parcel::replaceCallingWorkSourceUid(uid_t uid) { if (!mRequestHeaderPresent) { return false; } const size_t initialPosition = dataPosition(); setDataPosition(mWorkSourceRequestHeaderPosition); status_t err = writeInt32(uid); setDataPosition(initialPosition); return err == NO_ERROR; } uid_t Parcel::readCallingWorkSourceUid() { if (!mRequestHeaderPresent) { return IPCThreadState::kUnsetWorkSource; } const size_t initialPosition = dataPosition(); setDataPosition(mWorkSourceRequestHeaderPosition); uid_t uid = readInt32(); setDataPosition(initialPosition); return uid; } bool Parcel::checkInterface(IBinder* binder) const { return enforceInterface(binder->getInterfaceDescriptor()); Loading @@ -634,6 +670,7 @@ bool Parcel::enforceInterface(const String16& interface, threadState->setStrictModePolicy(strictPolicy); } // WorkSource. updateWorkSourceRequestHeaderPosition(); int32_t workSource = readInt32(); threadState->setCallingWorkSourceUidWithoutPropagation(workSource); // Interface descriptor. Loading Loading @@ -2889,6 +2926,8 @@ void Parcel::initState() mAllowFds = true; mOwner = nullptr; mOpenAshmemSize = 0; mWorkSourceRequestHeaderPosition = 0; mRequestHeaderPresent = false; // racing multiple init leads only to multiple identical write if (gMaxFds == 0) { Loading
libs/binder/include/binder/Parcel.h +10 −0 Original line number Diff line number Diff line Loading @@ -395,6 +395,12 @@ public: static size_t getGlobalAllocSize(); static size_t getGlobalAllocCount(); bool replaceCallingWorkSourceUid(uid_t uid); // Returns the work source provided by the caller. This can only be trusted for trusted calling // uid. uid_t readCallingWorkSourceUid(); void readRequestHeaders() const; private: typedef void (*release_func)(Parcel* parcel, const uint8_t* data, size_t dataSize, Loading Loading @@ -429,6 +435,7 @@ private: void initState(); void scanForFds() const; status_t validateReadData(size_t len) const; void updateWorkSourceRequestHeaderPosition() const; template<class T> status_t readAligned(T *pArg) const; Loading Loading @@ -477,6 +484,9 @@ private: mutable size_t mNextObjectHint; mutable bool mObjectsSorted; mutable bool mRequestHeaderPresent; mutable size_t mWorkSourceRequestHeaderPosition; mutable bool mFdsKnown; mutable bool mHasFds; bool mAllowFds; Loading