Merge "Assert type of 16-bit value in MultiStateCounter parcelables" into udc-dev am: a07255e755 am: 004f1f8d17

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23698712

Change-Id: Ieab7fb01cc769ef79eb4bcc2ab84ed8a6f5f0dfd
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Dmitri Plotnikov
2023-08-12 02:08:12 +00:00
committed by Automerger Merge Worker
4 changed files with 97 additions and 6 deletions

View File

@@ -127,16 +127,17 @@ static void native_writeToParcel(JNIEnv *env, jobject self, jlong nativePtr, job
}
}
static void throwReadRE(JNIEnv *env, binder_status_t status) {
static void throwReadException(JNIEnv *env, binder_status_t status) {
ALOGE("Could not read LongArrayMultiStateCounter from Parcel, status = %d", status);
jniThrowRuntimeException(env, "Could not read LongArrayMultiStateCounter from Parcel");
jniThrowException(env, "android.os.BadParcelableException",
"Could not read LongArrayMultiStateCounter from Parcel");
}
#define THROW_AND_RETURN_ON_READ_ERROR(expr) \
{ \
binder_status_t status = expr; \
if (status != STATUS_OK) { \
throwReadRE(env, status); \
throwReadException(env, status); \
return 0L; \
} \
}
@@ -147,6 +148,11 @@ static jlong native_initFromParcel(JNIEnv *env, jclass theClass, jobject jParcel
int32_t stateCount;
THROW_AND_RETURN_ON_READ_ERROR(AParcel_readInt32(parcel.get(), &stateCount));
if (stateCount < 0 || stateCount > 0xEFFF) {
throwReadException(env, STATUS_INVALID_OPERATION);
return 0L;
}
int32_t arrayLength;
THROW_AND_RETURN_ON_READ_ERROR(AParcel_readInt32(parcel.get(), &arrayLength));

View File

@@ -131,16 +131,17 @@ static void native_writeToParcel(JNIEnv *env, jobject self, jlong nativePtr, job
}
}
static void throwReadRE(JNIEnv *env, binder_status_t status) {
static void throwReadException(JNIEnv *env, binder_status_t status) {
ALOGE("Could not read LongMultiStateCounter from Parcel, status = %d", status);
jniThrowRuntimeException(env, "Could not read LongMultiStateCounter from Parcel");
jniThrowException(env, "android.os.BadParcelableException",
"Could not read LongMultiStateCounter from Parcel");
}
#define THROW_AND_RETURN_ON_READ_ERROR(expr) \
{ \
binder_status_t status = expr; \
if (status != STATUS_OK) { \
throwReadRE(env, status); \
throwReadException(env, status); \
return 0L; \
} \
}
@@ -151,6 +152,11 @@ static jlong native_initFromParcel(JNIEnv *env, jclass theClass, jobject jParcel
int32_t stateCount;
THROW_AND_RETURN_ON_READ_ERROR(AParcel_readInt32(parcel.get(), &stateCount));
if (stateCount < 0 || stateCount > 0xEFFF) {
throwReadException(env, STATUS_INVALID_OPERATION);
return 0L;
}
auto counter = std::make_unique<battery::LongMultiStateCounter>(stateCount, 0);
for (battery::state_t state = 0; state < stateCount; state++) {

View File

@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import android.os.BadParcelableException;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
@@ -162,6 +163,45 @@ public class LongArrayMultiStateCounterTest {
() -> LongArrayMultiStateCounter.CREATOR.createFromParcel(parcel));
}
@Test
public void createFromBadBundle() {
Parcel data = Parcel.obtain();
int bundleLenPos = data.dataPosition();
data.writeInt(0);
data.writeInt(0x4C444E42); // BaseBundle.BUNDLE_MAGIC
int bundleStart = data.dataPosition();
data.writeInt(1);
data.writeString("key");
data.writeInt(4);
int lazyValueLenPos = data.dataPosition();
data.writeInt(0);
int lazyValueStart = data.dataPosition();
data.writeString("com.android.internal.os.LongArrayMultiStateCounter");
// Invalid int16 value
data.writeInt(0x10000); // stateCount
data.writeInt(10); // arrayLength
for (int i = 0; i < 0x10000; ++i) {
data.writeLong(0);
}
backPatchLength(data, lazyValueLenPos, lazyValueStart);
backPatchLength(data, bundleLenPos, bundleStart);
data.setDataPosition(0);
assertThrows(BadParcelableException.class,
() -> data.readBundle().getParcelable("key", LongArrayMultiStateCounter.class));
}
private static void backPatchLength(Parcel parcel, int lengthPos, int startPos) {
int endPos = parcel.dataPosition();
parcel.setDataPosition(lengthPos);
parcel.writeInt(endPos - startPos);
parcel.setDataPosition(endPos);
}
@Test
public void combineValues() {
long[] values = new long[] {0, 1, 2, 3, 42};

View File

@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import android.os.BadParcelableException;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
@@ -210,4 +211,42 @@ public class LongMultiStateCounterTest {
assertThrows(RuntimeException.class,
() -> LongMultiStateCounter.CREATOR.createFromParcel(parcel));
}
@Test
public void createFromBadBundle() {
Parcel data = Parcel.obtain();
int bundleLenPos = data.dataPosition();
data.writeInt(0);
data.writeInt(0x4C444E42); // BaseBundle.BUNDLE_MAGIC
int bundleStart = data.dataPosition();
data.writeInt(1);
data.writeString("key");
data.writeInt(4);
int lazyValueLenPos = data.dataPosition();
data.writeInt(0);
int lazyValueStart = data.dataPosition();
data.writeString("com.android.internal.os.LongMultiStateCounter");
// Invalid int16 value
data.writeInt(0x10000); // stateCount
for (int i = 0; i < 0x10000; ++i) {
data.writeLong(0);
}
backPatchLength(data, lazyValueLenPos, lazyValueStart);
backPatchLength(data, bundleLenPos, bundleStart);
data.setDataPosition(0);
assertThrows(BadParcelableException.class,
() -> data.readBundle().getParcelable("key", LongMultiStateCounter.class));
}
private static void backPatchLength(Parcel parcel, int lengthPos, int startPos) {
int endPos = parcel.dataPosition();
parcel.setDataPosition(lengthPos);
parcel.writeInt(endPos - startPos);
parcel.setDataPosition(endPos);
}
}