1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tests.init; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assume.assumeTrue; 21 22 import com.android.server.os.TombstoneProtos.Tombstone; 23 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 24 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; 25 import com.android.tradefed.util.CommandResult; 26 import java.io.File; 27 import java.io.FileInputStream; 28 import java.io.InputStream; 29 import java.util.Arrays; 30 import org.junit.After; 31 import org.junit.Before; 32 import org.junit.Test; 33 import org.junit.runner.RunWith; 34 35 @RunWith(DeviceJUnit4ClassRunner.class) 36 public class PermissiveMteTest extends BaseHostJUnit4Test { 37 String mUUID; 38 39 @Before setUp()40 public void setUp() throws Exception { 41 mUUID = java.util.UUID.randomUUID().toString(); 42 CommandResult result = 43 getDevice().executeShellV2Command("/data/local/tmp/mte_crash setUp " + mUUID); 44 assumeTrue("mte_crash needs to segfault", result.getExitCode() == 139); 45 } 46 parseTombstone(String tombstonePath)47 Tombstone parseTombstone(String tombstonePath) throws Exception { 48 File tombstoneFile = getDevice().pullFile(tombstonePath); 49 InputStream istr = new FileInputStream(tombstoneFile); 50 Tombstone tombstoneProto; 51 try { 52 tombstoneProto = Tombstone.parseFrom(istr); 53 } finally { 54 istr.close(); 55 } 56 return tombstoneProto; 57 } 58 59 @After tearDown()60 public void tearDown() throws Exception { 61 String[] tombstones = getDevice().getChildren("/data/tombstones"); 62 for (String tombstone : tombstones) { 63 if (!tombstone.endsWith(".pb")) { 64 continue; 65 } 66 String tombstonePath = "/data/tombstones/" + tombstone; 67 Tombstone tombstoneProto = parseTombstone(tombstonePath); 68 if (!tombstoneProto.getCommandLineList().stream().anyMatch(x -> x.contains(mUUID))) { 69 continue; 70 } 71 getDevice().deleteFile(tombstonePath); 72 // remove the non .pb file as well. 73 getDevice().deleteFile(tombstonePath.substring(0, tombstonePath.length() - 3)); 74 } 75 } 76 77 @Test testCrash()78 public void testCrash() throws Exception { 79 CommandResult result = getDevice().executeShellV2Command( 80 "MTE_PERMISSIVE=1 /data/local/tmp/mte_crash testCrash " + mUUID); 81 assertThat(result.getExitCode()).isEqualTo(0); 82 int numberTombstones = 0; 83 String[] tombstones = getDevice().getChildren("/data/tombstones"); 84 for (String tombstone : tombstones) { 85 if (!tombstone.endsWith(".pb")) { 86 continue; 87 } 88 String tombstonePath = "/data/tombstones/" + tombstone; 89 Tombstone tombstoneProto = parseTombstone(tombstonePath); 90 if (!tombstoneProto.getCommandLineList().stream().anyMatch(x -> x.contains(mUUID))) { 91 continue; 92 } 93 if (!tombstoneProto.getCommandLineList().stream().anyMatch(x -> x.contains("testCrash"))) { 94 continue; 95 } 96 numberTombstones++; 97 } 98 assertThat(numberTombstones).isEqualTo(1); 99 } 100 @Test testCrashProperty()101 public void testCrashProperty() throws Exception { 102 String prevValue = getDevice().getProperty("persist.sys.mte.permissive"); 103 if (prevValue == null) { 104 prevValue = ""; 105 } 106 assertThat(getDevice().setProperty("persist.sys.mte.permissive", "1")).isTrue(); 107 CommandResult result = 108 getDevice().executeShellV2Command("/data/local/tmp/mte_crash testCrash " + mUUID); 109 assertThat(result.getExitCode()).isEqualTo(0); 110 int numberTombstones = 0; 111 String[] tombstones = getDevice().getChildren("/data/tombstones"); 112 for (String tombstone : tombstones) { 113 if (!tombstone.endsWith(".pb")) { 114 continue; 115 } 116 String tombstonePath = "/data/tombstones/" + tombstone; 117 Tombstone tombstoneProto = parseTombstone(tombstonePath); 118 if (!tombstoneProto.getCommandLineList().stream().anyMatch(x -> x.contains(mUUID))) { 119 continue; 120 } 121 if (!tombstoneProto.getCommandLineList().stream().anyMatch(x -> x.contains("testCrash"))) { 122 continue; 123 } 124 numberTombstones++; 125 } 126 assertThat(numberTombstones).isEqualTo(1); 127 assertThat(getDevice().setProperty("persist.sys.mte.permissive", prevValue)).isTrue(); 128 } 129 } 130