1 /* 2 * Copyright (C) 2024 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 android.permission.cts_root; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assume.assumeTrue; 22 23 import android.content.Context; 24 import android.content.pm.PackageManager; 25 import android.content.pm.SigningDetails; 26 import android.os.Build; 27 import android.permission.flags.Flags; 28 import android.platform.test.annotations.RequiresFlagsEnabled; 29 import android.platform.test.flag.junit.CheckFlagsRule; 30 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 31 32 import androidx.annotation.NonNull; 33 import androidx.test.filters.SdkSuppress; 34 import androidx.test.platform.app.InstrumentationRegistry; 35 import androidx.test.runner.AndroidJUnit4; 36 37 import com.android.compatibility.common.util.SystemUtil; 38 import com.android.server.LocalManagerRegistry; 39 import com.android.server.permission.PermissionManagerLocal; 40 import com.android.server.pm.PackageManagerLocal; 41 import com.android.server.pm.pkg.PackageState; 42 import com.android.xts.root.annotations.RequireAdbRoot; 43 44 import org.junit.After; 45 import org.junit.Before; 46 import org.junit.BeforeClass; 47 import org.junit.Rule; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 51 import java.util.Map; 52 53 @RequireAdbRoot 54 @RunWith(AndroidJUnit4.class) 55 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = "VanillaIceCream") 56 public final class SignaturePermissionAllowlistTest { 57 private static final String NORMAL_APP_APK_PATH = "/data/local/tmp/cts-root-permission/" 58 + "CtsRootPermissionSignaturePermissionAllowlistNormalApp.apk"; 59 private static final String NORMAL_APP_PACKAGE_NAME = 60 "android.permission.cts_root.apps.signaturepermissionallowlist.normal"; 61 62 @Rule 63 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 64 65 @NonNull 66 private final PackageManagerLocal mPackageManagerLocal = 67 LocalManagerRegistry.getManager(PackageManagerLocal.class); 68 @NonNull 69 private final PermissionManagerLocal mPermissionManagerLocal = 70 LocalManagerRegistry.getManager(PermissionManagerLocal.class); 71 @NonNull 72 private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext(); 73 @NonNull 74 private final PackageManager mPackageManager = mContext.getPackageManager(); 75 76 @NonNull 77 private SigningDetails mNormalAppSigningDetails; 78 79 @BeforeClass setUpClass()80 public static void setUpClass() throws Exception { 81 assumeTrue(Build.isDebuggable()); 82 } 83 84 @Before setUp()85 public void setUp() throws Exception { 86 mPermissionManagerLocal.setSignaturePermissionAllowlistForceEnforced(true); 87 installPackage(NORMAL_APP_APK_PATH); 88 SigningDetails platformSigningDetails; 89 try (var snapshot = mPackageManagerLocal.withUnfilteredSnapshot()) { 90 Map<String, PackageState> packageStates = snapshot.getPackageStates(); 91 mNormalAppSigningDetails = packageStates.get(NORMAL_APP_PACKAGE_NAME) 92 .getAndroidPackage().getSigningDetails(); 93 platformSigningDetails = packageStates.get("android").getAndroidPackage() 94 .getSigningDetails(); 95 } 96 uninstallPackage(NORMAL_APP_PACKAGE_NAME); 97 mPackageManagerLocal.addOverrideSigningDetails(mNormalAppSigningDetails, 98 platformSigningDetails); 99 installPackage(NORMAL_APP_APK_PATH); 100 } 101 102 @After tearDown()103 public void tearDown() throws Exception { 104 uninstallPackage(NORMAL_APP_PACKAGE_NAME); 105 mPackageManagerLocal.removeOverrideSigningDetails(mNormalAppSigningDetails); 106 mPermissionManagerLocal.setSignaturePermissionAllowlistForceEnforced(false); 107 } 108 109 @RequiresFlagsEnabled(Flags.FLAG_SIGNATURE_PERMISSION_ALLOWLIST_ENABLED) 110 @Test normalAppCanNotGetSignaturePermissionWithoutAllowlist()111 public void normalAppCanNotGetSignaturePermissionWithoutAllowlist() throws Exception { 112 assertThat(mPackageManager.checkPermission(android.Manifest.permission.BRICK, 113 NORMAL_APP_PACKAGE_NAME)).isEqualTo(PackageManager.PERMISSION_DENIED); 114 } 115 116 @RequiresFlagsEnabled(Flags.FLAG_SIGNATURE_PERMISSION_ALLOWLIST_ENABLED) 117 @Test normalAppCanGetSignaturePermissionWithAllowlist()118 public void normalAppCanGetSignaturePermissionWithAllowlist() throws Exception { 119 assertThat(mPackageManager.checkPermission( 120 android.Manifest.permission.RESERVED_FOR_TESTING_SIGNATURE, 121 NORMAL_APP_PACKAGE_NAME)).isEqualTo(PackageManager.PERMISSION_GRANTED); 122 } 123 installPackage(@onNull String apkPath)124 private void installPackage(@NonNull String apkPath) throws Exception { 125 SystemUtil.runShellCommandOrThrow("pm install " + apkPath); 126 } 127 uninstallPackage(@onNull String packageName)128 private void uninstallPackage(@NonNull String packageName) throws Exception { 129 SystemUtil.runShellCommandOrThrow("pm uninstall " + packageName); 130 } 131 } 132