From f28b295df90da3b9610cc5d6100039e54d95f49a Mon Sep 17 00:00:00 2001 From: Dan Austin Date: Thu, 10 Sep 2015 13:46:02 -0700 Subject: Benign unsigned integer overflow in Parcel The realloc case in continueWrite did not update the gParcelGlobalAllocCount value when an allocation occurred. In addition, there are conditions that could cause the gParcelGlobalAllocCount value to be decremented below 0, resulting in a benign unsigned integer overflow that can cause corrupted values to be returned through system profiling mechanisms. BUG: 23972600 (cherry picked from commit 48fd7b457bb0657253d6012e787f50498b32ae42) Change-Id: I1ad2ac02ab370402481550f6ab8f21fce42455e4 --- libs/binder/Parcel.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'libs/binder/Parcel.cpp') diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 22d7ef36c3..df7a712c73 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -1671,8 +1671,14 @@ void Parcel::freeDataNoInit() if (mData) { LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity); pthread_mutex_lock(&gParcelGlobalAllocSizeLock); - gParcelGlobalAllocSize -= mDataCapacity; - gParcelGlobalAllocCount--; + if (mDataCapacity <= gParcelGlobalAllocSize) { + gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity; + } else { + gParcelGlobalAllocSize = 0; + } + if (gParcelGlobalAllocCount > 0) { + gParcelGlobalAllocCount--; + } pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); free(mData); } @@ -1851,6 +1857,7 @@ status_t Parcel::continueWrite(size_t desired) pthread_mutex_lock(&gParcelGlobalAllocSizeLock); gParcelGlobalAllocSize += desired; gParcelGlobalAllocSize -= mDataCapacity; + gParcelGlobalAllocCount++; pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); mData = data; mDataCapacity = desired; -- cgit v1.2.3-59-g8ed1b From cfe27deac7e0ede89a78b9f03fb4a4159d68be8e Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Wed, 16 Sep 2015 09:49:15 -0700 Subject: handle size_t > java max int size Cleanly abort if we would have returned a value which can't be safely handled by the java APIs. I'm not sure this code is reachable, but adding the check just in case. Bug: 16676699 (cherry picked from commit 3f6b702b5834330ef061f4ed97677ae90a541f23) Change-Id: Iddc16f32cb5d46219a4dcb3548bcfeaade0f9c9e --- libs/binder/Parcel.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'libs/binder/Parcel.cpp') diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index df7a712c73..7e2f0d034e 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -378,13 +378,11 @@ size_t Parcel::dataSize() const size_t Parcel::dataAvail() const { - // TODO: decide what to do about the possibility that this can - // report an available-data size that exceeds a Java int's max - // positive value, causing havoc. Fortunately this will only - // happen if someone constructs a Parcel containing more than two - // gigabytes of data, which on typical phone hardware is simply - // not possible. - return dataSize() - dataPosition(); + size_t result = dataSize() - dataPosition(); + if (result > INT32_MAX) { + abort(); + } + return result; } size_t Parcel::dataPosition() const -- cgit v1.2.3-59-g8ed1b