Snap for 7550844 from 141103d189a92ffe72038f0c7b5dc7b22e91bdd2 to mainline-os-statsd-release Change-Id: I6804839504540d84f92e70e738b278a516ad474d
diff --git a/Android.bp b/Android.bp index ae84ebb..6f2869c 100644 --- a/Android.bp +++ b/Android.bp
@@ -12,10 +12,44 @@ // See the License for the specific language governing permissions and // limitations under the License. +package { + default_applicable_licenses: ["system_libhwbinder_license"], +} + +// Added automatically by a large-scale-change +// http://go/android-license-faq +license { + name: "system_libhwbinder_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + ], + license_text: [ + "NOTICE", + ], +} + +cc_library_headers { + name: "libhwbinder_headers", + export_include_dirs: ["include"], + host_supported: true, + recovery_available: true, + vendor_available: true, + product_available: true, + // TODO(b/153609531): remove when no longer needed. + native_bridge_supported: true, + apex_available: [ + "//apex_available:platform", + "//apex_available:anyapex", + ], + min_sdk_version: "29", +} + cc_defaults { name: "libhwbinder_defaults", - export_include_dirs: ["include"], + header_libs: ["libhwbinder_headers"], + export_header_lib_headers: ["libhwbinder_headers"], sanitize: { misc_undefined: ["integer"], @@ -31,6 +65,7 @@ "ProcessState.cpp", "Static.cpp", "TextOutput.cpp", + "Utils.cpp", ], product_variables: { @@ -60,13 +95,17 @@ } // WARNING: this should no longer be used +// This is automatically removed by bpfix. Once there are no makefiles, fixes can be automatically applied, and this can be removed. cc_library { name: "libhwbinder", vendor_available: true, export_include_dirs: ["include"], - visibility: [":__subpackages__"], + visibility: [ + ":__subpackages__", + "//vendor:__subpackages__", + ], } // Combined into libhidlbase for efficiency. @@ -88,6 +127,7 @@ host_supported: true, recovery_available: true, vendor_available: true, + product_available: true, // TODO(b/153609531): remove when no longer needed. native_bridge_supported: true, apex_available: [
diff --git a/Binder.cpp b/Binder.cpp index 9edd27b..b90639f 100644 --- a/Binder.cpp +++ b/Binder.cpp
@@ -16,15 +16,21 @@ #include <hwbinder/Binder.h> -#include <atomic> -#include <utils/misc.h> +#include <android-base/macros.h> +#include <cutils/android_filesystem_config.h> +#include <cutils/multiuser.h> #include <hwbinder/BpHwBinder.h> #include <hwbinder/IInterface.h> +#include <hwbinder/IPCThreadState.h> #include <hwbinder/Parcel.h> +#include <utils/Log.h> +#include <utils/misc.h> #include <linux/sched.h> #include <stdio.h> +#include <atomic> + namespace android { namespace hardware { @@ -110,6 +116,19 @@ { data.setDataPosition(0); + if (reply != nullptr && (flags & FLAG_CLEAR_BUF)) { + reply->markSensitive(); + } + + // extra comment to try to force running all tests + if (UNLIKELY(code == HIDL_DEBUG_TRANSACTION)) { + uid_t uid = IPCThreadState::self()->getCallingUid(); + if (multiuser_get_app_id(uid) >= AID_APP_START) { + ALOGE("Can not call IBase::debug from apps"); + return PERMISSION_DENIED; + } + } + status_t err = NO_ERROR; switch (code) { default:
diff --git a/BufferedTextOutput.cpp b/BufferedTextOutput.cpp index 5addba4..a0152b1 100644 --- a/BufferedTextOutput.cpp +++ b/BufferedTextOutput.cpp
@@ -16,15 +16,14 @@ #define LOG_TAG "hw-BufferedTextOutput" -#include <hwbinder/BufferedTextOutput.h> #include <hwbinder/Debug.h> #include <cutils/atomic.h> -#include <cutils/threads.h> #include <utils/Log.h> #include <utils/RefBase.h> #include <utils/Vector.h> +#include "BufferedTextOutput.h" #include <hwbinder/Static.h> #include <pthread.h> @@ -94,22 +93,6 @@ static pthread_mutex_t gMutex = PTHREAD_MUTEX_INITIALIZER; -static thread_store_t tls; - -BufferedTextOutput::ThreadState* BufferedTextOutput::getThreadState() -{ - ThreadState* ts = (ThreadState*) thread_store_get( &tls ); - if (ts) return ts; - ts = new ThreadState; - thread_store_set( &tls, ts, threadDestructor ); - return ts; -} - -void BufferedTextOutput::threadDestructor(void *st) -{ - delete ((ThreadState*)st); -} - static volatile int32_t gSequence = 0; static volatile int32_t gFreeBufferIndex = -1; @@ -264,16 +247,14 @@ BufferedTextOutput::BufferState* BufferedTextOutput::getBuffer() const { if ((mFlags&MULTITHREADED) != 0) { - ThreadState* ts = getThreadState(); - if (ts) { - while (ts->states.size() <= (size_t)mIndex) ts->states.add(nullptr); - BufferState* bs = ts->states[mIndex].get(); - if (bs != nullptr && bs->seq == mSeq) return bs; + thread_local ThreadState ts; + while (ts.states.size() <= (size_t)mIndex) ts.states.add(nullptr); + BufferState* bs = ts.states[mIndex].get(); + if (bs != nullptr && bs->seq == mSeq) return bs; - ts->states.editItemAt(mIndex) = new BufferState(mIndex); - bs = ts->states[mIndex].get(); - if (bs != nullptr) return bs; - } + ts.states.editItemAt(mIndex) = new BufferState(mIndex); + bs = ts.states[mIndex].get(); + if (bs != nullptr) return bs; } return mGlobalState;
diff --git a/include/hwbinder/BufferedTextOutput.h b/BufferedTextOutput.h similarity index 93% rename from include/hwbinder/BufferedTextOutput.h rename to BufferedTextOutput.h index 3541659..c8042aa 100644 --- a/include/hwbinder/BufferedTextOutput.h +++ b/BufferedTextOutput.h
@@ -17,7 +17,8 @@ #ifndef ANDROID_HARDWARE_BUFFEREDTEXTOUTPUT_H #define ANDROID_HARDWARE_BUFFEREDTEXTOUTPUT_H -#include <hwbinder/TextOutput.h> +#include "TextOutput.h" + #include <utils/threads.h> #include <sys/uio.h> @@ -49,9 +50,6 @@ struct BufferState; struct ThreadState; - static ThreadState*getThreadState(); - static void threadDestructor(void *st); - BufferState*getBuffer() const; uint32_t mFlags;
diff --git a/IPCThreadState.cpp b/IPCThreadState.cpp index 2f4464d..aa050fc 100644 --- a/IPCThreadState.cpp +++ b/IPCThreadState.cpp
@@ -20,7 +20,6 @@ #include <hwbinder/Binder.h> #include <hwbinder/BpHwBinder.h> -#include <hwbinder/TextOutput.h> #include <android-base/macros.h> #include <utils/CallStack.h> @@ -30,6 +29,7 @@ #include "binder_kernel.h" #include <hwbinder/Static.h> +#include "TextOutput.h" #include <atomic> #include <errno.h> @@ -88,6 +88,8 @@ "BR_DEAD_BINDER", "BR_CLEAR_DEATH_NOTIFICATION_DONE", "BR_FAILED_REPLY", + "BR_FROZEN_REPLY", + "BR_ONEWAY_SPAM_SUSPECT", "BR_TRANSACTION_SEC_CTX", }; @@ -407,7 +409,7 @@ void IPCThreadState::flushCommands() { - if (mProcess->mDriverFD <= 0) + if (mProcess->mDriverFD < 0) return; talkWithDriver(false); // The flush could have caused post-write refcount decrements to have @@ -421,18 +423,6 @@ } } -void IPCThreadState::blockUntilThreadAvailable() -{ - pthread_mutex_lock(&mProcess->mThreadCountLock); - while (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads) { - ALOGW("Waiting for thread to be free. mExecutingThreadsCount=%lu mMaxThreads=%lu\n", - static_cast<unsigned long>(mProcess->mExecutingThreadsCount), - static_cast<unsigned long>(mProcess->mMaxThreads)); - pthread_cond_wait(&mProcess->mThreadCountDecrement, &mProcess->mThreadCountLock); - } - pthread_mutex_unlock(&mProcess->mThreadCountLock); -} - status_t IPCThreadState::getAndExecuteCommand() { status_t result; @@ -472,7 +462,6 @@ } mProcess->mStarvationStartTimeMs = 0; } - pthread_cond_broadcast(&mProcess->mThreadCountDecrement); pthread_mutex_unlock(&mProcess->mThreadCountLock); } @@ -580,7 +569,7 @@ int IPCThreadState::setupPolling(int* fd) { - if (mProcess->mDriverFD <= 0) { + if (mProcess->mDriverFD < 0) { return -EBADF; } @@ -815,6 +804,11 @@ } switch (cmd) { + case BR_ONEWAY_SPAM_SUSPECT: + ALOGE("Process seems to be sending too many oneway calls."); + CallStack::logStack("oneway spamming", CallStack::getCurrent().get(), + ANDROID_LOG_ERROR); + [[fallthrough]]; case BR_TRANSACTION_COMPLETE: if (!reply && !acquireResult) goto finish; break; @@ -889,7 +883,7 @@ status_t IPCThreadState::talkWithDriver(bool doReceive) { - if (mProcess->mDriverFD <= 0) { + if (mProcess->mDriverFD < 0) { return -EBADF; } @@ -946,7 +940,7 @@ #else err = INVALID_OPERATION; #endif - if (mProcess->mDriverFD <= 0) { + if (mProcess->mDriverFD < 0) { err = -EBADF; } IF_LOG_COMMANDS() { @@ -1183,6 +1177,8 @@ << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl; } + constexpr size_t kForwardReplyFlags = TF_CLEAR_BUF; + auto reply_callback = [&] (auto &replyParcel) { if (reply_sent) { // Reply was sent earlier, ignore it. @@ -1192,7 +1188,7 @@ reply_sent = true; if ((tr.flags & TF_ONE_WAY) == 0) { replyParcel.setError(NO_ERROR); - sendReply(replyParcel, 0); + sendReply(replyParcel, (tr.flags & kForwardReplyFlags)); } else { ALOGE("Not sending reply in one-way transaction"); } @@ -1219,7 +1215,7 @@ // Should have been a reply but there wasn't, so there // must have been an error instead. reply.setError(error); - sendReply(reply, 0); + sendReply(reply, (tr.flags & kForwardReplyFlags)); } else { if (error != NO_ERROR) { ALOGE("transact() returned error after sending reply."); @@ -1297,7 +1293,7 @@ if (self) { self->flushCommands(); #if defined(__ANDROID__) - if (self->mProcess->mDriverFD > 0) { + if (self->mProcess->mDriverFD >= 0) { ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0); } #endif
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 --- a/MODULE_LICENSE_APACHE2 +++ /dev/null
diff --git a/Parcel.cpp b/Parcel.cpp index 2c6bf5d..b5648a5 100644 --- a/Parcel.cpp +++ b/Parcel.cpp
@@ -35,10 +35,8 @@ #include <hwbinder/IPCThreadState.h> #include <hwbinder/Parcel.h> #include <hwbinder/ProcessState.h> -#include <hwbinder/TextOutput.h> #include <cutils/ashmem.h> -#include <utils/Debug.h> #include <utils/Log.h> #include <utils/misc.h> #include <utils/String8.h> @@ -46,6 +44,10 @@ #include "binder_kernel.h" #include <hwbinder/Static.h> +#include "TextOutput.h" +#include "Utils.h" + +#include <atomic> #define LOG_REFS(...) //#define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__) @@ -74,9 +76,8 @@ namespace android { namespace hardware { -static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER; -static size_t gParcelGlobalAllocSize = 0; -static size_t gParcelGlobalAllocCount = 0; +static std::atomic<size_t> gParcelGlobalAllocCount; +static std::atomic<size_t> gParcelGlobalAllocSize; static size_t gMaxFds = 0; @@ -261,17 +262,11 @@ } size_t Parcel::getGlobalAllocSize() { - pthread_mutex_lock(&gParcelGlobalAllocSizeLock); - size_t size = gParcelGlobalAllocSize; - pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); - return size; + return gParcelGlobalAllocSize.load(); } size_t Parcel::getGlobalAllocCount() { - pthread_mutex_lock(&gParcelGlobalAllocSizeLock); - size_t count = gParcelGlobalAllocCount; - pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); - return count; + return gParcelGlobalAllocCount.load(); } const uint8_t* Parcel::data() const @@ -361,6 +356,11 @@ return err; } +void Parcel::markSensitive() const +{ + mDeallocZero = true; +} + // Write RPC headers. (previously just the interface token) status_t Parcel::writeInterfaceToken(const char* interface) { @@ -470,7 +470,7 @@ const size_t padded = pad_size(len); - // sanity check for integer overflow + // validate for integer overflow if (mDataPos+padded < mDataPos) { return nullptr; } @@ -889,11 +889,6 @@ parent_buffer_handle, parent_offset); } -void Parcel::remove(size_t /*start*/, size_t /*amt*/) -{ - LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!"); -} - status_t Parcel::read(void* outData, size_t len) const { if (len > INT32_MAX) { @@ -932,7 +927,7 @@ template<class T> status_t Parcel::readAligned(T *pArg) const { - COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); + static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); if ((mDataPos+sizeof(T)) <= mDataSize) { const void* data = mData+mDataPos; @@ -956,7 +951,7 @@ template<class T> status_t Parcel::writeAligned(T val) { - COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); + static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); if ((mDataPos+sizeof(val)) <= mDataCapacity) { restart_write: @@ -1731,16 +1726,11 @@ releaseObjects(); if (mData) { LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity); - pthread_mutex_lock(&gParcelGlobalAllocSizeLock); - if (mDataCapacity <= gParcelGlobalAllocSize) { - gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity; - } else { - gParcelGlobalAllocSize = 0; + gParcelGlobalAllocSize -= mDataCapacity; + gParcelGlobalAllocCount--; + if (mDeallocZero) { + zeroMemory(mData, mDataSize); } - if (gParcelGlobalAllocCount > 0) { - gParcelGlobalAllocCount--; - } - pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); free(mData); } if (mObjects) free(mObjects); @@ -1760,6 +1750,21 @@ return continueWrite(newSize); } +static uint8_t* reallocZeroFree(uint8_t* data, size_t oldCapacity, size_t newCapacity, bool zero) { + if (!zero) { + return (uint8_t*)realloc(data, newCapacity); + } + uint8_t* newData = (uint8_t*)malloc(newCapacity); + if (!newData) { + return nullptr; + } + + memcpy(newData, data, std::min(oldCapacity, newCapacity)); + zeroMemory(data, oldCapacity); + free(data); + return newData; +} + status_t Parcel::restartWrite(size_t desired) { if (desired > INT32_MAX) { @@ -1773,7 +1778,7 @@ return continueWrite(desired); } - uint8_t* data = (uint8_t*)realloc(mData, desired); + uint8_t* data = reallocZeroFree(mData, mDataCapacity, desired, mDeallocZero); if (!data && desired > mDataCapacity) { mError = NO_MEMORY; return NO_MEMORY; @@ -1781,15 +1786,17 @@ releaseObjects(); - if (data) { + if (data || desired == 0) { LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired); - pthread_mutex_lock(&gParcelGlobalAllocSizeLock); - gParcelGlobalAllocSize += desired; - gParcelGlobalAllocSize -= mDataCapacity; + if (mDataCapacity > desired) { + gParcelGlobalAllocSize -= (mDataCapacity - desired); + } else { + gParcelGlobalAllocSize += (desired - mDataCapacity); + } + if (!mData) { gParcelGlobalAllocCount++; } - pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); mData = data; mDataCapacity = desired; } @@ -1877,10 +1884,8 @@ mOwner = nullptr; LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired); - pthread_mutex_lock(&gParcelGlobalAllocSizeLock); gParcelGlobalAllocSize += desired; gParcelGlobalAllocCount++; - pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); mData = data; mObjects = objects; @@ -1923,14 +1928,12 @@ // We own the data, so we can just do a realloc(). if (desired > mDataCapacity) { - uint8_t* data = (uint8_t*)realloc(mData, desired); + uint8_t* data = reallocZeroFree(mData, mDataCapacity, desired, mDeallocZero); if (data) { LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity, desired); - pthread_mutex_lock(&gParcelGlobalAllocSizeLock); gParcelGlobalAllocSize += desired; gParcelGlobalAllocSize -= mDataCapacity; - pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); mData = data; mDataCapacity = desired; } else { @@ -1962,10 +1965,8 @@ } LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired); - pthread_mutex_lock(&gParcelGlobalAllocSizeLock); gParcelGlobalAllocSize += desired; gParcelGlobalAllocCount++; - pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); mData = data; mDataSize = mDataPos = 0; @@ -1994,6 +1995,7 @@ mHasFds = false; mFdsKnown = true; mAllowFds = true; + mDeallocZero = false; mOwner = nullptr; clearCache();
diff --git a/ProcessState.cpp b/ProcessState.cpp index 694efd1..dbd6c87 100644 --- a/ProcessState.cpp +++ b/ProcessState.cpp
@@ -40,6 +40,7 @@ #define DEFAULT_BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2) #define DEFAULT_MAX_BINDER_THREADS 0 +#define DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION 1 // ------------------------------------------------------------------------- @@ -66,83 +67,40 @@ sp<ProcessState> ProcessState::self() { - Mutex::Autolock _l(gProcessMutex); - if (gProcess != nullptr) { - return gProcess; - } - gProcess = new ProcessState(DEFAULT_BINDER_VM_SIZE); - return gProcess; + return init(DEFAULT_BINDER_VM_SIZE, false /*requireMmapSize*/); } sp<ProcessState> ProcessState::selfOrNull() { - Mutex::Autolock _l(gProcessMutex); - return gProcess; + return init(0, false /*requireMmapSize*/); } -sp<ProcessState> ProcessState::initWithMmapSize(size_t mmap_size) { - Mutex::Autolock _l(gProcessMutex); - if (gProcess != nullptr) { - LOG_ALWAYS_FATAL_IF(mmap_size != gProcess->getMmapSize(), - "ProcessState already initialized with a different mmap size."); +sp<ProcessState> ProcessState::initWithMmapSize(size_t mmapSize) { + return init(mmapSize, true /*requireMmapSize*/); +} + +sp<ProcessState> ProcessState::init(size_t mmapSize, bool requireMmapSize) { + [[clang::no_destroy]] static sp<ProcessState> gProcess; + [[clang::no_destroy]] static std::mutex gProcessMutex; + + if (mmapSize == 0) { + std::lock_guard<std::mutex> l(gProcessMutex); return gProcess; } - gProcess = new ProcessState(mmap_size); + [[clang::no_destroy]] static std::once_flag gProcessOnce; + std::call_once(gProcessOnce, [&](){ + std::lock_guard<std::mutex> l(gProcessMutex); + gProcess = new ProcessState(mmapSize); + }); + + if (requireMmapSize) { + LOG_ALWAYS_FATAL_IF(mmapSize != gProcess->getMmapSize(), + "ProcessState already initialized with a different mmap size."); + } + return gProcess; } -void ProcessState::setContextObject(const sp<IBinder>& object) -{ - setContextObject(object, String16("default")); -} - -sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) -{ - return getStrongProxyForHandle(0); -} - -void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name) -{ - AutoMutex _l(mLock); - mContexts.add(name, object); -} - -sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller) -{ - mLock.lock(); - sp<IBinder> object( - mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : nullptr); - mLock.unlock(); - - //printf("Getting context object %s for %p\n", String8(name).string(), caller.get()); - - if (object != nullptr) return object; - - // Don't attempt to retrieve contexts if we manage them - if (mManagesContexts) { - ALOGE("getContextObject(%s) failed, but we manage the contexts!\n", - String8(name).string()); - return nullptr; - } - - IPCThreadState* ipc = IPCThreadState::self(); - { - Parcel data, reply; - // no interface token on this magic transaction - data.writeString16(name); - data.writeStrongBinder(caller); - status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0); - if (result == NO_ERROR) { - object = reply.readStrongBinder(); - } - } - - ipc->flushCommands(); - - if (object != nullptr) setContextObject(object, name); - return object; -} - void ProcessState::startThreadPool() { AutoMutex _l(mLock); @@ -154,41 +112,32 @@ } } -bool ProcessState::isContextManager(void) const +sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) { - return mManagesContexts; + return getStrongProxyForHandle(0); } -bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData) +void ProcessState::becomeContextManager() { - if (!mManagesContexts) { - AutoMutex _l(mLock); - mBinderContextCheckFunc = checkFunc; - mBinderContextUserData = userData; + AutoMutex _l(mLock); - flat_binder_object obj { - .flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX, - }; + flat_binder_object obj { + .flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX, + }; - status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj); + status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj); - // fallback to original method - if (result != 0) { - android_errorWriteLog(0x534e4554, "121035042"); + // 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) { - mBinderContextCheckFunc = nullptr; - mBinderContextUserData = nullptr; - ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno)); - } + int unused = 0; + result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &unused); } - return mManagesContexts; + + if (result == -1) { + ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno)); + } } // Get references to userspace objects held by the kernel binder driver @@ -359,6 +308,9 @@ } status_t ProcessState::setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool) { + LOG_ALWAYS_FATAL_IF(mThreadPoolStarted && maxThreads < mMaxThreads, + "Binder threadpool cannot be shrunk after starting"); + // if the caller joins the pool, then there will be one thread which is impossible. LOG_ALWAYS_FATAL_IF(maxThreads == 0 && callerJoinsPool, "Binder threadpool must have a minimum of one thread if caller joins pool."); @@ -392,6 +344,15 @@ return NO_ERROR; } +status_t ProcessState::enableOnewaySpamDetection(bool enable) { + uint32_t enableDetection = enable ? 1 : 0; + if (ioctl(mDriverFD, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enableDetection) == -1) { + ALOGI("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno)); + return -errno; + } + return NO_ERROR; +} + size_t ProcessState::getMaxThreads() { return mMaxThreads; } @@ -421,27 +382,28 @@ if (result == -1) { ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); } + uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION; + result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable); + if (result == -1) { + ALOGD("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno)); + } } else { ALOGW("Opening '/dev/hwbinder' failed: %s\n", strerror(errno)); } return fd; } -ProcessState::ProcessState(size_t mmap_size) +ProcessState::ProcessState(size_t mmapSize) : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER) - , mThreadCountDecrement(PTHREAD_COND_INITIALIZER) , mExecutingThreadsCount(0) , mMaxThreads(DEFAULT_MAX_BINDER_THREADS) , mStarvationStartTimeMs(0) - , mManagesContexts(false) - , mBinderContextCheckFunc(nullptr) - , mBinderContextUserData(nullptr) , mThreadPoolStarted(false) , mSpawnThreadOnStart(true) , mThreadPoolSeq(1) - , mMmapSize(mmap_size) + , mMmapSize(mmapSize) , mCallRestriction(CallRestriction::NONE) { if (mDriverFD >= 0) {
diff --git a/Static.cpp b/Static.cpp index 2fb12e6..305f5f2 100644 --- a/Static.cpp +++ b/Static.cpp
@@ -19,7 +19,8 @@ #include <hwbinder/Static.h> -#include <hwbinder/BufferedTextOutput.h> +#include "BufferedTextOutput.h" + #include <hwbinder/IPCThreadState.h> #include <utils/Log.h> @@ -49,10 +50,5 @@ static LogTextOutput gLogTextOutput; TextOutput& alog(gLogTextOutput); -// ------------ ProcessState.cpp - -Mutex& gProcessMutex = *new Mutex; -sp<ProcessState> gProcess; - } // namespace hardware } // namespace android
diff --git a/TEST_MAPPING b/TEST_MAPPING index 2bd0463..dfede5a 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING
@@ -2,6 +2,14 @@ "presubmit": [ { "name": "libbinderthreadstateutils_test" + }, + { + "name": "SettingsGoogleUnitTests", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] } ] }
diff --git a/TextOutput.cpp b/TextOutput.cpp index e6e8cb7..5628f5c 100644 --- a/TextOutput.cpp +++ b/TextOutput.cpp
@@ -14,7 +14,7 @@ * limitations under the License. */ -#include <hwbinder/TextOutput.h> +#include "TextOutput.h" #include <hwbinder/Debug.h>
diff --git a/include/hwbinder/TextOutput.h b/TextOutput.h similarity index 100% rename from include/hwbinder/TextOutput.h rename to TextOutput.h
diff --git a/Utils.cpp b/Utils.cpp new file mode 100644 index 0000000..5a29d6b --- /dev/null +++ b/Utils.cpp
@@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Utils.h" + +#include <string.h> + +namespace android::hardware { + +void zeroMemory(uint8_t* data, size_t size) { + memset(data, 0, size); +} + +} // namespace android::hardware
diff --git a/Utils.h b/Utils.h new file mode 100644 index 0000000..07a5e69 --- /dev/null +++ b/Utils.h
@@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cstdint> +#include <stddef.h> + +namespace android::hardware { + +// avoid optimizations +void zeroMemory(uint8_t* data, size_t size); + +} // namespace android::hardware
diff --git a/binder_kernel.h b/binder_kernel.h index fdf5b1e..2695f51 100644 --- a/binder_kernel.h +++ b/binder_kernel.h
@@ -17,15 +17,26 @@ #ifndef ANDROID_HARDWARE_BINDER_KERNEL_H #define ANDROID_HARDWARE_BINDER_KERNEL_H -/** - * Only need this file to fix the __packed__ keyword. - */ - // TODO(b/31559095): bionic on host #ifndef __ANDROID__ #define __packed __attribute__((__packed__)) #endif +#include <sys/ioctl.h> #include <linux/android/binder.h> +#ifndef BR_ONEWAY_SPAM_SUSPECT +// Temporary definition of BR_ONEWAY_SPAM_SUSPECT. For production +// this will come from UAPI binder.h +#define BR_ONEWAY_SPAM_SUSPECT _IO('r', 19) +#endif //BR_ONEWAY_SPAM_SUSPECT + +#ifndef BINDER_ENABLE_ONEWAY_SPAM_DETECTION +/* + * Temporary definitions for oneway spam detection support. For the final version + * these will be defined in the UAPI binder.h file from upstream kernel. + */ +#define BINDER_ENABLE_ONEWAY_SPAM_DETECTION _IOW('b', 16, __u32) +#endif //BINDER_ENABLE_ONEWAY_SPAM_DETECTION + #endif // ANDROID_HARDWARE_BINDER_KERNEL_H
diff --git a/include/hwbinder/Binder.h b/include/hwbinder/Binder.h index 88c155f..d05c6ff 100644 --- a/include/hwbinder/Binder.h +++ b/include/hwbinder/Binder.h
@@ -21,6 +21,10 @@ #include <stdint.h> #include <hwbinder/IBinder.h> +// WARNING: this code is part of libhwbinder, a fork of libbinder. Generally, +// this means that it is only relevant to HIDL. Any AIDL- or libbinder-specific +// code should not try to use these things. + // --------------------------------------------------------------------------- namespace android { namespace hardware { @@ -69,6 +73,9 @@ TransactCallback callback = nullptr); // This must be called before the object is sent to another process. Not thread safe. + // + // If this is called with true, and the kernel supports it, + // IPCThreadState::getCallingSid will return values for remote processes. void setRequestingSid(bool requestSid); int mSchedPolicy; // policy to run transaction from this node at
diff --git a/include/hwbinder/BpHwBinder.h b/include/hwbinder/BpHwBinder.h index a5b2245..36f82e1 100644 --- a/include/hwbinder/BpHwBinder.h +++ b/include/hwbinder/BpHwBinder.h
@@ -21,6 +21,10 @@ #include <utils/KeyedVector.h> #include <utils/threads.h> +// WARNING: this code is part of libhwbinder, a fork of libbinder. Generally, +// this means that it is only relevant to HIDL. Any AIDL- or libbinder-specific +// code should not try to use these things. + // --------------------------------------------------------------------------- namespace android { namespace hardware { @@ -114,7 +118,6 @@ volatile int32_t mObitsSent; Vector<Obituary>* mObituaries; ObjectManager mObjects; - Parcel* mConstantData; mutable String16 mDescriptorCache; };
diff --git a/include/hwbinder/Debug.h b/include/hwbinder/Debug.h index c23618c..cdc5fa0 100644 --- a/include/hwbinder/Debug.h +++ b/include/hwbinder/Debug.h
@@ -21,6 +21,10 @@ #include <sys/cdefs.h> #include <sys/types.h> +// WARNING: this code is part of libhwbinder, a fork of libbinder. Generally, +// this means that it is only relevant to HIDL. Any AIDL- or libbinder-specific +// code should not try to use these things. + namespace android { namespace hardware { // ---------------------------------------------------------------------------
diff --git a/include/hwbinder/IBinder.h b/include/hwbinder/IBinder.h index bc1f733..b5593fe 100644 --- a/include/hwbinder/IBinder.h +++ b/include/hwbinder/IBinder.h
@@ -23,6 +23,10 @@ #include <utils/RefBase.h> #include <utils/String16.h> +// WARNING: this code is part of libhwbinder, a fork of libbinder. Generally, +// this means that it is only relevant to HIDL. Any AIDL- or libbinder-specific +// code should not try to use these things. + // --------------------------------------------------------------------------- namespace android { namespace hardware { @@ -45,8 +49,40 @@ using TransactCallback = std::function<void(Parcel&)>; enum { + /* It is very important that these values NEVER change. These values + * must remain unchanged over the lifetime of android. This is + * because the framework on a device will be updated independently of + * the hals on a device. If the hals are compiled with one set of + * transaction values, and the framework with another, then the + * interface between them will be destroyed, and the device will not + * work. + */ + /////////////////// User defined transactions + FIRST_CALL_TRANSACTION = 0x00000001, + LAST_CALL_TRANSACTION = 0x0effffff, + /////////////////// HIDL reserved +#define B_PACK_CHARS_USER(c1, c2, c3, c4) \ + ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) + FIRST_HIDL_TRANSACTION = 0x0f000000, + HIDL_PING_TRANSACTION = B_PACK_CHARS_USER(0x0f, 'P', 'N', 'G'), + HIDL_DESCRIPTOR_CHAIN_TRANSACTION = B_PACK_CHARS_USER(0x0f, 'C', 'H', 'N'), + HIDL_GET_DESCRIPTOR_TRANSACTION = B_PACK_CHARS_USER(0x0f, 'D', 'S', 'C'), + HIDL_SYSPROPS_CHANGED_TRANSACTION = B_PACK_CHARS_USER(0x0f, 'S', 'Y', 'S'), + HIDL_LINK_TO_DEATH_TRANSACTION = B_PACK_CHARS_USER(0x0f, 'L', 'T', 'D'), + HIDL_UNLINK_TO_DEATH_TRANSACTION = B_PACK_CHARS_USER(0x0f, 'U', 'T', 'D'), + HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION = B_PACK_CHARS_USER(0x0f, 'I', 'N', 'T'), + HIDL_GET_REF_INFO_TRANSACTION = B_PACK_CHARS_USER(0x0f, 'R', 'E', 'F'), + HIDL_DEBUG_TRANSACTION = B_PACK_CHARS_USER(0x0f, 'D', 'B', 'G'), + HIDL_HASH_CHAIN_TRANSACTION = B_PACK_CHARS_USER(0x0f, 'H', 'S', 'H'), +#undef B_PACK_CHARS_USER + LAST_HIDL_TRANSACTION = 0x0fffffff, + // Corresponds to TF_ONE_WAY -- an asynchronous call. - FLAG_ONEWAY = 0x00000001 + FLAG_ONEWAY = 0x00000001, + + // Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call + // is made + FLAG_CLEAR_BUF = 0x00000020, }; IBinder();
diff --git a/include/hwbinder/IInterface.h b/include/hwbinder/IInterface.h index 7e13957..7fec75f 100644 --- a/include/hwbinder/IInterface.h +++ b/include/hwbinder/IInterface.h
@@ -20,6 +20,10 @@ #include <hwbinder/Binder.h> +// WARNING: this code is part of libhwbinder, a fork of libbinder. Generally, +// this means that it is only relevant to HIDL. Any AIDL- or libbinder-specific +// code should not try to use these things. + namespace android { namespace hardware { // ----------------------------------------------------------------------
diff --git a/include/hwbinder/IPCThreadState.h b/include/hwbinder/IPCThreadState.h index ca99591..f4c9f9d 100644 --- a/include/hwbinder/IPCThreadState.h +++ b/include/hwbinder/IPCThreadState.h
@@ -24,6 +24,10 @@ #include <functional> +// WARNING: this code is part of libhwbinder, a fork of libbinder. Generally, +// this means that it is only relevant to HIDL. Any AIDL- or libbinder-specific +// code should not try to use these things. + #if defined(_WIN32) typedef int uid_t; #endif @@ -87,10 +91,6 @@ static void shutdown(); - // Call blocks until the number of executing binder threads is less than - // the maximum number of binder threads threads allowed for this process. - void blockUntilThreadAvailable(); - // Service manager registration void setTheContextObject(sp<BHwBinder> obj);
diff --git a/include/hwbinder/Parcel.h b/include/hwbinder/Parcel.h index d3bdfe6..4822fa0 100644 --- a/include/hwbinder/Parcel.h +++ b/include/hwbinder/Parcel.h
@@ -27,6 +27,10 @@ #include <hwbinder/IInterface.h> +// WARNING: this code is part of libhwbinder, a fork of libbinder. Generally, +// this means that it is only relevant to HIDL. Any AIDL- or libbinder-specific +// code should not try to use these things. + struct binder_buffer_object; struct flat_binder_object; @@ -66,6 +70,13 @@ status_t setData(const uint8_t* buffer, size_t len); + // Zeros data when reallocating. Other mitigations may be added + // in the future. + // + // WARNING: some read methods may make additional copies of data. + // In order to verify this, heap dumps should be used. + void markSensitive() const; + // Writes the RPC header. status_t writeInterfaceToken(const char* interface); @@ -118,8 +129,6 @@ size_t parent_offset = 0); status_t writeNativeHandleNoDup(const native_handle* handle); - void remove(size_t start, size_t amt); - status_t read(void* outData, size_t len) const; const void* readInplace(size_t len) const; status_t readInt8(int8_t *pArg) const; @@ -294,6 +303,10 @@ mutable bool mHasFds; bool mAllowFds; + // if this parcelable is involved in a secure transaction, force the + // data to be overridden with zero when deallocated + mutable bool mDeallocZero; + release_func mOwner; void* mOwnerCookie; };
diff --git a/include/hwbinder/ProcessState.h b/include/hwbinder/ProcessState.h index 91337d8..56ac846 100644 --- a/include/hwbinder/ProcessState.h +++ b/include/hwbinder/ProcessState.h
@@ -26,6 +26,10 @@ #include <pthread.h> +// WARNING: this code is part of libhwbinder, a fork of libbinder. Generally, +// this means that it is only relevant to HIDL. Any AIDL- or libbinder-specific +// code should not try to use these things. + // --------------------------------------------------------------------------- namespace android { namespace hardware { @@ -38,26 +42,14 @@ static sp<ProcessState> self(); static sp<ProcessState> selfOrNull(); // Note: don't call self() or selfOrNull() before initWithMmapSize() + // with '0' as an argument, this is the same as selfOrNull static sp<ProcessState> initWithMmapSize(size_t mmapSize); // size in bytes - void setContextObject(const sp<IBinder>& object); - sp<IBinder> getContextObject(const sp<IBinder>& caller); - - void setContextObject(const sp<IBinder>& object, - const String16& name); - sp<IBinder> getContextObject(const String16& name, - const sp<IBinder>& caller); - void startThreadPool(); - typedef bool (*context_check_func)(const String16& name, - const sp<IBinder>& caller, - void* userData); - - bool isContextManager(void) const; - bool becomeContextManager( - context_check_func checkFunc, - void* userData); + sp<IBinder> getContextObject(const sp<IBinder>& /*caller*/); + // only call once, without creating a pool + void becomeContextManager(); sp<IBinder> getStrongProxyForHandle(int32_t handle); wp<IBinder> getWeakProxyForHandle(int32_t handle); @@ -66,6 +58,7 @@ void spawnPooledThread(bool isMain); status_t setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool); + status_t enableOnewaySpamDetection(bool enable); size_t getMaxThreads(); void giveThreadPoolName(); @@ -91,8 +84,10 @@ void setCallRestriction(CallRestriction restriction); private: + static sp<ProcessState> init(size_t mmapSize, bool requireMmapSize); + friend class IPCThreadState; - explicit ProcessState(size_t mmap_size); + explicit ProcessState(size_t mmapSize); ~ProcessState(); ProcessState(const ProcessState& o); @@ -111,7 +106,6 @@ // Protects thread count variable below. pthread_mutex_t mThreadCountLock; - pthread_cond_t mThreadCountDecrement; // Number of binder threads current executing a command. size_t mExecutingThreadsCount; // Maximum number for binder threads allowed for this process. @@ -123,14 +117,6 @@ Vector<handle_entry>mHandleToObject; - bool mManagesContexts; - context_check_func mBinderContextCheckFunc; - void* mBinderContextUserData; - - KeyedVector<String16, sp<IBinder> > - mContexts; - - String8 mRootDir; bool mThreadPoolStarted; bool mSpawnThreadOnStart;
diff --git a/include/hwbinder/Static.h b/include/hwbinder/Static.h index 4b84c89..75bbcea 100644 --- a/include/hwbinder/Static.h +++ b/include/hwbinder/Static.h
@@ -22,15 +22,15 @@ #include <hwbinder/IBinder.h> #include <hwbinder/ProcessState.h> +// WARNING: this code is part of libhwbinder, a fork of libbinder. Generally, +// this means that it is only relevant to HIDL. Any AIDL- or libbinder-specific +// code should not try to use these things. + namespace android { namespace hardware { // For TextStream.cpp extern Vector<int32_t> gTextBuffers; -// For ProcessState.cpp -extern Mutex& gProcessMutex; -extern sp<ProcessState> gProcess; - } // namespace hardware } // namespace android
diff --git a/vts/performance/Android.bp b/vts/performance/Android.bp index 35f61d5..9508c83 100644 --- a/vts/performance/Android.bp +++ b/vts/performance/Android.bp
@@ -14,6 +14,14 @@ // limitations under the License. // +package { + // http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // the below license kinds from "system_libhwbinder_license": + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["system_libhwbinder_license"], +} + cc_defaults { name: "libhwbinder_test_defaults", defaults: ["hwbinder_benchmark_pgo",],
diff --git a/vts/performance/Benchmark.cpp b/vts/performance/Benchmark.cpp index e7d75cd..f995ec7 100644 --- a/vts/performance/Benchmark.cpp +++ b/vts/performance/Benchmark.cpp
@@ -106,7 +106,7 @@ } int main(int argc, char* argv []) { - setenv("TREBLE_TESTING_OVERRIDE", "true", true); + android::hardware::details::setTrebleTestingOverride(true); enum HwBinderMode { kBinderize = 0,
diff --git a/vts/performance/Benchmark_throughput.cpp b/vts/performance/Benchmark_throughput.cpp index 42c1c6f..d197d2d 100644 --- a/vts/performance/Benchmark_throughput.cpp +++ b/vts/performance/Benchmark_throughput.cpp
@@ -28,6 +28,7 @@ #include <android/hardware/tests/libhwbinder/1.0/IBenchmark.h> #include <hidl/HidlSupport.h> +#include <hidl/ServiceManagement.h> using namespace std; using namespace android; @@ -297,7 +298,7 @@ } int main(int argc, char *argv[]) { - setenv("TREBLE_TESTING_OVERRIDE", "true", true); + android::hardware::details::setTrebleTestingOverride(true); enum HwBinderMode { kBinderize = 0,
diff --git a/vts/performance/Latency.cpp b/vts/performance/Latency.cpp index a4c0751..13a93ad 100644 --- a/vts/performance/Latency.cpp +++ b/vts/performance/Latency.cpp
@@ -282,7 +282,7 @@ // atrace --async_start -c sched idle workq binder_driver freq && \ // libhwbinder_latency -i 10000 -pair 4 -trace int main(int argc, char** argv) { - setenv("TREBLE_TESTING_OVERRIDE", "true", true); + android::hardware::details::setTrebleTestingOverride(true); vector<Pipe> client_pipes; vector<Pipe> service_pipes;