diff options
| author | 2019-04-03 11:00:11 -0700 | |
|---|---|---|
| committer | 2019-04-03 11:00:11 -0700 | |
| commit | 94c0cd9393c22759d3a375cf222d24e90bdcd8a9 (patch) | |
| tree | 253d3e2b9a72ffaf68e225cad52421ca2e2a49a4 | |
| parent | b7350658a584317b8ff4830b0e86c814674a4e4f (diff) | |
| parent | 06c65b864b3f7c2869f8d5b92cc53b1626c0b39a (diff) | |
Merge changes from topic "kernel_v503_2"
am: 06c65b864b
Change-Id: I920dbe69867a81fe8a41aaeb2fe450892abd74ee
| -rw-r--r-- | libs/binder/Binder.cpp | 62 | ||||
| -rw-r--r-- | libs/binder/IPCThreadState.cpp | 34 | ||||
| -rw-r--r-- | libs/binder/Parcel.cpp | 5 | ||||
| -rw-r--r-- | libs/binder/ProcessState.cpp | 16 | ||||
| -rw-r--r-- | libs/binder/include/binder/Binder.h | 6 | ||||
| -rw-r--r-- | libs/binder/include/binder/IPCThreadState.h | 7 | ||||
| -rw-r--r-- | libs/binder/include/binder/Parcel.h | 3 |
7 files changed, 110 insertions, 23 deletions
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp index f6cc3afc97..96ee29556c 100644 --- a/libs/binder/Binder.cpp +++ b/libs/binder/Binder.cpp @@ -86,6 +86,10 @@ status_t IBinder::shellCommand(const sp<IBinder>& target, int in, int out, int e class BBinder::Extras { public: + // unlocked objects + bool mRequestingSid = false; + + // for below objects Mutex mLock; BpBinder::ObjectManager mObjects; }; @@ -163,19 +167,8 @@ void BBinder::attachObject( const void* objectID, void* object, void* cleanupCookie, object_cleanup_func func) { - Extras* e = mExtras.load(std::memory_order_acquire); - - if (!e) { - e = new Extras; - Extras* expected = nullptr; - if (!mExtras.compare_exchange_strong(expected, e, - std::memory_order_release, - std::memory_order_acquire)) { - delete e; - e = expected; // Filled in by CAS - } - if (e == nullptr) return; // out of memory - } + Extras* e = getOrCreateExtras(); + if (!e) return; // out of memory AutoMutex _l(e->mLock); e->mObjects.attach(objectID, object, cleanupCookie, func); @@ -204,6 +197,30 @@ BBinder* BBinder::localBinder() return this; } +bool BBinder::isRequestingSid() +{ + Extras* e = mExtras.load(std::memory_order_acquire); + + return e && e->mRequestingSid; +} + +void BBinder::setRequestingSid(bool requestingSid) +{ + Extras* e = mExtras.load(std::memory_order_acquire); + + if (!e) { + // default is false. Most things don't need sids, so avoiding allocations when possible. + if (!requestingSid) { + return; + } + + e = getOrCreateExtras(); + if (!e) return; // out of memory + } + + e->mRequestingSid = true; +} + BBinder::~BBinder() { Extras* e = mExtras.load(std::memory_order_relaxed); @@ -267,6 +284,25 @@ status_t BBinder::onTransact( } } +BBinder::Extras* BBinder::getOrCreateExtras() +{ + Extras* e = mExtras.load(std::memory_order_acquire); + + if (!e) { + e = new Extras; + Extras* expected = nullptr; + if (!mExtras.compare_exchange_strong(expected, e, + std::memory_order_release, + std::memory_order_acquire)) { + delete e; + e = expected; // Filled in by CAS + } + if (e == nullptr) return nullptr; // out of memory + } + + return e; +} + // --------------------------------------------------------------------------- enum { diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index 22f6f54e28..e60f03ae54 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -88,7 +88,8 @@ static const char *kReturnStrings[] = { "BR_FINISHED", "BR_DEAD_BINDER", "BR_CLEAR_DEATH_NOTIFICATION_DONE", - "BR_FAILED_REPLY" + "BR_FAILED_REPLY", + "BR_TRANSACTION_SEC_CTX", }; static const char *kCommandStrings[] = { @@ -363,6 +364,11 @@ pid_t IPCThreadState::getCallingPid() const return mCallingPid; } +const char* IPCThreadState::getCallingSid() const +{ + return mCallingSid; +} + uid_t IPCThreadState::getCallingUid() const { return mCallingUid; @@ -370,6 +376,7 @@ uid_t IPCThreadState::getCallingUid() const int64_t IPCThreadState::clearCallingIdentity() { + // ignore mCallingSid for legacy reasons int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid; clearCaller(); return token; @@ -398,12 +405,14 @@ int32_t IPCThreadState::getLastTransactionBinderFlags() const void IPCThreadState::restoreCallingIdentity(int64_t token) { mCallingUid = (int)(token>>32); + mCallingSid = nullptr; // not enough data to restore mCallingPid = (int)token; } void IPCThreadState::clearCaller() { mCallingPid = getpid(); + mCallingSid = nullptr; // expensive to lookup mCallingUid = getuid(); } @@ -1089,10 +1098,19 @@ status_t IPCThreadState::executeCommand(int32_t cmd) } break; + case BR_TRANSACTION_SEC_CTX: case BR_TRANSACTION: { - binder_transaction_data tr; - result = mIn.read(&tr, sizeof(tr)); + binder_transaction_data_secctx tr_secctx; + binder_transaction_data& tr = tr_secctx.transaction_data; + + if (cmd == (int) BR_TRANSACTION_SEC_CTX) { + result = mIn.read(&tr_secctx, sizeof(tr_secctx)); + } else { + result = mIn.read(&tr, sizeof(tr)); + tr_secctx.secctx = 0; + } + ALOG_ASSERT(result == NO_ERROR, "Not enough command data for brTRANSACTION"); if (result != NO_ERROR) break; @@ -1108,15 +1126,18 @@ status_t IPCThreadState::executeCommand(int32_t cmd) tr.offsets_size/sizeof(binder_size_t), freeBuffer, this); const pid_t origPid = mCallingPid; + const char* origSid = mCallingSid; const uid_t origUid = mCallingUid; const int32_t origStrictModePolicy = mStrictModePolicy; const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags; mCallingPid = tr.sender_pid; + mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx); mCallingUid = tr.sender_euid; mLastTransactionBinderFlags = tr.flags; - //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid); + // ALOGI(">>>> TRANSACT from pid %d sid %s uid %d\n", mCallingPid, + // (mCallingSid ? mCallingSid : "<N/A>"), mCallingUid); Parcel reply; status_t error; @@ -1148,8 +1169,8 @@ status_t IPCThreadState::executeCommand(int32_t cmd) } mIPCThreadStateBase->popCurrentState(); - //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n", - // mCallingPid, origPid, origUid); + //ALOGI("<<<< TRANSACT from pid %d restore pid %d sid %s uid %d\n", + // mCallingPid, origPid, (origSid ? origSid : "<N/A>"), origUid); if ((tr.flags & TF_ONE_WAY) == 0) { LOG_ONEWAY("Sending reply to %d!", mCallingPid); @@ -1160,6 +1181,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) } mCallingPid = origPid; + mCallingSid = origSid; mCallingUid = origUid; mStrictModePolicy = origStrictModePolicy; mLastTransactionBinderFlags = origTransactionBinderFlags; diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index ca6a97debb..9f8c40876e 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -215,7 +215,7 @@ status_t flatten_binder(const sp<ProcessState>& /*proc*/, } if (binder != nullptr) { - IBinder *local = binder->localBinder(); + BBinder *local = binder->localBinder(); if (!local) { BpBinder *proxy = binder->remoteBinder(); if (proxy == nullptr) { @@ -227,6 +227,9 @@ status_t flatten_binder(const sp<ProcessState>& /*proc*/, obj.handle = handle; obj.cookie = 0; } else { + if (local->isRequestingSid()) { + obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX; + } obj.hdr.type = BINDER_TYPE_BINDER; obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); obj.cookie = reinterpret_cast<uintptr_t>(local); diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index 1c74e7b077..63f49ddba7 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -181,8 +181,20 @@ bool ProcessState::becomeContextManager(context_check_func checkFunc, void* user mBinderContextCheckFunc = checkFunc; mBinderContextUserData = userData; - int dummy = 0; - status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy); + flat_binder_object obj { + .flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX, + }; + + status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj); + + // fallback to original method + if (result != 0) { + android_errorWriteLog(0x534e4554, "121035042"); + + int dummy = 0; + result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy); + } + if (result == 0) { mManagesContexts = true; } else if (result == -1) { diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h index c251468bdb..cf3ef84caa 100644 --- a/libs/binder/include/binder/Binder.h +++ b/libs/binder/include/binder/Binder.h @@ -60,6 +60,10 @@ public: virtual BBinder* localBinder(); + bool isRequestingSid(); + // This must be called before the object is sent to another process. Not thread safe. + void setRequestingSid(bool requestSid); + protected: virtual ~BBinder(); @@ -75,6 +79,8 @@ private: class Extras; + Extras* getOrCreateExtras(); + std::atomic<Extras*> mExtras; void* mReserved0; }; diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h index 745f6182f6..a20ef7c410 100644 --- a/libs/binder/include/binder/IPCThreadState.h +++ b/libs/binder/include/binder/IPCThreadState.h @@ -42,6 +42,11 @@ public: status_t clearLastError(); pid_t getCallingPid() const; + // nullptr if unavailable + // + // this can't be restored once it's cleared, and it does not return the + // context of the current process when not in a binder call. + const char* getCallingSid() const; uid_t getCallingUid() const; void setStrictModePolicy(int32_t policy); @@ -51,6 +56,7 @@ public: int32_t getLastTransactionBinderFlags() const; int64_t clearCallingIdentity(); + // Restores PID/UID (not SID) void restoreCallingIdentity(int64_t token); int setupPolling(int* fd); @@ -154,6 +160,7 @@ private: Parcel mOut; status_t mLastError; pid_t mCallingPid; + const char* mCallingSid; uid_t mCallingUid; int32_t mStrictModePolicy; int32_t mLastTransactionBinderFlags; diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index c9c273acd8..f6560a7f09 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -20,6 +20,8 @@ #include <string> #include <vector> +#include <linux/android/binder.h> + #include <android-base/unique_fd.h> #include <cutils/native_handle.h> #include <utils/Errors.h> @@ -27,7 +29,6 @@ #include <utils/String16.h> #include <utils/Vector.h> #include <utils/Flattenable.h> -#include <linux/android/binder.h> #include <binder/IInterface.h> #include <binder/Parcelable.h> |