diff options
18 files changed, 238 insertions, 900 deletions
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING index ea21d51b0e9e..ab669cc141f1 100644 --- a/core/java/android/content/pm/TEST_MAPPING +++ b/core/java/android/content/pm/TEST_MAPPING @@ -48,9 +48,6 @@ "name":"CarrierAppIntegrationTestCases" }, { - "name":"ApkVerityTest" - }, - { "name":"CtsSilentUpdateHostTestCases" }, { diff --git a/core/java/com/android/internal/security/TEST_MAPPING b/core/java/com/android/internal/security/TEST_MAPPING index 2d598dc57613..0af3b03edefc 100644 --- a/core/java/com/android/internal/security/TEST_MAPPING +++ b/core/java/com/android/internal/security/TEST_MAPPING @@ -12,10 +12,6 @@ ] }, { - "name": "ApkVerityTest", - "file_patterns": ["VerityUtils\\.java"] - }, - { "name": "UpdatableSystemFontTest", "file_patterns": ["VerityUtils\\.java"] }, @@ -23,5 +19,11 @@ "name": "CtsApkVerityInstallHostTestCases", "file_patterns": ["VerityUtils\\.java"] } + ], + "postsubmit": [ + { + "name": "FsVerityTest", + "file_patterns": ["VerityUtils\\.java"] + } ] } diff --git a/tests/ApkVerityTest/Android.bp b/tests/ApkVerityTest/Android.bp index f026bea80470..53606a32b185 100644 --- a/tests/ApkVerityTest/Android.bp +++ b/tests/ApkVerityTest/Android.bp @@ -22,7 +22,7 @@ package { } java_test_host { - name: "ApkVerityTest", + name: "FsVerityTest", srcs: ["src/**/*.java"], libs: [ "tradefed", @@ -30,8 +30,10 @@ java_test_host { "compatibility-host-util", ], static_libs: [ + "android.security.flags-aconfig-java-host", "block_device_writer_jar", "frameworks-base-hostutils", + "flag-junit-host", ], test_suites: [ "general-tests", @@ -41,14 +43,6 @@ java_test_host { "block_device_writer", ], data: [ - ":ApkVerityTestCertDer", - ":ApkVerityTestApp", - ":ApkVerityTestAppFsvSig", - ":ApkVerityTestAppDm", - ":ApkVerityTestAppDmFsvSig", - ":ApkVerityTestAppSplit", - ":ApkVerityTestAppSplitFsvSig", - ":ApkVerityTestAppSplitDm", - ":ApkVerityTestAppSplitDmFsvSig", + ":FsVerityTestApp", ], } diff --git a/tests/ApkVerityTest/AndroidTest.xml b/tests/ApkVerityTest/AndroidTest.xml index 4487cefb4f9c..49cbde0d4611 100644 --- a/tests/ApkVerityTest/AndroidTest.xml +++ b/tests/ApkVerityTest/AndroidTest.xml @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> -<configuration description="APK fs-verity integration/regression test"> +<configuration description="fs-verity end-to-end test"> <option name="test-suite-tag" value="apct" /> <object type="module_controller" class="com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController"> @@ -24,19 +24,9 @@ <!-- This test requires root to write against block device. --> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> - <target_preparer class="com.android.tradefed.targetprep.DeviceSetup"> - <!-- Disable package verifier prevents it holding the target APK's fd that prevents cache - eviction. --> - <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" /> - <option name="restore-settings" value="true" /> - - <!-- Skip in order to prevent reboot that confuses the test flow. --> - <option name="force-skip-system-props" value="true" /> - </target_preparer> - - <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> - <option name="cleanup" value="true" /> - <option name="push" value="ApkVerityTestCert.der->/data/local/tmp/ApkVerityTestCert.der" /> + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="test-file-name" value="FsVerityTestApp.apk"/> + <option name="cleanup-apks" value="true"/> </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> @@ -48,9 +38,7 @@ <option name="push" value="block_device_writer->/data/local/tmp/block_device_writer" /> </target_preparer> - <!-- Skip on HWASan. TODO(b/232288278): Re-enable --> - <object type="module_controller" class="com.android.tradefed.testtype.suite.module.SkipHWASanModuleController" /> <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > - <option name="jar" value="ApkVerityTest.jar" /> + <option name="jar" value="FsVerityTest.jar" /> </test> </configuration> diff --git a/tests/ApkVerityTest/ApkVerityTestApp/feature_split/AndroidManifest.xml b/tests/ApkVerityTest/ApkVerityTestApp/feature_split/AndroidManifest.xml deleted file mode 100644 index 3f1a4f3a26a1..000000000000 --- a/tests/ApkVerityTest/ApkVerityTestApp/feature_split/AndroidManifest.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - --> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.apkverity" - android:isFeatureSplit="true" - split="feature_x"> - <application> - <activity android:name=".feature_x.DummyActivity"/> - </application> -</manifest> diff --git a/tests/ApkVerityTest/ApkVerityTestApp/feature_split/src/com/android/apkverity/feature_x/DummyActivity.java b/tests/ApkVerityTest/ApkVerityTestApp/feature_split/src/com/android/apkverity/feature_x/DummyActivity.java deleted file mode 100644 index fe9126003967..000000000000 --- a/tests/ApkVerityTest/ApkVerityTestApp/feature_split/src/com/android/apkverity/feature_x/DummyActivity.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.apkverity.feature_x; - -import android.app.Activity; - -/** Placeholder class just to generate some dex */ -public class DummyActivity extends Activity {} diff --git a/tests/ApkVerityTest/ApkVerityTestApp/src/com/android/apkverity/DummyActivity.java b/tests/ApkVerityTest/ApkVerityTestApp/src/com/android/apkverity/DummyActivity.java deleted file mode 100644 index a7bd771400c0..000000000000 --- a/tests/ApkVerityTest/ApkVerityTestApp/src/com/android/apkverity/DummyActivity.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.apkverity; - -import android.app.Activity; - -/** Placeholder class just to generate some dex */ -public class DummyActivity extends Activity {} diff --git a/tests/ApkVerityTest/ApkVerityTestApp/Android.bp b/tests/ApkVerityTest/FsVerityTestApp/Android.bp index adf8f9f9d321..43da3ff9fec1 100644 --- a/tests/ApkVerityTest/ApkVerityTestApp/Android.bp +++ b/tests/ApkVerityTest/FsVerityTestApp/Android.bp @@ -22,17 +22,8 @@ package { } android_test_helper_app { - name: "ApkVerityTestApp", - manifest: "AndroidManifest.xml", - srcs: ["src/**/*.java"], -} - -android_test_helper_app { - name: "ApkVerityTestAppSplit", - manifest: "feature_split/AndroidManifest.xml", - srcs: ["src/**/*.java"], - aaptflags: [ - "--custom-package com.android.apkverity.feature_x", - "--package-id 0x80", - ], + name: "FsVerityTestApp", + manifest: "AndroidManifest.xml", + srcs: ["src/**/*.java"], + static_libs: ["compatibility-device-util-axt"], } diff --git a/tests/ApkVerityTest/ApkVerityTestApp/AndroidManifest.xml b/tests/ApkVerityTest/FsVerityTestApp/AndroidManifest.xml index 0b3ff77c2cdf..42fe49be66d9 100644 --- a/tests/ApkVerityTest/ApkVerityTestApp/AndroidManifest.xml +++ b/tests/ApkVerityTest/FsVerityTestApp/AndroidManifest.xml @@ -16,8 +16,12 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.apkverity"> + package="com.android.fsverity"> <application> <activity android:name=".DummyActivity"/> </application> + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.fsverity" + android:label="Helper app of fs-verity test"> + </instrumentation>/> </manifest> diff --git a/tests/ApkVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java b/tests/ApkVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java new file mode 100644 index 000000000000..2ed4fec4a93c --- /dev/null +++ b/tests/ApkVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.fsverity; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.assertThrows; + +import android.content.Context; +import android.security.FileIntegrityManager; +import android.util.Log; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.Test; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Test helper that works with the host-side test to set up a test file, and to verify fs-verity + * verification is done expectedly. + */ +public class Helper { + private static final String TAG = "FsVerityTest"; + + private static final String FILENAME = "test.file"; + + private static final long BLOCK_SIZE = 4096; + + @Test + public void prepareTest() throws Exception { + Context context = ApplicationProvider.getApplicationContext(); + android.os.Bundle testArgs = InstrumentationRegistry.getArguments(); + + String basename = testArgs.getString("basename"); + context.deleteFile(basename); + + assertThat(testArgs).isNotNull(); + int fileSize = Integer.parseInt(testArgs.getString("fileSize")); + Log.d(TAG, "Preparing test file with size " + fileSize); + + byte[] bytes = new byte[8192]; + Arrays.fill(bytes, (byte) '1'); + try (FileOutputStream os = context.openFileOutput(basename, Context.MODE_PRIVATE)) { + for (int i = 0; i < fileSize; i += bytes.length) { + if (i + bytes.length > fileSize) { + os.write(bytes, 0, fileSize % bytes.length); + } else { + os.write(bytes); + } + } + } + + // Enable fs-verity + FileIntegrityManager fim = context.getSystemService(FileIntegrityManager.class); + fim.setupFsVerity(context.getFileStreamPath(basename)); + } + + @Test + public void verifyFileRead() throws Exception { + Context context = ApplicationProvider.getApplicationContext(); + + // Collect indices that the backing blocks are supposed to be corrupted. + android.os.Bundle testArgs = InstrumentationRegistry.getArguments(); + assertThat(testArgs).isNotNull(); + String filePath = testArgs.getString("filePath"); + String csv = testArgs.getString("brokenBlockIndicesCsv"); + Log.d(TAG, "brokenBlockIndicesCsv: " + csv); + String[] strings = csv.split(","); + var corrupted = new ArrayList(strings.length); + for (int i = 0; i < strings.length; i++) { + corrupted.add(Integer.parseInt(strings[i])); + } + + // Expect the read to succeed or fail per the prior. + try (var file = new RandomAccessFile(filePath, "r")) { + long total_blocks = (file.length() + BLOCK_SIZE - 1) / BLOCK_SIZE; + for (int i = 0; i < (int) total_blocks; i++) { + file.seek(i * BLOCK_SIZE); + if (corrupted.contains(i)) { + Log.d(TAG, "Expecting read at block #" + i + " to fail"); + assertThrows(IOException.class, () -> file.read()); + } else { + assertThat(file.readByte()).isEqualTo('1'); + } + } + } + } +} diff --git a/tests/ApkVerityTest/TEST_MAPPING b/tests/ApkVerityTest/TEST_MAPPING index 72d96148c69f..39944bed3f60 100644 --- a/tests/ApkVerityTest/TEST_MAPPING +++ b/tests/ApkVerityTest/TEST_MAPPING @@ -1,11 +1,11 @@ { - "presubmit": [ + "postsubmit": [ { - "name": "ApkVerityTest" + "name": "FsVerityTest" }, // nextgen test only runs during postsubmit. { - "name": "ApkVerityTest", + "name": "FsVerityTest", "keywords": ["nextgen"] } ] diff --git a/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java b/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java deleted file mode 100644 index 482f633e2fe1..000000000000 --- a/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.apkverity; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.platform.test.annotations.RootPermissionTest; - -import com.android.blockdevicewriter.BlockDeviceWriter; -import com.android.tradefed.device.DeviceNotAvailableException; -import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.log.LogUtil.CLog; -import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; -import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; -import com.android.tradefed.util.CommandResult; -import com.android.tradefed.util.CommandStatus; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * This test makes sure app installs with fs-verity signature, and on-access verification works. - * - * <p>When an app is installed, all or none of the files should have their corresponding .fsv_sig - * signature file. Otherwise, install will fail. - * - * <p>Once installed, file protected by fs-verity is verified by kernel every time a block is loaded - * from disk to memory. The file is immutable by design, enforced by filesystem. - * - * <p>In order to make sure a block of the file is readable only if the underlying block on disk - * stay intact, the test needs to bypass the filesystem and tampers with the corresponding physical - * address against the block device. - * - * <p>Requirements to run this test: - * <ul> - * <li>Device is rootable</li> - * <li>The filesystem supports fs-verity</li> - * <li>The feature flag is enabled</li> - * </ul> - */ -@RootPermissionTest -@RunWith(DeviceJUnit4ClassRunner.class) -public class ApkVerityTest extends BaseHostJUnit4Test { - private static final String TARGET_PACKAGE = "com.android.apkverity"; - - private static final String BASE_APK = "ApkVerityTestApp.apk"; - private static final String BASE_APK_DM = "ApkVerityTestApp.dm"; - private static final String SPLIT_APK = "ApkVerityTestAppSplit.apk"; - private static final String SPLIT_APK_DM = "ApkVerityTestAppSplit.dm"; - - private static final String INSTALLED_BASE_APK = "base.apk"; - private static final String INSTALLED_BASE_DM = "base.dm"; - private static final String INSTALLED_SPLIT_APK = "split_feature_x.apk"; - private static final String INSTALLED_SPLIT_DM = "split_feature_x.dm"; - private static final String INSTALLED_BASE_APK_FSV_SIG = "base.apk.fsv_sig"; - private static final String INSTALLED_BASE_DM_FSV_SIG = "base.dm.fsv_sig"; - private static final String INSTALLED_SPLIT_APK_FSV_SIG = "split_feature_x.apk.fsv_sig"; - private static final String INSTALLED_SPLIT_DM_FSV_SIG = "split_feature_x.dm.fsv_sig"; - - private static final String DAMAGING_EXECUTABLE = "/data/local/tmp/block_device_writer"; - private static final String CERT_PATH = "/data/local/tmp/ApkVerityTestCert.der"; - - /** Only 4K page is supported by fs-verity currently. */ - private static final int FSVERITY_PAGE_SIZE = 4096; - - private ITestDevice mDevice; - private boolean mDmRequireFsVerity; - - @Before - public void setUp() throws DeviceNotAvailableException { - mDevice = getDevice(); - mDmRequireFsVerity = "true".equals( - mDevice.getProperty("pm.dexopt.dm.require_fsverity")); - - expectRemoteCommandToSucceed("cmd file_integrity append-cert " + CERT_PATH); - uninstallPackage(TARGET_PACKAGE); - } - - @After - public void tearDown() throws DeviceNotAvailableException { - expectRemoteCommandToSucceed("cmd file_integrity remove-last-cert"); - uninstallPackage(TARGET_PACKAGE); - } - - @Test - public void testFsverityKernelSupports() throws DeviceNotAvailableException { - ITestDevice.MountPointInfo mountPoint = mDevice.getMountPointInfo("/data"); - expectRemoteCommandToSucceed("test -f /sys/fs/" + mountPoint.type + "/features/verity"); - } - - @Test - public void testInstallBase() throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG); - verifyInstalledFilesHaveFsverity(INSTALLED_BASE_APK); - } - - @Test - public void testInstallBaseWithWrongSignature() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFile(BASE_APK) - .addFile(SPLIT_APK_DM + ".fsv_sig", - BASE_APK + ".fsv_sig") - .runExpectingFailure(); - } - - @Test - public void testInstallBaseWithSplit() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .addFileAndSignature(SPLIT_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_APK_FSV_SIG); - verifyInstalledFilesHaveFsverity( - INSTALLED_BASE_APK, - INSTALLED_SPLIT_APK); - } - - @Test - public void testInstallBaseWithDm() throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG, - INSTALLED_BASE_DM, - INSTALLED_BASE_DM_FSV_SIG); - verifyInstalledFilesHaveFsverity( - INSTALLED_BASE_APK, - INSTALLED_BASE_DM); - } - - @Test - public void testInstallEverything() throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .addFileAndSignature(SPLIT_APK) - .addFileAndSignature(SPLIT_APK_DM) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG, - INSTALLED_BASE_DM, - INSTALLED_BASE_DM_FSV_SIG, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_APK_FSV_SIG, - INSTALLED_SPLIT_DM, - INSTALLED_SPLIT_DM_FSV_SIG); - verifyInstalledFilesHaveFsverity( - INSTALLED_BASE_APK, - INSTALLED_BASE_DM, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_DM); - } - - @Test - public void testInstallSplitOnly() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG); - - new InstallMultiple() - .inheritFrom(TARGET_PACKAGE) - .addFileAndSignature(SPLIT_APK) - .run(); - - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_APK_FSV_SIG); - verifyInstalledFilesHaveFsverity( - INSTALLED_BASE_APK, - INSTALLED_SPLIT_APK); - } - - @Test - public void testInstallSplitOnlyMissingSignature() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG); - - new InstallMultiple() - .inheritFrom(TARGET_PACKAGE) - .addFile(SPLIT_APK) - .runExpectingFailure(); - } - - @Test - public void testInstallSplitOnlyWithoutBaseSignature() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFile(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - verifyInstalledFiles(INSTALLED_BASE_APK); - - new InstallMultiple() - .inheritFrom(TARGET_PACKAGE) - .addFileAndSignature(SPLIT_APK) - .run(); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_APK_FSV_SIG); - } - - @Test - public void testInstallOnlyDmHasFsvSig() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFile(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .addFile(SPLIT_APK) - .addFileAndSignature(SPLIT_APK_DM) - .run(); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_DM, - INSTALLED_BASE_DM_FSV_SIG, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_DM, - INSTALLED_SPLIT_DM_FSV_SIG); - verifyInstalledFilesHaveFsverity( - INSTALLED_BASE_DM, - INSTALLED_SPLIT_DM); - } - - @Test - public void testInstallDmWithoutFsvSig_Base() - throws DeviceNotAvailableException, FileNotFoundException { - InstallMultiple installer = new InstallMultiple() - .addFile(BASE_APK) - .addFile(BASE_APK_DM) - .addFile(SPLIT_APK) - .addFileAndSignature(SPLIT_APK_DM); - if (mDmRequireFsVerity) { - installer.runExpectingFailure(); - } else { - installer.run(); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_DM, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_DM, - INSTALLED_SPLIT_DM_FSV_SIG); - verifyInstalledFilesHaveFsverity(INSTALLED_SPLIT_DM); - } - } - - @Test - public void testInstallDmWithoutFsvSig_Split() - throws DeviceNotAvailableException, FileNotFoundException { - InstallMultiple installer = new InstallMultiple() - .addFile(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .addFile(SPLIT_APK) - .addFile(SPLIT_APK_DM); - if (mDmRequireFsVerity) { - installer.runExpectingFailure(); - } else { - installer.run(); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_DM, - INSTALLED_BASE_DM_FSV_SIG, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_DM); - verifyInstalledFilesHaveFsverity(INSTALLED_BASE_DM); - } - } - - @Test - public void testInstallSomeApkIsMissingFsvSig_Base() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .addFile(SPLIT_APK) - .addFileAndSignature(SPLIT_APK_DM) - .runExpectingFailure(); - } - - @Test - public void testInstallSomeApkIsMissingFsvSig_Split() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFile(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .addFileAndSignature(SPLIT_APK) - .addFileAndSignature(SPLIT_APK_DM) - .runExpectingFailure(); - } - - @Test - public void testInstallBaseWithFsvSigThenSplitWithout() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG); - - new InstallMultiple() - .addFile(SPLIT_APK) - .runExpectingFailure(); - } - - @Test - public void testInstallBaseWithoutFsvSigThenSplitWith() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFile(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - verifyInstalledFiles(INSTALLED_BASE_APK); - - new InstallMultiple() - .addFileAndSignature(SPLIT_APK) - .runExpectingFailure(); - } - - @Test - public void testFsverityFileIsImmutableAndReadable() throws DeviceNotAvailableException { - new InstallMultiple().addFileAndSignature(BASE_APK).run(); - String apkPath = getApkPath(TARGET_PACKAGE); - - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - expectRemoteCommandToFail("echo -n '' >> " + apkPath); - expectRemoteCommandToSucceed("cat " + apkPath + " > /dev/null"); - } - - @Test - public void testFsverityFailToReadModifiedBlockAtFront() throws DeviceNotAvailableException { - new InstallMultiple().addFileAndSignature(BASE_APK).run(); - String apkPath = getApkPath(TARGET_PACKAGE); - - long apkSize = getFileSizeInBytes(apkPath); - long offsetFirstByte = 0; - - // The first two pages should be both readable at first. - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, offsetFirstByte)); - if (apkSize > offsetFirstByte + FSVERITY_PAGE_SIZE) { - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, - offsetFirstByte + FSVERITY_PAGE_SIZE)); - } - - // Damage the file directly against the block device. - damageFileAgainstBlockDevice(apkPath, offsetFirstByte); - - // Expect actual read from disk to fail but only at damaged page. - expectReadFromBlockDeviceToFail(apkPath, offsetFirstByte); - if (apkSize > offsetFirstByte + FSVERITY_PAGE_SIZE) { - long lastByteOfTheSamePage = - offsetFirstByte % FSVERITY_PAGE_SIZE + FSVERITY_PAGE_SIZE - 1; - assertFalse(BlockDeviceWriter.canReadByte(mDevice, apkPath, lastByteOfTheSamePage)); - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, lastByteOfTheSamePage + 1)); - } - } - - @Test - public void testFsverityFailToReadModifiedBlockAtBack() throws DeviceNotAvailableException { - new InstallMultiple().addFileAndSignature(BASE_APK).run(); - String apkPath = getApkPath(TARGET_PACKAGE); - - long apkSize = getFileSizeInBytes(apkPath); - long offsetOfLastByte = apkSize - 1; - - // The first two pages should be both readable at first. - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, offsetOfLastByte)); - if (offsetOfLastByte - FSVERITY_PAGE_SIZE > 0) { - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, - offsetOfLastByte - FSVERITY_PAGE_SIZE)); - } - - // Damage the file directly against the block device. - damageFileAgainstBlockDevice(apkPath, offsetOfLastByte); - - // Expect actual read from disk to fail but only at damaged page. - expectReadFromBlockDeviceToFail(apkPath, offsetOfLastByte); - if (offsetOfLastByte - FSVERITY_PAGE_SIZE > 0) { - long firstByteOfTheSamePage = offsetOfLastByte - offsetOfLastByte % FSVERITY_PAGE_SIZE; - assertFalse(BlockDeviceWriter.canReadByte(mDevice, apkPath, firstByteOfTheSamePage)); - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, firstByteOfTheSamePage - 1)); - } - } - - private void verifyInstalledFilesHaveFsverity(String... filenames) - throws DeviceNotAvailableException { - // Verify that all files are protected by fs-verity - String apkPath = getApkPath(TARGET_PACKAGE); - String appDir = apkPath.substring(0, apkPath.lastIndexOf("/")); - long kTargetOffset = 0; - for (String basename : filenames) { - String path = appDir + "/" + basename; - damageFileAgainstBlockDevice(path, kTargetOffset); - - expectReadFromBlockDeviceToFail(path, kTargetOffset); - } - } - - private void expectReadFromBlockDeviceToFail(String readPath, long offset) - throws DeviceNotAvailableException { - // Retry is sometimes needed to pass the test. Package manager may have FD leaks - // (see b/122744005 as example) that prevents the file in question to be evicted - // from filesystem cache. Forcing GC workarounds the problem. - int retry = 5; - for (; retry > 0; retry--) { - BlockDeviceWriter.dropCaches(mDevice); - if (!BlockDeviceWriter.canReadByte(mDevice, readPath, offset)) { - break; - } - try { - String openFiles = expectRemoteCommandToSucceed("lsof " + readPath); - CLog.d("lsof: " + openFiles); - Thread.sleep(1000); - forceGCOnOpenFilesProcess(getOpenFilesPIDs(openFiles)); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return; - } - } - assertTrue("Read from " + readPath + " should fail", retry > 0); - } - - /** - * This is a helper method that parses the lsof output to get PIDs of process holding FD. - * Here is an example output of lsof. This method extracts the second columns(PID). - * - * Example lsof output: - * COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME - * .example.app 1063 u0_a38 mem REG 253,6 8599 12826 example.apk - * .example.app 1063 u0_a38 99r REG 253,6 8599 12826 example.apk - */ - private Set<String> getOpenFilesPIDs(String lsof) { - Set<String> openFilesPIDs = new HashSet<>(); - String[] lines = lsof.split("\n"); - for (int i = 1; i < lines.length; i++) { - openFilesPIDs.add(lines[i].split("\\s+")[1]); - } - return openFilesPIDs; - } - - /** - * This is a helper method that forces GC on processes given their PIDs. - * That is to execute shell command "kill -10" on PIDs. - */ - private void forceGCOnOpenFilesProcess(Set<String> openFilesPIDs) - throws DeviceNotAvailableException { - for (String openFilePID : openFilesPIDs) { - mDevice.executeShellV2Command("kill -10 " + openFilePID); - } - } - - private void verifyInstalledFiles(String... filenames) throws DeviceNotAvailableException { - String apkPath = getApkPath(TARGET_PACKAGE); - String appDir = apkPath.substring(0, apkPath.lastIndexOf("/")); - // Exclude directories since we only care about files. - HashSet<String> actualFiles = new HashSet<>(Arrays.asList( - expectRemoteCommandToSucceed("ls -p " + appDir + " | grep -v '/'").split("\n"))); - - HashSet<String> expectedFiles = new HashSet<>(Arrays.asList(filenames)); - assertEquals(expectedFiles, actualFiles); - } - - private void damageFileAgainstBlockDevice(String path, long offsetOfTargetingByte) - throws DeviceNotAvailableException { - assertTrue(path.startsWith("/data/")); - ITestDevice.MountPointInfo mountPoint = mDevice.getMountPointInfo("/data"); - ArrayList<String> args = new ArrayList<>(); - args.add(DAMAGING_EXECUTABLE); - if ("f2fs".equals(mountPoint.type)) { - args.add("--use-f2fs-pinning"); - } - args.add(mountPoint.filesystem); - args.add(path); - args.add(Long.toString(offsetOfTargetingByte)); - expectRemoteCommandToSucceed(String.join(" ", args)); - } - - private String getApkPath(String packageName) throws DeviceNotAvailableException { - String line = expectRemoteCommandToSucceed("pm path " + packageName + " | grep base.apk"); - int index = line.trim().indexOf(":"); - assertTrue(index >= 0); - return line.substring(index + 1); - } - - private long getFileSizeInBytes(String packageName) throws DeviceNotAvailableException { - return Long.parseLong(expectRemoteCommandToSucceed("stat -c '%s' " + packageName).trim()); - } - - private String expectRemoteCommandToSucceed(String cmd) throws DeviceNotAvailableException { - CommandResult result = mDevice.executeShellV2Command(cmd); - assertEquals("`" + cmd + "` failed: " + result.getStderr(), CommandStatus.SUCCESS, - result.getStatus()); - return result.getStdout(); - } - - private void expectRemoteCommandToFail(String cmd) throws DeviceNotAvailableException { - CommandResult result = mDevice.executeShellV2Command(cmd); - assertTrue("Unexpected success from `" + cmd + "`: " + result.getStderr(), - result.getStatus() != CommandStatus.SUCCESS); - } - - private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> { - InstallMultiple() { - super(getDevice(), getBuild()); - } - - InstallMultiple addFileAndSignature(String filename) { - try { - addFile(filename); - addFile(filename + ".fsv_sig"); - } catch (FileNotFoundException e) { - fail("Missing test file: " + e); - } - return this; - } - } -} diff --git a/tests/ApkVerityTest/src/com/android/apkverity/BaseInstallMultiple.java b/tests/ApkVerityTest/src/com/android/apkverity/BaseInstallMultiple.java deleted file mode 100644 index 02e73d157dde..000000000000 --- a/tests/ApkVerityTest/src/com/android/apkverity/BaseInstallMultiple.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.apkverity; - -import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; -import com.android.tradefed.build.IBuildInfo; -import com.android.tradefed.device.DeviceNotAvailableException; -import com.android.tradefed.device.ITestDevice; - -import junit.framework.TestCase; - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Base class for invoking the install-multiple command via ADB. Subclass this for less typing: - * - * <code> private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> { public - * InstallMultiple() { super(getDevice(), null); } } </code> - */ -/*package*/ class BaseInstallMultiple<T extends BaseInstallMultiple<?>> { - - private final ITestDevice mDevice; - private final IBuildInfo mBuild; - - private final List<String> mArgs = new ArrayList<>(); - private final Map<File, String> mFileToRemoteMap = new HashMap<>(); - - /*package*/ BaseInstallMultiple(ITestDevice device, IBuildInfo buildInfo) { - mDevice = device; - mBuild = buildInfo; - addArg("-g"); - } - - T addArg(String arg) { - mArgs.add(arg); - return (T) this; - } - - T addFile(String filename) throws FileNotFoundException { - return addFile(filename, filename); - } - - T addFile(String filename, String remoteName) throws FileNotFoundException { - CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuild); - mFileToRemoteMap.put(buildHelper.getTestFile(filename), remoteName); - return (T) this; - } - - T inheritFrom(String packageName) { - addArg("-r"); - addArg("-p " + packageName); - return (T) this; - } - - void run() throws DeviceNotAvailableException { - run(true); - } - - void runExpectingFailure() throws DeviceNotAvailableException { - run(false); - } - - private void run(boolean expectingSuccess) throws DeviceNotAvailableException { - final ITestDevice device = mDevice; - - // Create an install session - final StringBuilder cmd = new StringBuilder(); - cmd.append("pm install-create"); - for (String arg : mArgs) { - cmd.append(' ').append(arg); - } - - String result = device.executeShellCommand(cmd.toString()); - TestCase.assertTrue(result, result.startsWith("Success")); - - final int start = result.lastIndexOf("["); - final int end = result.lastIndexOf("]"); - int sessionId = -1; - try { - if (start != -1 && end != -1 && start < end) { - sessionId = Integer.parseInt(result.substring(start + 1, end)); - } - } catch (NumberFormatException e) { - throw new IllegalStateException("Failed to parse install session: " + result); - } - if (sessionId == -1) { - throw new IllegalStateException("Failed to create install session: " + result); - } - - // Push our files into session. Ideally we'd use stdin streaming, - // but ddmlib doesn't support it yet. - for (final Map.Entry<File, String> entry : mFileToRemoteMap.entrySet()) { - final File file = entry.getKey(); - final String remoteName = entry.getValue(); - final String remotePath = "/data/local/tmp/" + file.getName(); - if (!device.pushFile(file, remotePath)) { - throw new IllegalStateException("Failed to push " + file); - } - - cmd.setLength(0); - cmd.append("pm install-write"); - cmd.append(' ').append(sessionId); - cmd.append(' ').append(remoteName); - cmd.append(' ').append(remotePath); - - result = device.executeShellCommand(cmd.toString()); - TestCase.assertTrue(result, result.startsWith("Success")); - } - - // Everything staged; let's pull trigger - cmd.setLength(0); - cmd.append("pm install-commit"); - cmd.append(' ').append(sessionId); - - result = device.executeShellCommand(cmd.toString()); - if (expectingSuccess) { - TestCase.assertTrue(result, result.contains("Success")); - } else { - TestCase.assertFalse(result, result.contains("Success")); - } - } -} diff --git a/tests/ApkVerityTest/src/com/android/fsverity/FsVerityHostTest.java b/tests/ApkVerityTest/src/com/android/fsverity/FsVerityHostTest.java new file mode 100644 index 000000000000..be479f205ff2 --- /dev/null +++ b/tests/ApkVerityTest/src/com/android/fsverity/FsVerityHostTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.fsverity; + +import static com.google.common.truth.Truth.assertThat; + +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.annotations.RootPermissionTest; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.host.HostFlagsValueProvider; +import android.security.Flags; + +import com.android.blockdevicewriter.BlockDeviceWriter; +import com.android.tradefed.device.ITestDevice; +import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; +import com.android.tradefed.testtype.junit4.DeviceTestRunOptions; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * This test verifies fs-verity works end-to-end. There is a corresponding helper app. + * + * <p>The helper app uses a FileIntegrityManager API to enable fs-verity to a file. The host test + * here * tampers with the file's backing storage, then tells the helper app to read and expect + * success/failure on read. + * + * <p>In order to make sure a block of the file is readable only if the underlying block on disk + * stay intact, the test needs to bypass the filesystem and tampers with the corresponding physical + * address against the block device. + */ +@RootPermissionTest +@RunWith(DeviceJUnit4ClassRunner.class) +@RequiresFlagsEnabled(Flags.FLAG_FSVERITY_API) +public class FsVerityHostTest extends BaseHostJUnit4Test { + private static final String TARGET_PACKAGE = "com.android.fsverity"; + + private static final String BASENAME = "test.file"; + private static final String TARGET_PATH = "/data/data/" + TARGET_PACKAGE + "/files/" + BASENAME; + + @Rule + public final CheckFlagsRule mCheckFlagsRule = + HostFlagsValueProvider.createCheckFlagsRule(this::getDevice); + + @Test + public void testFsVeritySmallFile() throws Exception { + prepareTest(10000); + + ITestDevice device = getDevice(); + BlockDeviceWriter.damageFileAgainstBlockDevice(device, TARGET_PATH, 0); + BlockDeviceWriter.damageFileAgainstBlockDevice(device, TARGET_PATH, 8192); + BlockDeviceWriter.dropCaches(device); + + verifyRead(TARGET_PATH, "0,2"); + } + + @Test + public void testFsVerityLargerFileWithOneMoreMerkleTreeLevel() throws Exception { + prepareTest(128 * 4096 + 1); + + ITestDevice device = getDevice(); + BlockDeviceWriter.damageFileAgainstBlockDevice(device, TARGET_PATH, 4096); + BlockDeviceWriter.damageFileAgainstBlockDevice(device, TARGET_PATH, 100 * 4096); + BlockDeviceWriter.damageFileAgainstBlockDevice(device, TARGET_PATH, 128 * 4096 + 1); + BlockDeviceWriter.dropCaches(device); + + verifyRead(TARGET_PATH, "1,100,128"); + } + + private void prepareTest(int fileSize) throws Exception { + DeviceTestRunOptions options = new DeviceTestRunOptions(TARGET_PACKAGE); + options.setTestClassName(TARGET_PACKAGE + ".Helper"); + options.setTestMethodName("prepareTest"); + options.addInstrumentationArg("basename", BASENAME); + options.addInstrumentationArg("fileSize", String.valueOf(fileSize)); + assertThat(runDeviceTests(options)).isTrue(); + } + + private void verifyRead(String path, String indicesCsv) throws Exception { + DeviceTestRunOptions options = new DeviceTestRunOptions(TARGET_PACKAGE); + options.setTestClassName(TARGET_PACKAGE + ".Helper"); + options.setTestMethodName("verifyFileRead"); + options.addInstrumentationArg("brokenBlockIndicesCsv", indicesCsv); + options.addInstrumentationArg("filePath", TARGET_PATH); + assertThat(runDeviceTests(options)).isTrue(); + } +} diff --git a/tests/ApkVerityTest/testdata/Android.bp b/tests/ApkVerityTest/testdata/Android.bp index ccfc4c99a347..2d578d36423d 100644 --- a/tests/ApkVerityTest/testdata/Android.bp +++ b/tests/ApkVerityTest/testdata/Android.bp @@ -37,51 +37,3 @@ filegroup { name: "ApkVerityTestCertDer", srcs: ["ApkVerityTestCert.der"], } - -filegroup { - name: "ApkVerityTestAppDm", - srcs: ["ApkVerityTestApp.dm"], -} - -filegroup { - name: "ApkVerityTestAppSplitDm", - srcs: ["ApkVerityTestAppSplit.dm"], -} - -genrule_defaults { - name: "apk_verity_sig_gen_default", - tools: ["fsverity"], - tool_files: [":ApkVerityTestKeyPem", ":ApkVerityTestCertPem"], - cmd: "$(location fsverity) sign $(in) $(out) " + - "--key=$(location :ApkVerityTestKeyPem) " + - "--cert=$(location :ApkVerityTestCertPem) " + - "> /dev/null", -} - -genrule { - name: "ApkVerityTestAppFsvSig", - defaults: ["apk_verity_sig_gen_default"], - srcs: [":ApkVerityTestApp"], - out: ["ApkVerityTestApp.apk.fsv_sig"], -} - -genrule { - name: "ApkVerityTestAppDmFsvSig", - defaults: ["apk_verity_sig_gen_default"], - srcs: [":ApkVerityTestAppDm"], - out: ["ApkVerityTestApp.dm.fsv_sig"], -} - -genrule { - name: "ApkVerityTestAppSplitFsvSig", - defaults: ["apk_verity_sig_gen_default"], - srcs: [":ApkVerityTestAppSplit"], - out: ["ApkVerityTestAppSplit.apk.fsv_sig"], -} - -genrule { - name: "ApkVerityTestAppSplitDmFsvSig", - defaults: ["apk_verity_sig_gen_default"], - srcs: [":ApkVerityTestAppSplitDm"], - out: ["ApkVerityTestAppSplit.dm.fsv_sig"], -} diff --git a/tests/ApkVerityTest/testdata/ApkVerityTestApp.dm b/tests/ApkVerityTest/testdata/ApkVerityTestApp.dm Binary files differdeleted file mode 100644 index e53a86131366..000000000000 --- a/tests/ApkVerityTest/testdata/ApkVerityTestApp.dm +++ /dev/null diff --git a/tests/ApkVerityTest/testdata/ApkVerityTestAppSplit.dm b/tests/ApkVerityTest/testdata/ApkVerityTestAppSplit.dm Binary files differdeleted file mode 100644 index 75396f1ba730..000000000000 --- a/tests/ApkVerityTest/testdata/ApkVerityTestAppSplit.dm +++ /dev/null diff --git a/tests/ApkVerityTest/testdata/README.md b/tests/ApkVerityTest/testdata/README.md deleted file mode 100644 index 163cb183a5ad..000000000000 --- a/tests/ApkVerityTest/testdata/README.md +++ /dev/null @@ -1,13 +0,0 @@ -This test only runs on rooted / debuggable device. - -The test tries to install subsets of base.{apk,dm}, split.{apk,dm} and their -corresponding .fsv_sig files (generated by build rule). If installed, the -tests also tries to tamper with the file at absolute disk offset to verify -if fs-verity is effective. - -How to generate dex metadata (.dm) -================================== - - adb shell profman --generate-test-profile=/data/local/tmp/primary.prof - adb pull /data/local/tmp/primary.prof - zip foo.dm primary.prof |