From d1df8f4df2714a27da58c8677f2b2cf0224c5d4a Mon Sep 17 00:00:00 2001 From: Jeongsik Mun Date: Wed, 10 Feb 2021 16:59:21 +0900 Subject: [PATCH] Fix a bug in RuleIndexingController where StackOverflowError occurs A map with a single entry passed into searchKeysRangeContainingKey() will lead to StackOverflowError due to infinite recursion. There is a possibility that it could happen if the indexing file is corrupted and has a few bytes. This fix adds a termination condition of recursion to break out and a check to make sure the indexing file is not corrupted. Test: atest FrameworksServicesTests:RuleIndexingControllerTest Bug: 178185562 Change-Id: Ic79584d7fabd56ae298d452060ce8d588bc02d21 --- .../parser/RuleIndexingController.java | 6 ++++++ .../parser/RuleIndexingControllerTest.java | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/services/core/java/com/android/server/integrity/parser/RuleIndexingController.java b/services/core/java/com/android/server/integrity/parser/RuleIndexingController.java index 60e8cce55730f..348a03be7317a 100644 --- a/services/core/java/com/android/server/integrity/parser/RuleIndexingController.java +++ b/services/core/java/com/android/server/integrity/parser/RuleIndexingController.java @@ -92,6 +92,9 @@ public class RuleIndexingController { break; } } + if (keyToIndexMap.size() < 2) { + throw new IllegalStateException("Indexing file is corrupt."); + } return keyToIndexMap; } @@ -106,6 +109,9 @@ public class RuleIndexingController { private static List searchKeysRangeContainingKey( List sortedKeyList, String key, int startIndex, int endIndex) { + if (endIndex <= startIndex) { + throw new IllegalStateException("Indexing file is corrupt."); + } if (endIndex - startIndex == 1) { return Arrays.asList(sortedKeyList.get(startIndex), sortedKeyList.get(endIndex)); } diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleIndexingControllerTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleIndexingControllerTest.java index 0784b7a7d519d..415e63537aafa 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleIndexingControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleIndexingControllerTest.java @@ -25,6 +25,8 @@ import static com.android.server.integrity.utils.TestUtils.getValueBits; import static com.google.common.truth.Truth.assertThat; +import static org.testng.Assert.assertThrows; + import android.content.integrity.AppInstallMetadata; import org.junit.Test; @@ -163,6 +165,22 @@ public class RuleIndexingControllerTest { new RuleIndexRange(900, 945)); } + @Test + public void verifyIndexingFileIsCorrupt() throws IOException { + byte[] stringBytes = + getBytes( + getKeyValueString(START_INDEXING_KEY, 100) + + getKeyValueString("ccc", 200) + + getKeyValueString(END_INDEXING_KEY, 300) + + getKeyValueString(END_INDEXING_KEY, 900)); + ByteBuffer rule = ByteBuffer.allocate(stringBytes.length); + rule.put(stringBytes); + InputStream inputStream = new ByteArrayInputStream(rule.array()); + + assertThrows(IllegalStateException.class, + () -> new RuleIndexingController(inputStream)); + } + private static InputStream obtainDefaultIndexingMapForTest() { byte[] stringBytes = getBytes(