InputMethodSubtypeArray: prevent negative count injection

Fixes an issue where negative counts could be injected
via the Parcel constructor. The writeToParcel method
in that case would write data that a subsequent read would
not consume.

Fixes: 277916797
Test: atest InputMethodSubtypeArrayTest
Change-Id: I7e881d82415051179c59bf5df97f8ba0a41e693e
This commit is contained in:
Adrian Roos
2023-06-02 13:57:57 +00:00
parent 485a81164f
commit bc2fbfc0b7
2 changed files with 40 additions and 0 deletions

View File

@@ -17,6 +17,7 @@
package android.view.inputmethod;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.BadParcelableException;
import android.os.Parcel;
import android.util.Slog;
@@ -69,6 +70,9 @@ public class InputMethodSubtypeArray {
*/
public InputMethodSubtypeArray(final Parcel source) {
mCount = source.readInt();
if (mCount < 0) {
throw new BadParcelableException("mCount must be non-negative.");
}
if (mCount > 0) {
mDecompressedSize = source.readInt();
mCompressedData = source.createByteArray();

View File

@@ -16,9 +16,14 @@
package android.view.inputmethod;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals;
import android.os.BadParcelableException;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
import androidx.test.filters.SmallTest;
@@ -31,6 +36,7 @@ import java.util.ArrayList;
@SmallTest
@RunWith(AndroidJUnit4.class)
@Presubmit
public class InputMethodSubtypeArrayTest {
@Test
@@ -59,6 +65,36 @@ public class InputMethodSubtypeArrayTest {
assertEquals(clonedArray.get(2), clonedClonedArray.get(2));
}
@Test
public void testNegativeCount() throws Exception {
InputMethodSubtypeArray negativeCountArray;
try {
// Construct a InputMethodSubtypeArray with: mCount = -1
var p = Parcel.obtain();
p.writeInt(-1);
p.setDataPosition(0);
negativeCountArray = new InputMethodSubtypeArray(p);
} catch (BadParcelableException e) {
// Expected with fix: Prevent negative mCount
assertThat(e).hasMessageThat().contains("mCount");
return;
}
assertWithMessage("Test set-up failed")
.that(negativeCountArray.getCount()).isEqualTo(-1);
var p = Parcel.obtain();
// Writes: int (mCount), int (mDecompressedSize), byte[] (mCompressedData)
negativeCountArray.writeToParcel(p);
p.setDataPosition(0);
// Reads: int (mCount)
// Leaves: int (mDecompressedSize), byte[] (mCompressedData)
new InputMethodSubtypeArray(p);
assertWithMessage("Didn't read all data that was previously written")
.that(p.dataPosition())
.isEqualTo(p.dataSize());
}
InputMethodSubtypeArray cloneViaParcel(final InputMethodSubtypeArray original) {
Parcel parcel = null;
try {