Snap for 7316203 from 270b9ca26af8c8f8c76c5c3ee0b2e93181f3cd0e to rvc-platform-release
Change-Id: Id6d3acdd230c803fc38cdd94dbd0f3d87e23c60b
diff --git a/common/util/src/com/android/compatibility/common/util/CrashUtils.java b/common/util/src/com/android/compatibility/common/util/CrashUtils.java
index b397794..04051b9 100644
--- a/common/util/src/com/android/compatibility/common/util/CrashUtils.java
+++ b/common/util/src/com/android/compatibility/common/util/CrashUtils.java
@@ -24,6 +24,8 @@
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import java.math.BigInteger;
import org.json.JSONArray;
import org.json.JSONException;
@@ -45,6 +47,7 @@
public static final Pattern sNewTestPattern =
Pattern.compile(NEW_TEST_ALERT + "(\\w+?)\\(.*?\\)");
public static final String SIGNAL = "signal";
+ public static final String ABORT_MESSAGE = "abortmessage";
public static final String NAME = "name";
public static final String PROCESS = "process";
public static final String PID = "pid";
@@ -61,9 +64,9 @@
Pattern.compile(
"\\w+? \\d+? \\((.*?)\\), code -*?\\d+? \\(.*?\\), fault addr "
+ "(?:0x(\\p{XDigit}+)|-+)");
- // Matches the abort message line if it contains CHECK_
- private static Pattern sAbortMessageCheckPattern =
- Pattern.compile("(?i)Abort message.*?CHECK_");
+ // Matches the abort message line
+ private static Pattern sAbortMessagePattern =
+ Pattern.compile("(?i)Abort message: (.*)");
public static final String SIGSEGV = "SIGSEGV";
public static final String SIGBUS = "SIGBUS";
@@ -126,6 +129,24 @@
continue;
}
+ if (crash.has(ABORT_MESSAGE)) {
+ String crashAbortMessage = crash.getString(ABORT_MESSAGE);
+ if (!config.abortMessageIncludes.isEmpty()) {
+ if (!config.abortMessageIncludes.stream()
+ .filter(p -> p.matcher(crashAbortMessage).find())
+ .findFirst()
+ .isPresent()) {
+ continue;
+ }
+ }
+ if (config.abortMessageExcludes.stream()
+ .filter(p -> p.matcher(crashAbortMessage).find())
+ .findFirst()
+ .isPresent()) {
+ continue;
+ }
+ }
+
// if check specified, reject crash if address is unlikely to be security-related
if (config.checkMinAddress) {
BigInteger faultAddress = getBigInteger(crash, FAULT_ADDRESS);
@@ -163,6 +184,7 @@
String name = null;
String process = null;
String signal = null;
+ String abortMessage = null;
Matcher pidtidNameMatcher = sPidtidNamePattern.matcher(crashStr);
if (pidtidNameMatcher.find()) {
@@ -186,19 +208,24 @@
} catch (NumberFormatException e) {}
}
}
- if (!sAbortMessageCheckPattern.matcher(crashStr).find()) {
- try {
- JSONObject crash = new JSONObject();
- crash.put(PID, pid);
- crash.put(TID, tid);
- crash.put(NAME, name);
- crash.put(PROCESS, process);
- crash.put(FAULT_ADDRESS,
- faultAddress == null ? null : faultAddress.toString(16));
- crash.put(SIGNAL, signal);
- crashes.put(crash);
- } catch (JSONException e) {}
+
+ Matcher abortMessageMatcher = sAbortMessagePattern.matcher(crashStr);
+ if (abortMessageMatcher.find()) {
+ abortMessage = abortMessageMatcher.group(1);
}
+
+ try {
+ JSONObject crash = new JSONObject();
+ crash.put(PID, pid);
+ crash.put(TID, tid);
+ crash.put(NAME, name);
+ crash.put(PROCESS, process);
+ crash.put(FAULT_ADDRESS,
+ faultAddress == null ? null : faultAddress.toString(16));
+ crash.put(SIGNAL, signal);
+ crash.put(ABORT_MESSAGE, abortMessage);
+ crashes.put(crash);
+ } catch (JSONException e) {}
}
return crashes;
}
@@ -208,11 +235,15 @@
private BigInteger minCrashAddress;
private List<String> signals;
private List<Pattern> processPatterns;
+ private List<Pattern> abortMessageIncludes;
+ private List<Pattern> abortMessageExcludes;
public Config() {
checkMinAddress = true;
minCrashAddress = MIN_CRASH_ADDR;
setSignals(SIGSEGV, SIGBUS);
+ abortMessageIncludes = new ArrayList<>();
+ setAbortMessageExcludes("CHECK_", "CANNOT LINK EXECUTABLE");
processPatterns = new ArrayList();
}
@@ -236,12 +267,50 @@
return this;
}
+ public Config setAbortMessageIncludes(String... abortMessages) {
+ this.abortMessageIncludes = new ArrayList<>(toPatterns(abortMessages));
+ return this;
+ }
+
+ public Config setAbortMessageIncludes(Pattern... abortMessages) {
+ this.abortMessageIncludes = new ArrayList<>(Arrays.asList(abortMessages));
+ return this;
+ }
+
+ public Config appendAbortMessageIncludes(String... abortMessages) {
+ this.abortMessageIncludes.addAll(toPatterns(abortMessages));
+ return this;
+ }
+
+ public Config appendAbortMessageIncludes(Pattern... abortMessages) {
+ Collections.addAll(this.abortMessageIncludes, abortMessages);
+ return this;
+ }
+
+ public Config setAbortMessageExcludes(String... abortMessages) {
+ this.abortMessageExcludes = new ArrayList<>(toPatterns(abortMessages));
+ return this;
+ }
+
+ public Config setAbortMessageExcludes(Pattern... abortMessages) {
+ this.abortMessageExcludes = new ArrayList<>(Arrays.asList(abortMessages));
+ return this;
+ }
+
+ public Config appendAbortMessageExcludes(String... abortMessages) {
+ this.abortMessageExcludes.addAll(toPatterns(abortMessages));
+ return this;
+ }
+
+ public Config appendAbortMessageExcludes(Pattern... abortMessages) {
+ Collections.addAll(this.abortMessageExcludes, abortMessages);
+ return this;
+ }
+
+
public Config setProcessPatterns(String... processPatternStrings) {
- Pattern[] processPatterns = new Pattern[processPatternStrings.length];
- for (int i = 0; i < processPatternStrings.length; i++) {
- processPatterns[i] = Pattern.compile(processPatternStrings[i]);
- }
- return setProcessPatterns(processPatterns);
+ this.processPatterns = new ArrayList<>(toPatterns(processPatternStrings));
+ return this;
}
public Config setProcessPatterns(Pattern... processPatterns) {
@@ -253,9 +322,18 @@
return Collections.unmodifiableList(processPatterns);
}
+ public Config appendProcessPatterns(String... processPatternStrings) {
+ this.processPatterns.addAll(toPatterns(processPatternStrings));
+ return this;
+ }
+
public Config appendProcessPatterns(Pattern... processPatterns) {
Collections.addAll(this.processPatterns, processPatterns);
return this;
}
}
+
+ private static List<Pattern> toPatterns(String... patternStrings) {
+ return Stream.of(patternStrings).map(Pattern::compile).collect(Collectors.toList());
+ }
}
diff --git a/common/util/src/com/android/compatibility/common/util/GasTest.java b/common/util/src/com/android/compatibility/common/util/GasTest.java
index 4c3b555..1300383 100644
--- a/common/util/src/com/android/compatibility/common/util/GasTest.java
+++ b/common/util/src/com/android/compatibility/common/util/GasTest.java
@@ -25,5 +25,23 @@
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface GasTest {
+ // The GAS requirement ID the GasTest applies to.
+ // Example: @GasTest(requirement = "G-0-000")
String requirement();
+
+ // The minimum GAS software requirement version the GasTest applies to.
+ // Example: @GasTest(requirement = "G-0-000", minSoftwareVersion = 0.1)
+ double minSoftwareVersion() default 0;
+
+ // The maximum GAS software requirement version the GasTest applies to.
+ // Example: @GasTest(requirement = "G-0-000", maxSoftwareVersion = 0.1)
+ double maxSoftwareVersion() default 0;
+
+ // The minimum GAS hardware requirement version the GasTest applies to.
+ // Example: @GasTest(requirement = "G-0-000", minHardwareVersion = 0.1)
+ double minHardwareVersion() default 0;
+
+ // The maximum GAS hardware requirement version the GasTest applies to.
+ // Example: @GasTest(requirement = "G-0-000", maxHardwareVersion = 0.1)
+ double maxHardwareVersion() default 0;
}
diff --git a/common/util/tests/assets/logcat.txt b/common/util/tests/assets/logcat.txt
index b9d10d0..ffb28ad 100644
--- a/common/util/tests/assets/logcat.txt
+++ b/common/util/tests/assets/logcat.txt
@@ -229,7 +229,6 @@
05-04 21:59:23.743 9363 9363 F DEBUG : #22 pc 00000000001a1f94 /system/lib64/hw/bluetooth.default.so (run_thread(void*)+184)
05-04 21:59:23.743 9363 9363 F DEBUG : #23 pc 0000000000067d80 /system/lib64/libc.so (__pthread_start(void*)+36)
05-04 21:59:23.743 9363 9363 F DEBUG : #24 pc 000000000001ec18 /system/lib64/libc.so (__start_thread+68)
-1-25 19:47:35.417 8080 11665 F MPEG4Extractor: frameworks/av/media/libstagefright/MPEG4Extractor.cpp:6853 CHECK_EQ( (unsigned)ptr[0],1u) failed: 129 vs. 1
11-25 19:47:35.417 8080 11665 F libc : Fatal signal 6 (SIGABRT), code -6 in tid 11665 (generic)
11-25 19:47:35.487 940 940 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
11-25 19:47:35.487 940 940 F DEBUG : Build fingerprint: 'samsung/hero2qltezc/hero2qltechn:6.0.1/MMB29M/G9350ZCU2APJ6:user/release-keys'
diff --git a/common/util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java b/common/util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java
index 071733f..2d80509 100644
--- a/common/util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java
+++ b/common/util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java
@@ -54,29 +54,40 @@
public void testGetAllCrashes() throws Exception {
JSONArray expectedResults = new JSONArray();
expectedResults.put(createCrashJson(
- 11071, 11189, "AudioOut_D", "/system/bin/audioserver", "e9380000", "SIGSEGV"));
+ 11071, 11189, "AudioOut_D", "/system/bin/audioserver", "e9380000", "SIGSEGV", null));
expectedResults.put(createCrashJson(
- 12736, 12761, "Binder:12736_2", "/system/bin/audioserver", "0", "SIGSEGV"));
+ 12736, 12761, "Binder:12736_2", "/system/bin/audioserver", "0", "SIGSEGV", null));
expectedResults.put(createCrashJson(
- 26201, 26227, "Binder:26201_3", "/system/bin/audioserver", "0", "SIGSEGV"));
+ 26201, 26227, "Binder:26201_3", "/system/bin/audioserver", "0", "SIGSEGV", null));
expectedResults.put(createCrashJson(
- 26246, 26282, "Binder:26246_5", "/system/bin/audioserver", "0", "SIGSEGV"));
+ 26246, 26282, "Binder:26246_5", "/system/bin/audioserver", "0", "SIGSEGV", null));
expectedResults.put(createCrashJson(
- 245, 245, "installd", "/system/bin/installd", null, "SIGABRT"));
+ 245, 245, "installd", "/system/bin/installd", null, "SIGABRT",
+ "'utils.cpp:67] Check failed: is_valid_package_name(package_name) == 0 '"));
expectedResults.put(createCrashJson(
- 6371, 8072, "media.codec", "omx@1.0-service", "ed000000", "SIGSEGV"));
+ 6371, 8072, "media.codec", "omx@1.0-service", "ed000000", "SIGSEGV", null));
expectedResults.put(createCrashJson(
- 8373, 8414, "loo", "com.android.bluetooth", null, "SIGABRT"));
+ 8373, 8414, "loo", "com.android.bluetooth", null, "SIGABRT",
+ "'[FATAL:allocation_tracker.cc(143)] Check failed: map_entry != allocations.end()."));
expectedResults.put(createCrashJson(
- 11071, 11189, "synthetic_thread", "synthetic_process_0", "e9380000", "SIGSEGV"));
+ 8080, 11665, "generic", "/system/bin/mediaserver", null, "SIGABRT",
+ "'frameworks/av/media/libstagefright/MPEG4Extractor.cpp:6853 CHECK_EQ( (unsigned)ptr[0],1u) failed: 129 vs. 1'"));
expectedResults.put(createCrashJson(
- 12736, 12761, "synthetic_thread", "synthetic_process_1", "0", "SIGSEGV"));
+ 11071, 11189, "synthetic_thread", "synthetic_process_0", "e9380000", "SIGSEGV", null));
+ expectedResults.put(createCrashJson(
+ 12736, 12761, "synthetic_thread", "synthetic_process_1", "0", "SIGSEGV", null));
- Assert.assertEquals(mCrashes.toString(), expectedResults.toString());
+ Assert.assertEquals(expectedResults.toString() + "\n" + mCrashes.toString() + "\n", expectedResults.toString(), mCrashes.toString());
}
public JSONObject createCrashJson(
- int pid, int tid, String name, String process, String faultaddress, String signal) {
+ int pid,
+ int tid,
+ String name,
+ String process,
+ String faultaddress,
+ String signal,
+ String abortMessage) {
JSONObject json = new JSONObject();
try {
json.put(CrashUtils.PID, pid);
@@ -85,6 +96,7 @@
json.put(CrashUtils.PROCESS, process);
json.put(CrashUtils.FAULT_ADDRESS, faultaddress);
json.put(CrashUtils.SIGNAL, signal);
+ json.put(CrashUtils.ABORT_MESSAGE, abortMessage);
} catch (JSONException e) {}
return json;
}
@@ -143,9 +155,65 @@
@Test
public void testNullFaultAddress() throws Exception {
JSONArray crashes = new JSONArray();
- crashes.put(createCrashJson(8373, 8414, "loo", "com.android.bluetooth", null, "SIGSEGV"));
+ crashes.put(createCrashJson(8373, 8414, "loo", "com.android.bluetooth", null, "SIGSEGV", ""));
Assert.assertTrue(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
.checkMinAddress(true)
.setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
}
+
+ @Test
+ public void testAbortMessageInclude() throws Exception {
+ JSONArray crashes = new JSONArray();
+ crashes.put(createCrashJson(8373, 8414, "loo", "com.android.bluetooth", null, "SIGABRT",
+ "'[FATAL:allocation_tracker.cc(143)] Check failed: map_entry != allocations.end()."));
+ Assert.assertTrue(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .appendAbortMessageIncludes("Check failed:")
+ .setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
+
+ Assert.assertFalse(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .appendAbortMessageIncludes("include not matches")
+ .setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
+ }
+
+ @Test
+ public void testAbortMessageExclude() throws Exception {
+ JSONArray crashes = new JSONArray();
+ crashes.put(createCrashJson(8373, 8414, "loo", "com.android.bluetooth", null, "SIGABRT",
+ "'[FATAL:allocation_tracker.cc(143)] Check failed: map_entry != allocations.end()."));
+ Assert.assertFalse(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .appendAbortMessageExcludes("Check failed:")
+ .setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
+
+ Assert.assertTrue(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .appendAbortMessageExcludes("exclude not matches")
+ .setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
+ }
+
+ @Test
+ public void testAbortMessageExcludeCannotLink() throws Exception {
+ JSONArray crashes = new JSONArray();
+ crashes.put(createCrashJson(
+ 18959, 18959, "CVE-2020-0073", "/data/local/tmp/CVE-2020-0073", null, "SIGABRT",
+ "'CANNOT LINK EXECUTABLE \"/data/local/tmp/CVE-2020-0073\": library "
+ + "\"libnfc-nci.so\" (\"(default)\", \"/data/local/tmp/CVE-2020-0073\", \"\") "
+ + "not found'"));
+ Assert.assertFalse(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .setProcessPatterns(Pattern.compile("CVE-2020-0073"))));
+
+ crashes.put(createCrashJson(
+ 5105, 5105, "CVE-2015-6616-2", "/data/local/tmp/CVE-2015-6616-2", null, "SIGABRT",
+ "'CANNOT LINK EXECUTABLE \"/data/local/tmp/CVE-2015-6616-2\": "
+ + "cannot locate symbol \""
+ + "_ZN7android14MediaExtractor17CreateFromServiceERKNS_2spINS_10DataSourceEEEPKc"
+ + "\" referenced by \"/data/local/tmp/CVE-2015-6616-2\"...'"));
+ Assert.assertFalse(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
+ .appendSignals(CrashUtils.SIGABRT)
+ .setProcessPatterns(Pattern.compile("CVE-2015-6616-2"))));
+
+ }
}