diff options
| author | 2023-07-26 03:37:29 +0000 | |
|---|---|---|
| committer | 2023-07-26 03:37:29 +0000 | |
| commit | 7679a1ccf66a56bb50efa902493cf805552cce6e (patch) | |
| tree | af5407a95643b00b63f5dca44572557c80cbda09 | |
| parent | 27b7e898ef5dabc08dd7274af3de813ab03488d0 (diff) | |
| parent | dd6680b6a2ff0b87179e3d6381c0bba4fb94c35c (diff) | |
Merge "Add preinstalled partition to seinfo" into udc-dev-plus-aosp am: a2163dc806 am: dd6680b6a2
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/24171318
Change-Id: Iecc8471389c0c98f42da70eaa328596fd88d39ea
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
3 files changed, 154 insertions, 27 deletions
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java index 25960062fa67..a8cdef4ec64c 100644 --- a/services/core/java/com/android/server/pm/SELinuxMMAC.java +++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java @@ -83,6 +83,8 @@ public final class SELinuxMMAC { // Append targetSdkVersion=n to existing seinfo label where n is the app's targetSdkVersion private static final String TARGETSDKVERSION_STR = ":targetSdkVersion="; + private static final String PARTITION_STR = ":partition="; + /** * Allows opt-in to the latest targetSdkVersion enforced changes without changing target SDK. * Turning this change on for an app targeting the latest SDK or higher is a no-op. @@ -373,15 +375,33 @@ public final class SELinuxMMAC { return pkg.getTargetSdkVersion(); } + private static String getPartition(PackageState state) { + if (state.isSystemExt()) { + return "system_ext"; + } else if (state.isProduct()) { + return "product"; + } else if (state.isVendor()) { + return "vendor"; + } else if (state.isOem()) { + return "oem"; + } else if (state.isOdm()) { + return "odm"; + } else if (state.isSystem()) { + return "system"; + } + return ""; + } + /** * Selects a security label to a package based on input parameters and the seinfo tag taken * from a matched policy. All signature based policy stanzas are consulted and, if no match * is found, the default seinfo label of 'default' is used. The security label is attached to * the ApplicationInfo instance of the package. * - * @param pkg object representing the package to be labeled. - * @param sharedUser if the app shares a sharedUserId, then this has the shared setting. - * @param compatibility the PlatformCompat service to ask about state of compat changes. + * @param packageState {@link PackageState} object representing the package to be labeled. + * @param pkg {@link AndroidPackage} object representing the package to be labeled. + * @param sharedUser if the app shares a sharedUserId, then this has the shared setting. + * @param compatibility the PlatformCompat service to ask about state of compat changes. * @return String representing the resulting seinfo. */ public static String getSeInfo(@NonNull PackageState packageState, @NonNull AndroidPackage pkg, @@ -393,7 +413,7 @@ public final class SELinuxMMAC { final boolean isPrivileged = (sharedUser != null) ? sharedUser.isPrivileged() | packageState.isPrivileged() : packageState.isPrivileged(); - return getSeInfo(pkg, isPrivileged, targetSdkVersion); + return getSeInfo(packageState, pkg, isPrivileged, targetSdkVersion); } /** @@ -402,15 +422,16 @@ public final class SELinuxMMAC { * is found, the default seinfo label of 'default' is used. The security label is attached to * the ApplicationInfo instance of the package. * - * @param pkg object representing the package to be labeled. - * @param isPrivileged boolean. + * @param packageState {@link PackageState} object representing the package to be labeled. + * @param pkg {@link AndroidPackage} object representing the package to be labeled. + * @param isPrivileged boolean. * @param targetSdkVersion int. If this pkg runs as a sharedUser, targetSdkVersion is the * greater of: lowest targetSdk for all pkgs in the sharedUser, or * MINIMUM_TARGETSDKVERSION. * @return String representing the resulting seinfo. */ - public static String getSeInfo(AndroidPackage pkg, boolean isPrivileged, - int targetSdkVersion) { + public static String getSeInfo(PackageState packageState, AndroidPackage pkg, + boolean isPrivileged, int targetSdkVersion) { String seInfo = null; synchronized (sPolicies) { if (!sPolicyRead) { @@ -437,8 +458,13 @@ public final class SELinuxMMAC { seInfo += TARGETSDKVERSION_STR + targetSdkVersion; + String partition = getPartition(packageState); + if (!partition.isEmpty()) { + seInfo += PARTITION_STR + partition; + } + if (DEBUG_POLICY_INSTALL) { - Slog.i(TAG, "package (" + pkg.getPackageName() + ") labeled with " + Slog.i(TAG, "package (" + packageState.getPackageName() + ") labeled with " + "seinfo=" + seInfo); } return seInfo; diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java index a037ae8ead04..9376259c08b1 100644 --- a/services/core/java/com/android/server/pm/SharedUserSetting.java +++ b/services/core/java/com/android/server/pm/SharedUserSetting.java @@ -285,7 +285,7 @@ public final class SharedUserSetting extends SettingBase implements SharedUserAp continue; } final boolean isPrivileged = isPrivileged() | ps.isPrivileged(); - ps.getPkgState().setOverrideSeInfo(SELinuxMMAC.getSeInfo(ps.getPkg(), isPrivileged, + ps.getPkgState().setOverrideSeInfo(SELinuxMMAC.getSeInfo(ps, ps.getPkg(), isPrivileged, seInfoTargetSdkVersion)); onChanged(); } diff --git a/services/tests/servicestests/src/com/android/server/pm/SELinuxMMACTest.java b/services/tests/servicestests/src/com/android/server/pm/SELinuxMMACTest.java index 77bdf198edf3..3a3ab84b1c89 100644 --- a/services/tests/servicestests/src/com/android/server/pm/SELinuxMMACTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/SELinuxMMACTest.java @@ -18,6 +18,8 @@ package com.android.server.pm; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsNot.not; +import static org.hamcrest.core.StringContains.containsString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -53,7 +55,7 @@ public class SELinuxMMACTest { @Test public void getSeInfoOptInToLatest() { - var packageState = makePackageState(Build.VERSION_CODES.P); + var packageState = new PackageStateBuilder(Build.VERSION_CODES.P).build(); when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES), argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) .thenReturn(true); @@ -64,7 +66,7 @@ public class SELinuxMMACTest { @Test public void getSeInfoOptInToR() { - var packageState = makePackageState(Build.VERSION_CODES.P); + var packageState = new PackageStateBuilder(Build.VERSION_CODES.P).build(); when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_R_CHANGES), argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) .thenReturn(true); @@ -75,7 +77,7 @@ public class SELinuxMMACTest { @Test public void getSeInfoNoOptIn() { - var packageState = makePackageState(Build.VERSION_CODES.P); + var packageState = new PackageStateBuilder(Build.VERSION_CODES.P).build(); when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES), argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) .thenReturn(false); @@ -86,7 +88,7 @@ public class SELinuxMMACTest { @Test public void getSeInfoNoOptInButAlreadyLatest() { - var packageState = makePackageState(LATEST_OPT_IN_VERSION); + var packageState = new PackageStateBuilder(LATEST_OPT_IN_VERSION).build(); when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES), argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) .thenReturn(false); @@ -97,7 +99,7 @@ public class SELinuxMMACTest { @Test public void getSeInfoTargetingCurDevelopment() { - var packageState = makePackageState(Build.VERSION_CODES.CUR_DEVELOPMENT); + var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT).build(); when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES), argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) .thenReturn(true); @@ -108,7 +110,7 @@ public class SELinuxMMACTest { @Test public void getSeInfoNoOptInButAlreadyR() { - var packageState = makePackageState(R_OPT_IN_VERSION); + var packageState = new PackageStateBuilder(R_OPT_IN_VERSION).build(); when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_R_CHANGES), argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) .thenReturn(false); @@ -119,7 +121,7 @@ public class SELinuxMMACTest { @Test public void getSeInfoOptInRButLater() { - var packageState = makePackageState(R_OPT_IN_VERSION + 1); + var packageState = new PackageStateBuilder(R_OPT_IN_VERSION + 1).build(); when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_R_CHANGES), argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) .thenReturn(true); @@ -128,15 +130,114 @@ public class SELinuxMMACTest { is("default:targetSdkVersion=" + (R_OPT_IN_VERSION + 1))); } - private PackageState makePackageState(int targetSdkVersion) { - var packageState = Mockito.mock(PackageState.class); - when(packageState.getPackageName()).thenReturn(PACKAGE_NAME); - when(packageState.getAndroidPackage()).thenReturn( - ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) - .setTargetSdkVersion(targetSdkVersion) - .hideAsParsed()) - .hideAsFinal() - ); - return packageState; + @Test + public void getSeInfoPreinstalledToSystem() { + var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT) + .setSystem(true).build(); + when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES), + argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) + .thenReturn(true); + assertThat(SELinuxMMAC.getSeInfo(packageState, packageState.getAndroidPackage(), null, + mMockCompatibility), + containsString(":partition=system")); + } + + + @Test + public void getSeInfoPreinstalledToSystemExt() { + var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT) + .setSystem(true).setSystemExt(true).build(); + when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES), + argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) + .thenReturn(true); + assertThat(SELinuxMMAC.getSeInfo(packageState, packageState.getAndroidPackage(), null, + mMockCompatibility), + containsString(":partition=system_ext")); + } + + + @Test + public void getSeInfoPreinstalledToProduct() { + var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT) + .setSystem(true).setProduct(true).build(); + when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES), + argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) + .thenReturn(true); + assertThat(SELinuxMMAC.getSeInfo(packageState, packageState.getAndroidPackage(), null, + mMockCompatibility), + containsString(":partition=product")); + } + + + @Test + public void getSeInfoPreinstalledToVendor() { + var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT) + .setSystem(true).setVendor(true).build(); + when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES), + argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) + .thenReturn(true); + assertThat(SELinuxMMAC.getSeInfo(packageState, packageState.getAndroidPackage(), null, + mMockCompatibility), + containsString(":partition=vendor")); + } + + + @Test + public void getSeInfoNotPreinstalled() { + var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT).build(); + when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES), + argThat(argument -> argument.packageName.equals(packageState.getPackageName())))) + .thenReturn(true); + assertThat(SELinuxMMAC.getSeInfo(packageState, packageState.getAndroidPackage(), null, + mMockCompatibility), + not(containsString(":partition="))); + } + + private static class PackageStateBuilder { + private final int mTargetSdkVersion; + private boolean mIsSystem = false; + private boolean mIsSystemExt = false; + private boolean mIsProduct = false; + private boolean mIsVendor = false; + + PackageStateBuilder(int targetSdkVersion) { + mTargetSdkVersion = targetSdkVersion; + } + + PackageStateBuilder setSystem(boolean isSystem) { + mIsSystem = isSystem; + return this; + } + + PackageStateBuilder setSystemExt(boolean isSystemExt) { + mIsSystemExt = isSystemExt; + return this; + } + + PackageStateBuilder setProduct(boolean isProduct) { + mIsProduct = isProduct; + return this; + } + + PackageStateBuilder setVendor(boolean isVendor) { + mIsVendor = isVendor; + return this; + } + + PackageState build() { + var packageState = Mockito.mock(PackageState.class); + when(packageState.getPackageName()).thenReturn(PACKAGE_NAME); + when(packageState.getAndroidPackage()).thenReturn( + ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) + .setTargetSdkVersion(mTargetSdkVersion) + .hideAsParsed()) + .hideAsFinal() + ); + when(packageState.isSystem()).thenReturn(mIsSystem); + when(packageState.isSystemExt()).thenReturn(mIsSystemExt); + when(packageState.isProduct()).thenReturn(mIsProduct); + when(packageState.isVendor()).thenReturn(mIsVendor); + return packageState; + } } } |